diff options
239 files changed, 17917 insertions, 7472 deletions
diff --git a/.gitignore b/.gitignore index ab1f3004f..e1f12f68c 100644 --- a/.gitignore +++ b/.gitignore @@ -10,12 +10,10 @@ .DS_Store .autotest /db/test_structure.sql -moo.txt *#*# TAGS /vendor/plugins/*theme /locale/model_attributes.rb /files/ -public/download -general.yml - +/public/download +/public/*theme diff --git a/app/controllers/admin_general_controller.rb b/app/controllers/admin_general_controller.rb index ae51e0923..0b7e9bec0 100644 --- a/app/controllers/admin_general_controller.rb +++ b/app/controllers/admin_general_controller.rb @@ -78,6 +78,10 @@ class AdminGeneralController < AdminController end def debug + @current_commit = `git log -1 --format="%H"` + @current_branch = `git branch | grep "\*" | awk '{print $2}'` + repo = `git remote show origin -n | grep Fetch | awk '{print $3}' | sed -re 's/.*:(.*).git/\\1/'` + @github_origin = "https://github.com/#{repo.strip}/tree/" @request_env = request.env end end diff --git a/app/controllers/admin_public_body_controller.rb b/app/controllers/admin_public_body_controller.rb index e249cef11..bf7c07905 100644 --- a/app/controllers/admin_public_body_controller.rb +++ b/app/controllers/admin_public_body_controller.rb @@ -27,12 +27,12 @@ class AdminPublicBodyController < AdminController end @public_bodies = PublicBody.paginate :order => "public_body_translations.name", :page => @page, :per_page => 100, :conditions => @query.nil? ? "public_body_translations.locale = '#{@locale}'" : - ["(lower(public_body_translations.name) like lower('%'||?||'%') or + ["(lower(public_body_translations.name) like lower('%'||?||'%') or lower(public_body_translations.short_name) like lower('%'||?||'%') or lower(public_body_translations.request_email) like lower('%'||?||'%' )) AND (public_body_translations.locale = '#{@locale}')", @query, @query, @query], :joins => :translations - @public_bodies_by_tag = PublicBody::Translation.find_by_tag(@query) end + @public_bodies_by_tag = PublicBody.find_by_tag(@query) end def list @@ -56,7 +56,7 @@ class AdminPublicBodyController < AdminController flash[:notice] = "Added tag to table of bodies." end - redirect_to admin_url('body/list') + "?query=" + @query + (@page.nil? ? "" : "&page=" + @page) # XXX construct this URL properly + redirect_to admin_body_list_url(:query => @query, :page => @page) end def missing_scheme @@ -127,14 +127,14 @@ class AdminPublicBodyController < AdminController if public_body.info_requests.size > 0 flash[:notice] = "There are requests associated with the authority, so can't destroy it" - redirect_to admin_url('body/show/' + public_body.id.to_s) + redirect_to admin_body_show_url(public_body) return end public_body.tag_string = "" public_body.destroy flash[:notice] = "PublicBody was successfully destroyed." - redirect_to admin_url('body/list') + redirect_to admin_body_list_url end end diff --git a/app/controllers/admin_user_controller.rb b/app/controllers/admin_user_controller.rb index 5d90e74fe..12b4e553f 100644 --- a/app/controllers/admin_user_controller.rb +++ b/app/controllers/admin_user_controller.rb @@ -45,6 +45,7 @@ class AdminUserController < AdminController @admin_user.admin_level = params[:admin_user][:admin_level] @admin_user.ban_text = params[:admin_user][:ban_text] @admin_user.about_me = params[:admin_user][:about_me] + @admin_user.no_limit = params[:admin_user][:no_limit] if @admin_user.valid? @admin_user.save! diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index b7457c48e..b681f455d 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -11,10 +11,15 @@ require 'open-uri' class ApplicationController < ActionController::Base + class PermissionDenied < StandardError + end # Standard headers, footers and navigation for whole site layout "default" include FastGettext::Translation # make functions like _, n_, N_ etc available) - + + # Send notification email on exceptions + include ExceptionNotification::Notifiable + # Note: a filter stops the chain if it redirects or renders something before_filter :authentication_check before_filter :set_gettext_locale @@ -84,6 +89,7 @@ class ApplicationController < ActionController::Base def record_memory record_memory = MySociety::Config.get('DEBUG_RECORD_MEMORY', false) if record_memory + logger.info "Processing request for #{request.url} with Rails process #{Process.pid}" File.read("/proc/#{Process.pid}/status").match(/VmRSS:\s+(\d+)/) rss_before_action = $1.to_i yield @@ -117,8 +123,11 @@ class ApplicationController < ActionController::Base case exception when ActiveRecord::RecordNotFound, ActionController::UnknownAction, ActionController::RoutingError @status = 404 + when PermissionDenied + @status = 403 else @status = 500 + notify_about_exception exception end # Display user appropriate error message @exception_backtrace = exception.backtrace.join("\n") @@ -169,11 +178,13 @@ class ApplicationController < ActionController::Base end def foi_fragment_cache_path(param) - path = foi_fragment_cache_part_path(param) - path = "/views" + path - foi_cache_path = File.join(File.dirname(__FILE__), '../../cache') - return File.join(foi_cache_path, path) + path = File.join(RAILS_ROOT, 'cache', 'views', foi_fragment_cache_part_path(param)) + max_file_length = 255 - 35 # we subtract 35 because tempfile + # adds on a variable number of + # characters + return File.join(File.split(path).map{|x| x[0...max_file_length]}) end + def foi_fragment_cache_all_for_request(info_request) # return stub path so admin can expire it first_three_digits = info_request.id.to_s()[0..2] @@ -185,10 +196,12 @@ class ApplicationController < ActionController::Base return File.exists?(key_path) end def foi_fragment_cache_read(key_path) - cached = File.read(key_path) + logger.info "Reading from fragment cache #{key_path}" + return File.read(key_path) end def foi_fragment_cache_write(key_path, content) FileUtils.mkdir_p(File.dirname(key_path)) + logger.info "Writing to fragment cache #{key_path}" File.atomic_write(key_path) do |f| f.write(content) end @@ -341,9 +354,7 @@ class ApplicationController < ActionController::Base @sortby = sortby # Work out sorting method - order_pair = order_to_sort_by(@sortby) - order = order_pair[0] - ascending = order_pair[1] + order, ascending = order_to_sort_by(@sortby) # Peform the search @per_page = per_page @@ -352,23 +363,71 @@ class ApplicationController < ActionController::Base else @page = this_page end - return InfoRequest.full_search(models, @query, order, ascending, collapse, @per_page, @page) + result = InfoRequest.full_search(models, @query, order, ascending, collapse, @per_page, @page) + result.results # Touch the results to load them, otherwise accessing them from the view + # might fail later if the database has subsequently been reopened. + return result end def get_search_page_from_params return (params[:page] || "1").to_i end + def perform_search_typeahead(query, model) + @page = get_search_page_from_params + @per_page = 10 + query_words = query.split(/ +(?![-+]+)/) + if query_words.last.nil? || query_words.last.strip.length < 3 + xapian_requests = nil + else + if model == PublicBody + collapse = nil + elsif model == InfoRequestEvent + collapse = 'request_collapse' + end + options = { + :offset => (@page - 1) * @per_page, + :limit => @per_page, + :sort_by_prefix => nil, + :sort_by_ascending => true, + :collapse_by_prefix => collapse, + } + ActsAsXapian.readable_init + old_default_op = ActsAsXapian.query_parser.default_op + ActsAsXapian.query_parser.default_op = Xapian::Query::OP_OR + begin + user_query = ActsAsXapian.query_parser.parse_query( + query.strip + '*', + Xapian::QueryParser::FLAG_LOVEHATE | Xapian::QueryParser::FLAG_WILDCARD | + Xapian::QueryParser::FLAG_SPELLING_CORRECTION) + xapian_requests = ActsAsXapian::Search.new([model], query, options, user_query) + rescue RuntimeError => e + if e.message =~ /^QueryParserError: Wildcard/ + # Wildcard expands to too many terms + logger.info "Wildcard query '#{query.strip + '*'}' caused: #{e.message}" + + user_query = ActsAsXapian.query_parser.parse_query( + query, + Xapian::QueryParser::FLAG_LOVEHATE | + Xapian::QueryParser::FLAG_SPELLING_CORRECTION) + xapian_requests = ActsAsXapian::Search.new([model], query, options, user_query) + end + end + ActsAsXapian.query_parser.default_op = old_default_op + end + return xapian_requests + end + # Store last visited pages, for contact form; but only for logged in users, as otherwise this breaks caching def set_last_request(info_request) if !session[:user_id].nil? - session[:last_request_id] = info_request.id - session[:last_body_id] = nil + cookies["last_request_id"] = info_request.id + cookies["last_body_id"] = nil end end def set_last_body(public_body) if !session[:user_id].nil? - session[:last_request_id] = nil - session[:last_body_id] = public_body.id + cookies["last_request_id"] = nil + cookies["last_body_id"] = public_body.id end end @@ -406,7 +465,7 @@ class ApplicationController < ActionController::Base params[:latest_status] = [params[:latest_status]] end if params[:latest_status].include?("recent") || params[:latest_status].include?("all") - query += " variety:sent" + query += " (variety:sent OR variety:followup_sent OR variety:response OR variety:comment)" end if params[:latest_status].include? "successful" statuses << ['latest_status:successful', 'latest_status:partially_successful'] @@ -415,7 +474,7 @@ class ApplicationController < ActionController::Base statuses << ['latest_status:rejected', 'latest_status:not_held'] end if params[:latest_status].include? "awaiting" - statuses << ['latest_status:waiting_response', 'latest_status:waiting_clarification', 'waiting_classification:true'] + statuses << ['latest_status:waiting_response', 'latest_status:waiting_clarification', 'waiting_classification:true', 'latest_status:internal_review','latest_status:gone_postal', 'latest_status:error_message', 'latest_status:requires_admin'] end if params[:latest_status].include? "internal_review" statuses << ['status:internal_review'] @@ -475,12 +534,22 @@ class ApplicationController < ActionController::Base default = MySociety::Config.get('ISO_COUNTRY_CODE', '') country = "" if !gaze.empty? - country = open("#{gaze}/gaze-rest?f=get_country_from_ip;ip=#{request.remote_ip}").read.strip + country = quietly_try_to_open("#{gaze}/gaze-rest?f=get_country_from_ip;ip=#{request.remote_ip}") end country = default if country.empty? return country end + def quietly_try_to_open(url) + begin + result = open(url).read.strip + rescue OpenURI::HTTPError, SocketError, Errno::ETIMEDOUT, Errno::ECONNREFUSED, Errno::EHOSTUNREACH + logger.warn("Unable to open third-party URL #{url}") + result = "" + end + return result + end + # URL generating functions are needed by all controllers (for redirects), # views (for links) and mailers (for use in emails), so include them into # all of all. diff --git a/app/controllers/general_controller.rb b/app/controllers/general_controller.rb index 194a1cec0..82b1b8629 100644 --- a/app/controllers/general_controller.rb +++ b/app/controllers/general_controller.rb @@ -32,12 +32,12 @@ class GeneralController < ApplicationController if body_short_names.empty? # This is too slow @popular_bodies = PublicBody.find(:all, - :select => "public_bodies.*, (select count(*) from info_requests where info_requests.public_body_id = public_bodies.id) as c", - :order => "c desc", - :limit => 32, - :conditions => conditions, - :joins => :translations - ) + :select => "public_bodies.*, (select count(*) from info_requests where info_requests.public_body_id = public_bodies.id) as c", + :order => "c desc", + :limit => 32, + :conditions => conditions, + :joins => :translations + ) else conditions[0] += " and public_bodies.url_name in (" + body_short_names + ")" @popular_bodies = PublicBody.find(:all, @@ -45,20 +45,21 @@ class GeneralController < ApplicationController :joins => :translations) end end - # Get some successful requests # + # Get some successful requests begin query = 'variety:response (status:successful OR status:partially_successful)' - # query = 'variety:response' # XXX debug - sortby = "described" + sortby = "newest" max_count = 5 xapian_object = perform_search([InfoRequestEvent], query, sortby, 'request_title_collapse', max_count) @request_events = xapian_object.results.map { |r| r[:model] } - @request_events = @request_events.sort_by { |e| e.described_at }.reverse + + # If there are not yet enough successful requests, fill out the list with + # other requests if @request_events.count < max_count query = 'variety:sent' xapian_object = perform_search([InfoRequestEvent], query, sortby, 'request_title_collapse', max_count-@request_events.count) more_events = xapian_object.results.map { |r| r[:model] } - @request_events += more_events.sort_by { |e| e.described_at }.reverse + @request_events += more_events end rescue @request_events = [] @@ -71,48 +72,34 @@ class GeneralController < ApplicationController medium_cache @feed_autodetect = [] @feed_url = "#{MySociety::Config.get('BLOG_FEED', '')}?lang=#{self.locale_from_params()}" + @blog_items = [] if not @feed_url.empty? - content = open(@feed_url).read - @data = XmlSimple.xml_in(content) - @channel = @data['channel'][0] - @blog_items = @channel['item'] - @feed_autodetect = [{:url => @feed_url, :title => "#{site_name} blog"}] - else - @blog_items = [] + content = quietly_try_to_open(@feed_url) + if !content.empty? + @data = XmlSimple.xml_in(content) + @channel = @data['channel'][0] + @blog_items = @channel['item'] + @feed_autodetect = [{:url => @feed_url, :title => "#{site_name} blog"}] + end end @twitter_user = MySociety::Config.get('TWITTER_USERNAME', '') end # Just does a redirect from ?query= search to /query def search_redirect - if params[:advanced].nil? - @query, _ = make_query_from_params - else - @query, _ = params[:query] - end - @sortby = params[:sortby] - path = request.path.split("/") - if path.size > 0 && (['newest', 'described', 'relevant'].include?(path[-1])) - @sort_postfix = path.pop - end - if path.size > 0 && (['bodies', 'requests', 'users', 'all'].include?(path[-1])) - @variety_postfix = path.pop - end - @variety_postfix = "bodies" if @variety_postfix.nil? && !params[:bodies].nil? - @variety_postfix = "requests" if @variety_postfix.nil? - if @variety_postfix != "users" - @common_query = get_tags_from_params - end - [:latest_status, :request_variety, :request_date_after, :request_date_before, :query, :tags].each do |x| - session[x] = params[x] - end + @query = params.delete(:query) if @query.nil? || @query.empty? @query = nil @page = 1 @advanced = !params[:advanced].nil? render :action => "search" else - redirect_to search_url(@query, @variety_postfix, @sort_postfix, params[:advanced]) + query_parts = @query.split("/") + if !['bodies', 'requests', 'users', 'all'].include?(query_parts[-1]) + redirect_to search_url([@query, "all"], params) + else + redirect_to search_url(@query, params) + end end end @@ -120,13 +107,6 @@ class GeneralController < ApplicationController def search # XXX Why is this so complicated with arrays and stuff? Look at the route # in config/routes.rb for comments. - if !params[:commit].nil? - search_redirect - return - end - [:latest_status, :request_variety, :request_date_after, :request_date_before, :query, :tags].each do |x| - params[x] = session[x] if params[x].nil? - end combined = params[:combined] @sortby = nil @bodies = @requests = @users = true diff --git a/app/controllers/help_controller.rb b/app/controllers/help_controller.rb index c6d246b4c..b08438b52 100644 --- a/app/controllers/help_controller.rb +++ b/app/controllers/help_controller.rb @@ -26,20 +26,20 @@ class HelpController < ApplicationController # if they clicked remove for link to request/body, remove it if params[:remove] @last_request = nil - session[:last_request_id] = nil - session[:last_body_id] = nil + cookies["last_request_id"] = nil + cookies["last_body_id"] = nil end # look up link to request/body - @last_request_id = session[:last_request_id].to_i - if @last_request_id > 0 - @last_request = InfoRequest.find(@last_request_id) + last_request_id = cookies["last_request_id"].to_i + if last_request_id > 0 + @last_request = InfoRequest.find(last_request_id) else @last_request = nil end - @last_body_id = session[:last_body_id].to_i - if @last_body_id > 0 - @last_body = PublicBody.find(@last_body_id) + last_body_id = cookies["last_body_id"].to_i + if last_body_id > 0 + @last_body = PublicBody.find(last_body_id) else @last_body = nil end diff --git a/app/controllers/public_body_controller.rb b/app/controllers/public_body_controller.rb index 62229a441..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,19 +118,22 @@ 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 @public_bodies = PublicBody.paginate( - :order => "public_body_translations.name", :page => params[:page], :per_page => 1000, # fit all councils on one page + :order => "public_body_translations.name", :page => params[:page], :per_page => 100, :conditions => conditions, :joins => :translations ) @@ -185,14 +189,8 @@ class PublicBodyController < ApplicationController def search_typeahead # Since acts_as_xapian doesn't support the Partial match flag, we work around it # by making the last work a wildcard, which is quite the same - query = params[:q] - query = query.split(' ') - if query.last.nil? || query.last.strip.length < 3 - @xapian_requests = nil - else - query = query.join(' OR ') # XXX: HACK for OR instead of default AND! - @xapian_requests = perform_search([PublicBody], query, 'relevant', nil, 5) - end + query = params[:query] + @xapian_requests = perform_search_typeahead(query, PublicBody) render :partial => "public_body/search_ahead" end end diff --git a/app/controllers/request_controller.rb b/app/controllers/request_controller.rb index dad5e81cd..2295d6718 100644 --- a/app/controllers/request_controller.rb +++ b/app/controllers/request_controller.rb @@ -13,6 +13,9 @@ require 'open-uri' class RequestController < ApplicationController before_filter :check_read_only, :only => [ :new, :show_response, :describe_state, :upload_response ] protect_from_forgery :only => [ :new, :show_response, :describe_state, :upload_response ] # See ActionController::RequestForgeryProtection for details + + MAX_RESULTS = 500 + PER_PAGE = 25 @@custom_states_loaded = false begin @@ -35,11 +38,9 @@ class RequestController < ApplicationController # do nothing - as "authenticated?" has done the redirect to signin page for us return end - if !params[:query].nil? - query = params[:query] + '*' - query = query.split(' ').join(' OR ') # XXX: HACK for OR instead of default AND! - @xapian_requests = perform_search([PublicBody], query, 'relevant', nil, 5) + query = params[:query] + @xapian_requests = perform_search_typeahead(query, PublicBody) end medium_cache end @@ -73,8 +74,9 @@ class RequestController < ApplicationController @info_request_events = @info_request.info_request_events @status = @info_request.calculate_status @collapse_quotes = params[:unfold] ? false : true - @update_status = params[:update_status] ? true : false + @update_status = params[:update_status] ? true : false @old_unclassified = @info_request.is_old_unclassified? && !authenticated_user.nil? + @is_owning_user = @info_request.is_owning_user?(authenticated_user) if @update_status return if !@is_owning_user && !authenticated_as_user?(@info_request.user, @@ -107,7 +109,6 @@ class RequestController < ApplicationController # For send followup link at bottom @last_response = @info_request.get_last_response - @is_owning_user = @info_request.is_owning_user?(authenticated_user) respond_to do |format| format.html { @has_json = true; render :template => 'request/show'} format.json { render :json => @info_request.json_for_api(true) } @@ -119,11 +120,14 @@ class RequestController < ApplicationController def details long_cache @info_request = InfoRequest.find_by_url_title(params[:url_title]) - if !@info_request.user_can_view?(authenticated_user) - render :template => 'request/hidden', :status => 410 # gone - return + if @info_request.nil? + raise ActiveRecord::RecordNotFound.new("Request not found") + else + if !@info_request.user_can_view?(authenticated_user) + render :template => 'request/hidden', :status => 410 # gone + return + end end - @columns = ['id', 'event_type', 'created_at', 'described_state', 'last_described_at', 'calculated_state' ] end @@ -150,15 +154,26 @@ class RequestController < ApplicationController def list medium_cache @view = params[:view] + @page = get_search_page_from_params if !@page # used in cache case, as perform_search sets @page as side effect + if @view == "recent" + return redirect_to request_list_all_path(:action => "list", :view => "all", :page => @page), :status => :moved_permanently + end + + # Later pages are very expensive to load + if @page > MAX_RESULTS / PER_PAGE + raise ActiveRecord::RecordNotFound.new("Sorry. No pages after #{MAX_RESULTS / PER_PAGE}.") + end + params[:latest_status] = @view query = make_query_from_params @title = _("View and search requests") sortby = "newest" - @page = get_search_page_from_params if !@page # used in cache case, as perform_search sets @page as side effect - behavior_cache :tag => [@view, @page] do + @cache_tag = Digest::MD5.hexdigest(query + @page.to_s) + behavior_cache :tag => [@cache_tag] do xapian_object = perform_search([InfoRequestEvent], query, sortby, 'request_collapse') @list_results = xapian_object.results.map { |r| r[:model] } @matches_estimated = xapian_object.matches_estimated + @show_no_more_than = (@matches_estimated > MAX_RESULTS) ? MAX_RESULTS : @matches_estimated end @title = @title + " (page " + @page.to_s + ")" if (@page > 1) @@ -192,14 +207,28 @@ class RequestController < ApplicationController end # Banned from making new requests? + user_exceeded_limit = false if !authenticated_user.nil? && !authenticated_user.can_file_requests? - @details = authenticated_user.can_fail_html - render :template => 'user/banned' - return + # If the reason the user cannot make new requests is that they are + # rate-limited, it’s possible they composed a request before they + # logged in and we want to include the text of the request so they + # can squirrel it away for tomorrow, so we detect this later after + # we have constructed the InfoRequest. + user_exceeded_limit = authenticated_user.exceeded_limit? + if !user_exceeded_limit + @details = authenticated_user.can_fail_html + render :template => 'user/banned' + return + end end # First time we get to the page, just display it if params[:submitted_new_request].nil? || params[:reedit] + if user_exceeded_limit + render :template => 'user/rate_limited' + return + end + params[:info_request] = { } if !params[:info_request] # Read parameters in - first the public body (by URL name or id) @@ -299,6 +328,11 @@ class RequestController < ApplicationController return end + if user_exceeded_limit + render :template => 'user/rate_limited' + return + end + if !authenticated?( :web => _("To send your FOI request"), :email => _("Then your FOI request to {{public_body_name}} will be sent.",:public_body_name=>@info_request.public_body.name), @@ -602,7 +636,9 @@ class RequestController < ApplicationController def authenticate_attachment # Test for hidden incoming_message = IncomingMessage.find(params[:incoming_message_id]) + raise ActiveRecord::RecordNotFound.new("Message not found") if incoming_message.nil? if !incoming_message.info_request.user_can_view?(authenticated_user) + @info_request = incoming_message.info_request # used by view render :template => 'request/hidden', :status => 410 # gone end end @@ -615,8 +651,8 @@ class RequestController < ApplicationController else key = params.merge(:only_path => true) key_path = foi_fragment_cache_path(key) - if foi_fragment_cache_exists?(key_path) + raise PermissionDenied.new("Directory listing not allowed") if File.directory?(key_path) cached = foi_fragment_cache_read(key_path) response.content_type = AlaveteliFileTypes.filename_to_mimetype(params[:file_name].join("/")) || 'application/octet-stream' render_for_text(cached) @@ -676,10 +712,15 @@ class RequestController < ApplicationController # Internal function def get_attachment_internal(html_conversion) @incoming_message = IncomingMessage.find(params[:incoming_message_id]) + @requested_request = InfoRequest.find(params[:id]) @incoming_message.parse_raw_email! @info_request = @incoming_message.info_request if @incoming_message.info_request_id != params[:id].to_i - raise sprintf("Incoming message %d does not belong to request %d", @incoming_message.info_request_id, params[:id]) + # Note that params[:id] might not be an integer, though + # if we’ve got this far then it must begin with an integer + # and that integer must be the id number of an actual request. + message = "Incoming message %d does not belong to request '%s'" % [@incoming_message.info_request_id, params[:id]] + raise ActiveRecord::RecordNotFound.new(message) end @part_number = params[:part].to_i @filename = params[:file_name].join("/") @@ -756,13 +797,7 @@ class RequestController < ApplicationController # Since acts_as_xapian doesn't support the Partial match flag, we work around it # by making the last work a wildcard, which is quite the same query = params[:q] - query = query.split(' ') - if query.last.nil? || query.last.strip.length < 3 - @xapian_requests = nil - else - query = query.join(' OR ') # XXX: HACK for OR instead of default AND! - @xapian_requests = perform_search([InfoRequestEvent], query, 'relevant', 'request_collapse', 5) - end + @xapian_requests = perform_search_typeahead(query, InfoRequestEvent) render :partial => "request/search_ahead.rhtml" end @@ -815,7 +850,8 @@ class RequestController < ApplicationController for message in info_request.incoming_messages attachments = message.get_attachments_for_display for attachment in attachments - zipfile.get_output_stream(attachment.display_filename) { |f| + filename = "#{attachment.url_part_number}_#{attachment.display_filename}" + zipfile.get_output_stream(filename) { |f| f.puts(attachment.body) } end diff --git a/app/controllers/services_controller.rb b/app/controllers/services_controller.rb index 6fb20336e..225790d71 100644 --- a/app/controllers/services_controller.rb +++ b/app/controllers/services_controller.rb @@ -1,12 +1,4 @@ -# controllers/application.rb: -# Parent class of all controllers in FOI site. Filters added to this controller -# apply to all controllers in the application. Likewise, all the methods added -# will be available for all controllers. -# -# Copyright (c) 2007 UK Citizens Online Democracy. All rights reserved. -# Email: francis@mysociety.org; WWW: http://www.mysociety.org/ -# -# $Id: application.rb,v 1.59 2009-09-17 13:01:56 francis Exp $ +# controllers/services_controller.rb: require 'open-uri' diff --git a/app/controllers/track_controller.rb b/app/controllers/track_controller.rb index e06701a5f..e39a0489d 100644 --- a/app/controllers/track_controller.rb +++ b/app/controllers/track_controller.rb @@ -46,7 +46,14 @@ class TrackController < ApplicationController # Track all updates to a particular public body def track_public_body - @public_body = PublicBody.find_by_url_name(params[:url_name]) + @public_body = PublicBody.find_by_url_name_with_historic(params[:url_name]) + raise ActiveRecord::RecordNotFound.new("None found") if @public_body.nil? + # If found by historic name, or alternate locale name, redirect to new name + if @public_body.url_name != params[:url_name] + redirect_to track_public_body_url(:url_name => @public_body.url_name, :feed => params[:feed]) + return + end + @track_thing = TrackThing.create_track_for_public_body(@public_body) return atom_feed_internal if params[:feed] == 'feed' diff --git a/app/controllers/user_controller.rb b/app/controllers/user_controller.rb index 96dbfba74..f49fc9165 100644 --- a/app/controllers/user_controller.rb +++ b/app/controllers/user_controller.rb @@ -23,7 +23,17 @@ class UserController < ApplicationController redirect_to :url_name => MySociety::Format.simplify_url_part(params[:url_name], 'user', 32), :status => :moved_permanently return end - + if params[:view].nil? + @show_requests = true + @show_profile = true + elsif params[:view] == 'profile' + @show_profile = true + @show_requests = false + elsif params[:view] == 'requests' + @show_profile = false + @show_requests = true + end + @display_user = User.find(:first, :conditions => [ "url_name = ? and email_confirmed = ?", params[:url_name], true ]) if not @display_user raise ActiveRecord::RecordNotFound.new("user not found, url_name=" + params[:url_name]) @@ -34,31 +44,33 @@ class UserController < ApplicationController # Use search query for this so can collapse and paginate easily # XXX really should just use SQL query here rather than Xapian. - begin - requests_query = 'requested_by:' + @display_user.url_name - comments_query = 'commented_by:' + @display_user.url_name - if !params[:user_query].nil? - requests_query += " " + params[:user_query] - comments_query += " " + params[:user_query] - @match_phrase = _("{{search_results}} matching '{{query}}'", :search_results => "", :query => params[:user_query]) - end - @xapian_requests = perform_search([InfoRequestEvent], requests_query, 'newest', 'request_collapse') - @xapian_comments = perform_search([InfoRequestEvent], comments_query, 'newest', nil) - - if (@page > 1) - @page_desc = " (page " + @page.to_s + ")" - else - @page_desc = "" + if @show_requests + begin + requests_query = 'requested_by:' + @display_user.url_name + comments_query = 'commented_by:' + @display_user.url_name + if !params[:user_query].nil? + requests_query += " " + params[:user_query] + comments_query += " " + params[:user_query] + @match_phrase = _("{{search_results}} matching '{{query}}'", :search_results => "", :query => params[:user_query]) + end + @xapian_requests = perform_search([InfoRequestEvent], requests_query, 'newest', 'request_collapse') + @xapian_comments = perform_search([InfoRequestEvent], comments_query, 'newest', nil) + + if (@page > 1) + @page_desc = " (page " + @page.to_s + ")" + else + @page_desc = "" + end + rescue + @xapian_requests = nil + @xapian_comments = nil end - rescue - @xapian_requests = nil - @xapian_comments = nil - end - # Track corresponding to this page - @track_thing = TrackThing.create_track_for_user(@display_user) - @feed_autodetect = [ { :url => do_track_url(@track_thing, 'feed'), :title => @track_thing.params[:title_in_rss], :has_json => true } ] + # Track corresponding to this page + @track_thing = TrackThing.create_track_for_user(@display_user) + @feed_autodetect = [ { :url => do_track_url(@track_thing, 'feed'), :title => @track_thing.params[:title_in_rss], :has_json => true } ] + end # All tracks for the user if @is_you @track_things = TrackThing.find(:all, :conditions => ["tracking_user_id = ? and track_medium = ?", @display_user.id, 'email_daily'], :order => 'created_at desc') @@ -104,8 +116,10 @@ class UserController < ApplicationController render :action => 'sign' return else - @user_signin = User.authenticate_from_form(params[:user_signin], @post_redirect.reason_params[:user_name] ? true : false) - if @user_signin.errors.size > 0 + if !@post_redirect.nil? + @user_signin = User.authenticate_from_form(params[:user_signin], @post_redirect.reason_params[:user_name] ? true : false) + end + if @post_redirect.nil? || @user_signin.errors.size > 0 # Failed to authenticate render :action => 'sign' return @@ -475,7 +489,8 @@ class UserController < ApplicationController raise ActiveRecord::RecordNotFound.new("user not found, url_name=" + params[:url_name]) end if !@display_user.profile_photo - raise "user has no profile photo, url_name=" + params[:url_name] + raise ActiveRecord::RecordNotFound.new("user has no profile photo, url_name=" + params[:url_name]) + end response.content_type = "image/png" diff --git a/app/helpers/link_to_helper.rb b/app/helpers/link_to_helper.rb index 5866c31f0..56c33e512 100755 --- a/app/helpers/link_to_helper.rb +++ b/app/helpers/link_to_helper.rb @@ -136,9 +136,19 @@ module LinkToHelper end # General pages. - def search_url(query, variety_postfix = nil, sort_postfix = nil, advanced = nil) - query = query - ["", nil] if query.kind_of?(Array) - url = search_general_url(:combined => query) + def search_url(query, params = nil) + if query.kind_of?(Array) + query = query - ["", nil] + query = query.join("/") + end + routing_info = {:controller => 'general', + :action => 'search', + :combined => query, + :view => nil} + if !params.nil? + routing_info = params.merge(routing_info) + end + url = url_for(routing_info) # Here we can't escape the slashes, as RFC 2396 doesn't allow slashes # within a path component. Rails is assuming when generating URLs that # either there aren't slashes, or we are in a query part where you can @@ -150,19 +160,10 @@ module LinkToHelper # http://rails.lighthouseapp.com/projects/8994/tickets/144-patch-bug-in-rails-route-globbing url = url.gsub("%2F", "/") - if !variety_postfix.nil? && !variety_postfix.empty? - url = url + "/" + variety_postfix - end - if !sort_postfix.nil? && !sort_postfix.empty? - url = url + "/" + sort_postfix - end - if !advanced.nil? && (advanced) - url = url + "/advanced" - end return url end def search_link(query, variety_postfix = nil, sort_postfix = nil, advanced = nil) - link_to h(query), search_url(query, variety_postfix, sort_postfix, advanced) + link_to h(query), search_url(query) end # Admin pages @@ -189,10 +190,14 @@ module LinkToHelper url_prefix = "http://" + MySociety::Config.get("DOMAIN", '127.0.0.1:3000') url = url_prefix + relative_path if !append.nil? - env = Rack::MockRequest.env_for(url) - req = Rack::Request.new(env) - req.path_info += append - url = req.url + begin + env = Rack::MockRequest.env_for(url) + req = Rack::Request.new(env) + req.path_info += append + url = req.url + rescue URI::InvalidURIError + # don't append to it + end end return url end diff --git a/app/models/about_me_validator.rb b/app/models/about_me_validator.rb index ec2b03201..e24c5512c 100644 --- a/app/models/about_me_validator.rb +++ b/app/models/about_me_validator.rb @@ -21,7 +21,7 @@ class AboutMeValidator < ActiveRecord::BaseWithoutTable def validate if !self.about_me.blank? && self.about_me.size > 500 - errors.add(_("Please keep it shorter than 500 characters")) + errors.add(:about_me, _("Please keep it shorter than 500 characters")) end end diff --git a/app/models/censor_rule.rb b/app/models/censor_rule.rb index e2dc12d6f..201e60746 100644 --- a/app/models/censor_rule.rb +++ b/app/models/censor_rule.rb @@ -1,12 +1,12 @@ # == Schema Information -# Schema version: 95 +# Schema version: 108 # # Table name: censor_rules # # id :integer not null, primary key -# info_request_id :integer -# user_id :integer -# public_body_id :integer +# info_request_id :integer +# user_id :integer +# public_body_id :integer # text :text not null # replacement :text not null # last_edit_editor :string(255) not null diff --git a/app/models/change_email_validator.rb b/app/models/change_email_validator.rb index f7ec6d17e..e3f8fa892 100644 --- a/app/models/change_email_validator.rb +++ b/app/models/change_email_validator.rb @@ -1,11 +1,12 @@ # == Schema Information -# Schema version: 95 +# Schema version: 108 # # Table name: change_email_validators # -# old_email :string -# new_email :string -# password :string +# old_email :string +# new_email :string +# password :string +# user_circumstance :string # # models/changeemail_validator.rb: diff --git a/app/models/comment.rb b/app/models/comment.rb index b7ece9ba9..44a1079cd 100644 --- a/app/models/comment.rb +++ b/app/models/comment.rb @@ -1,16 +1,17 @@ # == Schema Information -# Schema version: 95 +# Schema version: 108 # # Table name: comments # # id :integer not null, primary key # user_id :integer not null # comment_type :string(255) default("internal_error"), not null -# info_request_id :integer +# info_request_id :integer # body :text not null -# visible :boolean default(true), not null +# visible :boolean default(TRUE), not null # created_at :datetime not null # updated_at :datetime not null +# locale :text default(""), not null # # models/comments.rb: diff --git a/app/models/exim_log.rb b/app/models/exim_log.rb index 83f031a92..77e5e2d21 100644 --- a/app/models/exim_log.rb +++ b/app/models/exim_log.rb @@ -1,11 +1,11 @@ # == Schema Information -# Schema version: 95 +# Schema version: 108 # # Table name: exim_logs # # id :integer not null, primary key -# exim_log_done_id :integer -# info_request_id :integer +# exim_log_done_id :integer +# info_request_id :integer # order :integer not null # line :text not null # created_at :datetime not null diff --git a/app/models/foi_attachment.rb b/app/models/foi_attachment.rb index 057dcdb69..da92d1c2d 100644 --- a/app/models/foi_attachment.rb +++ b/app/models/foi_attachment.rb @@ -1,3 +1,19 @@ +# == Schema Information +# Schema version: 108 +# +# Table name: foi_attachments +# +# id :integer not null, primary key +# content_type :text +# filename :text +# charset :text +# display_size :text +# url_part_number :integer +# within_rfc822_subject :text +# incoming_message_id :integer +# hexdigest :string(32) +# + # encoding: UTF-8 # models/foi_attachment.rb: @@ -18,8 +34,15 @@ class FoiAttachment < ActiveRecord::Base before_validation :ensure_filename!, :only => [:filename] before_destroy :delete_cached_file! + BODY_MAX_TRIES = 3 + BODY_MAX_DELAY = 5 + def directory - base_dir = File.join("cache", "attachments_#{ENV['RAILS_ENV']}") + rails_env = ENV['RAILS_ENV'] + if rails_env.nil? || rails_env.empty? + raise "$RAILS_ENV is not set" + end + base_dir = File.join(File.dirname(__FILE__), "../../cache", "attachments_#{rails_env}") return File.join(base_dir, self.hexdigest[0..2]) end @@ -29,6 +52,7 @@ class FoiAttachment < ActiveRecord::Base def delete_cached_file! begin + @cached_body = nil File.delete(self.filepath) rescue end @@ -43,11 +67,29 @@ class FoiAttachment < ActiveRecord::Base file.write d } update_display_size! + @cached_body = d end def body if @cached_body.nil? - @cached_body = File.open(self.filepath, "rb" ).read + tries = 0 + delay = 1 + begin + @cached_body = File.open(self.filepath, "rb" ).read + rescue Errno::ENOENT + # we've lost our cached attachments for some reason. Reparse them. + if tries > BODY_MAX_TRIES + raise + else + sleep delay + end + tries += 1 + delay *= 2 + delay = BODY_MAX_DELAY if delay > BODY_MAX_DELAY + force = true + self.incoming_message.parse_raw_email!(force) + retry + end end return @cached_body end @@ -274,13 +316,9 @@ class FoiAttachment < ActiveRecord::Base tempfile.flush if self.content_type == 'application/pdf' - IO.popen("/usr/bin/pdftohtml -nodrm -zoom 1.0 -stdout -enc UTF-8 -noframes " + tempfile.path + "", "r") do |child| - html = child.read() - end + html = AlaveteliExternalCommand.run("pdftohtml", "-nodrm", "-zoom", "1.0", "-stdout", "-enc", "UTF-8", "-noframes", tempfile.path) elsif self.content_type == 'application/rtf' - IO.popen("/usr/bin/unrtf --html " + tempfile.path + "", "r") do |child| - html = child.read() - end + html = AlaveteliExternalCommand.run("unrtf", "--html", tempfile.path) elsif self.has_google_docs_viewer? html = '' # force error and using Google docs viewer else @@ -302,7 +340,7 @@ class FoiAttachment < ActiveRecord::Base body = $1.to_s body_without_tags = body.gsub(/\s+/,"").gsub(/\<[^\>]*\>/, "") contains_images = html.match(/<img/mi) ? true : false - if !$?.success? || html.size == 0 || (body_without_tags.size == 0 && !contains_images) + if html.size == 0 || !$?.success? || (body_without_tags.size == 0 && !contains_images) ret = "<html><head></head><body>"; if self.has_google_docs_viewer? wrapper_id = "wrapper_google_embed" diff --git a/app/models/holiday.rb b/app/models/holiday.rb index 4674d58f1..60b5ff443 100644 --- a/app/models/holiday.rb +++ b/app/models/holiday.rb @@ -1,11 +1,11 @@ # == Schema Information -# Schema version: 95 +# Schema version: 108 # # Table name: holidays # # id :integer not null, primary key -# day :date -# description :text +# day :date +# description :text # # models/holiday.rb: diff --git a/app/models/incoming_message.rb b/app/models/incoming_message.rb index a4519a17d..131970ba6 100644 --- a/app/models/incoming_message.rb +++ b/app/models/incoming_message.rb @@ -1,7 +1,5 @@ -# encoding: UTF-8 - # == Schema Information -# Schema version: 95 +# Schema version: 108 # # Table name: incoming_messages # @@ -10,11 +8,19 @@ # created_at :datetime not null # updated_at :datetime not null # raw_email_id :integer not null -# cached_attachment_text_clipped :text -# cached_main_body_text_folded :text -# cached_main_body_text_unfolded :text +# cached_attachment_text_clipped :text +# cached_main_body_text_folded :text +# cached_main_body_text_unfolded :text +# sent_at :time +# subject :text +# mail_from_domain :text +# valid_to_reply_to :boolean +# last_parsed :datetime +# mail_from :text # +# encoding: UTF-8 + # models/incoming_message.rb: # An (email) message from really anybody to be logged with a request. e.g. A # response from the public body. @@ -44,275 +50,6 @@ module TMail end end -# This is the type which is used to send data about attachments to the view -class FOIAttachment - attr_accessor :body - attr_accessor :content_type - attr_accessor :filename - attr_accessor :url_part_number - attr_accessor :within_rfc822_subject # we use the subject as the filename for email attachments - - # List of DSN codes taken from RFC 3463 - # http://tools.ietf.org/html/rfc3463 - DsnToMessage = { - 'X.1.0' => 'Other address status', - 'X.1.1' => 'Bad destination mailbox address', - 'X.1.2' => 'Bad destination system address', - 'X.1.3' => 'Bad destination mailbox address syntax', - 'X.1.4' => 'Destination mailbox address ambiguous', - 'X.1.5' => 'Destination mailbox address valid', - 'X.1.6' => 'Mailbox has moved', - 'X.1.7' => 'Bad sender\'s mailbox address syntax', - 'X.1.8' => 'Bad sender\'s system address', - 'X.2.0' => 'Other or undefined mailbox status', - 'X.2.1' => 'Mailbox disabled, not accepting messages', - 'X.2.2' => 'Mailbox full', - 'X.2.3' => 'Message length exceeds administrative limit.', - 'X.2.4' => 'Mailing list expansion problem', - 'X.3.0' => 'Other or undefined mail system status', - 'X.3.1' => 'Mail system full', - 'X.3.2' => 'System not accepting network messages', - 'X.3.3' => 'System not capable of selected features', - 'X.3.4' => 'Message too big for system', - 'X.4.0' => 'Other or undefined network or routing status', - 'X.4.1' => 'No answer from host', - 'X.4.2' => 'Bad connection', - 'X.4.3' => 'Routing server failure', - 'X.4.4' => 'Unable to route', - 'X.4.5' => 'Network congestion', - 'X.4.6' => 'Routing loop detected', - 'X.4.7' => 'Delivery time expired', - 'X.5.0' => 'Other or undefined protocol status', - 'X.5.1' => 'Invalid command', - 'X.5.2' => 'Syntax error', - 'X.5.3' => 'Too many recipients', - 'X.5.4' => 'Invalid command arguments', - 'X.5.5' => 'Wrong protocol version', - 'X.6.0' => 'Other or undefined media error', - 'X.6.1' => 'Media not supported', - 'X.6.2' => 'Conversion required and prohibited', - 'X.6.3' => 'Conversion required but not supported', - 'X.6.4' => 'Conversion with loss performed', - 'X.6.5' => 'Conversion failed', - 'X.7.0' => 'Other or undefined security status', - 'X.7.1' => 'Delivery not authorized, message refused', - 'X.7.2' => 'Mailing list expansion prohibited', - 'X.7.3' => 'Security conversion required but not possible', - 'X.7.4' => 'Security features not supported', - 'X.7.5' => 'Cryptographic failure', - 'X.7.6' => 'Cryptographic algorithm not supported', - 'X.7.7' => 'Message integrity failure' - } - - # Returns HTML, of extra comment to put by attachment - def extra_note - # For delivery status notification attachments, extract the status and - # look up what it means in the DSN table. - if @content_type == 'message/delivery-status' - if !@body.match(/Status:\s+([0-9]+\.([0-9]+\.[0-9]+))\s+/) - return "" - end - dsn = $1 - dsn_part = 'X.' + $2 - - dsn_message = "" - if DsnToMessage.include?(dsn_part) - dsn_message = " (" + DsnToMessage[dsn_part] + ")" - end - - return "<br><em>DSN: " + dsn + dsn_message + "</em>" - end - return "" - end - - # Called by controller so old filenames still work - def old_display_filename - filename = self._internal_display_filename - - # Convert weird spaces (e.g. \n) to normal ones - filename = filename.gsub(/\s/, " ") - # Remove slashes, they mess with URLs - filename = filename.gsub(/\//, "-") - - return filename - end - - # XXX changing this will break existing URLs, so have a care - maybe - # make another old_display_filename see above - def display_filename - filename = self._internal_display_filename - - # Sometimes filenames have e.g. %20 in - no point butchering that - # (without unescaping it, this would remove the % and leave 20s in there) - filename = CGI.unescape(filename) - - # Remove weird spaces - filename = filename.gsub(/\s+/, " ") - # Remove non-alphabetic characters - filename = filename.gsub(/[^A-Za-z0-9.]/, " ") - # Remove spaces near dots - filename = filename.gsub(/\s*\.\s*/, ".") - # Compress adjacent spaces down to a single one - filename = filename.gsub(/\s+/, " ") - filename = filename.strip - - return filename - end - - def _internal_display_filename - calc_ext = AlaveteliFileTypes.mimetype_to_extension(@content_type) - - if @filename - # Put right extension on if missing - if !filename.match(/\.#{calc_ext}$/) && calc_ext - filename + "." + calc_ext - else - filename - end - else - if !calc_ext - calc_ext = "bin" - end - if @within_rfc822_subject - @within_rfc822_subject + "." + calc_ext - else - "attachment." + calc_ext - end - end - end - - # Size to show next to the download link for the attachment - def display_size - s = self.body.size - - if s > 1024 * 1024 - return sprintf("%.1f", s.to_f / 1024 / 1024) + 'M' - else - return (s / 1024).to_s + 'K' - end - end - - # Whether this type can be shown in the Google Docs Viewer. - # The full list of supported types can be found at - # https://docs.google.com/support/bin/answer.py?hl=en&answer=1189935 - def has_google_docs_viewer? - return !! { - "application/pdf" => true, # .pdf - "image/tiff" => true, # .tiff - - "application/vnd.ms-word" => true, # .doc - "application/vnd.openxmlformats-officedocument.wordprocessingml.document" => true, # .docx - - "application/vnd.ms-powerpoint" => true, # .ppt - "application/vnd.openxmlformats-officedocument.presentationml.presentation" => true, # .pptx - - "application/vnd.ms-excel" => true, # .xls - "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" => true, # .xlsx - - } [self.content_type] - end - - # Whether this type has a "View as HTML" - def has_body_as_html? - return ( - !!{ - "text/plain" => true, - "application/rtf" => true, - }[self.content_type] or - self.has_google_docs_viewer? - ) - end - - # Name of type of attachment type - only valid for things that has_body_as_html? - def name_of_content_type - return { - "text/plain" => "Text file", - 'application/rtf' => "RTF file", - - 'application/pdf' => "PDF file", - 'image/tiff' => "TIFF image", - - 'application/vnd.ms-word' => "Word document", - 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' => "Word document", - - 'application/vnd.ms-powerpoint' => "PowerPoint presentation", - 'application/vnd.openxmlformats-officedocument.presentationml.presentation' => "PowerPoint presentation", - - 'application/vnd.ms-excel' => "Excel spreadsheet", - 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' => "Excel spreadsheet", - }[self.content_type] - end - - # For "View as HTML" of attachment - def body_as_html(dir) - html = nil - wrapper_id = "wrapper" - - # simple cases, can never fail - if self.content_type == 'text/plain' - text = self.body.strip - text = CGI.escapeHTML(text) - text = MySociety::Format.make_clickable(text) - html = text.gsub(/\n/, '<br>') - return '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" - "http://www.w3.org/TR/html4/loose.dtd"><html><head><title></title></head><body>' + html + "</body></html>", wrapper_id - end - - # the extractions will also produce image files, which go in the - # current directory, so change to the directory the function caller - # wants everything in - Dir.chdir(dir) do - tempfile = Tempfile.new('foiextract', '.') - tempfile.print self.body - tempfile.flush - - if self.content_type == 'application/pdf' - IO.popen("#{`which pdftohtml`.chomp} -nodrm -zoom 1.0 -stdout -enc UTF-8 -noframes " + tempfile.path + "", "r") do |child| - html = child.read() - end - elsif self.content_type == 'application/rtf' - IO.popen("/usr/bin/unrtf --html " + tempfile.path + "", "r") do |child| - html = child.read() - end - elsif self.has_google_docs_viewer? - html = '' # force error and using Google docs viewer - else - raise "No HTML conversion available for type " + self.content_type - end - - tempfile.close - tempfile.delete - end - - # We need to look at: - # a) Any error code - # b) The output size, as pdftohtml does not return an error code upon error. - # c) For cases when there is no text in the body of the HTML, or - # images, so nothing will be rendered. This is to detect some bug in - # pdftohtml, which sometimes makes it return just <hr>s and no other - # content. - html.match(/(\<body[^>]*\>.*)/mi) - body = $1.to_s - body_without_tags = body.gsub(/\s+/,"").gsub(/\<[^\>]*\>/, "") - contains_images = html.match(/<img/mi) ? true : false - if !$?.success? || html.size == 0 || (body_without_tags.size == 0 && !contains_images) - ret = "<html><head></head><body>"; - if self.has_google_docs_viewer? - wrapper_id = "wrapper_google_embed" - ret = ret + "<iframe src='http://docs.google.com/viewer?url=<attachment-url-here>&embedded=true' width='100%' height='100%' style='border: none;'></iframe>"; - else - ret = ret + "<p>Sorry, we were unable to convert this file to HTML. Please use the download link at the top right.</p>" - end - ret = ret + "</body></html>" - return ret, wrapper_id - end - - return html, wrapper_id - end - -end - - class IncomingMessage < ActiveRecord::Base belongs_to :info_request validates_presence_of :info_request @@ -380,7 +117,7 @@ class IncomingMessage < ActiveRecord::Base if !self.mail['return-path'].nil? && self.mail['return-path'].addr == "<>" return false end - if !self.mail['auto-submitted'].nil? && !self.mail['auto-submitted'].keys.empty? + if !self.mail['auto-submitted'].nil? return false end return true @@ -390,22 +127,27 @@ class IncomingMessage < ActiveRecord::Base # The following fields may be absent; we treat them as cached # values in case we want to regenerate them (due to mail # parsing bugs, etc). + if self.raw_email.nil? + raise "Incoming message id=#{id} has no raw_email" + end if (!force.nil? || self.last_parsed.nil?) - self.extract_attachments! - self.sent_at = self.mail.date || self.created_at - self.subject = self.mail.subject - # XXX can probably remove from_name_if_present (which is a - # monkey patch) by just calling .from_addrs[0].name here - # instead? - self.mail_from = self.mail.from_name_if_present - begin - self.mail_from_domain = PublicBody.extract_domain_from_email(self.mail.from_addrs[0].spec) - rescue NoMethodError - self.mail_from_domain = "" + ActiveRecord::Base.transaction do + self.extract_attachments! + self.sent_at = self.mail.date || self.created_at + self.subject = self.mail.subject + # XXX can probably remove from_name_if_present (which is a + # monkey patch) by just calling .from_addrs[0].name here + # instead? + self.mail_from = self.mail.from_name_if_present + begin + self.mail_from_domain = PublicBody.extract_domain_from_email(self.mail.from_addrs[0].spec) + rescue NoMethodError + self.mail_from_domain = "" + end + self.valid_to_reply_to = self._calculate_valid_to_reply_to + self.last_parsed = Time.now + self.save! end - self.valid_to_reply_to = self._calculate_valid_to_reply_to - self.last_parsed = Time.now - self.save! end end @@ -527,11 +269,7 @@ class IncomingMessage < ActiveRecord::Base # Special cases for some content types if content_type == 'application/pdf' uncompressed_text = nil - IO.popen("#{`which pdftk`.chomp} - output - uncompress", "r+") do |child| - child.write(text) - child.close_write() - uncompressed_text = child.read() - end + uncompressed_text = AlaveteliExternalCommand.run("pdftk", "-", "output", "-", "uncompress", :stdin_string => text) # if we managed to uncompress the PDF... if !uncompressed_text.nil? && !uncompressed_text.empty? # then censor stuff (making a copy so can compare again in a bit) @@ -542,15 +280,11 @@ class IncomingMessage < ActiveRecord::Base # then use the altered file (recompressed) recompressed_text = nil if MySociety::Config.get('USE_GHOSTSCRIPT_COMPRESSION') == true - command = "gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/screen -dNOPAUSE -dQUIET -dBATCH -sOutputFile=- -" + command = ["gs", "-sDEVICE=pdfwrite", "-dCompatibilityLevel=1.4", "-dPDFSETTINGS=/screen", "-dNOPAUSE", "-dQUIET", "-dBATCH", "-sOutputFile=-", "-"] else - command = "#{`which pdftk`.chomp} - output - compress" - end - IO.popen(command, "r+") do |child| - child.write(censored_uncompressed_text) - child.close_write() - recompressed_text = child.read() + command = ["pdftk", "-", "output", "-", "compress"] end + recompressed_text = AlaveteliExternalCommand.run(*(command + [{:stdin_string=>censored_uncompressed_text}])) if recompressed_text.nil? || recompressed_text.empty? # buggy versions of pdftk sometimes fail on # compression, I don't see it's a disaster in @@ -586,8 +320,8 @@ class IncomingMessage < ActiveRecord::Base emails = ascii_chars.scan(MySociety::Validate.email_find_regexp) # Convert back to UCS-2, making a mask at the same time emails.map! {|email| [ - Iconv.conv('ucs-2', 'ascii', email[0]), - Iconv.conv('ucs-2', 'ascii', email[0].gsub(/[^@.]/, 'x')) + Iconv.conv('ucs-2le', 'ascii', email[0]), + Iconv.conv('ucs-2le', 'ascii', email[0].gsub(/[^@.]/, 'x')) ] } # Now search and replace the UCS-2 email with the UCS-2 mask for email, mask in emails @@ -792,7 +526,7 @@ class IncomingMessage < ActiveRecord::Base # it into conflict with ensure_parts_counted which it has to be # called both before and after. It will fail with cases of # attachments of attachments etc. - + charset = curr_mail.charset # save this, because overwriting content_type also resets charset # Don't allow nil content_types if curr_mail.content_type.nil? curr_mail.content_type = 'application/octet-stream' @@ -822,7 +556,6 @@ class IncomingMessage < ActiveRecord::Base curr_mail.content_type = 'application/octet-stream' end end - # If the part is an attachment of email if curr_mail.content_type == 'message/rfc822' || curr_mail.content_type == 'application/vnd.ms-outlook' || curr_mail.content_type == 'application/ms-tnef' ensure_parts_counted # fills in rfc822_attachment variable @@ -832,6 +565,8 @@ class IncomingMessage < ActiveRecord::Base curr_mail.within_rfc822_attachment = within_rfc822_attachment leaves_found += [curr_mail] end + # restore original charset + curr_mail.charset = charset end return leaves_found end @@ -887,64 +622,58 @@ class IncomingMessage < ActiveRecord::Base end # Returns body text from main text part of email, converted to UTF-8 def get_main_body_text_internal + parse_raw_email! main_part = get_main_body_text_part return _convert_part_body_to_text(main_part) end + # Given a main text part, converts it to text def _convert_part_body_to_text(part) if part.nil? text = "[ Email has no body, please see attachments ]" - text_charset = "utf-8" + source_charset = "utf-8" else - text = part.body - text_charset = part.charset + text = part.body # by default, TMail converts to UTF8 in this call + source_charset = part.charset if part.content_type == 'text/html' # e.g. http://www.whatdotheyknow.com/request/35/response/177 - # XXX This is a bit of a hack as it is calling a convert to text routine. - # Could instead call a sanitize HTML one. - text = self.class._get_attachment_text_internal_one_file(part.content_type, text) - end - end - - # Charset conversion, turn everything into UTF-8 - if not text_charset.nil? - begin - # XXX specially convert unicode pound signs, was needed here - # http://www.whatdotheyknow.com/request/88/response/352 - text = text.gsub("£", Iconv.conv(text_charset, 'utf-8', '£')) - # Try proper conversion - text = Iconv.conv('utf-8', text_charset, text) - rescue Iconv::IllegalSequence, Iconv::InvalidEncoding - # Clearly specified charset was nonsense - text_charset = nil + # XXX This is a bit of a hack as it is calling a + # convert to text routine. Could instead call a + # sanitize HTML one. + + # If the text isn't UTF8, it means TMail had a problem + # converting it (invalid characters, etc), and we + # should instead tell elinks to respect the source + # charset + use_charset = "utf-8" + begin + text = Iconv.conv('utf-8', 'utf-8', text) + rescue Iconv::IllegalSequence + use_charset = source_charset + end + text = self.class._get_attachment_text_internal_one_file(part.content_type, text, use_charset) end end - if text_charset.nil? - # No specified charset, so guess - - # Could use rchardet here, but it had trouble with - # http://www.whatdotheyknow.com/request/107/response/144 - # So I gave up - most likely in UK we'll only get windows-1252 anyway. + # If TMail can't convert text, it just returns it, so we sanitise it. + begin + # Test if it's good UTF-8 + text = Iconv.conv('utf-8', 'utf-8', text) + rescue Iconv::IllegalSequence + # Text looks like unlabelled nonsense, + # strip out anything that isn't UTF-8 begin - # See if it is good UTF-8 anyway - text = Iconv.conv('utf-8', 'utf-8', text) - rescue Iconv::IllegalSequence - begin - # Or is it good windows-1252, most likely - text = Iconv.conv('utf-8', 'windows-1252', text) - rescue Iconv::IllegalSequence - # Text looks like unlabelled nonsense, strip out anything that isn't UTF-8 - text = Iconv.conv('utf-8//IGNORE', 'utf-8', text) + - _("\n\n[ {{site_name}} note: The above text was badly encoded, and has had strange characters removed. ]", - :site_name => MySociety::Config.get('SITE_NAME', 'Alaveteli')) + text = Iconv.conv('utf-8//IGNORE', source_charset, text) + + _("\n\n[ {{site_name}} note: The above text was badly encoded, and has had strange characters removed. ]", + :site_name => MySociety::Config.get('SITE_NAME', 'Alaveteli')) + rescue Iconv::InvalidEncoding, Iconv::IllegalSequence + if source_charset != "utf-8" + source_charset = "utf-8" + retry end end end - # An assertion that we have ended up with UTF-8 XXX can remove as this should - # always be fine if code above is - Iconv.conv('utf-8', 'utf-8', text) # Fix DOS style linefeeds to Unix style ones (or other later regexps won't work) # Needed for e.g. http://www.whatdotheyknow.com/request/60/response/98 @@ -1004,9 +733,7 @@ class IncomingMessage < ActiveRecord::Base tempfile = Tempfile.new('foiuu') tempfile.print uu tempfile.flush - IO.popen("/usr/bin/uudecode " + tempfile.path + " -o -", "r") do |child| - content = child.read() - end + content = AlaveteliExternalCommand.run("uudecode", "-o", "/dev/stdout", tempfile.path) tempfile.close # Make attachment type from it, working out filename and mime type filename = uu.match(/^begin\s+[0-9]+\s+(.*)$/)[1] @@ -1192,7 +919,9 @@ class IncomingMessage < ActiveRecord::Base return self.cached_attachment_text_clipped end - def IncomingMessage._get_attachment_text_internal_one_file(content_type, body) + def IncomingMessage._get_attachment_text_internal_one_file(content_type, body, charset = 'utf-8') + # note re. charset: TMail always tries to convert email bodies + # to UTF8 by default, so normally it should already be that. text = '' # XXX - tell all these command line tools to return utf-8 if content_type == 'text/plain' @@ -1202,22 +931,23 @@ class IncomingMessage < ActiveRecord::Base tempfile.print body tempfile.flush if content_type == 'application/vnd.ms-word' - AlaveteliExternalCommand.run(`which wvText`.chomp, tempfile.path, tempfile.path + ".txt") + AlaveteliExternalCommand.run("wvText", tempfile.path, tempfile.path + ".txt") # Try catdoc if we get into trouble (e.g. for InfoRequestEvent 2701) if not File.exists?(tempfile.path + ".txt") - AlaveteliExternalCommand.run(`which catdoc`.chomp, tempfile.path, :append_to => text) + AlaveteliExternalCommand.run("catdoc", tempfile.path, :append_to => text) else text += File.read(tempfile.path + ".txt") + "\n\n" File.unlink(tempfile.path + ".txt") end elsif content_type == 'application/rtf' # catdoc on RTF prodcues less comments and extra bumf than --text option to unrtf - AlaveteliExternalCommand.run(`which catdoc`.chomp, tempfile.path, :append_to => text) + AlaveteliExternalCommand.run("catdoc", tempfile.path, :append_to => text) elsif content_type == 'text/html' - # lynx wordwraps links in its output, which then don't get formatted properly - # by Alaveteli. We use elinks instead, which doesn't do that. - AlaveteliExternalCommand.run(`which elinks`.chomp, "-eval", "'set document.codepage.assume = \"utf-8\"'", "-dump-charset", "utf-8", "-force-html", "-dump", - tempfile.path, :append_to => text) + # lynx wordwraps links in its output, which then don't + # get formatted properly by Alaveteli. We use elinks + # instead, which doesn't do that. + AlaveteliExternalCommand.run("elinks", "-eval", "set document.codepage.assume = \"#{charset}\"", "-eval", "set document.codepage.force_assumed = 1", "-dump-charset", "utf-8", "-force-html", "-dump", + tempfile.path, :append_to => text, :env => {"LANG" => "C"}) elsif content_type == 'application/vnd.ms-excel' # Bit crazy using /usr/bin/strings - but xls2csv, xlhtml and # py_xls2txt only extract text from cells, not from floating @@ -1227,9 +957,9 @@ class IncomingMessage < ActiveRecord::Base elsif content_type == 'application/vnd.ms-powerpoint' # ppthtml seems to catch more text, but only outputs HTML when # we want text, so just use catppt for now - AlaveteliExternalCommand.run(`which catppt`.chomp, tempfile.path, :append_to => text) + AlaveteliExternalCommand.run("catppt", tempfile.path, :append_to => text) elsif content_type == 'application/pdf' - AlaveteliExternalCommand.run(`which pdftotext`.chomp, tempfile.path, "-", :append_to => text) + AlaveteliExternalCommand.run("pdftotext", tempfile.path, "-", :append_to => text) elsif content_type == 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' # This is Microsoft's XML office document format. # Just pull out the main XML file, and strip it of text. @@ -1283,7 +1013,7 @@ class IncomingMessage < ActiveRecord::Base text = '' attachments = self.get_attachments_for_display for attachment in attachments - text += IncomingMessage._get_attachment_text_internal_one_file(attachment.content_type, attachment.body) + text += IncomingMessage._get_attachment_text_internal_one_file(attachment.content_type, attachment.body, attachment.charset) end # Remove any bad characters text = Iconv.conv('utf-8//IGNORE', 'utf-8', text) @@ -1376,7 +1106,7 @@ class IncomingMessage < ActiveRecord::Base if !self.mail['return-path'].nil? && self.mail['return-path'].addr == "<>" return false end - if !self.mail['auto-submitted'].nil? && !self.mail['auto-submitted'].keys.empty? + if !self.mail['auto-submitted'].nil? return false end return true diff --git a/app/models/info_request.rb b/app/models/info_request.rb index cfef6ebd8..b5a1cd833 100644 --- a/app/models/info_request.rb +++ b/app/models/info_request.rb @@ -1,6 +1,5 @@ - # == Schema Information -# Schema version: 95 +# Schema version: 108 # # Table name: info_requests # @@ -11,23 +10,17 @@ # created_at :datetime not null # updated_at :datetime not null # described_state :string(255) not null -# awaiting_description :boolean default(false), not null +# awaiting_description :boolean default(FALSE), not null # prominence :string(255) default("normal"), not null # url_title :text not null # law_used :string(255) default("foi"), not null # allow_new_responses_from :string(255) default("anybody"), not null # handle_rejected_responses :string(255) default("bounce"), not null +# idhash :string(255) not null # -# models/info_request.rb: -# A Freedom of Information request. -# -# Copyright (c) 2007 UK Citizens Online Democracy. All rights reserved. -# Email: francis@mysociety.org; WWW: http://www.mysociety.org/ -# -# $Id: info_request.rb,v 1.217 2009-10-26 17:52:39 francis Exp $ + require 'digest/sha1' -require File.join(File.dirname(__FILE__),'../../vendor/plugins/acts_as_xapian/lib/acts_as_xapian') class InfoRequest < ActiveRecord::Base strip_attributes! diff --git a/app/models/info_request_event.rb b/app/models/info_request_event.rb index 4ea89bf81..99f34cf9e 100644 --- a/app/models/info_request_event.rb +++ b/app/models/info_request_event.rb @@ -1,5 +1,5 @@ # == Schema Information -# Schema version: 95 +# Schema version: 108 # # Table name: info_request_events # @@ -8,12 +8,12 @@ # event_type :text not null # params_yaml :text not null # created_at :datetime not null -# described_state :string(255) -# calculated_state :string(255) -# last_described_at :datetime -# incoming_message_id :integer -# outgoing_message_id :integer -# comment_id :integer +# described_state :string(255) +# calculated_state :string(255) +# last_described_at :datetime +# incoming_message_id :integer +# outgoing_message_id :integer +# comment_id :integer # prominence :string(255) default("normal"), not null # @@ -109,7 +109,7 @@ class InfoRequestEvent < ActiveRecord::Base [ :tags, 'U', "tag" ] ], :if => :indexed_by_search?, - :eager_load => [ :incoming_message, :outgoing_message, :comment, { :info_request => [ :user, :public_body, :censor_rules ] } ] + :eager_load => [ :outgoing_message, :comment, { :info_request => [ :user, :public_body, :censor_rules ] } ] def requested_by self.info_request.user.url_name @@ -147,6 +147,7 @@ class InfoRequestEvent < ActiveRecord::Base return event.calculated_state end end + return end def waiting_classification @@ -175,7 +176,41 @@ class InfoRequestEvent < ActiveRecord::Base # format it here as no datetime support in Xapian's value ranges return self.created_at.strftime("%Y%m%d%H%M%S") end - # clipped = true - means return shorter text. It is used for snippets for + + def incoming_message_selective_columns(fields) + message = IncomingMessage.find(:all, + :select => fields + ", incoming_messages.info_request_id", + :joins => "INNER JOIN info_request_events ON incoming_messages.id = incoming_message_id ", + :conditions => "info_request_events.id = #{self.id}" + ) + message = message[0] + if !message.nil? + message.info_request = InfoRequest.find(message.info_request_id) + end + return message + end + + def get_clipped_response_efficiently + # XXX this ugly code is an attempt to not always load all the + # columns for an incoming message, which can be *very* large + # (due to all the cached text). We care particularly in this + # case because it's called for every search result on a page + # (to show the search snippet). Actually, we should review if we + # need all this data to be cached in the database at all, and + # then we won't need this horrid workaround. + message = self.incoming_message_selective_columns("cached_attachment_text_clipped, cached_main_body_text_folded") + clipped_body = message.cached_main_body_text_folded + clipped_attachment = message.cached_attachment_text_clipped + if clipped_body.nil? || clipped_attachment.nil? + # we're going to have to load it anyway + text = self.incoming_message.get_text_for_indexing_clipped + else + text = clipped_body.gsub("FOLDED_QUOTED_SECTION", " ").strip + "\n\n" + clipped_attachment + end + return text + "\n\n" + end + + # clipped = true - means return shorter text. It is used for snippets fore # performance reasons. Xapian will take the full text. def search_text_main(clipped = false) text = '' @@ -185,7 +220,7 @@ class InfoRequestEvent < ActiveRecord::Base text = text + self.outgoing_message.get_text_for_indexing + "\n\n" elsif self.event_type == 'response' if clipped - text = text + self.incoming_message.get_text_for_indexing_clipped + "\n\n" + text = text + self.get_clipped_response_efficiently else text = text + self.incoming_message.get_text_for_indexing_full + "\n\n" end @@ -295,7 +330,7 @@ class InfoRequestEvent < ActiveRecord::Base end - def is_incoming_message?() not self.incoming_message.nil? end + def is_incoming_message?() not self.incoming_message_selective_columns("incoming_messages.id").nil? end def is_outgoing_message?() not self.outgoing_message.nil? end def is_comment?() not self.comment.nil? end diff --git a/app/models/outgoing_message.rb b/app/models/outgoing_message.rb index b7e310b1e..cc561b21d 100644 --- a/app/models/outgoing_message.rb +++ b/app/models/outgoing_message.rb @@ -1,5 +1,5 @@ # == Schema Information -# Schema version: 95 +# Schema version: 108 # # Table name: outgoing_messages # @@ -10,8 +10,8 @@ # message_type :string(255) not null # created_at :datetime not null # updated_at :datetime not null -# last_sent_at :datetime -# incoming_message_followup_id :integer +# last_sent_at :datetime +# incoming_message_followup_id :integer # what_doing :string(255) not null # diff --git a/app/models/post_redirect.rb b/app/models/post_redirect.rb index b111d019d..59cc86799 100644 --- a/app/models/post_redirect.rb +++ b/app/models/post_redirect.rb @@ -1,17 +1,17 @@ # == Schema Information -# Schema version: 95 +# Schema version: 108 # # Table name: post_redirects # # id :integer not null, primary key # token :text not null # uri :text not null -# post_params_yaml :text +# post_params_yaml :text # created_at :datetime not null # updated_at :datetime not null # email_token :text not null -# reason_params_yaml :text -# user_id :integer +# reason_params_yaml :text +# user_id :integer # circumstance :text default("normal"), not null # diff --git a/app/models/profile_photo.rb b/app/models/profile_photo.rb index b15e3e4f4..43dbbbf0a 100644 --- a/app/models/profile_photo.rb +++ b/app/models/profile_photo.rb @@ -1,12 +1,12 @@ # == Schema Information -# Schema version: 95 +# Schema version: 108 # # Table name: profile_photos # # id :integer not null, primary key # data :binary not null -# user_id :integer -# draft :boolean default(false), not null +# user_id :integer +# draft :boolean default(FALSE), not null # # models/profile_photo.rb: diff --git a/app/models/public_body.rb b/app/models/public_body.rb index 453e3a6cf..961fa3cbb 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 @@ -395,7 +395,7 @@ class PublicBody < ActiveRecord::Base field_list = ['name', 'short_name', 'request_email', 'notes', 'publication_scheme', 'home_page', 'tag_string'] - if public_body = bodies_by_name[name] # Existing public body + if public_body = bodies_by_name[name] # Existing public body available_locales.each do |locale| PublicBody.with_locale(locale) do changed = ActiveSupport::OrderedHash.new diff --git a/app/models/raw_email.rb b/app/models/raw_email.rb index c6066cbf4..3e12a6feb 100644 --- a/app/models/raw_email.rb +++ b/app/models/raw_email.rb @@ -1,11 +1,10 @@ # == Schema Information -# Schema version: 95 +# Schema version: 108 # # Table name: raw_emails # -# id :integer not null, primary key -# data_text :text -# data_binary :binary +# id :integer not null, primary key +# # models/raw_email.rb: # The fat part of models/incoming_message.rb @@ -28,7 +27,7 @@ class RawEmail < ActiveRecord::Base def directory request_id = self.incoming_message.info_request.id.to_s if ENV["RAILS_ENV"] == "test" - return 'files/raw_email_test' + return File.join(RAILS_ROOT, 'files/raw_email_test') else return File.join(MySociety::Config.get('RAW_EMAILS_LOCATION', 'files/raw_emails'), @@ -44,41 +43,19 @@ class RawEmail < ActiveRecord::Base if !File.exists?(self.directory) FileUtils.mkdir_p self.directory end - File.open(self.filepath, "wb") { |file| + File.atomic_write(self.filepath) { |file| file.write d } end def data - if !File.exists?(self.filepath) - dbdata - else - File.open(self.filepath, "rb" ).read - end + File.open(self.filepath, "rb").read end def destroy_file_representation! File.delete(self.filepath) end - def dbdata=(d) - write_attribute(:data_binary, d) - end - - def dbdata - d = read_attribute(:data_binary) - if !d.nil? - return d - end - - d = read_attribute(:data_text) - if !d.nil? - return d - end - - raise "internal error, double nil value in RawEmail" - end - end diff --git a/app/models/request_mailer.rb b/app/models/request_mailer.rb index 272f2ea83..83cce9045 100644 --- a/app/models/request_mailer.rb +++ b/app/models/request_mailer.rb @@ -353,7 +353,18 @@ class RequestMailer < ApplicationMailer # That that patch has not been applied, despite bribes of beer, is # typical of the lack of quality of Rails. - info_requests = InfoRequest.find(:all, :conditions => [ "(select id from info_request_events where event_type = 'comment' and info_request_events.info_request_id = info_requests.id and created_at > ? limit 1) is not null", Time.now() - 1.month ], :include => [ { :info_request_events => :user_info_request_sent_alerts } ], :order => "info_requests.id, info_request_events.created_at" ) + info_requests = InfoRequest.find(:all, + :conditions => [ + "info_requests.id in ( + select info_request_id + from info_request_events + where event_type = 'comment' + and created_at > (now() - '1 month'::interval) + )" + ], + :include => [ { :info_request_events => :user_info_request_sent_alerts } ], + :order => "info_requests.id, info_request_events.created_at" + ) for info_request in info_requests # Count number of new comments to alert on diff --git a/app/models/track_thing.rb b/app/models/track_thing.rb index b74f7dad5..58d70ed86 100644 --- a/app/models/track_thing.rb +++ b/app/models/track_thing.rb @@ -1,18 +1,18 @@ # == Schema Information -# Schema version: 95 +# Schema version: 108 # # Table name: track_things # # id :integer not null, primary key # tracking_user_id :integer not null # track_query :string(255) not null -# info_request_id :integer -# tracked_user_id :integer -# public_body_id :integer +# info_request_id :integer +# tracked_user_id :integer +# public_body_id :integer # track_medium :string(255) not null # track_type :string(255) default("internal_error"), not null -# created_at :datetime -# updated_at :datetime +# created_at :datetime +# updated_at :datetime # # models/track_thing.rb: @@ -71,14 +71,13 @@ class TrackThing < ActiveRecord::Base def track_query_description # XXX this is very brittle... we should probably ask users # simply to name their tracks when they make them? - self.track_query = self.track_query.gsub(/([()]|OR)/, "") - filters = self.track_query.scan /\b\S+:\S+\b/ - text = self.track_query + original_text = parsed_text = self.track_query.gsub(/([()]|OR)/, "") + filters = parsed_text.scan /\b\S+:\S+\b/ varieties = Set.new date = "" statuses = Set.new for filter in filters - text = text.sub(filter, "") + parsed_text = parsed_text.sub(filter, "") if filter =~ /variety:user/ varieties << _("users") end @@ -105,7 +104,7 @@ class TrackThing < ActiveRecord::Base end end if filters.empty? - text = self.track_query + parsed_text = original_text end descriptions = [] if varieties.include? _("requests") @@ -116,10 +115,10 @@ class TrackThing < ActiveRecord::Base varieties << _("anything") end descriptions += Array(varieties) - text = text.strip + parsed_text = parsed_text.strip descriptions = descriptions.join(_(" or ")) - if !text.empty? - descriptions += _("{{list_of_things}} matching text '{{search_query}}'", :list_of_things => "", :search_query => text) + if !parsed_text.empty? + descriptions += _("{{list_of_things}} matching text '{{search_query}}'", :list_of_things => "", :search_query => parsed_text) end return descriptions end diff --git a/app/models/track_things_sent_email.rb b/app/models/track_things_sent_email.rb index d83bf05ff..777339d75 100644 --- a/app/models/track_things_sent_email.rb +++ b/app/models/track_things_sent_email.rb @@ -1,15 +1,15 @@ # == Schema Information -# Schema version: 95 +# Schema version: 108 # # Table name: track_things_sent_emails # # id :integer not null, primary key # track_thing_id :integer not null -# info_request_event_id :integer -# user_id :integer -# public_body_id :integer -# created_at :datetime -# updated_at :datetime +# info_request_event_id :integer +# user_id :integer +# public_body_id :integer +# created_at :datetime +# updated_at :datetime # # models/track_things_sent_email.rb: diff --git a/app/models/user.rb b/app/models/user.rb index e98d777b1..8c4b35fe6 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -1,5 +1,5 @@ # == Schema Information -# Schema version: 95 +# Schema version: 108 # # Table name: users # @@ -10,14 +10,16 @@ # salt :string(255) not null # created_at :datetime not null # updated_at :datetime not null -# email_confirmed :boolean default(false), not null +# email_confirmed :boolean default(FALSE), not null # url_name :text not null # last_daily_track_email :datetime default(Sat Jan 01 00:00:00 UTC 2000) # admin_level :string(255) default("none"), not null # ban_text :text default(""), not null # about_me :text default(""), not null -# email_bounced_at :datetime +# locale :string(255) +# email_bounced_at :datetime # email_bounce_message :text default(""), not null +# no_limit :boolean default(FALSE), not null # # models/user.rb: @@ -130,7 +132,7 @@ class User < ActiveRecord::Base name.strip! end if self.public_banned? - name = _("{{user_name}} (Banned)", :user_name=>name) + name = _("{{user_name}} (Account suspended)", :user_name=>name) end name end @@ -255,7 +257,7 @@ class User < ActiveRecord::Base end def User.owns_every_request?(user) - !user.nil? && user.owns_every_request? + !user.nil? && user.owns_every_request? end # Can the user see every request, even hidden ones? @@ -273,7 +275,18 @@ class User < ActiveRecord::Base end # Various ways the user can be banned, and text to describe it if failed def can_file_requests? - self.ban_text.empty? + self.ban_text.empty? && !self.exceeded_limit? + end + def exceeded_limit? + # Some users have no limit + return false if self.no_limit + + # Has the user issued as many as MAX_REQUESTS_PER_USER_PER_DAY requests in the past 24 hours? + daily_limit = MySociety::Config.get("MAX_REQUESTS_PER_USER_PER_DAY") + return false if daily_limit.nil? + recent_requests = InfoRequest.count(:conditions => ["user_id = ? and created_at > now() - '1 day'::interval", self.id]) + + return (recent_requests >= daily_limit) end def can_make_followup? self.ban_text.empty? @@ -285,7 +298,11 @@ class User < ActiveRecord::Base self.ban_text.empty? end def can_fail_html - text = self.ban_text.strip + if ban_text + text = self.ban_text.strip + else + raise "Unknown reason for ban" + end text = CGI.escapeHTML(text) text = MySociety::Format.make_clickable(text, :contract => 1) text = text.gsub(/\n/, '<br>') diff --git a/app/models/user_info_request_sent_alert.rb b/app/models/user_info_request_sent_alert.rb index d07b4e553..5f23355bf 100644 --- a/app/models/user_info_request_sent_alert.rb +++ b/app/models/user_info_request_sent_alert.rb @@ -1,5 +1,5 @@ # == Schema Information -# Schema version: 95 +# Schema version: 108 # # Table name: user_info_request_sent_alerts # @@ -7,7 +7,7 @@ # user_id :integer not null # info_request_id :integer not null # alert_type :string(255) not null -# info_request_event_id :integer +# info_request_event_id :integer # # models/user_info_request_sent_alert.rb: diff --git a/app/views/admin_general/debug.rhtml b/app/views/admin_general/debug.rhtml index 422edea03..40fe33616 100644 --- a/app/views/admin_general/debug.rhtml +++ b/app/views/admin_general/debug.rhtml @@ -7,6 +7,10 @@ <h2>Version numbers</h2> <p> +Alaveteli branch: <%= link_to @current_branch, @github_origin + @current_branch %> +<br> +Alaveteli commit: <%= link_to @current_commit, @github_origin + @current_commit %> +<br> RUBY_VERSION <%=h RUBY_VERSION %> <br> Rails::VERSION::STRING <%=h Rails::VERSION::STRING%> @@ -16,8 +20,6 @@ TMail::VERSION::STRING <%=h TMail::VERSION::STRING%> Xapian::version_string <%=h Xapian::version_string%> <br> Spec::VERSION::STRING <%=h Spec::VERSION::STRING%> -<br> -Spec::Rails::VERSION::STRING <%=h Spec::Rails::VERSION::STRING%> </p> <h2>Configuration</h2> diff --git a/app/views/admin_general/timeline.rhtml b/app/views/admin_general/timeline.rhtml index dc72e46cd..39a4b3e36 100644 --- a/app/views/admin_general/timeline.rhtml +++ b/app/views/admin_general/timeline.rhtml @@ -36,10 +36,9 @@ end %> <% elsif event.event_type == 'edit_outgoing' %> - <% outgoing_messages = OutgoingMessage.find(:all, event.params[:outgoing_message_id].to_i) %> + <% outgoing_message = OutgoingMessage.find(event.params[:outgoing_message_id].to_i) %> had outgoing message edited by administrator <strong><%=h event.params[:editor] %></strong>. - <% if outgoing_messages.size > 0 %> - <% outgoing_message = outgoing_messages[0] %> + <% if outgoing_message %> <% for p in ['body'] if event.params[p.to_sym] != event.params[('old_'+p).to_sym] %> Changed <%=p%> from '<%=h event.params[('old_'+p).to_sym]%>' to '<%=h event.params[p.to_sym] %>'. <% @@ -50,10 +49,9 @@ Missing outgoing message, internal error. <% end %> <% elsif event.event_type == 'edit_comment' %> - <% comments = Comment.find(:all, event.params[:comment_id].to_i) %> + <% comment = Comment.find(event.params[:comment_id].to_i) %> had annotation edited by administrator <strong><%=h event.params[:editor] %></strong>. - <% if comments.size > 0 %> - <% comment = comments[0] %> + <% if comment %> <% for p in ['body'] if event.params[p.to_sym] != event.params[('old_'+p).to_sym] %> Changed <%=p%> from '<%=h event.params[('old_'+p).to_sym]%>' to '<%=h event.params[p.to_sym] %>'. <% diff --git a/app/views/admin_public_body/_form.rhtml b/app/views/admin_public_body/_form.rhtml index 1cdc9b3fe..d854b53f5 100644 --- a/app/views/admin_public_body/_form.rhtml +++ b/app/views/admin_public_body/_form.rhtml @@ -50,12 +50,13 @@ <h3>Common Fields</h3> <p><label for="public_body_tag_string">Tags <small>(space separated; see list of tags on the right; also <strong>not_apply</strong> if FOI and EIR no longer apply to authority, <strong>eir_only</strong> if EIR but not FOI applies to authority, <strong>defunct</strong> if the authority no longer exists; charity:NUMBER if a registered charity)</small></label><br/> -<%= f.text_field :tag_string, :size => 60 %></p> + +<%= text_field :public_body, :tag_string, :size => 60, :id => 'public_body_tag_string' %></p> <p><label for="public_body_home_page">Home page <small>(of whole authority, not just their FOI page; set to <strong>blank</strong> (empty string) to guess it from the email)</small></label><br/> -<%= f.text_field :home_page, :size => 60 %></p> +<%= text_field :public_body, :home_page, :size => 60, :id => 'public_body_home_page' %></p> <p><label for="public_body_last_edit_comment"><strong>Comment</strong> for this edit</label> <small>(put URL or other source of new info)</small><br/> -<%= f.text_area :last_edit_comment, :rows => 3, :cols => 60 %></p> +<%= text_area :public_body, :last_edit_comment, :rows => 3, :cols => 60, :id => 'public_body_last_edit_comment' %></p> <!--[eoform:public_body]--> diff --git a/app/views/admin_public_body/edit.rhtml b/app/views/admin_public_body/edit.rhtml index b91f15a2e..b19477a6b 100644 --- a/app/views/admin_public_body/edit.rhtml +++ b/app/views/admin_public_body/edit.rhtml @@ -9,9 +9,9 @@ <%= render :partial => 'tag_help' %> <div id="public_body_form"> - <% form_for @public_body, :url => {:action => 'update'} do |f| %> - <%= render :partial => 'form', :locals => {:f => f} %> - <p><%= f.submit 'Save', :accesskey => 's' %></p> + <% form_tag '../update/' + @public_body.id.to_s do %> + <%= render :partial => 'form' %> + <p><%= submit_tag 'Save', :accesskey => 's' %></p> <% end %> <p> diff --git a/app/views/admin_public_body/import_csv.rhtml b/app/views/admin_public_body/import_csv.rhtml index ecd2c38b7..d5717de23 100644 --- a/app/views/admin_public_body/import_csv.rhtml +++ b/app/views/admin_public_body/import_csv.rhtml @@ -31,7 +31,7 @@ <p><strong>CSV file format:</strong> A first row with the list of fields, starting with '#', is optional but highly recommended. The fields 'name' - and 'request_email' are required; additionaly, translated values are supported by + and 'request_email' are required; additionally, translated values are supported by adding the locale name to the field name, e.g. 'name.es', 'name.de'... Example: </p> diff --git a/app/views/admin_public_body/new.rhtml b/app/views/admin_public_body/new.rhtml index b859fdf6a..047d5a5bb 100644 --- a/app/views/admin_public_body/new.rhtml +++ b/app/views/admin_public_body/new.rhtml @@ -11,9 +11,9 @@ <%= render :partial => 'tag_help' %> <div id="public_body_form"> - <% form_for :public_body, @public_body, :url => {:action => "create"} do |f| %> - <%= render :partial => 'form', :locals => {:f => f} %> - <p><%= f.submit "Create" %></p> + <% form_tag './create/' + @public_body.id.to_s do %> + <%= render :partial => 'form' %> + <p><%= submit_tag "Create" %></p> <% end %> <p> diff --git a/app/views/admin_user/_form.rhtml b/app/views/admin_user/_form.rhtml index ba2bd8f8b..be69d9a80 100644 --- a/app/views/admin_user/_form.rhtml +++ b/app/views/admin_user/_form.rhtml @@ -8,10 +8,10 @@ <p><label for="admin_user_email">Email</label> (<strong>you must</strong> first validate this)<br/> <%= text_field 'admin_user', 'email', :size => 60 %></p> -<p><label for="admin_level">Admin level</label> (<strong>none</strong> or <strong>super</strong>; this is for admin features and links which are in the site proper)<br/> +<p><label for="admin_user_admin_level">Admin level</label> (<strong>none</strong> or <strong>super</strong>; this is for admin features and links which are in the site proper)<br/> <%= text_field 'admin_user', 'admin_level', :size => 60 %></p> -<p><label for="ban_text">Ban text</label> <small>(if not blank will stop the +<p><label for="admin_user_ban_text">Ban text</label> <small>(if not blank will stop the user from filing new requests, making annotations or messaging other users; the text is shown in public on the user's page and when they try to do a forbidden action; write in the second person (you); see @@ -19,7 +19,9 @@ <%= text_area 'admin_user', 'ban_text', :cols => 60, :rows => 3 %></p> -<p><label for="about_me">About me</label> (user's own text on their profile, format like comments):<br/> +<p><label for="admin_user_about_me">About me</label> (user's own text on their profile, format like comments):<br/> <%= text_area 'admin_user', 'about_me', :cols => 60, :rows => 3 %></p> +<p><%= check_box 'admin_user', 'no_limit' %> +<label for="admin_user_no_limit">No rate limit</label> (disable the limit on daily requests)</p> diff --git a/app/views/general/_topnav.rhtml b/app/views/general/_topnav.rhtml index 619ff3593..8ef928bba 100644 --- a/app/views/general/_topnav.rhtml +++ b/app/views/general/_topnav.rhtml @@ -1,10 +1,10 @@ <div id="topnav"> <ul id="navigation"> - <li class="<%= 'selected' if params[:controller] == 'general' and params[:action] != 'blog' %>"><%= link_to _("Home"), frontpage_url %></li> + <li class="<%= 'selected' if params[:controller] == 'general' and params[:action] != 'blog' and params[:action] != 'search' %>"><%= link_to _("Home"), frontpage_url %></li> <li class="<%= 'selected' if params[:controller] == 'request' and ['new', 'select_authority'].include?(params[:action]) %>"><%= link_to _("Make a request"), select_authority_url, :id => 'make-request-link' %></li> <li class="<%= 'selected' if params[:controller] == 'request' and !['new', 'select_authority'].include?(params[:action]) %>"><%= link_to _("View requests"), request_list_successful_url %></li> <li class="<%= 'selected' if params[:controller] == 'public_body' %>"><%= link_to _("View authorities"), list_public_bodies_default %></li> <li class="<%= 'selected' if params[:controller] == 'general' and params[:action] == 'blog' %>"><%= link_to _("Read blog"), blog_url %></li> <li class="<%= 'selected' if params[:controller] == 'help' %>"><%= link_to _("Help"), help_about_url %></li> </ul> -</div>
\ No newline at end of file +</div> diff --git a/app/views/general/exception_caught.rhtml b/app/views/general/exception_caught.rhtml index b266b53a1..5f0dfe13d 100644 --- a/app/views/general/exception_caught.rhtml +++ b/app/views/general/exception_caught.rhtml @@ -19,6 +19,6 @@ <% end %> <h2><%= _('Technical details') %></h2> - <p><strong><%=@exception_class ? @exception_class : _("Unknown")%></strong></p> - <p><strong><%=@exception_message %></strong></p> + <p><strong><%= h(@exception_class ? @exception_class : _("Unknown")) %></strong></p> + <p><strong><%= h(@exception_message) %></strong></p> </div> diff --git a/app/views/general/frontpage.rhtml b/app/views/general/frontpage.rhtml index 35751b6a4..38133e7ab 100644 --- a/app/views/general/frontpage.rhtml +++ b/app/views/general/frontpage.rhtml @@ -12,20 +12,20 @@ <div id="right_column"> <div id="frontpage_search_box"> <h2> - <%= _("Search over<br/> + <%= _("Search over<br/> <strong>{{number_of_requests}} requests</strong> <span>and</span><br/> <strong>{{number_of_authorities}} authorities</strong>", - :number_of_requests => InfoRequest.count, :number_of_authorities => PublicBody.count) %> + :number_of_requests => InfoRequest.count, :number_of_authorities => PublicBody.count) %> </h2> <% form_tag({:action => "search_redirect"}, {:id => "search_form"}) do %> - <div> - <%= text_field_tag 'query', params[:query], { :size => 30 } %> - <%= submit_tag _('Search') %> - </div> + <div> + <%= text_field_tag 'query', params[:query], { :size => 30 } %> + <%= submit_tag _('Search') %> + </div> <% end %> </div> <div id="frontpage_right_to_know"> - <%= render :partial => 'frontpage_intro_sentence' %> + <%= render :partial => 'frontpage_intro_sentence' %> </div> </div> <div style="clear:both"></div> @@ -34,38 +34,38 @@ <div id="frontpage_examples"> <% if @popular_bodies.size > 0 %> <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.count) %> - <ul> + <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.count) %> + <ul> <% for popular_body in @popular_bodies %> <li><%=public_body_link(popular_body)%> <%= n_('%d request', '%d requests', popular_body.info_requests.count) % popular_body.info_requests.count %> </li> <% end%> - </ul> - <p><strong> - <%= link_to _('Browse all authorities...'), list_public_bodies_default %> - </strong></p> - </div> + </ul> + <p><strong> + <%= link_to _('Browse all authorities...'), list_public_bodies_default %> + </strong></p> + </div> <% end %> - <div id="examples_1"> - <h3><%= _("What information has been released?") %></h3> - <%= _("{{site_name}} users have made {{number_of_requests}} requests, including:", - :site_name => site_name, :number_of_requests => InfoRequest.count) %> - <ul> - <% for event in @request_events %> - <li> - <%= public_body_link(event.info_request.public_body) %> <%= _('answered a request about') %> - <%=link_to h(event.info_request.title), request_url(event.info_request)%> + <div id="examples_1"> + <h3><%= _("What information has been released?") %></h3> + <%= _("{{site_name}} users have made {{number_of_requests}} requests, including:", + :site_name => site_name, :number_of_requests => InfoRequest.count) %> + <ul> + <% for event in @request_events %> + <li> + <%= public_body_link(event.info_request.public_body) %> <%= _('answered a request about') %> + <%=link_to h(event.info_request.title), request_url(event.info_request)%> <%= _('{{length_of_time}} ago', :length_of_time => time_ago_in_words(event.described_at)) %> - <p class="excerpt" onclick="document.location.href='<%=request_url(event.info_request)%>'"><%= excerpt(event.info_request.title, "", 200) %></p> - </li> - <% end %> - </ul> - <p><strong><%=link_to _('More successful requests...'), request_list_successful_url %></strong></p> - </div> + <p class="excerpt" onclick="document.location.href='<%=request_url(event.info_request)%>'"><%= excerpt(event.search_text_main(true), "", 200) %></p> + </li> + <% end %> + </ul> + <p><strong><%=link_to _('More successful requests...'), request_list_successful_url %></strong></p> + </div> </div> diff --git a/app/views/general/search.rhtml b/app/views/general/search.rhtml index 87a6ab446..90ace809e 100644 --- a/app/views/general/search.rhtml +++ b/app/views/general/search.rhtml @@ -7,7 +7,7 @@ <% if @query.nil? %> <% @title = _("Search Freedom of Information requests, public authorities and users") %> <% elsif @total_hits == 0 %> - <% @title = _('There were no requests matching your query.') %> + <% @title = _('There were no results matching your query.') %> <% else %> <% @title = _("Results page {{page_number}}", :page_number => @page.to_s) %> <% end%> @@ -56,11 +56,7 @@ ["all", _("everything")]]%> <% for variety, label in labels %> <% if @variety_postfix != variety %> - <% if variety != "users" %> - <%= link_to label, search_url([params[:query], @common_query], variety, @sort_postfix) %> - <% else %> - <%= link_to label, search_url(params[:query], variety, @sort_postfix) %> - <% end %> + <%= link_to label, search_url([params[:query], variety, @sort_postfix]) %> <% else %> <%= label %> <% end %> @@ -126,9 +122,9 @@ <% if !@query.nil? %> <p id="search_controls"> - <%=link_to_unless @sortby == 'relevant', _("Show most relevant results first"), search_url(@query, @variety_postfix, 'relevant') %> + <%=link_to_unless @sortby == 'relevant', _("Show most relevant results first"), search_url([params[:query], @variety_postfix, 'relevant'], params) %> | - <%=link_to_unless @sortby == 'newest', _("Newest results first"), search_url(@query, @variety_postfix, 'newest') %> + <%=link_to_unless @sortby == 'newest', _("Newest results first"), search_url([params[:query], @variety_postfix, 'newest'], params) %> <% if @sortby == 'described' %> | <%= _('Recently described results first') %> <% end %> @@ -166,7 +162,6 @@ <%= will_paginate WillPaginate::Collection.new(@page, @bodies_per_page, @xapian_bodies.matches_estimated) %> <% elsif @bodies && !@query.nil? && @xapian_bodies.results.size == 0 && @page == 1 %> - <h2 class="publicbody_results"><%= _('No public authorities found') %></h2> <% if @spelling_correction %> <p id="did_you_mean"><%= _('Did you mean: {{correction}}', :correction => search_link(@spelling_correction, @postfix)) %></p> <% end %> @@ -187,6 +182,8 @@ <%= render :partial => 'user/user_listing_single', :locals => { :display_user => result[:model] } %> <% end %> </div> + <%= will_paginate WillPaginate::Collection.new(@page, @users_per_page, @xapian_users.matches_estimated) %> + <% end %> </div> diff --git a/app/views/layouts/default.rhtml b/app/views/layouts/default.rhtml index 2f8e0bf36..f439b27d2 100644 --- a/app/views/layouts/default.rhtml +++ b/app/views/layouts/default.rhtml @@ -10,13 +10,13 @@ </title> <link rel="shortcut icon" href="/favicon.ico"> - <%= stylesheet_link_tag 'main', :title => "Main", :rel => "stylesheet", :media => "all" %> - <%= stylesheet_link_tag 'fonts', :rel => "stylesheet", :media => "all" %> - <%= stylesheet_link_tag 'print', :rel => "stylesheet", :media => "print" %> - <% if !params[:print_stylesheet].nil? %> + <%= stylesheet_link_tag 'main', :title => "Main", :rel => "stylesheet", :media => "all" %> + <%= stylesheet_link_tag 'fonts', :rel => "stylesheet", :media => "all" %> + <%= stylesheet_link_tag 'print', :rel => "stylesheet", :media => "print" %> + <% if !params[:print_stylesheet].nil? %> <%= stylesheet_link_tag 'print', :rel => "stylesheet", :media => "all" %> - <% end %> - <%= javascript_include_tag 'jquery.js', 'jquery-ui.min','jquery.cookie.js', 'general.js' %> + <% end %> + <%= javascript_include_tag 'jquery.js', 'jquery-ui.min','jquery.cookie.js', 'general.js' %> <% if @profile_photo_javascript %> <script type="text/javascript" src="/javascripts/jquery.Jcrop.js"></script> @@ -24,7 +24,7 @@ <link rel="stylesheet" href="/stylesheets/jquery.Jcrop.css" type="text/css" > <% end %> - <%= stylesheet_link_tag 'admin-theme/jquery-ui-1.8.15.custom.css', :rel => 'stylesheet'%> + <%= stylesheet_link_tag 'admin-theme/jquery-ui-1.8.15.custom.css', :rel => 'stylesheet'%> <!--[if LT IE 7]> <style type="text/css">@import url("/stylesheets/ie6.css");</style> <![endif]--> @@ -34,8 +34,8 @@ <!--[if LT IE 8]> <style type="text/css">@import url("/stylesheets/ie7.css");</style> <![endif]--> - <!-- the following method for customising CSS is deprecated; see `doc/THEMES.md` for detail --> - <%= stylesheet_link_tag 'custom', :title => "Main", :rel => "stylesheet" %> + <!-- the following method for customising CSS is deprecated; see `doc/THEMES.md` for detail --> + <%= stylesheet_link_tag 'custom', :title => "Main", :rel => "stylesheet" %> <% if force_registration_on_new_request %> <%= stylesheet_link_tag 'jquery.fancybox-1.3.4', :rel => "stylesheet" %> <% end %> @@ -56,7 +56,7 @@ <meta name="robots" content="noindex, nofollow"> <% end %> - <%= render :partial => 'general/before_head_end' %> + <%= render :partial => 'general/before_head_end' %> </head> <body <%= "class='front'" if params[:action] == 'frontpage' %>> @@ -102,7 +102,8 @@ <%= _('Hello, {{username}}!', :username => h(@user.name))%> <% if @user %> - <%=link_to _("My profile"), user_url(@user) %> + <%=link_to _("My requests"), show_user_requests_path(:url_name => @user.url_name) %> + <%=link_to _("My profile"), show_user_profile_path(:url_name => @user.url_name) %> <% end %> diff --git a/app/views/public_body/_search_ahead.rhtml b/app/views/public_body/_search_ahead.rhtml index 436471544..7ade89b8e 100644 --- a/app/views/public_body/_search_ahead.rhtml +++ b/app/views/public_body/_search_ahead.rhtml @@ -1,4 +1,4 @@ -<p> +<div> <% if !@xapian_requests.nil? %> <% if @xapian_requests.results.size > 0 %> <h3><%= _('Top search results:') %></h3> @@ -13,8 +13,9 @@ <%= render :partial => 'body_listing_single', :locals => { :public_body => result[:model] } %> <% end %> </div> + <%= will_paginate WillPaginate::Collection.new(@page, @per_page, @xapian_requests.matches_estimated) %> <% end %> -</p> +</div> diff --git a/app/views/public_body/list.rhtml b/app/views/public_body/list.rhtml index af91d8ed2..8cb207bd4 100644 --- a/app/views/public_body/list.rhtml +++ b/app/views/public_body/list.rhtml @@ -44,7 +44,7 @@ </div> <% end %> -<h2 class="publicbody_results"><%= _('Found {{count}} public bodies {{description}}', :count=>@public_bodies.size, :description=>@description) %></h2> +<h2 class="publicbody_results"><%= _('Found {{count}} public bodies {{description}}', :count=>@public_bodies.total_entries, :description=>@description) %></h2> <%= render :partial => 'body_listing', :locals => { :public_bodies => @public_bodies } %> <%= will_paginate(@public_bodies) %><br/> diff --git a/app/views/public_body/show.rhtml b/app/views/public_body/show.rhtml index 7d37a35a7..5f20a9717 100644 --- a/app/views/public_body/show.rhtml +++ b/app/views/public_body/show.rhtml @@ -1,123 +1,123 @@ <% @title = h(@public_body.name) + _(" - view and make Freedom of Information requests") %> <div id="main_content"> - <div id="header_right"> + <div id="header_right"> <h2><%= _('Follow this authority')%></h2> - <% follower_count = TrackThing.count(:all, :conditions => ["public_body_id = ?", @public_body.id]) %> - <p><%= n_("There is %d person following this authority", "There are %d people following this authority", follower_count) % follower_count %></p> + <% follower_count = TrackThing.count(:all, :conditions => ["public_body_id = ?", @public_body.id]) %> + <p><%= n_("There is %d person following this authority", "There are %d people following this authority", follower_count) % follower_count %></p> - <%= render :partial => 'track/tracking_links', :locals => { :track_thing => @track_thing, :own_request => false, :location => 'sidebar' } %> - <h2><%= _('More about this authority')%></h2> - <% if !@public_body.calculated_home_page.nil? %> - <%= link_to _('Home page of authority'), @public_body.calculated_home_page %><br> - <% end %> - <% if !@public_body.publication_scheme.empty? %> - <%= link_to _('Publication scheme'), @public_body.publication_scheme %><br> - <% end %> - <% if @public_body.has_tag?("charity") %> - <% for tag_value in @public_body.get_tag_values("charity") %> - <% if tag_value.match(/^SC/) %> - <%= link_to _('Charity registration'), "http://www.oscr.org.uk/CharityIndexDetails.aspx?id=" + tag_value %><br> - <% else %> - <%= link_to _('Charity registration'), "http://www.charity-commission.gov.uk/SHOWCHARITY/RegisterOfCharities/CharityFramework.aspx?RegisteredCharityNumber=" + tag_value %><br> - <% end %> - <% end %> - <% end %> - <%= link_to _('View FOI email address'), view_public_body_email_url(@public_body.url_name) %><br> - </div> + <%= render :partial => 'track/tracking_links', :locals => { :track_thing => @track_thing, :own_request => false, :location => 'sidebar' } %> + <h2><%= _('More about this authority')%></h2> + <% if !@public_body.calculated_home_page.nil? %> + <%= link_to _('Home page of authority'), @public_body.calculated_home_page %><br> + <% end %> + <% if !@public_body.publication_scheme.empty? %> + <%= link_to _('Publication scheme'), @public_body.publication_scheme %><br> + <% end %> + <% if @public_body.has_tag?("charity") %> + <% for tag_value in @public_body.get_tag_values("charity") %> + <% if tag_value.match(/^SC/) %> + <%= link_to _('Charity registration'), "http://www.oscr.org.uk/CharityIndexDetails.aspx?id=" + tag_value %><br> + <% else %> + <%= link_to _('Charity registration'), "http://www.charity-commission.gov.uk/SHOWCHARITY/RegisterOfCharities/CharityFramework.aspx?RegisteredCharityNumber=" + tag_value %><br> + <% end %> + <% end %> + <% end %> + <%= link_to _('View FOI email address'), view_public_body_email_url(@public_body.url_name) %><br> + </div> - <div id="header_left"> - <p class="public-body-name-prefix"><%= _("Freedom of information requests to") %></p> - <h1><%=h(@public_body.name)%></h1> + <div id="header_left"> + <p class="public-body-name-prefix"><%= _("Freedom of information requests to") %></p> + <h1><%=h(@public_body.name)%></h1> - <p class="subtitle"> - <%=@public_body.type_of_authority(true)%><% if not @public_body.short_name.empty? %>, - <%= _('also called {{public_body_short_name}}', :public_body_short_name => h(@public_body.short_name))%><% end %> - <% if !@user.nil? && @user.admin_page_links? %> - (<%= link_to _("admin"), public_body_admin_url(@public_body) %>) - <% end %> - </p> + <p class="subtitle"> + <%=@public_body.type_of_authority(true)%><% if not @public_body.short_name.empty? %>, + <%= _('also called {{public_body_short_name}}', :public_body_short_name => h(@public_body.short_name))%><% end %> + <% if !@user.nil? && @user.admin_page_links? %> + (<%= link_to _("admin"), public_body_admin_url(@public_body) %>) + <% end %> + </p> - <% if @public_body.has_notes? && (@public_body.is_requestable? || @public_body.not_requestable_reason == 'bad_contact') %> - <p><%= @public_body.notes_as_html %></p> - <% end %> + <% if @public_body.has_notes? && (@public_body.is_requestable? || @public_body.not_requestable_reason == 'bad_contact') %> + <p><%= @public_body.notes_as_html %></p> + <% end %> - <% if @public_body.eir_only? %> - <p><%= _('You can only request information about the environment from this authority.')%></p> - <% end %> + <% if @public_body.eir_only? %> + <p><%= _('You can only request information about the environment from this authority.')%></p> + <% end %> - <div id="stepwise_make_request"> - <% if @public_body.is_requestable? || @public_body.not_requestable_reason == 'bad_contact' %> - <% if @public_body.eir_only? %> - <%= _('Make a new <strong>Environmental Information</strong> request')%> + <div id="stepwise_make_request"> + <% if @public_body.is_requestable? || @public_body.not_requestable_reason == 'bad_contact' %> + <% if @public_body.eir_only? %> + <%= _('Make a new <strong>Environmental Information</strong> request')%> + <% else %> + <%= _('Make a new <strong>Freedom of Information</strong> request to {{public_body}}', :public_body => h(@public_body.name))%> + <% end %> + <%= _('<a class="link_button_green" href="{{url}}">{{text}}</a>', :url=>new_request_to_body_url(:url_name => @public_body.url_name), :text=>_("Start"))%> + <% elsif @public_body.has_notes? %> + <%= @public_body.notes_as_html %> + <% elsif @public_body.not_requestable_reason == 'not_apply' %> + <%= _('Freedom of Information law does not apply to this authority, so you cannot make + a request to it.')%> + <% elsif @public_body.not_requestable_reason == 'defunct' %> + <%= _('This authority no longer exists, so you cannot make a request to it.')%> <% else %> - <%= _('Make a new <strong>Freedom of Information</strong> request to {{public_body}}', :public_body => h(@public_body.name))%> + <%= _('For an unknown reason, it is not possible to make a request to this authority.')%> <% end %> - <%= _('<a class="link_button_green" href="{{url}}">{{text}}</a>', :url=>new_request_to_body_url(:url_name => @public_body.url_name), :text=>_("Start"))%> - <% elsif @public_body.has_notes? %> - <%= @public_body.notes_as_html %> - <% elsif @public_body.not_requestable_reason == 'not_apply' %> - <%= _('Freedom of Information law does not apply to this authority, so you cannot make - a request to it.')%> - <% elsif @public_body.not_requestable_reason == 'defunct' %> - <%= _('This authority no longer exists, so you cannot make a request to it.')%> - <% else %> - <%= _('For an unknown reason, it is not possible to make a request to this authority.')%> - <% end %> + </div> </div> - </div> - <div id="foi_results_section"> - <% if @public_body.info_requests.size == 0 %> - <% if @public_body.eir_only? %> - <h2><%= _('Environmental Information Regulations requests made using this site') %></h2> - <p>Nobody has made any Environmental Information Regulations requests to <%=h(@public_body.name)%> using this site yet.</p> - <% else %> - <h2><%= _('Freedom of Information requests made using this site')%></h2> - <p><%= _('Nobody has made any Freedom of Information requests to {{public_body_name}} using this site yet.', :public_body_name => h(@public_body.name))%></p> - <% end %> - <% else %> - <h2 class="foi_results"> - <% if @public_body.eir_only? %> - <%= pluralize(@public_body.info_requests.size, "Environmental Information Regulations request made using this site") %> + <div id="foi_results_section"> + <% if @public_body.info_requests.size == 0 %> + <% if @public_body.eir_only? %> + <h2><%= _('Environmental Information Regulations requests made using this site') %></h2> + <p>Nobody has made any Environmental Information Regulations requests to <%=h(@public_body.name)%> using this site yet.</p> + <% else %> + <h2><%= _('Freedom of Information requests made using this site')%></h2> + <p><%= _('Nobody has made any Freedom of Information requests to {{public_body_name}} using this site yet.', :public_body_name => h(@public_body.name))%></p> + <% end %> <% else %> - <% if @public_body.info_requests.size > 4 %> - <%= n_('Search within the %d Freedom of Information requests to %s', 'Search within the %d Freedom of Information requests made to %s', @public_body.info_requests.size) % [@public_body.info_requests.size, @public_body.name] %> - <% else %> - <%= n_('%d Freedom of Information request to %s', '%d Freedom of Information requests to %s', @public_body.info_requests.size) % [@public_body.info_requests.size, @public_body.name] %> - <% end %> + <h2 class="foi_results"> + <% if @public_body.eir_only? %> + <%= pluralize(@public_body.info_requests.size, "Environmental Information Regulations request made using this site") %> + <% else %> + <% if @public_body.info_requests.size > 4 %> + <%= n_('Search within the %d Freedom of Information requests to %s', 'Search within the %d Freedom of Information requests made to %s', @public_body.info_requests.size) % [@public_body.info_requests.size, @public_body.name] %> + <% else %> + <%= n_('%d Freedom of Information request to %s', '%d Freedom of Information requests to %s', @public_body.info_requests.size) % [@public_body.info_requests.size, @public_body.name] %> + <% end %> + <% end %> + <%= @page_desc %> + </h2> + <a name="results"></a> + + <% if @public_body.info_requests.size > 4 %> + <%= render :partial => 'request/request_filter_form' %> + <% end %> <% end %> - <%= @page_desc %> - </h2> - <a name="results"></a> - - <% if @public_body.info_requests.size > 4 %> - <%= render :partial => 'request/request_filter_form' %> - <% end %> - <% end %> - <div style="clear:both"> </div> - <% if !@xapian_requests.nil? %> + <div style="clear:both"> </div> + <% if !@xapian_requests.nil? %> <% for result in @xapian_requests.results %> <%= render :partial => 'request/request_listing_via_event', :locals => { :event => result[:model], :info_request => result[:model].info_request } %> <% end %> - <%= will_paginate WillPaginate::Collection.new(@page, @per_page, @public_body.info_requests.size) %> + <%= will_paginate WillPaginate::Collection.new(@page, @per_page, @xapian_requests.matches_estimated) %> - <% 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> - <% end %> + <% 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> + <% end %> - <% else %> - <% if @public_body.eir_only? %> - <h2><%= _('Environmental Information Regulations requests made') %></h2> - <% else %> - <h2> <%= _('Freedom of Information requests made')%></h2> + <% else %> + <% if @public_body.eir_only? %> + <h2><%= _('Environmental Information Regulations requests made') %></h2> + <% else %> + <h2> <%= _('Freedom of Information requests made')%></h2> + <% end %> + <p> <%= _('The search index is currently offline, so we can\'t show the Freedom of Information requests that have been made to this authority.')%></p> <% end %> - <p> <%= _('The search index is currently offline, so we can\'t show the Freedom of Information requests that have been made to this authority.')%></p> - <% end %> </div> </div> diff --git a/app/views/request/_request_listing_via_event.rhtml b/app/views/request/_request_listing_via_event.rhtml index e7c378cec..7a211ed88 100644 --- a/app/views/request/_request_listing_via_event.rhtml +++ b/app/views/request/_request_listing_via_event.rhtml @@ -4,9 +4,9 @@ end %> <div class="request_listing"> <div class="request_left"> - <span class="head"> + <span class="head"> <% if event.is_incoming_message? %> - <%= link_to highlight_words(info_request.title, @highlight_words), incoming_message_url(event.incoming_message) %> + <%= link_to highlight_words(info_request.title, @highlight_words), incoming_message_url(event.incoming_message_selective_columns("incoming_messages.id")) %> <% elsif event.is_outgoing_message? and event.event_type == 'followup_sent' %> <%= link_to highlight_words(info_request.title, @highlight_words), outgoing_message_url(event.outgoing_message) %> <% elsif event.is_comment? %> @@ -14,9 +14,9 @@ end %> <% else %> <%= link_to highlight_words(info_request.title, @highlight_words), request_url(info_request) %> <% end %> - </span> - <div class="requester"> - <% if event.event_type == 'sent' %> + </span> + <div class="requester"> + <% if event.event_type == 'sent' %> <%= _('Request sent to {{public_body_name}} by {{info_request_user}} on {{date}}.',:public_body_name=>public_body_link_absolute(info_request.public_body),:info_request_user=>user_link_absolute(info_request.user),:date=>simple_date(event.created_at )) %> <% elsif event.event_type == 'followup_sent' %> <%=event.display_status %> @@ -27,19 +27,22 @@ end %> <% elsif event.event_type == 'comment' %> <%= _('Request to {{public_body_name}} by {{info_request_user}}. Annotated by {{event_comment_user}} on {{date}}.',:public_body_name=>public_body_link_absolute(info_request.public_body),:info_request_user=>user_link_absolute(info_request.user),:event_comment_user=>user_link_absolute(event.comment.user),:date=>simple_date(event.created_at)) %> <% else %> - <% raise _("unknown event type indexed ") + event.event_type %> + <%# Events of other types will not be indexed: see InfoRequestEvent#indexed_by_search? + However, it can happen that we see other types of event transiently here in the period + between a change being made and the update-xapian-index job being run. %> + <!-- Event of type '<%= event.event_type %>', id=<%= event.id %> --> <% end %> - </div> - <span class="bottomline icon_<%= info_request.calculate_status %>"> + </div> + <span class="bottomline icon_<%= info_request.calculate_status %>"> <strong> <%= info_request.display_status %> </strong><br> - </span> + </span> </div> <div class="request_right"> <span class="desc"> <%= highlight_and_excerpt(event.search_text_main(true), @highlight_words, 150) %> - </span> - </div> + </span> + </div> </div> diff --git a/app/views/request/_search_ahead.rhtml b/app/views/request/_search_ahead.rhtml index d0b19de7d..1e65a5458 100644 --- a/app/views/request/_search_ahead.rhtml +++ b/app/views/request/_search_ahead.rhtml @@ -8,7 +8,7 @@ <% end %> <p> - <a id="body-site-search-link" target="_blank"><%= _("Or search in their website for this information.") %></a> + <a id="body-site-search-link"><%= _("Or search in their website for this information.") %></a> </p> <% end %> </div> diff --git a/app/views/request/list.rhtml b/app/views/request/list.rhtml index 3890fa28b..7cbd982f1 100644 --- a/app/views/request/list.rhtml +++ b/app/views/request/list.rhtml @@ -14,11 +14,11 @@ <div style="clear:both"></div> <div class="results_section"> - <% view_cache :ttl => 5.minutes.to_i, :tag => [@view, @page, I18n.locale] do %> + <% view_cache :ttl => 5.minutes.to_i, :tag => [@cache_tag] do %> <% if @list_results.empty? %> <p> <%= _('No requests of this sort yet.')%></p> <% else %> - <h2 class="foi_results"><%= _('{{count}} FOI requests found', :count => @list_results.size) %></h2> + <h2 class="foi_results"><%= _('{{count}} FOI requests found', :count => @matches_estimated) %></h2> <div class="results_block"> <% for result in @list_results%> <% if result.class.to_s == 'InfoRequestEvent' %> @@ -30,6 +30,6 @@ </div> <% end %> - <%= will_paginate WillPaginate::Collection.new(@page, @per_page, @matches_estimated) %> + <%= will_paginate WillPaginate::Collection.new(@page, @per_page, @show_no_more_than) %> <% end %> </div> 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/app/views/request/select_authority.rhtml b/app/views/request/select_authority.rhtml index 55ebc40c4..521136f8e 100644 --- a/app/views/request/select_authority.rhtml +++ b/app/views/request/select_authority.rhtml @@ -7,16 +7,17 @@ // http://benalman.com/projects/jquery-throttle-debounce-plugin/ $("#query").keypress($.debounce( 300, function() { // Do a type ahead search and display results - $("#typeahead_response").load("<%=search_ahead_bodies_url%>?q="+encodeURI(this.value), function() { + $("#typeahead_response").load("<%=search_ahead_bodies_url%>?query="+encodeURI(this.value), function() { $("#authority_preview").hide(); // Hide the preview, since results have changed }); })); // We're using the existing body list: we intercept the clicks on the titles to // display a preview on the right hand side of the screen - $("#typeahead_response a").live('click', function() { + $("#typeahead_response .head a").live('click', function() { $("#authority_preview").load(this.href+" #public_body_show", function() { $("#authority_preview").show(); + $(window).scrollTop($("#banner").height()); $("#authority_preview #header_right").hide(); }); return false; @@ -33,8 +34,8 @@ <p> <p> <%= _('First, type in the <strong>name of the UK public authority</strong> you\'d - <br>like information from. <strong>By law, they have to respond</strong> - (<a href="%s">why?</a>).') % help_about_url %> + like information from. <strong>By law, they have to respond</strong> + (<a href="%s#%s">why?</a>).') % [help_about_url, "whybother_them"] %> </p> <%= text_field_tag 'query', params[:query], { :size => 30 } %> <%= hidden_field_tag 'bodies', 1 %> @@ -56,6 +57,7 @@ <%= render :partial => 'public_body/body_listing_single', :locals => { :public_body => result[:model] } %> <% end %> </div> + <% end %> diff --git a/app/views/user/rate_limited.rhtml b/app/views/user/rate_limited.rhtml new file mode 100644 index 000000000..c1e8f360e --- /dev/null +++ b/app/views/user/rate_limited.rhtml @@ -0,0 +1,17 @@ +<% @title = "Too many requests" %> + +<h1><%=@title%></h1> + +<p><%= _("There is a limit on the number of requests that you can make in any one day. You can make more requests tomorrow.")%></p> + +<!-- Insert explanation of why we have a limit --> + +<p><%= _("If you need to make more requests than this, <a href='%s'>get in touch</a> and we’ll consider it.") % [help_contact_path] %></p> + +<% if @info_request %> + <p><%= _("Here is the message you wrote, in case you would like to copy the text and save it for later.") %></p> + + <div class="correspondence"> + <div class="correspondence_text"><%= @info_request.outgoing_messages[0].get_body_for_html_display %></div> + </div> +<% end %> diff --git a/app/views/user/show.rhtml b/app/views/user/show.rhtml index baf6621df..8f1803442 100644 --- a/app/views/user/show.rhtml +++ b/app/views/user/show.rhtml @@ -1,4 +1,8 @@ -<% @title = h(@display_user.name) + " - Freedom of Information requests" %> +<% if @show_requests %> + <% @title = h(@display_user.name) + " - Freedom of Information requests" %> +<% else %> + <% @title = h(@display_user.name) + " - user profile" %> +<% end %> <% if (@same_name_users.size >= 1) %> <p><%= _('There is <strong>more than one person</strong> who uses this site and has this name. @@ -7,7 +11,7 @@ <% end %> <% end%> -<% if @is_you && @undescribed_requests.size > 0 %> +<% if @show_profile && @is_you && @undescribed_requests.size > 0 %> <div class="undescribed_requests"> <p><%= _('Please <strong>go to the following requests</strong>, and let us know if there was information in the recent responses to them.')%></p> @@ -24,17 +28,18 @@ </div> <% end %> +<% if @show_profile %> <div id="user_profile_header"> <div id="header_right"> - <h2><%= _('Track this person')%></h2> - <%= render :partial => 'track/tracking_links', :locals => { :track_thing => @track_thing, :own_request => false, :location => 'sidebar' } %> - - <h2><%= _('On this page')%></h2> - <a href="#foi_requests"><%= _('FOI requests')%></a> - <br><a href="#annotations"><%= _('Annotations')%></a> - <% if @is_you %> - <br><a href="#email_subscriptions"><%= _('Email subscriptions')%></a> - <% end %> + <% if !@track_thing.nil? %> + <h2><%= _('Track this person')%></h2> + <%= render :partial => 'track/tracking_links', :locals => { :track_thing => @track_thing, :own_request => false, :location => 'sidebar' } %> + <% end %> + <% if !@xapian_requests.nil? %> + <h2><%= _('On this page')%></h2> + <a href="#foi_requests"><%= _('FOI requests')%></a> + <br><a href="#annotations"><%= _('Annotations')%></a> + <% end %> </div> <div class="header_left"> @@ -76,7 +81,7 @@ <div id="user_public_banned"> <p> <strong> - <%= _('This user has been banned from {{site_name}} ', :site_name=>site_name)%> + <%= _('This user has been banned from {{site_name}} ', :site_name=>site_name)%> </strong> </p> <p> @@ -116,19 +121,20 @@ </div> </div> <div style="clear:both"></div> +<% end %> +<% if @show_requests %> <div id="user_profile_search"> - <% form_tag(show_user_url, :method => "get", :id=>"search_form") do %> - <div> - <%= text_field_tag(:user_query, params[:user_query]) %> - <% if @is_you %> - <%= submit_tag(_("Search your contributions")) %> - <% else %> - <%= submit_tag(_("Search contributions by this person")) %> - <% end %> - </div> - <% end %> - + <% form_tag(show_user_url, :method => "get", :id=>"search_form") do %> + <div> + <%= text_field_tag(:user_query, params[:user_query]) %> + <% if @is_you %> + <%= submit_tag(_("Search your contributions")) %> + <% else %> + <%= submit_tag(_("Search contributions by this person")) %> + <% end %> + </div> + <% end %> <% if !@xapian_requests.nil? %> <% if @xapian_requests.results.empty? %> @@ -136,16 +142,16 @@ <h2 class="foi_results" id="foi_requests"><%= @is_you ? 'Freedom of Information requests made by you' : 'Freedom of Information requests made by this person' %> <%= @match_phrase %> </h2> <p><%= @is_you ? _('You have made no Freedom of Information requests using this site.') : _('This person has made no Freedom of Information requests using this site.') %> - <%= @page_desc %> + <%= @page_desc %> <% end %> <% else %> <h2 class="foi_results" id="foi_requests"> - <%= @is_you ? n_('Your %d Freedom of Information request', 'Your %d Freedom of Information requests', @xapian_requests.results.size) % @xapian_requests.results.size : n_('This person\'s %d Freedom of Information request', 'This person\'s %d Freedom of Information requests', @xapian_requests.results.size) % @xapian_requests.results.size %> + <%= @is_you ? n_('Your %d Freedom of Information request', 'Your %d Freedom of Information requests', @xapian_requests.matches_estimated.to_s) % @xapian_requests.matches_estimated.to_s : n_('This person\'s %d Freedom of Information request', 'This person\'s %d Freedom of Information requests', @xapian_requests.matches_estimated.to_s) % @xapian_requests.matches_estimated %> <!-- matches_estimated <%=@xapian_requests.matches_estimated%> --> <%= @match_phrase %> - <%= @page_desc %> + <%= @page_desc %> </h2> - + <% for result in @xapian_requests.results %> <%= render :partial => 'request/request_listing_via_event', :locals => { :event => result[:model], :info_request => result[:model].info_request } %> @@ -154,17 +160,19 @@ <%= will_paginate WillPaginate::Collection.new(@page, @per_page, @display_user.info_requests.size) %> <% end %> <% else %> + <% if @show_requests %> <h2 class="foi_results" id="foi_requests"><%= @is_you ? _('Freedom of Information requests made by you') : _('Freedom of Information requests made by this person') %> </h2> <p><%= _('The search index is currently offline, so we can\'t show the Freedom of Information requests this person has made.')%></p> + <% end %> <% end %> <% if !@xapian_comments.nil? %> <% if @xapian_comments.results.empty? %> <% if @page == 1 %> <h2><%= @is_you ? _('Your annotations') : _('This person\'s annotations') %> - <%= @match_phrase %> - </h2> - <p><%= _('None made.')%></p> + <%= @match_phrase %> + </h2> + <p><%= _('None made.')%></p> <% end %> <% else %> <h2 id="annotations"> @@ -181,55 +189,56 @@ <% end %> <% end %> - <% if @is_you %> - <% if @track_things.empty? %> - <h2 id="email_subscriptions"> <%= _('Your email subscriptions')%></h2> - <p><%= _('None made.')%></p> - <% else %> - <h2 id="email_subscriptions"> Your <%=pluralize(@track_things.size, _('email subscription')) %> </h2> - <% if @track_things_grouped.size == 1 %> +</div> +<% end %> +<% if @show_profile && @is_you %> + <% if @track_things.empty? %> + <h2 id="email_subscriptions"> <%= _('Your email subscriptions')%></h2> + <p><%= _('None made.')%></p> + <% else %> + <h2 id="email_subscriptions"> Your <%=pluralize(@track_things.size, _('email subscription')) %> </h2> + <% if @track_things_grouped.size == 1 %> + <% form_tag({:controller => 'track', :action => 'delete_all_type'}, :class => "feed_form") do %> + <h3> + <%=TrackThing.track_type_description(@track_things[0].track_type)%> + <%= hidden_field_tag 'track_type', @track_things[0].track_type %> + <%= hidden_field_tag 'user', @display_user.id %> + <%= hidden_field_tag 'r', request.request_uri %> + <% if @track_things.size > 1 %> + <%= submit_tag _('unsubscribe all') %> + <% end %> + </h3> + <% end %> + <% end %> + <% for track_type, track_things in @track_things_grouped %> + <% if @track_things_grouped.size > 1 %> <% form_tag({:controller => 'track', :action => 'delete_all_type'}, :class => "feed_form") do %> <h3> - <%=TrackThing.track_type_description(@track_things[0].track_type)%> - <%= hidden_field_tag 'track_type', @track_things[0].track_type %> + <%=TrackThing.track_type_description(track_type)%> + <%= hidden_field_tag 'track_type', track_type %> <%= hidden_field_tag 'user', @display_user.id %> <%= hidden_field_tag 'r', request.request_uri %> - <% if @track_things.size > 1 %> - <%= submit_tag _('unsubscribe all') %> - <% end %> + <% if track_things.size > 1 %> + <%= submit_tag _('unsubscribe all')%> + <% end %> </h3> <% end %> <% end %> - <% for track_type, track_things in @track_things_grouped %> - <% if @track_things_grouped.size > 1 %> - <% form_tag({:controller => 'track', :action => 'delete_all_type'}, :class => "feed_form") do %> - <h3> - <%=TrackThing.track_type_description(track_type)%> - <%= hidden_field_tag 'track_type', track_type %> - <%= hidden_field_tag 'user', @display_user.id %> - <%= hidden_field_tag 'r', request.request_uri %> - <% if track_things.size > 1 %> - <%= submit_tag _('unsubscribe all')%> - <% end %> - </h3> - <% end %> - <% end %> - <ul> - <% for track_thing in track_things %> - <li> - <% form_tag({:controller => 'track', :action => 'update', :track_id => track_thing.id}, :class => "feed_form") do %> - <div> - <%= track_thing.params[:list_description] %> - <%= hidden_field_tag 'track_medium', "delete", { :id => 'track_medium_' + track_thing.id.to_s } %> - <%= hidden_field_tag 'r', request.request_uri, { :id => 'r_' + track_thing.id.to_s } %> - <%= submit_tag _('unsubscribe') %> - </div> - <% end %> - </li> - <% end %> - </ul> + <ul> + <% for track_thing in track_things %> + <li> + <% form_tag({:controller => 'track', :action => 'update', :track_id => track_thing.id}, :class => "feed_form") do %> + <div> + <%= track_thing.params[:list_description] %> + <%= hidden_field_tag 'track_medium', "delete", { :id => 'track_medium_' + track_thing.id.to_s } %> + <%= hidden_field_tag 'r', request.request_uri, { :id => 'r_' + track_thing.id.to_s } %> + <%= submit_tag _('unsubscribe') %> + </div> + <% end %> + </li> <% end %> + </ul> <% end %> <% end %> -</div>
\ No newline at end of file +<% end %> diff --git a/app/views/user/sign.rhtml b/app/views/user/sign.rhtml index afdb90162..bfd0fa63e 100644 --- a/app/views/user/sign.rhtml +++ b/app/views/user/sign.rhtml @@ -1,4 +1,4 @@ -<% if @post_redirect.reason_params[:user_name] %> +<% if !@post_redirect.nil? && @post_redirect.reason_params[:user_name] %> <% @title = _("Sign in") %> <div id="sign_alone"> @@ -19,16 +19,7 @@ <% else %> <% @title = _('Sign in or make a new account') %> - <div id="sign_together"> - - <!--<p id="sign_in_reason"> - <% if @post_redirect.reason_params[:web].empty? %> - <%= _(' Please sign in or make a new account.') %> - <% else %> - <%= @post_redirect.reason_params[:web] %>, <%= _('please sign in or make a new account.') %> - <% end %> - </p>--> - + <div id="sign_together"> <div id="left_half"> <h1><%= _('Sign in') %></h1> <%= render :partial => 'signin', :locals => { :sign_in_as_existing_user => false } %> diff --git a/commonlib b/commonlib -Subproject 16e32f0575107068ae1f16c26e31c598e4fef41 +Subproject c200fcbb73981113fcb2ccd132e1a2b386823c6 diff --git a/config/crontab.ugly b/config/crontab.ugly index 5f2fbdb3b..a22d5afd7 100644 --- a/config/crontab.ugly +++ b/config/crontab.ugly @@ -10,7 +10,7 @@ PATH=/usr/local/bin:/usr/bin:/bin MAILTO=cron-!!(*= $site *)!!@mysociety.org # Every 5 minutes -*/5 * * * * !!(*= $user *)!! run-with-lockfile -n /data/vhost/!!(*= $vhost *)!!/update-xapian-index.lock /data/vhost/!!(*= $vhost *)!!/!!(*= $vcspath *)!!/script/update-xapian-index || echo "stalled?" +*/5 * * * * !!(*= $user *)!! run-with-lockfile -n /data/vhost/!!(*= $vhost *)!!/change-xapian-database.lock "/data/vhost/!!(*= $vhost *)!!/!!(*= $vcspath *)!!/script/update-xapian-index verbose=true" >> /data/vhost/!!(*= $vhost *)!!/logs/update-xapian-index.log || echo "stalled?" # Every 10 minutes 5,15,25,35,45,55 * * * * !!(*= $user *)!! /etc/init.d/foi-alert-tracks check @@ -28,7 +28,7 @@ MAILTO=cron-!!(*= $site *)!!@mysociety.org 2 4 * * * !!(*= $user *)!! run-with-lockfile -n /data/vhost/!!(*= $vhost *)!!/check-recent-requests-sent.lock /data/vhost/!!(*= $vhost *)!!/!!(*= $vcspath *)!!/script/check-recent-requests-sent || echo "stalled?" 45 3 * * * !!(*= $user *)!! run-with-lockfile -n /data/vhost/!!(*= $vhost *)!!/stop-new-responses-on-old-requests.lock /data/vhost/!!(*= $vhost *)!!/!!(*= $vcspath *)!!/script/stop-new-responses-on-old-requests || echo "stalled?" # Only root can restart apache -31 1 * * * root run-with-lockfile -n /data/vhost/!!(*= $vhost *)!!/compact-xapian-database.lock "/data/vhost/!!(*= $vhost *)!!/!!(*= $vcspath *)!!/script/compact-xapian-database production" || echo "stalled?" +31 1 * * * root run-with-lockfile -n /data/vhost/!!(*= $vhost *)!!/change-xapian-database.lock "/data/vhost/!!(*= $vhost *)!!/!!(*= $vcspath *)!!/script/compact-xapian-database production" || echo "stalled?" # Once a day on all servers diff --git a/config/environment.rb b/config/environment.rb index d15ee9a0e..f2164f1c8 100644 --- a/config/environment.rb +++ b/config/environment.rb @@ -131,6 +131,9 @@ I18n.locale = default_locale I18n.available_locales = available_locales.map {|locale_name| locale_name.to_sym} I18n.default_locale = default_locale +# Customise will_paginate URL generation +WillPaginate::ViewHelpers.pagination_options[:renderer] = 'WillPaginateExtension::LinkRenderer' + # Load monkey patches and other things from lib/ require 'ruby19.rb' require 'tmail_extensions.rb' @@ -139,10 +142,13 @@ require 'timezone_fixes.rb' require 'use_spans_for_errors.rb' require 'make_html_4_compliant.rb' require 'activerecord_errors_extensions.rb' -require 'willpaginate_hack.rb' +require 'willpaginate_extension.rb' require 'sendmail_return_path.rb' require 'tnef.rb' require 'i18n_fixes.rb' require 'rack_quote_monkeypatch.rb' require 'world_foi_websites.rb' require 'alaveteli_external_command.rb' + +ExceptionNotification::Notifier.sender_address = MySociety::Config::get('EXCEPTION_NOTIFICATIONS_FROM') +ExceptionNotification::Notifier.exception_recipients = MySociety::Config::get('EXCEPTION_NOTIFICATIONS_TO') diff --git a/config/environments/test.rb b/config/environments/test.rb index 8058487ad..be28c3df6 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -1,5 +1,7 @@ # Settings specified here will take precedence over those in config/environment.rb +require 'lib/patches/fixtures_constraint_disabling' + # The test environment is used exclusively to run your application's # test suite. You never need to work with it otherwise. Remember that # your test database is "scratch space" for the test suite and is wiped @@ -18,6 +20,7 @@ config.action_controller.perform_caching = false # ActionMailer::Base.deliveries array. config.action_mailer.delivery_method = :test config.gem 'rspec-rails', :version => '>= 1.3.3', :lib => false unless File.directory?(File.join(Rails.root, 'vendor/plugins/rspec-rails')) +config.gem 'fakeweb', :version => '>=1.3.0' # Disable request forgery protection in test environment config.action_controller.allow_forgery_protection = false diff --git a/config/general.yml b/config/general.yml deleted file mode 100644 index 7c70f8e71..000000000 --- a/config/general.yml +++ /dev/null @@ -1,118 +0,0 @@ -# general.yml-example: -# Example values for the "general" config file. -# -# Configuration parameters, in YAML syntax. -# -# Copy this file to one called "general.yml" in the same directory. Or -# have multiple config files and use a symlink to change between them. - -# Site name appears in various places throughout the site -SITE_NAME: 'Alaveteli' - -# Domain used in URLs generated by scripts (e.g. for going in some emails) -DOMAIN: 'localhost:3000' - -# ISO country code of country currrently deployed in -# (http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) -ISO_COUNTRY_CODE: DE - -# These feeds are displayed accordingly on the Alaveteli "blog" page: -BLOG_FEED: 'http://www.mysociety.org/category/projects/whatdotheyknow/feed/' -TWITTER_USERNAME: 'alaveteli_foi' - -# Locales we wish to support in this app, space-delimited -AVAILABLE_LOCALES: 'en' -DEFAULT_LOCALE: 'en' - -# if 'true', respect the user's choice of language in the browser -USE_DEFAULT_BROWSER_LANGUAGE: true - -# How many days should have passed before an answer to a request is officially late? -REPLY_LATE_AFTER_DAYS: 20 -REPLY_VERY_LATE_AFTER_DAYS: 40 -# We give some types of authority like schools a bit longer than everyone else -SPECIAL_REPLY_VERY_LATE_AFTER_DAYS: 60 - -# example searches for the home page, semicolon delimited. -FRONTPAGE_SEARCH_EXAMPLES: 'Geraldine Quango; Department for Humpadinking' - -# example public bodies for the home page, semicolon delimited - short_names -FRONTPAGE_PUBLICBODY_EXAMPLES: 'tgq' - -# URL of theme to install (when running rails-post-deploy script) -THEME_URL: 'git://github.com/sebbacon/alavetelitheme.git' - - -## Incoming email -# Your email domain, e.g. 'foifa.com' -INCOMING_EMAIL_DOMAIN: 'localhost' - -# An optional prefix to help you distinguish FOI requests, e.g. 'foi+' -INCOMING_EMAIL_PREFIX: '' - -# used for hash in request email address -INCOMING_EMAIL_SECRET: 'xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx' - -# used as envelope from at the incoming email domain for cases where we don't care about failure -BLACKHOLE_PREFIX: 'do-not-reply-to-this-address' - -## Administration - -# Leave these two blank to skip admin authorisation -ADMIN_USERNAME: 'asd' -ADMIN_PASSWORD: 'qwe' - -# Email "from" details -CONTACT_EMAIL: 'postmaster@localhost' -CONTACT_NAME: 'Alaveteli Webmaster' - -# Where the raw incoming email data gets stored; make sure you back -# this up! -RAW_EMAILS_LOCATION: 'files/raw_emails' - -# The base URL for admin pages. You probably don't want to change this. -ADMIN_BASE_URL: '/admin/' - -# Where /stylesheets sits under for admin pages. See asset_host in -# config/environment.rb. Can be full domain or relative path (not an -# absolute path beginning with /). Again, unlikely to want to change -# this. -ADMIN_PUBLIC_URL: '' - -# Secret key for signing cookie_store sessions -COOKIE_STORE_SESSION_SECRET: 'your secret key here, make it long and random' - -# If present, puts the site in read only mode, and uses the text as reason -# (whole paragraph). Please use a read-only database user as well, as it only -# checks in a few obvious places. -READ_ONLY: '' - -# Doesn't do anything right now. -STAGING_SITE: 1 - -# Recaptcha, for detecting humans. Get keys here: http://recaptcha.net/whyrecaptcha.html -RECAPTCHA_PUBLIC_KEY: '6LcsnMcSAAAAAAL4FqMix7IOsEIwdMh42MuOFztv' -RECAPTCHA_PRIVATE_KEY: '6LcsnMcSAAAAAFjbWcf2dI874as0fmYSAiC9Jgvx' - -# For debugging memory problems. If true, the app logs -# the memory use increase of the Ruby process due to the -# request (Linux only). Since Ruby never returns memory to the OS, if the -# existing process previously served a larger request, this won't -# show any consumption for the later request. -DEBUG_RECORD_MEMORY: false - -# If you have Alaveteli set up behind an HTTP caching proxy -# (accelerator) like Varnish or Squid, you can cause the application -# to purge selected URLs by setting these two variables (see -# `../doc/CACHING.md` for details) -ACCELERATOR_HOST: 'localhost' -ACCELERATOR_PORT: '6081' - -# mySociety's gazeteer service. Shouldn't change. -GAZE_URL: http://gaze.mysociety.org - -# Path to a program that converts a page at a URL to HTML. It should -# take two arguments: the URL, and a path to an output file. A static -# binary of wkhtmltopdf is recommended: -# http://code.google.com/p/wkhtmltopdf/downloads/list -HTML_TO_PDF_COMMAND: /usr/local/bin/wkhtmltopdf-amd64
\ No newline at end of file diff --git a/config/general.yml-example b/config/general.yml-example index 8c59b1b0e..98f04d0bf 100644 --- a/config/general.yml-example +++ b/config/general.yml-example @@ -35,7 +35,7 @@ SPECIAL_REPLY_VERY_LATE_AFTER_DAYS: 60 FRONTPAGE_PUBLICBODY_EXAMPLES: 'tgq' # URL of theme to install (when running rails-post-deploy script) -THEME_URL: 'git://github.com/mysociety/whatdotheyknow-theme.git' +THEME_URL: 'git://github.com/sebbacon/alavetelitheme.git' # Whether a user needs to sign in to start the New Request process FORCE_REGISTRATION_ON_NEW_REQUEST: false @@ -129,4 +129,13 @@ FORWARD_NONBOUNCE_RESPONSES_TO: user-support@localhost # http://code.google.com/p/wkhtmltopdf/downloads/list # If the command is not present, a text-only version will be rendered # instead. -HTML_TO_PDF_COMMAND: /usr/local/bin/wkhtmltopdf-amd64
\ No newline at end of file +HTML_TO_PDF_COMMAND: /usr/local/bin/wkhtmltopdf-amd64 + +# Exception notifications +EXCEPTION_NOTIFICATIONS_FROM: do-not-reply-to-this-address@example.com +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/config/httpd.conf b/config/httpd.conf index 47e7f9c72..3bbe50fb3 100644 --- a/config/httpd.conf +++ b/config/httpd.conf @@ -34,10 +34,11 @@ RewriteRule /files/(.+) http://files.whatdotheyknow.com/$1 <IfModule mod_passenger.c> # Set this to something like 100 if you have memory leak issues - PassengerMaxRequests 0 + PassengerMaxRequests 20 PassengerResolveSymlinksInDocumentRoot on # Recommend setting this to 3 or less on servers with 512MB RAM PassengerMaxPoolSize 6 + RailsEnv production </IfModule> # Gzip font resources diff --git a/config/packages b/config/packages index a42785824..76a5c29d6 100644 --- a/config/packages +++ b/config/packages @@ -41,3 +41,4 @@ rubygems libfcgi-dev gettext python-yaml +wkhtmltopdf-static diff --git a/config/routes.rb b/config/routes.rb index 511b5fc1e..c4339209a 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -26,7 +26,7 @@ ActionController::Routing::Routes.draw do |map| # Couldn't find a way to do this in routes which also picked up multiple other slashes # and dots and other characters that can appear in search query. So we sort it all # out in the controller. - general.search_general '/search/*combined/requests', :action => 'search', :view => 'requests' + general.search_general '/search/*combined/all', :action => 'search', :view => 'all' general.search_general '/search/*combined', :action => 'search' general.advanced_search '/advancedsearch', :action => 'search_redirect', :advanced => true @@ -78,6 +78,8 @@ ActionController::Routing::Routes.draw do |map| user.confirm '/c/:email_token', :action => 'confirm' user.show_user '/user/:url_name.:format', :action => 'show' + user.show_user_profile '/user/:url_name/profile.:format', :action => 'show', :view => 'profile' + user.show_user_requests '/user/:url_name/requests.:format', :action => 'show', :view => 'requests' user.contact_user '/user/contact/:id', :action => 'contact' user.signchangepassword '/profile/change_password', :action => 'signchangepassword' @@ -167,6 +169,7 @@ ActionController::Routing::Routes.draw do |map| body.admin_body_create '/admin/body/create/:id', :action => 'create' body.admin_body_destroy '/admin/body/destroy/:id', :action => 'destroy' body.admin_body_import_csv '/admin/body/import_csv', :action => 'import_csv' + body.admin_body_mass_tag_add '/admin/body/mass_tag_add', :action => 'mass_tag_add' end map.with_options :controller => 'admin_general' do |admin| diff --git a/config/test.yml b/config/test.yml index c13b9c9db..6a423b47a 100644 --- a/config/test.yml +++ b/config/test.yml @@ -10,7 +10,7 @@ SITE_NAME: 'Alaveteli' # Domain used in URLs generated by scripts (e.g. for going in some emails) -DOMAIN: 'localhost:3000' +DOMAIN: 'test.localdomain' # ISO country code of country currrently deployed in # (http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) @@ -115,4 +115,11 @@ GAZE_URL: http://gaze.mysociety.org # take two arguments: the URL, and a path to an output file. A static # binary of wkhtmltopdf is recommended: # http://code.google.com/p/wkhtmltopdf/downloads/list -HTML_TO_PDF_COMMAND: /usr/local/bin/wkhtmltopdf-amd64
\ No newline at end of file +HTML_TO_PDF_COMMAND: /usr/local/bin/wkhtmltopdf-amd64 + +# Exception notifications +EXCEPTION_NOTIFICATIONS_FROM: do-not-reply-to-this-address@example.com +EXCEPTION_NOTIFICATIONS_TO: + +MAX_REQUESTS_PER_USER_PER_DAY: 2 + diff --git a/config/varnish-alaveteli.vcl b/config/varnish-alaveteli.vcl index 3312c381b..7eedf83fc 100644 --- a/config/varnish-alaveteli.vcl +++ b/config/varnish-alaveteli.vcl @@ -27,9 +27,9 @@ sub vcl_recv { remove req.http.X-Forwarded-For; set req.http.X-Forwarded-For = client.ip; - # Remove has_js and Google Analytics cookies. - set req.http.Cookie = regsuball(req.http.Cookie, "(^|;\s*)(__[a-z]+|has_js)=[^;]*", ""); - + # Remove Google Analytics, has_js, and last-seen cookies + set req.http.Cookie = regsuball(req.http.Cookie, "(^|;\s*)(__[a-z]+|has_js|has_seen_country_message|seen_foi2)=[^;]*", ""); + # Normalize the Accept-Encoding header if (req.http.Accept-Encoding) { if (req.url ~ "\.(jpg|jpeg|png|gif|gz|tgz|bz2|tbz|mp3|ogg|swf|flv|pdf|ico)$") { diff --git a/db/migrate/109_change_sent_at_to_datetime.rb b/db/migrate/109_change_sent_at_to_datetime.rb new file mode 100644 index 000000000..5fc9b29ae --- /dev/null +++ b/db/migrate/109_change_sent_at_to_datetime.rb @@ -0,0 +1,12 @@ +class ChangeSentAtToDatetime < ActiveRecord::Migration + def self.up + remove_column :incoming_messages, :sent_at + add_column :incoming_messages, :sent_at, :timestamp + ActiveRecord::Base.connection.execute("update incoming_messages set last_parsed = null") + end + + def self.down + remove_column :incoming_messages, :sent_at + add_column :incoming_messages, :sent_at, :time + end +end diff --git a/db/migrate/110_add_user_no_limit.rb b/db/migrate/110_add_user_no_limit.rb new file mode 100644 index 000000000..d78a05f75 --- /dev/null +++ b/db/migrate/110_add_user_no_limit.rb @@ -0,0 +1,13 @@ +require 'digest/sha1' + +class AddUserNoLimit < ActiveRecord::Migration + def self.up + add_column :users, :no_limit, :boolean, :default => false, :null => false + end + def self.down + remove_column :users, :no_limit + end +end + + + diff --git a/doc/CHANGES.md b/doc/CHANGES.md index 758e6b56e..d80acec3c 100644 --- a/doc/CHANGES.md +++ b/doc/CHANGES.md @@ -6,14 +6,23 @@ * 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 -* **IMPORTANT! We now depend on Xapian 1.2**, which means you may need to install Xapian from backports. See [issue #159] for more info. +* **IMPORTANT! We now depend on Xapian 1.2**, which means you may need to install Xapian from backports. See [issue #159](https://github.com/sebbacon/alaveteli/issues/159) for more info. * Themes created for 0.4 and below should be changed to match the new format (although the old way should continue to work): * You should create a resources folder at `<yourtheme>/public/` and symlink to it from the main rails app. See the `install.rb` in `alaveteli-theme` example theme for details. * Your styles should be moved from `general/custom_css.rhtml` to a standalone stylesheet in `<yourtheme>/public/stylesheets/` * The partial at `general/_before_head_end.rhtml` should be changed in the theme to include this stylesheet - +* [issue #281](https://github.com/sebbacon/alaveteli/issues/281) fixes some bugs relating to display of internationalised emails. To fix any wrongly displayed emails, you'll need to run the script at `script/clear-caches` so that the caches can be regenerated +* During this release, a bug was discovered in pdftk 1.44 which caused it to loop forever. Until it's incorporated into an official release, you'll need to patch it yourself or use the Debian package compiled by mySociety (see link in [issue 305](https://github.com/sebbacon/alaveteli/issues/305)) +* 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 # Version 0.4 diff --git a/doc/INSTALL.md b/doc/INSTALL.md index a666ac2f0..9dd05b93e 100644 --- a/doc/INSTALL.md +++ b/doc/INSTALL.md @@ -36,21 +36,31 @@ Some of the files also have a version number listed in config/packages - check that you have appropriate versions installed. Some also list "|" and offer a choice of packages. + You will also want to install mySociety's common ruby libraries and the Rails code. Run: - git submodule update --init + git submodule update --init to fetch the contents of the submodules. -Optionally, you may want to install -[wkhtmltopdf](http://code.google.com/p/wkhtmltopdf/downloads/list). +If you would like users to be able to download pretty PDFs as part of +the downloadable zipfile of their request history, you should also install +[wkhtmltopdf](http://code.google.com/p/wkhtmltopdf/downloads/list). We recommend downloading the latest, statically compiled version from the project website, as this allows running headless (i.e. without a graphical interface running) on Linux. If you do install `wkhtmltopdf`, you need to edit a setting in the config file to point -to it (see below). +to it (see below). If you don't install it, everything will still work, but +users will get ugly, plain text versions of their requests when they +download them. +Version 1.44 of `pdftk` contains a bug which makes it to loop forever +in certain edge conditions. Until it's incorporated into an official +release, you can either hope you don't encounter the bug (it ties up a +rails process until you kill it) you'll need to patch it yourself or +use the Debian package compiled by mySociety (see link in +[issue 305](https://github.com/sebbacon/alaveteli/issues/305)) # Configure Database @@ -77,8 +87,8 @@ constraints whilst running the tests they also need to be a superuser. The following command will set up a user 'foi' with password 'foi': - echo "CREATE DATABASE foi_development encoding = 'UTF8'; - CREATE DATABASE foi_test encoding = 'UTF8'; + echo "CREATE DATABASE foi_development encoding 'SQL_ASCII' template template0; + CREATE DATABASE foi_test encoding 'SQL_ASCII' template template0; CREATE USER foi WITH CREATEUSER; ALTER USER foi WITH PASSWORD 'foi'; ALTER USER foi WITH CREATEDB; @@ -86,6 +96,12 @@ The following command will set up a user 'foi' with password 'foi': GRANT ALL PRIVILEGES ON DATABASE foi_test TO foi; ALTER DATABASE foi_development OWNER TO foi; ALTER DATABASE foi_test OWNER TO foi;" | psql + +We create using the ``SQL_ASCII`` encoding, because in postgres this +is means "no encoding"; and because we handle and store all kinds of +data that may not be valid UTF (for example, data originating from +various broken email clients that's not 8-bit clean), it's safer to be +able to store *anything*, than reject data at runtime. # Configure email @@ -295,8 +311,9 @@ is supplied in `../conf/varnish-alaveteli.vcl`. to `/etc/elinks/elinks.conf`: set document.codepage.assume = "utf-8" - - You should also check that your locale is set up wrongly. See + set document.codepage.force_assumed = 1 + + You should also check that your locale is set up correctly. See [https://github.com/sebbacon/alaveteli/issues/128#issuecomment-1814845](this issue followup) for further discussion. diff --git a/doc/THEMES.md b/doc/THEMES.md index c2381b61f..55c0c017f 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 @@ -35,6 +39,10 @@ This document is about what you can do in a theme. To get started, install the sample theme by running ./script/plugin install git://github.com/sebbacon/alavetelitheme.git + +This downloads and installs the theme in +`vendor/plugins/alavetelitheme` and contains examples for nearly +everything you might want to customise. # Branding the site @@ -44,16 +52,23 @@ 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 stylesheet and associated resources for your theme live (by -convention) in at `alavatelitheme/public/`. This is symlinked from +convention) in at `alavetelitheme/public/`. This is symlinked from the main Rails app -- see `alavetelitheme/install.rb` to see how this happens. @@ -64,7 +79,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 +101,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 +135,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/doc/TRANSLATE.md b/doc/TRANSLATE.md index be88dafa0..639423f47 100644 --- a/doc/TRANSLATE.md +++ b/doc/TRANSLATE.md @@ -8,12 +8,14 @@ an account there (ask on the mailing list). # Summary 1. Make some changes to the software with `_('translatable strings')` -2. Run `./script/generate_pot.sh` -3. This should just cause the file at `locale/app.pot` to change. Commit and push -4. Send a message to the alaveteli-dev mailing list warning them that you're going to upload this file to transifex -5. Wait a day or so -6. Update the `app.pot` resource in Transifex -7. When new translations are available, run `tx pull -a` and commit the results to the repository +2. Temporarily move any theme containing translations out of the way (there's a bug in gettext_i18n_rails that can't cope with translation chains) +3. Run `./script/generate_pot.sh` +4. This should just cause the file at `locale/app.pot` to change. Commit and push +5. Move your theme back in place +6. Send a message to the alaveteli-dev mailing list warning them that you're going to upload this file to transifex +7. Wait a day or so to make sure they've uploaded any of their outstanding translations and have a copy of any old ones +8. Update the `app.pot` resource in Transifex +9. When new translations are available, run `tx pull -a` and commit the results to the repository # Detail diff --git a/lib/alaveteli_external_command.rb b/lib/alaveteli_external_command.rb index b967c89b5..b1d4f17d1 100644 --- a/lib/alaveteli_external_command.rb +++ b/lib/alaveteli_external_command.rb @@ -11,11 +11,26 @@ module AlaveteliExternalCommand opts = args.pop end - xc = ExternalCommand.new(program_name, *args) + if program_name =~ %r(^/) + program_path = program_name + else + utility_search_path = MySociety::Config.get("UTILITY_SEARCH_PATH", ["/usr/bin", "/usr/local/bin"]) + found = false + utility_search_path.each do |d| + program_path = File.join(d, program_name) + if File.file? program_path and File.executable? program_path + found = true + break + end + end + raise "Could not find #{program_name} in any of #{utility_search_path.join(', ')}" if !found + end + + xc = ExternalCommand.new(program_path, *args) if opts.has_key? :append_to xc.out = opts[:append_to] end - xc.run() + xc.run(opts[:stdin_string], opts[:env] || {}) if xc.status != 0 # Error $stderr.puts("Error from #{program_name} #{args.join(' ')}:") diff --git a/lib/i18n_fixes.rb b/lib/i18n_fixes.rb index fad258a72..6e684d44a 100644 --- a/lib/i18n_fixes.rb +++ b/lib/i18n_fixes.rb @@ -22,9 +22,9 @@ def gettext_interpolate(string, values) if escaped pattern elsif INTERPOLATION_RESERVED_KEYS.include?(pattern) - raise ReservedInterpolationKey.new(pattern, string) + raise I18n::ReservedInterpolationKey.new(pattern, string) elsif !values.include?(key) - raise MissingInterpolationArgument.new(pattern, string) + raise I18n::MissingInterpolationArgument.new(pattern, string) else values[key].to_s end diff --git a/lib/patches/fixtures_constraint_disabling.rb b/lib/patches/fixtures_constraint_disabling.rb new file mode 100644 index 000000000..7d97e81f7 --- /dev/null +++ b/lib/patches/fixtures_constraint_disabling.rb @@ -0,0 +1,21 @@ +# An alternative way of disabling foreign keys in fixture loading in Postgres and +# does not require superuser permissions +# http://kopongo.com/2008/7/25/postgres-ri_constrainttrigger-error +require 'active_record/connection_adapters/postgresql_adapter' +module ActiveRecord + module ConnectionAdapters + class PostgreSQLAdapter < AbstractAdapter + def disable_referential_integrity(&block) + transaction { + begin + execute "SET CONSTRAINTS ALL DEFERRED" + yield + ensure + execute "SET CONSTRAINTS ALL IMMEDIATE" + end + } + end + end + end +end + 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/lib/public_body_categories_en.rb b/lib/public_body_categories_en.rb index 5fe762357..95eed750b 100644 --- a/lib/public_body_categories_en.rb +++ b/lib/public_body_categories_en.rb @@ -1,83 +1,19 @@ -# lib/public_body_categories.rb: -# Categorisations of public bodies. +# The PublicBodyCategories structure works like this: +# [ +# "Main category name", +# [ "tag_to_use_as_category", "Sub category title", "sentence that can describes things in this subcategory" ], +# [ "another_tag", "Second sub category title", "another descriptive sentence for things in this subcategory"], +# "Another main category name", +# [ "another_tag_2", "Another sub category title", "another descriptive sentence"] +# ]) # -# Copyright (c) 2009 UK Citizens Online Democracy. All rights reserved. -# Email: francis@mysociety.org; WWW: http://www.mysociety.org/ -# -# $Id: public_body_categories.rb,v 1.1 2009-09-14 14:45:48 francis Exp $ +# DO NOT EDIT THIS FILE! It should be overridden in a custom theme. +# See doc/THEMES.md for more info PublicBodyCategories.add(:en, [ - "Miscellaneous", - [ "other", "Miscellaneous", "miscellaneous" ], - "Central government", - [ "department", "Ministerial departments", "a ministerial department" ], - [ "non_ministerial_department", "Non-ministerial departments", "a non-ministerial department" ], - [ "executive_agency", "Executive agencies", "an executive agency" ], - [ "government_office", "Government offices for the regions", "a government office for the regions" ], - [ "advisory_committee", "Advisory committees", "an advisory committee" ], - [ "awc", "Agricultural wages committees", "an agriculatural wages committee" ], - [ "adhac", "Agricultural dwelling house advisory committees", "an agriculatural dwelling house advisory committee" ], - [ "newdeal", "New Deal for Communities partnership", "a New Deal for Communities partnership" ], - "Local and regional", - [ "local_council", "Local councils", "a local council" ], - [ "parish_council", "Town and Parish councils", "a town or parish council"], - [ "housing_association", "Housing associations", "a housing association"], - [ "almo", "Housing ALMOs", "a housing ALMO"], - [ "municipal_bank", "Municipal bank", "a municipal bank"], - [ "nsbody", "North/south bodies", "a north/south body"], - [ "pbo", "Professional buying organisations", "a professional buying organisation"], - [ "regional_assembly", "Regional assemblies", "a regional assembly"], - [ "rda", "Regional development agencies", "a regional development agency" ], - "Education", - [ "university", "Universities", "a university" ], - [ "university_college", "University colleges", "a university college" ], - [ "cambridge_college", "Cambridge colleges", "a Cambridge college" ], - [ "durham_college", "Durham colleges", "a Durham college" ], - [ "oxford_college", "Oxford colleges", "an Oxford college or permanent private hall" ], - [ "york_college", "York colleges", "a college of the University of York" ], - [ "university_owned_company", "University owned companies", "a university owned company" ], - [ "hei", "Higher education institutions", "a higher educational institution" ], - [ "fei", "Further education institutions", "a further educational institution" ], - [ "school", "Schools", "a school" ], - [ "research_council", "Research councils", "a research council" ], - [ "lib_board", "Education and library boards", "an education and library board" ], - [ "rbc", "Regional Broadband Consortia", "a Regional Broadband Consortium" ], - "Environment", - [ "npa", "National park authorities", "a national park authority" ], - [ "rpa", "Regional park authorities", "a regional park authority" ], - [ "sea_fishery_committee", "Sea fisheries committees", "a sea fisheries committee" ], - [ "watercompanies", "Water companies", "a water company" ], - [ "idb", "Internal drainage boards", "an internal drainage board" ], - [ "rfdc", "Regional flood defence committees", "a regional flood defence committee" ], - [ "wda", "Waste disposal authorities", "a waste disposal authority" ], - [ "zoo", "Zoos", "a zoo" ], - "Health", - [ "nhstrust", "NHS trusts", "an NHS trust" ], - [ "pct", "Primary care trusts", "a primary care trust" ], - [ "nhswales", "NHS in Wales", "part of the NHS in Wales" ], - [ "nhsni", "NHS in Northern Ireland", "part of the NHS in Northern Ireland" ], - [ "hscr", "Health / social care", "Relating to health / social care" ], - [ "pha", "Port health authorities", "a port health authority"], - [ "sha", "Strategic health authorities", "a strategic health authority" ], - [ "specialha", "Special health authorities", "a special health authority" ], - "Media and culture", - [ "media", "Media", "a media organisation" ], - [ "rcc", "Cultural consortia", "a cultural consortium"], - [ "museum", "Museums and galleries", "a museum or gallery" ], - "Military and security services", - [ "military_college", "Military colleges", "a military college" ], - [ "security_services", "Security services", "a security services body" ], - "Emergency services and the courts", - [ "police", "Police forces", "a police force" ], - [ "police_authority", "Police authorities", "a police authority" ], - [ "dpp", "District policing partnerships", "a district policing partnership" ], - [ "fire_service", "Fire and rescue services", "a fire and rescue service" ], - [ "prob_board", "Probation boards", "a probation board" ], - [ "rules_committee", "Rules commitees", "a rules committee" ], - [ "tribunal", "Tribunals", "a tribunal"], - "Transport", - [ "npte", "Passenger transport executives", "a passenger transport executive" ], - [ "port_authority", "Port authorities", "a port authority" ], - [ "scp", "Safety Camera Partnerships", "a safety camera partnership" ], - [ "srp", "Safer Roads Partnership", "a safer roads partnership" ] + "Silly ministries", + [ "useless_agency", "Useless ministries", "a useless ministry" ], + [ "lonely_agency", "Lonely agencies", "a lonely agency"], + "Popular agencies", + [ "popular_agency", "Popular agencies", "a lonely agency"] ]) diff --git a/lib/tasks/gettext.rake b/lib/tasks/gettext.rake index 017e7c837..8ffd5ce1b 100644 --- a/lib/tasks/gettext.rake +++ b/lib/tasks/gettext.rake @@ -1,5 +1,23 @@ namespace :gettext do + + desc "Update pot file only, without fuzzy guesses (these are done by Transifex)" + task :findpot => :environment do + load_gettext + $LOAD_PATH << File.join(File.dirname(__FILE__),'..','..','lib') + require 'gettext_i18n_rails/haml_parser' + files = files_to_translate + + #write found messages to tmp.pot + temp_pot = "tmp.pot" + GetText::rgettext(files, temp_pot) + + #merge tmp.pot and existing pot + FileUtils.mkdir_p('locale') + GetText::msgmerge("locale/app.pot", temp_pot, "version 0.0.1", :po_root => 'locale', :msgmerge=>[ :no_fuzzy_matching, :sort_output ]) + File.delete(temp_pot) + end + def files_to_translate Dir.glob("{app,lib,config,locale}/**/*.{rb,erb,haml,rhtml}") end -end
\ No newline at end of file +end diff --git a/lib/tmail_extensions.rb b/lib/tmail_extensions.rb index 6a5044cdb..f35565352 100644 --- a/lib/tmail_extensions.rb +++ b/lib/tmail_extensions.rb @@ -30,7 +30,7 @@ module TMail # Monkeypatch! Return the name part of from address, or nil if there isn't one def from_name_if_present if self.from && self.from_addrs[0].name - return self.from_addrs[0].name + return TMail::Unquoter.unquote_and_convert_to(self.from_addrs[0].name, "utf-8") else return nil end diff --git a/lib/willpaginate_extension.rb b/lib/willpaginate_extension.rb new file mode 100644 index 000000000..3cdb0ae60 --- /dev/null +++ b/lib/willpaginate_extension.rb @@ -0,0 +1,59 @@ +# this extension is loaded in environment.rb +module WillPaginateExtension + class LinkRenderer < WillPaginate::LinkRenderer + def page_link(page, text, attributes = {}) + # Hack for admin pages, when proxied via https on mySociety servers, they + # need a relative URL. + url = url_for(page) + if url.match(/\/admin.*(\?.*)/) + url = $1 + end + # Hack around our type-ahead search magic + if url.match(/\/body\/search_ahead/) + url.sub!("/body/search_ahead", "/select_authority") + end + @template.link_to text, url, attributes + end + + # Returns URL params for +page_link_or_span+, taking the current GET params + # and <tt>:params</tt> option into account. + def url_for(page) + page_one = page == 1 + unless @url_string and !page_one + @url_params = {} + # page links should preserve GET parameters + stringified_merge @url_params, @template.params if @template.request.get? + stringified_merge @url_params, @options[:params] if @options[:params] + if complex = param_name.index(/[^\w-]/) + page_param = parse_query_parameters("#{param_name}=#{page}") + + stringified_merge @url_params, page_param + else + @url_params[param_name] = page_one ? 1 : 2 + end + # the following line makes pagination work on our specially munged search page + combined = @template.request.path_parameters["combined"] + @url_params["combined"] = combined if !combined.nil? + url = @template.url_for(@url_params) + return url if page_one + + if complex + @url_string = url.sub(%r!((?:\?|&)#{CGI.escape param_name}=)#{page}!, "\\1\0") + return url + else + @url_string = url + @url_params[param_name] = 3 + @template.url_for(@url_params).split(//).each_with_index do |char, i| + if char == '3' and url[i, 1] == '2' + @url_string[i] = "\0" + break + end + end + end + end + # finally! + @url_string.sub "\0", page.to_s + end + + end +end diff --git a/lib/willpaginate_hack.rb b/lib/willpaginate_hack.rb deleted file mode 100644 index 084329e82..000000000 --- a/lib/willpaginate_hack.rb +++ /dev/null @@ -1,14 +0,0 @@ -# Monkeypatch! Hack for admin pages, when proxied via https on mySociety servers, they -# need a relative URL. -module WillPaginate - class LinkRenderer - def page_link(page, text, attributes = {}) - url = url_for(page) - if url.match(/^\/admin.*(\?.*)/) - url = $1 - end - @template.link_to text, url, attributes - end - end -end - diff --git a/locale/app.pot b/locale/app.pot index 2b14b8b9d..60c9745d6 100644 --- a/locale/app.pot +++ b/locale/app.pot @@ -7,3811 +7,4603 @@ msgid "" msgstr "" "Project-Id-Version: version 0.0.1\n" -"POT-Creation-Date: 2011-10-09 01:10+0200\n" +"POT-Creation-Date: 2012-02-02 14:42-0000\n" "PO-Revision-Date: 2011-10-09 01:10+0200\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" +"Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" -#: app/controllers/application_controller.rb:298 -msgid "<p>{{site_name}} is currently in maintenance. You can only view existing requests. You cannot make new ones, add followups or annotations, or otherwise change the database.</p> <p>{{read_only}}</p>" +#: app/models/incoming_message.rb:667 +msgid "" +"\n" +"\n" +"[ {{site_name}} note: The above text was badly encoded, and has had strange " +"characters removed. ]" msgstr "" -#: app/controllers/comment_controller.rb:55 -msgid "To post your annotation" +#: app/views/user/set_profile_about_me.rhtml:14 +msgid "" +" This will appear on your {{site_name}} profile, to make it\n" +" easier for others to get involved with what you're doing." msgstr "" -#: app/controllers/comment_controller.rb:56 -msgid "Then your annotation to {{info_request_title}} will be posted." +#: app/views/comment/_comment_form.rhtml:16 +msgid "" +" (<strong>no ranty</strong> politics, read our <a href=\"%s\">moderation " +"policy</a>)" msgstr "" -#: app/controllers/comment_controller.rb:57 -msgid "Confirm your annotation to {{info_request_title}}" +#: app/views/request/upload_response.rhtml:40 +msgid "" +" (<strong>patience</strong>, especially for large files, it may take a " +"while!)" msgstr "" -#: app/controllers/comment_controller.rb:62 -msgid "Thank you for making an annotation!" +#: app/views/user/show.rhtml:64 +msgid " (you)" msgstr "" -#: app/controllers/comment_controller.rb:73 -msgid " You will also be emailed updates about the request." +#: app/views/public_body/show.rhtml:1 +msgid " - view and make Freedom of Information requests" msgstr "" -#: app/controllers/comment_controller.rb:75 -msgid " You are already being emailed updates about the request." +#: app/views/user/signchangepassword_send_confirm.rhtml:18 +msgid "" +" <strong>Note:</strong>\n" +" We will send you an email. Follow the instructions in it to change\n" +" your password." msgstr "" -#: app/controllers/help_controller.rb:63 -msgid "Your message has been sent. Thank you for getting in touch! We'll get back to you soon." +#: app/views/user/contact.rhtml:35 +msgid " <strong>Privacy note:</strong> Your email address will be given to" msgstr "" -#: app/controllers/public_body_controller.rb:82 app/controllers/user_controller.rb:140 -msgid "There was an error with the words you entered, please try again." +#: app/views/comment/new.rhtml:34 +msgid " <strong>Summarise</strong> the content of any information returned. " msgstr "" -#: app/controllers/public_body_controller.rb:123 -msgid "beginning with" +#: app/views/comment/new.rhtml:24 +msgid " Advise on how to <strong>best clarify</strong> the request." msgstr "" -#: app/controllers/request_controller.rb:31 app/controllers/request_controller.rb:303 -msgid "To send your FOI request" +#: app/views/comment/new.rhtml:50 +msgid "" +" Ideas on what <strong>other documents to request</strong> which the " +"authority may hold. " msgstr "" -#: app/controllers/request_controller.rb:32 -msgid "Then you'll be allowed to send FOI requests." +#: app/views/public_body/view_email.rhtml:30 +msgid "" +" If you know the address to use, then please <a href=\"%s\">send it to us</" +"a>.\n" +" You may be able to find the address on their website, or by phoning " +"them up and asking." msgstr "" -#: app/controllers/request_controller.rb:33 -msgid "Confirm your email address" +#: app/views/user/set_profile_about_me.rhtml:26 +msgid "" +" Include relevant links, such as to a campaign page, your blog or a\n" +" twitter account. They will be made clickable. \n" +" e.g." msgstr "" -#: app/controllers/request_controller.rb:81 -msgid "To update the status of this FOI request" +#: app/views/comment/new.rhtml:28 +msgid "" +" Link to the information requested, if it is <strong>already available</" +"strong> on the Internet. " msgstr "" -#: app/controllers/request_controller.rb:82 -msgid "Then you can update the status of your request to " +#: app/views/comment/new.rhtml:30 +msgid "" +" Offer better ways of <strong>wording the request</strong> to get the " +"information. " msgstr "" -#: app/controllers/request_controller.rb:83 -msgid "Update the status of your request to " +#: app/views/comment/new.rhtml:35 +msgid "" +" Say how you've <strong>used the information</strong>, with links if " +"possible." msgstr "" -#: app/controllers/request_controller.rb:155 -msgid "View and search requests" +#: app/views/comment/new.rhtml:29 +msgid "" +" Suggest <strong>where else</strong> the requester might find the " +"information. " msgstr "" -#: app/controllers/request_controller.rb:285 -msgid "<p>You do not need to include your email in the request in order to get a reply, as we will ask for it on the next screen (<a href=\"%s\">details</a>).</p>" +#: app/views/user/set_profile_about_me.rhtml:11 +msgid " What are you investigating using Freedom of Information? " msgstr "" -#: app/controllers/request_controller.rb:287 -msgid "<p>You do not need to include your email in the request in order to get a reply (<a href=\"%s\">details</a>).</p>" +#: app/controllers/comment_controller.rb:75 +msgid " You are already being emailed updates about the request." msgstr "" -#: app/controllers/request_controller.rb:289 -msgid "<p>We recommend that you edit your request and remove the email address.\n If you leave it, the email address will be sent to the authority, but will not be displayed on the site.</p>" +#: app/controllers/comment_controller.rb:73 +msgid " You will also be emailed updates about the request." msgstr "" -#: app/controllers/request_controller.rb:293 -msgid "<p>Your request contains a <strong>postcode</strong>. Unless it directly relates to the subject of your request, please remove any address as it will <strong>appear publicly on the Internet</strong>.</p>" +#: app/views/request/upload_response.rhtml:5 +msgid " made by " msgstr "" -#: app/controllers/request_controller.rb:304 -msgid "Then your FOI request to {{public_body_name}} will be sent." +#: app/models/track_thing.rb:111 app/models/track_thing.rb:119 +msgid " or " msgstr "" -#: app/controllers/request_controller.rb:305 -msgid "Confirm your FOI request to " +#: app/views/user/contact.rhtml:36 +msgid " when you send this message." msgstr "" -#: app/controllers/request_controller.rb:316 -msgid "<p>Your {{law_used_full}} request has been <strong>sent on its way</strong>!</p>\n <p><strong>We will email you</strong> when there is a response, or after {{late_number_of_days}} working days if the authority still hasn't\n replied by then.</p>\n <p>If you write about this request (for example in a forum or a blog) please link to this page, and add an \n annotation below telling people about your writing.</p>" +#: app/views/public_body/show.rhtml:87 +msgid "%d Freedom of Information request to %s" +msgid_plural "%d Freedom of Information requests to %s" +msgstr[0] "" +msgstr[1] "" + +#: app/views/general/frontpage.rhtml:43 +msgid "%d request" +msgid_plural "%d requests" +msgstr[0] "" +msgstr[1] "" + +#: app/views/public_body/_body_listing_single.rhtml:21 +msgid "%d request made." +msgid_plural "%d requests made." +msgstr[0] "" +msgstr[1] "" + +#: app/views/request/new.rhtml:92 +msgid "'Crime statistics by ward level for Wales'" msgstr "" -#: app/controllers/request_controller.rb:343 -msgid "To classify the response to this FOI request" +#: app/views/request/new.rhtml:90 +msgid "'Pollution levels over time for the River Tyne'" msgstr "" -#: app/controllers/request_controller.rb:344 -msgid "Then you can classify the FOI response you have got from " +#: app/models/track_thing.rb:245 +msgid "'{{link_to_authority}}', a public authority" msgstr "" -#: app/controllers/request_controller.rb:345 -msgid "Classify an FOI response from " +#: app/models/track_thing.rb:194 +msgid "'{{link_to_request}}', a request" msgstr "" -#: app/controllers/request_controller.rb:352 -msgid "Please choose whether or not you got some of the information that you wanted." +#: app/models/track_thing.rb:261 +msgid "'{{link_to_user}}', a person" msgstr "" -#: app/controllers/request_controller.rb:358 -msgid "The request has been updated since you originally loaded this page. Please check for any new incoming messages below, and try again." +#: app/controllers/user_controller.rb:387 +msgid "" +",\n" +"\n" +"\n" +"\n" +"Yours,\n" +"\n" +"{{user_name}}" msgstr "" -#: app/controllers/request_controller.rb:384 -msgid "Thank you for updating the status of the request '<a href=\"{{url}}\">{{info_request_title}}</a>'. There are some more requests below for you to classify." +#: app/views/user/sign.rhtml:28 +msgid "- or -" msgstr "" -#: app/controllers/request_controller.rb:387 -msgid "Thank you for updating this request!" +#: app/views/request/select_authority.rhtml:30 +msgid "1. Select an authority" msgstr "" -#: app/controllers/request_controller.rb:395 -msgid "<p>Thank you! Hopefully your wait isn't too long.</p> <p>By law, you should get a response promptly, and normally before the end of <strong>\n{{date_response_required_by}}</strong>.</p>" +#: app/views/request/new.rhtml:22 +msgid "2. Ask for Information" msgstr "" -#: app/controllers/request_controller.rb:399 -msgid "<p>Thank you! Hope you don't have to wait much longer.</p> <p>By law, you should have got a response promptly, and normally before the end of <strong>{{date_response_required_by}}</strong>.</p>" +#: app/views/request/preview.rhtml:5 +msgid "3. Now check your request" msgstr "" -#: app/controllers/request_controller.rb:402 -msgid "<p>Thank you! Your request is long overdue, by more than {{very_late_number_of_days}} working days. Most requests should be answered within {{late_number_of_days}} working days. You might like to complain about this, see below.</p>" +#: app/views/public_body/show.rhtml:56 +msgid "<a class=\"link_button_green\" href=\"{{url}}\">{{text}}</a>" msgstr "" -#: app/controllers/request_controller.rb:405 -msgid "<p>Thank you! Here are some ideas on what to do next:</p>\n <ul>\n <li>To send your request to another authority, first copy the text of your request below, then <a href=\"{{find_authority_url}}\">find the other authority</a>.</li>\n <li>If you would like to contest the authority's claim that they do not hold the information, here is \n <a href=\"{{complain_url}}\">how to complain</a>.\n </li>\n <li>We have <a href=\"{{other_means_url}}\">suggestions</a>\n on other means to answer your question.\n </li>\n </ul>" +#: app/views/request/_after_actions.rhtml:9 +msgid "<a href=\"%s\">Add an annotation</a> (to help the requester or others)" msgstr "" -#: app/controllers/request_controller.rb:420 -msgid "Oh no! Sorry to hear that your request was refused. Here is what to do now." +#: app/views/public_body/list.rhtml:29 +msgid "<a href=\"%s\">Are we missing a public authority?</a>." msgstr "" -#: app/controllers/request_controller.rb:423 -msgid "<p>We're glad you got all the information that you wanted. If you write about or make use of the information, please come back and add an annotation below saying what you did.</p><p>If you found {{site_name}} useful, <a href=\"{{donation_url}}\">make a donation</a> to the charity which runs it.</p>" +#: app/views/request/_sidebar.rhtml:39 +msgid "" +"<a href=\"%s\">Are you the owner of\n" +" any commercial copyright on this page?</a>" msgstr "" -#: app/controllers/request_controller.rb:426 -msgid "<p>We're glad you got some of the information that you wanted. If you found {{site_name}} useful, <a href=\"{{donation_url}}\">make a donation</a> to the charity which runs it.</p><p>If you want to try and get the rest of the information, here's what to do now.</p>" +#: app/views/general/search.rhtml:168 +msgid "<a href=\"%s\">Browse all</a> or <a href=\"%s\">ask us to add one</a>." msgstr "" -#: app/controllers/request_controller.rb:429 -msgid "Please write your follow up message containing the necessary clarifications below." +#: app/views/public_body/list.rhtml:51 +msgid "<a href=\"%s\">Can't find the one you want?</a>" msgstr "" -#: app/controllers/request_controller.rb:434 -msgid "<p>Thank you! Hopefully your wait isn't too long.</p><p>You should get a response within {{late_number_of_days}} days, or be told if it will take longer (<a href=\"{{review_url}}\">details</a>).</p>" +#: app/views/user/show.rhtml:118 +msgid "" +"<a href=\"%s\">Sign in</a> to change password, subscriptions and more " +"({{user_name}} only)" msgstr "" -#: app/controllers/request_controller.rb:437 -msgid "<p>Thank you! We'll look into what happened and try and fix it up.</p><p>If the error was a delivery failure, and you can find an up to date FOI email address for the authority, please tell us using the form below.</p>" +#: app/views/request/_followup.rhtml:66 app/views/request/_followup.rhtml:73 +#: app/views/request/show.rhtml:83 app/views/request/show.rhtml:87 +msgid "<a href=\"%s\">details</a>" msgstr "" -#: app/controllers/request_controller.rb:440 -msgid "Please use the form below to tell us more." +#: app/views/request/_followup.rhtml:101 +msgid "<a href=\"%s\">what's that?</a>" msgstr "" -#: app/controllers/request_controller.rb:443 -msgid "If you have not done so already, please write a message below telling the authority that you have withdrawn your request. Otherwise they will not know it has been withdrawn." +#: app/controllers/request_game_controller.rb:23 +msgid "" +"<p>All done! Thank you very much for your help.</p><p>There are <a href=" +"\"{{helpus_url}}\">more things you can do</a> to help {{site_name}}.</p>" msgstr "" -#: app/controllers/request_controller.rb:548 -msgid "To send a follow up message to " +#: app/controllers/request_controller.rb:439 +msgid "" +"<p>Thank you! Here are some ideas on what to do next:</p>\n" +" <ul>\n" +" <li>To send your request to another authority, first copy the " +"text of your request below, then <a href=\"{{find_authority_url}}\">find the " +"other authority</a>.</li>\n" +" <li>If you would like to contest the authority's claim that they " +"do not hold the information, here is \n" +" <a href=\"{{complain_url}}\">how to complain</a>.\n" +" </li>\n" +" <li>We have <a href=\"{{other_means_url}}\">suggestions</a>\n" +" on other means to answer your question.\n" +" </li>\n" +" </ul>" +msgstr "" + +#: app/controllers/request_controller.rb:433 +msgid "" +"<p>Thank you! Hope you don't have to wait much longer.</p> <p>By law, you " +"should have got a response promptly, and normally before the end of <strong>" +"{{date_response_required_by}}</strong>.</p>" msgstr "" -#: app/controllers/request_controller.rb:549 -msgid "To reply to " +#: app/controllers/request_controller.rb:429 +msgid "" +"<p>Thank you! Hopefully your wait isn't too long.</p> <p>By law, you should " +"get a response promptly, and normally before the end of <strong>\n" +"{{date_response_required_by}}</strong>.</p>" msgstr "" -#: app/controllers/request_controller.rb:551 -msgid "Then you can write follow up message to " +#: app/controllers/request_controller.rb:468 +msgid "" +"<p>Thank you! Hopefully your wait isn't too long.</p><p>You should get a " +"response within {{late_number_of_days}} days, or be told if it will take " +"longer (<a href=\"{{review_url}}\">details</a>).</p>" msgstr "" -#: app/controllers/request_controller.rb:552 -msgid "Then you can write your reply to " +#: app/controllers/request_controller.rb:471 +msgid "" +"<p>Thank you! We'll look into what happened and try and fix it up.</p><p>If " +"the error was a delivery failure, and you can find an up to date FOI email " +"address for the authority, please tell us using the form below.</p>" msgstr "" -#: app/controllers/request_controller.rb:554 -msgid "Write your FOI follow up message to " +#: app/controllers/request_controller.rb:436 +msgid "" +"<p>Thank you! Your request is long overdue, by more than " +"{{very_late_number_of_days}} working days. Most requests should be answered " +"within {{late_number_of_days}} working days. You might like to complain " +"about this, see below.</p>" msgstr "" -#: app/controllers/request_controller.rb:555 -msgid "Write a reply to " +#: app/controllers/user_controller.rb:528 +msgid "" +"<p>Thanks for changing the text about you on your profile.</p>\n" +" <p><strong>Next...</strong> You can upload a profile photograph " +"too.</p>" msgstr "" -#: app/controllers/request_controller.rb:562 -msgid "Your follow up has not been sent because this request has been stopped to prevent spam. Please <a href=\"%s\">contact us</a> if you really want to send a follow up message." +#: app/controllers/user_controller.rb:449 +msgid "" +"<p>Thanks for updating your profile photo.</p>\n" +" <p><strong>Next...</strong> You can put some text about you " +"and your research on your profile.</p>" msgstr "" -#: app/controllers/request_controller.rb:565 -msgid "You previously submitted that exact follow up message for this request." +#: app/controllers/request_controller.rb:318 +msgid "" +"<p>We recommend that you edit your request and remove the email address.\n" +" If you leave it, the email address will be sent to the " +"authority, but will not be displayed on the site.</p>" msgstr "" -#: app/controllers/request_controller.rb:588 -msgid "Your internal review request has been sent on its way." +#: app/controllers/request_controller.rb:457 +msgid "" +"<p>We're glad you got all the information that you wanted. If you write " +"about or make use of the information, please come back and add an annotation " +"below saying what you did.</p><p>If you found {{site_name}} useful, <a href=" +"\"{{donation_url}}\">make a donation</a> to the charity which runs it.</p>" msgstr "" -#: app/controllers/request_controller.rb:590 -msgid "Your follow up message has been sent on its way." +#: app/controllers/request_controller.rb:460 +msgid "" +"<p>We're glad you got some of the information that you wanted. If you found " +"{{site_name}} useful, <a href=\"{{donation_url}}\">make a donation</a> to " +"the charity which runs it.</p><p>If you want to try and get the rest of the " +"information, here's what to do now.</p>" msgstr "" -#: app/controllers/request_controller.rb:712 -msgid "To upload a response, you must be logged in using an email address from " +#: app/controllers/request_controller.rb:316 +msgid "" +"<p>You do not need to include your email in the request in order to get a " +"reply (<a href=\"%s\">details</a>).</p>" msgstr "" -#: app/controllers/request_controller.rb:713 -msgid "Then you can upload an FOI response. " +#: app/controllers/request_controller.rb:314 +msgid "" +"<p>You do not need to include your email in the request in order to get a " +"reply, as we will ask for it on the next screen (<a href=\"%s\">details</a>)." +"</p>" msgstr "" -#: app/controllers/request_controller.rb:714 app/controllers/user_controller.rb:542 -msgid "Confirm your account on {{site_name}}" +#: app/controllers/request_controller.rb:322 +msgid "" +"<p>Your request contains a <strong>postcode</strong>. Unless it directly " +"relates to the subject of your request, please remove any address as it will " +"<strong>appear publicly on the Internet</strong>.</p>" msgstr "" -#: app/controllers/request_controller.rb:741 -msgid "Please type a message and/or choose a file containing your response." +#: app/controllers/request_controller.rb:350 +msgid "" +"<p>Your {{law_used_full}} request has been <strong>sent on its way</strong>!" +"</p>\n" +" <p><strong>We will email you</strong> when there is a response, " +"or after {{late_number_of_days}} working days if the authority still hasn't\n" +" replied by then.</p>\n" +" <p>If you write about this request (for example in a forum or a " +"blog) please link to this page, and add an \n" +" annotation below telling people about your writing.</p>" msgstr "" -#: app/controllers/request_controller.rb:747 -msgid "Thank you for responding to this FOI request! Your response has been published below, and a link to your response has been emailed to " +#: app/controllers/application_controller.rb:311 +msgid "" +"<p>{{site_name}} is currently in maintenance. You can only view existing " +"requests. You cannot make new ones, add followups or annotations, or " +"otherwise change the database.</p> <p>{{read_only}}</p>" msgstr "" -#: app/controllers/request_controller.rb:773 -msgid "To download the zip file" +#: app/views/user/confirm.rhtml:11 +msgid "" +"<small>If you use web-based email or have \"junk mail\" filters, also check " +"your\n" +"bulk/spam mail folders. Sometimes, our messages are marked that way.</" +"small>\n" +"</p>" msgstr "" -#: app/controllers/request_controller.rb:774 -msgid "Then you can download a zip file of {{info_request_title}}." +#: app/views/request/new.rhtml:135 +msgid "" +"<strong> Can I request information about myself?</strong>\n" +"\t\t\t<a href=\"%s\">No! (Click here for details)</a>" msgstr "" -#: app/controllers/request_controller.rb:775 -msgid "Log in to download a zip file of {{info_request_title}}" +#: app/views/general/_advanced_search_tips.rhtml:12 +msgid "" +"<strong><code>commented_by:tony_bowden</code></strong> to search annotations " +"made by Tony Bowden, typing the name as in the URL." msgstr "" -#: app/controllers/request_game_controller.rb:23 -msgid "<p>All done! Thank you very much for your help.</p><p>There are <a href=\"{{helpus_url}}\">more things you can do</a> to help {{site_name}}.</p>" +#: app/views/general/_advanced_search_tips.rhtml:14 +msgid "" +"<strong><code>filetype:pdf</code></strong> to find all responses with PDF " +"attachments. Or try these: <code>{{list_of_file_extensions}}</code>" msgstr "" -#: app/controllers/request_game_controller.rb:40 -msgid "To play the request categorisation game" +#: app/views/general/_advanced_search_tips.rhtml:13 +msgid "" +"<strong><code>request:</code></strong> to restrict to a specific request, " +"typing the title as in the URL." msgstr "" -#: app/controllers/request_game_controller.rb:41 -msgid "Then you can play the request categorisation game." +#: app/views/general/_advanced_search_tips.rhtml:11 +msgid "" +"<strong><code>requested_by:julian_todd</code></strong> to search requests " +"made by Julian Todd, typing the name as in the URL." msgstr "" -#: app/controllers/request_game_controller.rb:42 -msgid "Play the request categorisation game" +#: app/views/general/_advanced_search_tips.rhtml:10 +msgid "" +"<strong><code>requested_from:home_office</code></strong> to search requests " +"from the Home Office, typing the name as in the URL." msgstr "" -#: app/controllers/request_game_controller.rb:52 -msgid "Thank you for helping us keep the site tidy!" +#: app/views/general/_advanced_search_tips.rhtml:8 +msgid "" +"<strong><code>status:</code></strong> to select based on the status or " +"historical status of the request, see the <a href=\"{{statuses_url}}\">table " +"of statuses</a> below." msgstr "" -#: app/controllers/services_controller.rb:21 -msgid "Hello! You can make Freedom of Information requests within {{country_name}} at {{link_to_website}}" +#: app/views/general/_advanced_search_tips.rhtml:16 +msgid "" +"<strong><code>tag:charity</code></strong> to find all public bodies or " +"requests with a given tag. You can include multiple tags, \n" +" and tag values, e.g. <code>tag:openlylocal AND tag:" +"financial_transaction:335633</code>. Note that by default any of the tags\n" +" can be present, you have to put <code>AND</code> explicitly if you only " +"want results them all present." msgstr "" -#: app/controllers/track_controller.rb:98 -msgid "You are already being emailed updates about " +#: app/views/general/_advanced_search_tips.rhtml:9 +msgid "" +"<strong><code>variety:</code></strong> to select type of thing to search " +"for, see the <a href=\"{{varieties_url}}\">table of varieties</a> below." msgstr "" -#: app/controllers/track_controller.rb:111 -msgid "You will now be emailed updates about " +#: app/views/comment/new.rhtml:57 +msgid "" +"<strong>Advice</strong> on how to get a response that will satisfy the " +"requester. </li>" msgstr "" -#: app/controllers/track_controller.rb:143 -msgid "To cancel this alert" +#: app/views/request/_other_describe_state.rhtml:56 +msgid "<strong>All the information</strong> has been sent" msgstr "" -#: app/controllers/track_controller.rb:144 -msgid "Then you can cancel the alert." +#: app/views/request/_followup.rhtml:106 +msgid "<strong>Anything else</strong>, such as clarifying, prompting, thanking" msgstr "" -#: app/controllers/track_controller.rb:145 -msgid "Cancel a {{site_name}} alert" +#: app/views/request/details.rhtml:12 +msgid "" +"<strong>Caveat emptor!</strong> To use this data in an honourable way, you " +"will need \n" +"a good internal knowledge of user behaviour on {{site_name}}. How, \n" +"why and by whom requests are categorised is not straightforward, and there " +"will\n" +"be user error and ambiguity. You will also need to understand FOI law, and " +"the\n" +"way authorities use it. Plus you'll need to be an elite statistician. " +"Please\n" +"<a href=\"{{contact_path}}\">contact us</a> with questions." msgstr "" -#: app/controllers/track_controller.rb:154 -msgid "You will no longer be emailed updates about " +#: app/views/request/_other_describe_state.rhtml:28 +msgid "<strong>Clarification</strong> has been requested" msgstr "" -#: app/controllers/track_controller.rb:173 -msgid "To cancel these alerts" +#: app/views/request/_other_describe_state.rhtml:14 +msgid "" +"<strong>No response</strong> has been received\n" +" <small>(maybe there's just an acknowledgement)</small>" msgstr "" -#: app/controllers/track_controller.rb:174 -msgid "Then you can cancel the alerts." +#: app/views/user/signchangeemail.rhtml:30 +msgid "" +"<strong>Note:</strong>\n" +" We will send an email to your new email address. Follow the\n" +" instructions in it to confirm changing your email." msgstr "" -#: app/controllers/track_controller.rb:175 -msgid "Cancel some {{site_name}} alerts" +#: app/views/user/contact.rhtml:32 +msgid "" +"<strong>Note:</strong> You're sending a message to yourself, presumably\n" +" to try out how it works." msgstr "" -#: app/controllers/track_controller.rb:183 -msgid "You will no longer be emailed updates for those alerts" +#: app/views/request/preview.rhtml:31 +msgid "" +"<strong>Privacy note:</strong> If you want to request private information " +"about\n" +" yourself then <a href=\"%s\">click here</a>." msgstr "" -#: app/controllers/user_controller.rb:43 -msgid "{{search_results}} matching '{{query}}'" +#: app/views/user/set_crop_profile_photo.rhtml:35 +msgid "" +"<strong>Privacy note:</strong> Your photo will be shown in public on the " +"Internet, \n" +" wherever you do something on {{site_name}}." msgstr "" -#: app/controllers/user_controller.rb:207 -msgid "That doesn't look like a valid email address. Please check you have typed it correctly." +#: app/views/request/followup_preview.rhtml:37 +msgid "" +"<strong>Privacy warning:</strong> Your message, and any response\n" +" to it, will be displayed publicly on this website." msgstr "" -#: app/controllers/user_controller.rb:221 -msgid "Then you can change your password on {{site_name}}" +#: app/views/request/_other_describe_state.rhtml:52 +msgid "<strong>Some of the information</strong> has been sent " msgstr "" -#: app/controllers/user_controller.rb:222 -msgid "Change your password {{site_name}}" +#: app/views/comment/new.rhtml:36 +msgid "<strong>Thank</strong> the public authority or " msgstr "" -#: app/controllers/user_controller.rb:249 -msgid "Your password has been changed." +#: app/views/request/show.rhtml:91 +msgid "<strong>did not have</strong> the information requested." msgstr "" -#: app/controllers/user_controller.rb:266 -msgid "To change your email address used on {{site_name}}" +#: app/views/comment/new.rhtml:46 +msgid "" +"A <strong>summary</strong> of the response if you have received it by post. " msgstr "" -#: app/controllers/user_controller.rb:267 -msgid "Then you can change your email address used on {{site_name}}" +#: app/models/info_request.rb:284 +msgid "A Freedom of Information request" msgstr "" -#: app/controllers/user_controller.rb:268 app/views/user/signchangeemail.rhtml:1 -#: app/views/user/signchangeemail.rhtml:11 -msgid "Change your email address used on {{site_name}}" +#: app/models/public_body.rb:278 +#: app/views/general/_advanced_search_tips.rhtml:46 +msgid "A public authority" msgstr "" -#: app/controllers/user_controller.rb:328 -msgid "You have now changed your email address used on {{site_name}}" +#: app/views/request/_other_describe_state.rhtml:34 +msgid "A response will be sent <strong>by post</strong>" msgstr "" -#: app/controllers/user_controller.rb:347 -msgid "To send a message to " +#: app/views/general/_advanced_search_tips.rhtml:35 +msgid "A strange reponse, required attention by the {{site_name}} team" msgstr "" -#: app/controllers/user_controller.rb:348 -msgid "Then you can send a message to " +#: app/views/general/_advanced_search_tips.rhtml:47 +msgid "A {{site_name}} user" msgstr "" -#: app/controllers/user_controller.rb:349 -msgid "Send a message to " +#: app/views/user/set_profile_about_me.rhtml:20 +msgid "About you:" msgstr "" -#: app/controllers/user_controller.rb:367 -msgid "Your message to {{recipient_user_name}} has been sent!" +#: app/views/request/_sidebar.rhtml:8 +msgid "Act on what you've learnt" msgstr "" -#: app/controllers/user_controller.rb:373 -msgid ",\n\n\n\nYours,\n\n{{user_name}}" +#: app/views/comment/new.rhtml:14 +msgid "Add an annotation" msgstr "" -#: app/controllers/user_controller.rb:389 -msgid "You need to be logged in to change your profile photo." +#: app/views/request/show_response.rhtml:45 +msgid "" +"Add an annotation to your request with choice quotes, or\n" +" a <strong>summary of the response</strong>." msgstr "" -#: app/controllers/user_controller.rb:416 app/controllers/user_controller.rb:432 -msgid "Thank you for updating your profile photo" +#: app/views/public_body/_body_listing_single.rhtml:27 +msgid "Added on {{date}}" msgstr "" -#: app/controllers/user_controller.rb:435 -msgid "<p>Thanks for updating your profile photo.</p>\n <p><strong>Next...</strong> You can put some text about you and your research on your profile.</p>" +#: app/models/user.rb:58 +msgid "Admin level is not included in list" msgstr "" -#: app/controllers/user_controller.rb:451 -msgid "You need to be logged in to clear your profile photo." +#: app/views/request_mailer/requires_admin.rhtml:9 +msgid "Administration URL:" msgstr "" -#: app/controllers/user_controller.rb:460 -msgid "You've now cleared your profile photo" +#: app/views/general/search.rhtml:46 +msgid "Advanced search" msgstr "" -#: app/controllers/user_controller.rb:488 -msgid "You need to be logged in to change the text about you on your profile." +#: app/views/general/_advanced_search_tips.rhtml:3 +msgid "Advanced search tips" msgstr "" -#: app/controllers/user_controller.rb:510 -msgid "You have now changed the text about you on your profile." +#: app/views/comment/new.rhtml:53 +msgid "" +"Advise on whether the <strong>refusal is legal</strong>, and how to complain " +"about it if not." msgstr "" -#: app/controllers/user_controller.rb:513 -msgid "<p>Thanks for changing the text about you on your profile.</p>\n <p><strong>Next...</strong> You can upload a profile photograph too.</p>" +#: app/views/request/new.rhtml:67 +msgid "" +"Air, water, soil, land, flora and fauna (including how these effect\n" +" human beings)" msgstr "" -#: app/controllers/user_controller.rb:541 -msgid "Then you can sign in to {{site_name}}" +#: app/views/general/_advanced_search_tips.rhtml:30 +msgid "All of the information requested has been received" msgstr "" -#: app/models/about_me_validator.rb:24 -msgid "Please keep it shorter than 500 characters" +#: app/views/general/_advanced_search_tips.rhtml:23 +msgid "" +"All the options below can use <strong>status</strong> or " +"<strong>latest_status</strong> before the colon. For example, <strong>status:" +"not_held</strong> will match requests which have <em>ever</em> been marked " +"as not held; <strong>latest_status:not_held</strong> will match only " +"requests that are <em>currently</em> marked as not held." msgstr "" -#: app/models/change_email_validator.rb:29 -msgid "Please enter your old email address" +#: app/views/general/_advanced_search_tips.rhtml:40 +msgid "" +"All the options below can use <strong>variety</strong> or " +"<strong>latest_variety</strong> before the colon. For example, " +"<strong>variety:sent</strong> will match requests which have <em>ever</em> " +"been sent; <strong>latest_variety:sent</strong> will match only requests " +"that are <em>currently</em> marked as sent." msgstr "" -#: app/models/change_email_validator.rb:30 -msgid "Please enter your new email address" +#: app/views/public_body/_body_listing_single.rhtml:12 +msgid "Also called {{other_name}}." msgstr "" -#: app/models/change_email_validator.rb:31 -msgid "Please enter your password" +#: app/views/track_mailer/event_digest.rhtml:60 +msgid "Alter your subscription" msgstr "" -#: app/models/change_email_validator.rb:39 -msgid "Old email doesn't look like a valid address" +#: app/views/request_mailer/new_response.rhtml:12 +msgid "" +"Although all responses are automatically published, we depend on\n" +"you, the original requester, to evaluate them." msgstr "" -#: app/models/change_email_validator.rb:44 -msgid "Old email address isn't the same as the address of the account you are logged in with" +#: app/views/request/_other_describe_state.rhtml:70 +msgid "An <strong>error message</strong> has been received" msgstr "" -#: app/models/change_email_validator.rb:47 -msgid "Password is not correct" +#: app/models/info_request.rb:286 +msgid "An Environmental Information Regulations request" msgstr "" -#: app/models/change_email_validator.rb:53 -msgid "New email doesn't look like a valid address" +#: app/views/general/_advanced_search_tips.rhtml:45 +msgid "Annotation added to request" msgstr "" -#: app/models/comment.rb:59 -msgid "Please enter your annotation" +#: app/views/user/show.rhtml:41 +msgid "Annotations" msgstr "" -#: app/models/comment.rb:62 -msgid "Please write your annotation using a mixture of capital and lower case letters. This makes it easier for others to read." +#: app/views/comment/new.rhtml:18 +msgid "" +"Annotations are so anyone, including you, can help the requester with their " +"request. For example:" msgstr "" -#: app/models/contact_validator.rb:28 app/models/user.rb:38 -msgid "Please enter your name" +#: app/views/comment/new.rhtml:70 +msgid "" +"Annotations will be posted publicly here, and are \n" +" <strong>not</strong> sent to {{public_body_name}}." msgstr "" -#: app/models/contact_validator.rb:29 app/models/user.rb:36 -msgid "Please enter your email address" +#: app/views/request/_after_actions.rhtml:6 +msgid "Anyone:" msgstr "" -#: app/models/contact_validator.rb:30 -msgid "Please enter a subject" +#: app/views/request/new.rhtml:105 +msgid "" +"Ask for <strong>specific</strong> documents or information, this site is not " +"suitable for general enquiries." msgstr "" -#: app/models/contact_validator.rb:31 -msgid "Please enter the message you want to send" +#: app/views/request/show_response.rhtml:29 +msgid "" +"At the bottom of this page, write a reply to them trying to persuade them to " +"scan it in\n" +" (<a href=\"%s\">more details</a>)." msgstr "" -#: app/models/contact_validator.rb:34 -msgid "Email doesn't look like a valid address" +#: app/views/request/upload_response.rhtml:33 +msgid "Attachment (optional):" msgstr "" -#: app/models/incoming_message.rb:867 -msgid "\n\n[ {{site_name}} note: The above text was badly encoded, and has had strange characters removed. ]" +#: app/views/request/simple_correspondence.rhtml:21 +msgid "Attachment:" msgstr "" -#: app/models/info_request.rb:34 -msgid "Please enter a summary of your request" +#: app/models/info_request.rb:779 +msgid "Awaiting classification." msgstr "" -#: app/models/info_request.rb:35 -msgid "Please write a summary with some text in it" +#: app/models/info_request.rb:799 +msgid "Awaiting internal review." msgstr "" -#: app/models/info_request.rb:120 -msgid "Please write the summary using a mixture of capital and lower case letters. This makes it easier for others to read." +#: app/models/info_request.rb:781 +msgid "Awaiting response." msgstr "" -#: app/models/info_request.rb:123 -msgid "Please keep the summary short, like in the subject of an email. You can use a phrase, rather than a full sentence." +#: app/views/public_body/list.rhtml:4 +msgid "Beginning with" msgstr "" -#: app/models/info_request.rb:126 -msgid "Please describe more what the request is about in the subject. There is no need to say it is an FOI request, we add that on anyway." +#: app/views/request/new.rhtml:46 +msgid "" +"Browse <a href='{{url}}'>other requests</a> for examples of how to word your " +"request." msgstr "" -#: app/models/info_request.rb:395 -msgid "This request has been set by an administrator to \"allow new responses from nobody\"" +#: app/views/request/new.rhtml:44 +msgid "" +"Browse <a href='{{url}}'>other requests</a> to '{{public_body_name}}' for " +"examples of how to word your request." msgstr "" -#: app/models/info_request.rb:401 -msgid "Only the authority can reply to this request, but there is no \"From\" address to check against" +#: app/views/general/frontpage.rhtml:48 +msgid "Browse all authorities..." msgstr "" -#: app/models/info_request.rb:405 -msgid "Only the authority can reply to this request, and I don't recognise the address this reply was sent from" +#: app/views/request/show.rhtml:86 +msgid "" +"By law, under all circumstances, {{public_body_link}} should have responded " +"by now" msgstr "" -#: app/models/info_request.rb:785 -msgid "Awaiting classification." +#: app/views/request/show.rhtml:78 +msgid "" +"By law, {{public_body_link}} should normally have responded " +"<strong>promptly</strong> and" msgstr "" -#: app/models/info_request.rb:787 -msgid "Awaiting response." +#: app/controllers/track_controller.rb:152 +msgid "Cancel a {{site_name}} alert" msgstr "" -#: app/models/info_request.rb:789 -msgid "Delayed." +#: app/controllers/track_controller.rb:182 +msgid "Cancel some {{site_name}} alerts" msgstr "" -#: app/models/info_request.rb:791 -msgid "Long overdue." +#: app/views/user/set_draft_profile_photo.rhtml:55 +msgid "Cancel, return to your profile page" msgstr "" -#: app/models/info_request.rb:793 -msgid "Information not held." +#: locale/model_attributes.rb:46 +msgid "CensorRule|Last edit comment" msgstr "" -#: app/models/info_request.rb:795 -msgid "Refused." +#: locale/model_attributes.rb:45 +msgid "CensorRule|Last edit editor" msgstr "" -#: app/models/info_request.rb:797 -msgid "Partially successful." +#: locale/model_attributes.rb:44 +msgid "CensorRule|Replacement" msgstr "" -#: app/models/info_request.rb:799 -msgid "Successful." +#: locale/model_attributes.rb:43 +msgid "CensorRule|Text" msgstr "" -#: app/models/info_request.rb:801 -msgid "Waiting clarification." +#: app/views/user/signchangeemail.rhtml:37 +msgid "Change email on {{site_name}}" msgstr "" -#: app/models/info_request.rb:803 -msgid "Handled by post." +#: app/views/user/signchangepassword.rhtml:27 +msgid "Change password on {{site_name}}" msgstr "" -#: app/models/info_request.rb:805 -msgid "Awaiting internal review." +#: app/views/user/show.rhtml:109 app/views/user/set_crop_profile_photo.rhtml:1 +msgid "Change profile photo" msgstr "" -#: app/models/info_request.rb:807 -msgid "Delivery error" +#: app/views/user/set_profile_about_me.rhtml:1 +msgid "Change the text about you on your profile at {{site_name}}" msgstr "" -#: app/models/info_request.rb:809 -msgid "Unusual response." +#: app/views/user/show.rhtml:112 +msgid "Change your email" msgstr "" -#: app/models/info_request.rb:811 -msgid "Withdrawn by the requester." +#: app/controllers/user_controller.rb:282 +#: app/views/user/signchangeemail.rhtml:1 +#: app/views/user/signchangeemail.rhtml:11 +msgid "Change your email address used on {{site_name}}" msgstr "" -#: app/models/info_request.rb:816 app/models/info_request_event.rb:318 -msgid "unknown status " +#: app/views/user/show.rhtml:111 +msgid "Change your password" msgstr "" -#: app/models/info_request_event.rb:306 -msgid "Response" +#: app/views/user/signchangepassword_send_confirm.rhtml:1 +#: app/views/user/signchangepassword_send_confirm.rhtml:9 +#: app/views/user/signchangepassword.rhtml:1 +#: app/views/user/signchangepassword.rhtml:11 +msgid "Change your password on {{site_name}}" msgstr "" -#: app/models/info_request_event.rb:313 -msgid "Internal review request" +#: app/controllers/user_controller.rb:236 +msgid "Change your password {{site_name}}" msgstr "" -#: app/models/info_request_event.rb:316 -msgid "Clarification" +#: app/views/public_body/show.rhtml:20 app/views/public_body/show.rhtml:22 +msgid "Charity registration" msgstr "" -#: app/models/info_request_event.rb:320 -msgid "Follow up" +#: app/views/general/exception_caught.rhtml:8 +msgid "Check for mistakes if you typed or copied the address." msgstr "" -#: app/models/info_request_event.rb:323 -msgid "display_status only works for incoming and outgoing messages right now" +#: app/views/request/followup_preview.rhtml:14 +#: app/views/request/preview.rhtml:7 +msgid "Check you haven't included any <strong>personal information</strong>." msgstr "" -#: app/models/outgoing_message.rb:63 -msgid "Dear {{public_body_name}}," +#: lib/world_foi_websites.rb:29 +msgid "Chile" msgstr "" -#: app/models/outgoing_message.rb:68 -msgid "Yours sincerely," +#: app/views/user/set_draft_profile_photo.rhtml:5 +msgid "Choose your profile photo" msgstr "" -#: app/models/outgoing_message.rb:70 -msgid "Yours faithfully," +#: app/models/info_request_event.rb:351 +msgid "Clarification" msgstr "" -#: app/models/outgoing_message.rb:74 -msgid "GIVE DETAILS ABOUT YOUR COMPLAINT HERE" +#: app/controllers/request_controller.rb:379 +msgid "Classify an FOI response from " msgstr "" -#: app/models/outgoing_message.rb:146 -msgid "Please give details explaining why you want a review" +#: app/views/request_mailer/very_overdue_alert.rhtml:6 +msgid "" +"Click on the link below to send a message to {{public_body_name}} telling " +"them to reply to your request. You might like to ask for an internal\n" +"review, asking them to find out why response to the request has been so slow." msgstr "" -#: app/models/outgoing_message.rb:148 -msgid "Please enter your follow up message" +#: app/views/request_mailer/overdue_alert.rhtml:5 +msgid "" +"Click on the link below to send a message to {{public_body}} reminding them " +"to reply to your request." msgstr "" -#: app/models/outgoing_message.rb:151 -msgid "Please enter your letter requesting information" +#: locale/model_attributes.rb:22 +msgid "Comment|Body" msgstr "" -#: app/models/outgoing_message.rb:157 -msgid "Please sign at the bottom with your name, or alter the \"%{signoff}\" signature" +#: locale/model_attributes.rb:21 +msgid "Comment|Comment type" msgstr "" -#: app/models/outgoing_message.rb:160 -msgid "Please write your message using a mixture of capital and lower case letters. This makes it easier for others to read." +#: locale/model_attributes.rb:24 +msgid "Comment|Locale" msgstr "" -#: app/models/outgoing_message.rb:163 -msgid "Please choose what sort of reply you are making." +#: locale/model_attributes.rb:23 +msgid "Comment|Visible" msgstr "" -#: app/models/profile_photo.rb:91 -msgid "Please choose a file containing your photo." +#: app/models/track_thing.rb:219 +msgid "Confirm you want to be emailed about new requests" msgstr "" -#: app/models/profile_photo.rb:96 -msgid "Couldn't understand the image file that you uploaded. PNG, JPEG, GIF and many other common image file formats are supported." +#: app/models/track_thing.rb:286 +msgid "" +"Confirm you want to be emailed about new requests or responses matching your " +"search" msgstr "" -#: app/models/profile_photo.rb:101 -msgid "Failed to convert image to a PNG" +#: app/models/track_thing.rb:270 +msgid "Confirm you want to be emailed about requests by '{{user_name}}'" msgstr "" -#: app/models/profile_photo.rb:105 -msgid "Failed to convert image to the correct size: at %{cols}x%{rows}, need %{width}x%{height}" +#: app/models/track_thing.rb:254 +msgid "Confirm you want to be emailed about requests to '{{public_body_name}}'" msgstr "" -#: app/models/public_body.rb:36 -msgid "Name can't be blank" +#: app/models/track_thing.rb:235 +msgid "Confirm you want to be emailed when an FOI request succeeds" msgstr "" -#: app/models/public_body.rb:37 -msgid "URL name can't be blank" +#: app/models/track_thing.rb:203 +msgid "Confirm you want to follow updates to the request '{{request_title}}'" msgstr "" -#: app/models/public_body.rb:39 -msgid "Short name is already taken" +#: app/controllers/request_controller.rb:339 +msgid "Confirm your FOI request to " msgstr "" -#: app/models/public_body.rb:40 -msgid "Name is already taken" +#: app/controllers/user_controller.rb:557 +#: app/controllers/request_controller.rb:755 +msgid "Confirm your account on {{site_name}}" msgstr "" -#: app/models/request_mailer.rb:50 -msgid "FOI response requires admin - " +#: app/controllers/comment_controller.rb:57 +msgid "Confirm your annotation to {{info_request_title}}" msgstr "" -#: app/models/request_mailer.rb:67 -msgid "New response to your FOI request - " +#: app/controllers/request_controller.rb:36 +msgid "Confirm your email address" msgstr "" -#: app/models/request_mailer.rb:86 -msgid "Delayed response to your FOI request - " +#: app/models/user_mailer.rb:34 +msgid "Confirm your new email address on {{site_name}}" msgstr "" -#: app/models/request_mailer.rb:105 -msgid "You're long overdue a response to your FOI request - " +#: app/views/general/_footer.rhtml:2 +msgid "Contact {{site_name}}" msgstr "" -#: app/models/request_mailer.rb:125 -msgid "Was the response you got to your FOI request any good?" +#: app/models/request_mailer.rb:219 +msgid "Could not identify the request from the email address" msgstr "" -#: app/models/request_mailer.rb:168 -msgid "Somebody added a note to your FOI request - " +#: app/models/profile_photo.rb:96 +msgid "" +"Couldn't understand the image file that you uploaded. PNG, JPEG, GIF and " +"many other common image file formats are supported." msgstr "" -#: app/models/request_mailer.rb:177 -msgid "Some notes have been added to your FOI request - " +#: app/views/user/set_crop_profile_photo.rhtml:6 +msgid "Crop your profile photo" msgstr "" -#: app/models/request_mailer.rb:218 -msgid "Could not identify the request from the email address" +#: app/views/request/new.rhtml:72 +msgid "" +"Cultural sites and built structures (as they may be affected by the\n" +" environmental factors listed above)" msgstr "" -#: app/models/track_mailer.rb:25 -msgid "Your {{site_name}} email alert" +#: app/views/request/show.rhtml:68 +msgid "" +"Currently <strong>waiting for a response</strong> from {{public_body_link}}, " +"they must respond promptly and" msgstr "" -#: app/models/track_thing.rb:83 app/views/general/search.rhtml:54 -msgid "users" +#: app/views/request/simple_correspondence.rhtml:17 +#: app/views/request/simple_correspondence.rhtml:29 +#: app/views/request/simple_correspondence.rhtml:36 +msgid "Date:" msgstr "" -#: app/models/track_thing.rb:86 app/views/general/search.rhtml:103 -#: app/views/request/_request_filter_form.rhtml:14 -msgid "comments" +#: app/models/outgoing_message.rb:63 +msgid "Dear {{public_body_name}}," msgstr "" -#: app/models/track_thing.rb:89 app/views/general/search.rhtml:55 -msgid "authorities" +#: app/models/request_mailer.rb:87 +msgid "Delayed response to your FOI request - " msgstr "" -#: app/models/track_thing.rb:92 app/models/track_thing.rb:111 app/models/track_thing.rb:113 -#: app/views/general/search.rhtml:53 -msgid "requests" +#: app/models/info_request.rb:783 +msgid "Delayed." msgstr "" -#: app/models/track_thing.rb:95 -msgid "between two dates" +#: app/models/info_request.rb:801 +msgid "Delivery error" msgstr "" -#: app/models/track_thing.rb:98 -msgid "unsuccessful" +#: app/views/request/details.rhtml:1 app/views/request/details.rhtml:2 +msgid "Details of request '" msgstr "" -#: app/models/track_thing.rb:101 -msgid "successful" +#: app/views/general/search.rhtml:166 +msgid "Did you mean: {{correction}}" msgstr "" -#: app/models/track_thing.rb:104 -msgid "awaiting a response" +#: app/views/outgoing_mailer/_followup_footer.rhtml:1 +msgid "" +"Disclaimer: This message and any reply that you make will be published on " +"the internet. Our privacy and copyright policies:" msgstr "" -#: app/models/track_thing.rb:112 -msgid "requests which are {{list_of_statuses}}" +#: app/views/request/_followup.rhtml:19 +msgid "" +"Don't want to address your message to {{person_or_body}}? You can also " +"write to:" msgstr "" -#: app/models/track_thing.rb:112 app/models/track_thing.rb:120 -msgid " or " +#: app/views/general/_localised_datepicker.rhtml:4 +msgid "Done" msgstr "" -#: app/models/track_thing.rb:116 -msgid "anything" +#: app/views/request/_after_actions.rhtml:17 +msgid "Download a zip file of all correspondence" msgstr "" -#: app/models/track_thing.rb:122 -msgid "{{list_of_things}} matching text '{{search_query}}'" +#: app/views/request/_view_html_prefix.rhtml:6 +msgid "Download original attachment" msgstr "" -#: app/models/track_thing.rb:195 -msgid "'{{link_to_request}}', a request" +#: app/models/info_request.rb:268 +msgid "EIR" msgstr "" -#: app/models/track_thing.rb:196 -msgid "Track this request by email" +#: app/views/request/_followup.rhtml:112 +msgid "" +"Edit and add <strong>more details</strong> to the message above,\n" +" explaining why you are dissatisfied with their response." msgstr "" -#: app/models/track_thing.rb:197 -msgid "You are already tracking this request by email" +#: app/views/admin_public_body/_locale_selector.rhtml:2 +msgid "Edit language version:" msgstr "" -#: app/models/track_thing.rb:199 app/models/track_thing.rb:200 -msgid "New updates for the request '{{request_title}}'" +#: app/views/user/set_profile_about_me.rhtml:9 +msgid "Edit text about you" msgstr "" -#: app/models/track_thing.rb:202 -msgid "To follow updates to the request '{{request_title}}'" +#: app/views/request/preview.rhtml:40 +msgid "Edit this request" msgstr "" -#: app/models/track_thing.rb:203 -msgid "Then you will be emailed whenever the request '{{request_title}}' is updated." +#: app/models/user.rb:148 +msgid "Either the email or password was not recognised, please try again." msgstr "" -#: app/models/track_thing.rb:204 -msgid "Confirm you want to follow updates to the request '{{request_title}}'" +#: app/models/user.rb:150 +msgid "" +"Either the email or password was not recognised, please try again. Or create " +"a new account using the form on the right." msgstr "" -#: app/models/track_thing.rb:211 -msgid "any <a href=\"/list\">new requests</a>" +#: app/models/contact_validator.rb:34 +msgid "Email doesn't look like a valid address" msgstr "" -#: app/models/track_thing.rb:212 +#: app/views/comment/_comment_form.rhtml:8 +msgid "Email me future updates to this request" +msgstr "" + +#: app/models/track_thing.rb:227 +msgid "Email me new successful responses " +msgstr "" + +#: app/models/track_thing.rb:211 msgid "Email me when there are new requests" msgstr "" -#: app/models/track_thing.rb:213 -msgid "You are being emailed when there are new requests" +#: app/views/general/_advanced_search_tips.rhtml:5 +msgid "" +"Enter words that you want to find separated by spaces, e.g. <strong>climbing " +"lane</strong>" msgstr "" -#: app/models/track_thing.rb:215 app/models/track_thing.rb:216 -msgid "New Freedom of Information requests" +#: app/views/request/upload_response.rhtml:23 +msgid "" +"Enter your response below. You may attach one file (use email, or \n" +"<a href=\"%s\">contact us</a> if you need more)." msgstr "" -#: app/models/track_thing.rb:218 -msgid "To be emailed about any new requests" +#: app/models/info_request.rb:259 app/models/info_request.rb:277 +msgid "Environmental Information Regulations" msgstr "" -#: app/models/track_thing.rb:219 -msgid "Then you will be emailed whenever anyone makes a new FOI request." +#: app/views/public_body/show.rhtml:116 +msgid "Environmental Information Regulations requests made" msgstr "" -#: app/models/track_thing.rb:220 -msgid "Confirm you want to be emailed about new requests" +#: app/views/public_body/show.rhtml:73 +msgid "Environmental Information Regulations requests made using this site" msgstr "" -#: app/models/track_thing.rb:227 -msgid "any <a href=\"/list/successful\">successful requests</a>" +#: lib/world_foi_websites.rb:13 +msgid "European Union" msgstr "" -#: app/models/track_thing.rb:228 -msgid "Email me new successful responses " +#: app/views/request/details.rhtml:4 +msgid "Event history" msgstr "" -#: app/models/track_thing.rb:229 -msgid "You are being emailed about any new successful responses" +#: app/views/request/_sidebar.rhtml:35 +msgid "Event history details" msgstr "" -#: app/models/track_thing.rb:231 app/models/track_thing.rb:232 -msgid "Successful Freedom of Information requests" +#: app/views/request/new.rhtml:128 +msgid "" +"Everything that you enter on this page \n" +" will be <strong>displayed publicly</strong> on\n" +" this website forever (<a href=\"%s\">why?</a>)." msgstr "" -#: app/models/track_thing.rb:234 -msgid "To be emailed about any successful requests" +#: app/views/request/new.rhtml:120 +msgid "" +"Everything that you enter on this page, including <strong>your name</" +"strong>, \n" +" will be <strong>displayed publicly</strong> on\n" +" this website forever (<a href=\"%s\">why?</a>)." msgstr "" -#: app/models/track_thing.rb:235 -msgid "Then you will be emailed whenever an FOI request succeeds." +#: locale/model_attributes.rb:68 +msgid "EximLogDone|Filename" msgstr "" -#: app/models/track_thing.rb:236 -msgid "Confirm you want to be emailed when an FOI request succeeds" +#: locale/model_attributes.rb:69 +msgid "EximLogDone|Last stat" msgstr "" -#: app/models/track_thing.rb:246 -msgid "'{{link_to_authority}}', a public authority" +#: locale/model_attributes.rb:19 +msgid "EximLog|Line" msgstr "" -#: app/models/track_thing.rb:247 -msgid "Track requests to {{public_body_name}} by email" +#: locale/model_attributes.rb:18 +msgid "EximLog|Order" msgstr "" -#: app/models/track_thing.rb:248 -msgid "You are already tracking requests to {{public_body_name}} by email" +#: app/models/info_request.rb:266 +msgid "FOI" msgstr "" -#: app/models/track_thing.rb:253 -msgid "To be emailed about requests made using {{site_name}} to the public authority '{{public_body_name}}'" +#: app/views/public_body/view_email.rhtml:3 +msgid "FOI email address for {{public_body}}" msgstr "" -#: app/models/track_thing.rb:254 -msgid "Then you will be emailed whenever someone requests something or gets a response from '{{public_body_name}}'." +#: app/views/user/show.rhtml:40 +msgid "FOI requests" msgstr "" -#: app/models/track_thing.rb:255 -msgid "Confirm you want to be emailed about requests to '{{public_body_name}}'" +#: app/models/track_thing.rb:265 app/models/track_thing.rb:266 +msgid "FOI requests by '{{user_name}}'" msgstr "" -#: app/models/track_thing.rb:262 -msgid "'{{link_to_user}}', a person" +#: app/views/general/search.rhtml:195 +msgid "FOI requests {{start_count}} to {{end_count}} of {{total_count}}" msgstr "" -#: app/models/track_thing.rb:263 -msgid "Track this person by email" +#: app/models/request_mailer.rb:51 +msgid "FOI response requires admin - " msgstr "" -#: app/models/track_thing.rb:264 -msgid "You are already tracking this person by email" +#: app/models/profile_photo.rb:101 +msgid "Failed to convert image to a PNG" msgstr "" -#: app/models/track_thing.rb:266 app/models/track_thing.rb:267 -msgid "FOI requests by '{{user_name}}'" +#: app/models/profile_photo.rb:105 +msgid "" +"Failed to convert image to the correct size: at %{cols}x%{rows}, need " +"%{width}x%{height}" msgstr "" -#: app/models/track_thing.rb:269 -msgid "To be emailed about requests by '{{user_name}}'" +#: app/views/general/search.rhtml:117 +msgid "Filter" msgstr "" -#: app/models/track_thing.rb:270 -msgid "Then you will be emailed whenever '{{user_name}}' requests something or gets a response." +#: app/views/request/select_authority.rhtml:36 +msgid "" +"First, type in the <strong>name of the UK public authority</strong> you'd \n" +" like information from. <strong>By law, they have to respond</" +"strong>\n" +" (<a href=\"%s#%s\">why?</a>)." msgstr "" -#: app/models/track_thing.rb:271 -msgid "Confirm you want to be emailed about requests by '{{user_name}}'" +#: locale/model_attributes.rb:88 +msgid "FoiAttachment|Charset" msgstr "" -#: app/models/track_thing.rb:279 -msgid "Track things matching this search by email" +#: locale/model_attributes.rb:86 +msgid "FoiAttachment|Content type" msgstr "" -#: app/models/track_thing.rb:280 -msgid "You are already tracking things matching this search by email" +#: locale/model_attributes.rb:89 +msgid "FoiAttachment|Display size" msgstr "" -#: app/models/track_thing.rb:282 app/models/track_thing.rb:283 -msgid "Requests or responses matching your saved search" +#: locale/model_attributes.rb:87 +msgid "FoiAttachment|Filename" msgstr "" -#: app/models/track_thing.rb:285 -msgid "To follow requests and responses matching your search" +#: locale/model_attributes.rb:92 +msgid "FoiAttachment|Hexdigest" msgstr "" -#: app/models/track_thing.rb:286 -msgid "Then you will be emailed whenever a new request or response matches your search." +#: locale/model_attributes.rb:90 +msgid "FoiAttachment|Url part number" msgstr "" -#: app/models/track_thing.rb:287 -msgid "Confirm you want to be emailed about new requests or responses matching your search" +#: locale/model_attributes.rb:91 +msgid "FoiAttachment|Within rfc822 subject" msgstr "" -#: app/models/user.rb:40 -msgid "Please enter a password" +#: app/views/track/_tracking_links.rhtml:21 +msgid "Follow by email" msgstr "" -#: app/models/user.rb:51 -msgid "Please enter the same password twice" +#: app/views/request/list.rhtml:8 +msgid "Follow these requests" msgstr "" -#: app/models/user.rb:56 -msgid "Admin level is not included in list" +#: app/views/public_body/show.rhtml:4 +msgid "Follow this authority" msgstr "" -#: app/models/user.rb:117 -msgid "Please enter a valid email address" +#: app/views/request_mailer/old_unclassified_updated.rhtml:4 +msgid "Follow this link to see the request:" msgstr "" -#: app/models/user.rb:120 -msgid "Please enter your name, not your email address, in the name field." +#: app/views/request/_sidebar.rhtml:2 +msgid "Follow this request" msgstr "" -#: app/models/user.rb:133 -msgid "{{user_name}} (Banned)" +#: app/models/info_request_event.rb:355 +msgid "Follow up" msgstr "" -#: app/models/user.rb:146 -msgid "Either the email or password was not recognised, please try again." +#: app/views/general/_advanced_search_tips.rhtml:43 +msgid "Follow up message sent by requester" msgstr "" -#: app/models/user.rb:148 -msgid "Either the email or password was not recognised, please try again. Or create a new account using the form on the right." +#: app/views/public_body/view_email.rhtml:14 +msgid "Follow up messages to existing requests are sent to " msgstr "" -#: app/models/user_mailer.rb:34 -msgid "Confirm your new email address on {{site_name}}" +#: app/views/request/_followup.rhtml:43 +msgid "" +"Follow ups and new responses to this request have been stopped to prevent " +"spam. Please <a href=\"{{url}}\">contact us</a> if you are {{user_link}} and " +"need to send a follow up." msgstr "" -#: app/models/user_mailer.rb:45 -msgid "Unable to change email address on {{site_name}}" +#: app/views/general/blog.rhtml:7 app/views/general/_footer.rhtml:3 +msgid "Follow us on twitter" msgstr "" -#: app/views/admin_public_body/_locale_selector.rhtml:2 -msgid "Edit language version:" +#: app/views/public_body/show.rhtml:65 +msgid "" +"For an unknown reason, it is not possible to make a request to this " +"authority." msgstr "" -#: app/views/comment/_comment_form.rhtml:8 -msgid "Email me future updates to this request" +#: app/views/user/_signin.rhtml:21 +msgid "Forgotten your password?" msgstr "" -#: app/views/comment/_comment_form.rhtml:15 -msgid "Preview your annotation" +#: app/views/public_body/list.rhtml:47 +msgid "Found {{count}} public bodies {{description}}" msgstr "" -#: app/views/comment/_comment_form.rhtml:16 -msgid " (<strong>no ranty</strong> politics, read our <a href=\"%s\">moderation policy</a>)" +#: app/models/info_request.rb:257 +msgid "Freedom of Information" msgstr "" -#: app/views/comment/_single_comment.rhtml:10 -msgid "You" +#: app/models/info_request.rb:275 +msgid "Freedom of Information Act" msgstr "" -#: app/views/comment/_single_comment.rhtml:10 -msgid "left an annotation" +#: app/views/public_body/show.rhtml:60 +msgid "" +"Freedom of Information law does not apply to this authority, so you cannot " +"make\n" +" a request to it." msgstr "" -#: app/views/comment/_single_comment.rhtml:24 -msgid "Report abuse" +#: app/views/request/followup_bad.rhtml:11 +msgid "Freedom of Information law no longer applies to" msgstr "" -#: app/views/comment/new.rhtml:14 -msgid "Add an annotation" +#: app/views/public_body/view_email.rhtml:10 +msgid "" +"Freedom of Information law no longer applies to this authority.Follow up " +"messages to existing requests are sent to " msgstr "" -#: app/views/comment/new.rhtml:18 -msgid "Annotations are so anyone, including you, can help the requester with their request. For example:" +#: app/views/public_body/show.rhtml:118 +msgid "Freedom of Information requests made" msgstr "" -#: app/views/comment/new.rhtml:24 -msgid " Advise on how to <strong>best clarify</strong> the request." +#: app/views/user/show.rhtml:164 +msgid "Freedom of Information requests made by this person" msgstr "" -#: app/views/comment/new.rhtml:28 -msgid " Link to the information requested, if it is <strong>already available</strong> on the Internet. " +#: app/views/user/show.rhtml:164 +msgid "Freedom of Information requests made by you" msgstr "" -#: app/views/comment/new.rhtml:29 -msgid " Suggest <strong>where else</strong> the requester might find the information. " +#: app/views/public_body/show.rhtml:76 +msgid "Freedom of Information requests made using this site" msgstr "" -#: app/views/comment/new.rhtml:30 -msgid " Offer better ways of <strong>wording the request</strong> to get the information. " +#: app/views/public_body/show.rhtml:30 +msgid "Freedom of information requests to" msgstr "" -#: app/views/comment/new.rhtml:34 -msgid " <strong>Summarise</strong> the content of any information returned. " +#: app/views/request/followup_bad.rhtml:12 +msgid "" +"From the request page, try replying to a particular message, rather than " +"sending\n" +" a general followup. If you need to make a general followup, and know\n" +" an email which will go to the right place, please <a href=\"%s\">send it " +"to us</a>." msgstr "" -#: app/views/comment/new.rhtml:35 -msgid " Say how you've <strong>used the information</strong>, with links if possible." +#: app/views/request/_correspondence.rhtml:12 +#: app/views/request/_correspondence.rhtml:36 +#: app/views/request/simple_correspondence.rhtml:14 +#: app/views/request/simple_correspondence.rhtml:27 +msgid "From:" msgstr "" -#: app/views/comment/new.rhtml:36 -msgid "<strong>Thank</strong> the public authority or " +#: app/models/outgoing_message.rb:74 +msgid "GIVE DETAILS ABOUT YOUR COMPLAINT HERE" msgstr "" -#: app/views/comment/new.rhtml:39 -msgid "Suggest how the requester can find the <strong>rest of the information</strong>." +#: lib/world_foi_websites.rb:25 +msgid "Germany" msgstr "" -#: app/views/comment/new.rhtml:42 -msgid "Point to <strong>related information</strong>, campaigns or forums which may be useful." +#: app/models/info_request.rb:797 +msgid "Handled by post." msgstr "" -#: app/views/comment/new.rhtml:46 -msgid "A <strong>summary</strong> of the response if you have received it by post. " +#: app/controllers/services_controller.rb:13 +msgid "" +"Hello! You can make Freedom of Information requests within {{country_name}} " +"at {{link_to_website}}" msgstr "" -#: app/views/comment/new.rhtml:50 -msgid " Ideas on what <strong>other documents to request</strong> which the authority may hold. " +#: app/views/layouts/default.rhtml:102 +msgid "Hello, {{username}}!" msgstr "" -#: app/views/comment/new.rhtml:53 -msgid "Advise on whether the <strong>refusal is legal</strong>, and how to complain about it if not." +#: app/views/general/_topnav.rhtml:8 +msgid "Help" msgstr "" -#: app/views/comment/new.rhtml:57 -msgid "<strong>Advice</strong> on how to get a response that will satisfy the requester. </li>" +#: app/views/request/details.rhtml:50 +msgid "" +"Here <strong>described</strong> means when a user selected a status for the " +"request, and\n" +"the most recent event had its status updated to that value. " +"<strong>calculated</strong> is then inferred by\n" +"{{site_name}} for intermediate events, which weren't given an explicit\n" +"description by a user. See the <a href=\"{{search_path}}\">search tips</a> " +"for description of the states." msgstr "" -#: app/views/comment/new.rhtml:60 -msgid "You know what caused the error, and can <strong>suggest a solution</strong>, such as a working email address." +#: app/views/user/rate_limited.rhtml:12 +msgid "" +"Here is the message you wrote, in case you would like to copy the text and " +"save it for later." msgstr "" -#: app/views/comment/new.rhtml:63 -msgid "Your thoughts on what the {{site_name}} <strong>administrators</strong> should do about the request." +#: app/views/request/_other_describe_state.rhtml:4 +msgid "" +"Hi! We need your help. The person who made the following request\n" +" hasn't told us whether or not it was successful. Would you mind taking\n" +" a moment to read it and help us keep the place tidy for everyone?\n" +" Thanks." msgstr "" -#: app/views/comment/new.rhtml:70 -msgid "Annotations will be posted publicly here, and are \n <strong>not</strong> sent to {{public_body_name}}." +#: locale/model_attributes.rb:65 +msgid "Holiday|Day" msgstr "" -#: app/views/comment/preview.rhtml:1 -msgid "Preview new annotation on '{{info_request_title}}'" +#: locale/model_attributes.rb:66 +msgid "Holiday|Description" msgstr "" -#: app/views/comment/preview.rhtml:5 -msgid "Now preview your annotation" +#: app/views/general/_topnav.rhtml:3 +msgid "Home" msgstr "" -#: app/views/comment/preview.rhtml:10 -msgid "Your name and annotation will appear in <strong>search engines</strong>." +#: app/views/public_body/show.rhtml:12 +msgid "Home page of authority" msgstr "" -#: app/views/comment/preview.rhtml:20 -msgid "Re-edit this annotation" +#: app/views/request/new.rhtml:61 +msgid "" +"However, you have the right to request environmental\n" +" information under a different law" msgstr "" -#: app/views/comment/preview.rhtml:21 -msgid "Post annotation" +#: app/views/request/new.rhtml:71 +msgid "Human health and safety" msgstr "" -#: app/views/contact_mailer/message.rhtml:4 -msgid "Message sent using {{site_name}} contact form, " +#: app/views/request/_followup.rhtml:95 +msgid "I am asking for <strong>new information</strong>" msgstr "" -#: app/views/contact_mailer/message.rhtml:7 -msgid "Last request viewed: " +#: app/views/request/_followup.rhtml:100 +msgid "I am requesting an <strong>internal review</strong>" msgstr "" -#: app/views/contact_mailer/message.rhtml:10 -msgid "Last authority viewed: " +#: app/views/request_game/play.rhtml:39 +msgid "I don't like these ones — give me some more!" msgstr "" -#: app/views/contact_mailer/user_message.rhtml:2 -msgid "{{user_name}} has used {{site_name}} to send you the message below." +#: app/views/request_game/play.rhtml:40 +msgid "I don't want to do any more tidying now!" msgstr "" -#: app/views/contact_mailer/user_message.rhtml:3 -msgid "Your details have not been given to anyone, unless you choose to reply to this\nmessage, which will then go directly to the person who wrote the message." +#: app/views/request/_describe_state.rhtml:91 +msgid "I would like to <strong>withdraw this request</strong>" msgstr "" -#: app/views/contact_mailer/user_message.rhtml:10 -msgid "View Freedom of Information requests made by {{user_name}}:" +#: app/views/request/_describe_state.rhtml:11 +msgid "" +"I'm still <strong>waiting</strong> for my information\n" +" <small>(maybe you got an acknowledgement)</small>" msgstr "" -#: app/views/general/_advanced_search_tips.rhtml:3 -msgid "Advanced search tips" +#: app/views/request/_describe_state.rhtml:18 +msgid "I'm still <strong>waiting</strong> for the internal review" msgstr "" -#: app/views/general/_advanced_search_tips.rhtml:5 -msgid "Enter words that you want to find separated by spaces, e.g. <strong>climbing lane</strong>" +#: app/views/request/_describe_state.rhtml:32 +msgid "I'm waiting for an <strong>internal review</strong> response" msgstr "" -#: app/views/general/_advanced_search_tips.rhtml:6 -msgid "Use OR (in capital letters) where you don't mind which word, e.g. <strong><code>commons OR lords</code></strong>" +#: app/views/request/_describe_state.rhtml:25 +msgid "I've been asked to <strong>clarify</strong> my request" msgstr "" -#: app/views/general/_advanced_search_tips.rhtml:7 -msgid "Use quotes when you want to find an exact phrase, e.g. <strong><code>\"Liverpool City Council\"</code></strong>" +#: app/views/request/_describe_state.rhtml:60 +msgid "I've received <strong>all the information" msgstr "" -#: app/views/general/_advanced_search_tips.rhtml:8 -msgid "<strong><code>status:</code></strong> to select based on the status or historical status of the request, see the <a href=\"{{statuses_url}}\">table of statuses</a> below." +#: app/views/request/_describe_state.rhtml:56 +msgid "I've received <strong>some of the information</strong>" msgstr "" -#: app/views/general/_advanced_search_tips.rhtml:9 -msgid "<strong><code>variety:</code></strong> to select type of thing to search for, see the <a href=\"{{varieties_url}}\">table of varieties</a> below." +#: app/views/request/_describe_state.rhtml:76 +msgid "I've received an <strong>error message</strong>" msgstr "" -#: app/views/general/_advanced_search_tips.rhtml:10 -msgid "<strong><code>requested_from:home_office</code></strong> to search requests from the Home Office, typing the name as in the URL." +#: app/views/public_body/view_email.rhtml:28 +msgid "" +"If the address is wrong, or you know a better address, please <a href=\"%s" +"\">contact us</a>." msgstr "" -#: app/views/general/_advanced_search_tips.rhtml:11 -msgid "<strong><code>requested_by:julian_todd</code></strong> to search requests made by Julian Todd, typing the name as in the URL." +#: app/views/request_mailer/stopped_responses.rhtml:10 +msgid "" +"If this is incorrect, or you would like to send a late response to the " +"request\n" +"or an email on another subject to {{user}}, then please\n" +"email {{contact_email}} for help." msgstr "" -#: app/views/general/_advanced_search_tips.rhtml:12 -msgid "<strong><code>commented_by:tony_bowden</code></strong> to search annotations made by Tony Bowden, typing the name as in the URL." +#: app/views/request/_followup.rhtml:47 +msgid "" +"If you are dissatisfied by the response you got from\n" +" the public authority, you have the right to\n" +" complain (<a href=\"%s\">details</a>)." msgstr "" -#: app/views/general/_advanced_search_tips.rhtml:13 -msgid "<strong><code>request:</code></strong> to restrict to a specific request, typing the title as in the URL." +#: app/views/user/no_cookies.rhtml:20 +msgid "If you are still having trouble, please <a href=\"%s\">contact us</a>." msgstr "" -#: app/views/general/_advanced_search_tips.rhtml:14 -msgid "<strong><code>filetype:pdf</code></strong> to find all responses with PDF attachments. Or try these: <code>{{list_of_file_extensions}}</code>" +#: app/views/request/hidden.rhtml:15 +msgid "" +"If you are the requester, then you may <a href=\"%s\">sign in</a> to view " +"the request." msgstr "" -#: app/views/general/_advanced_search_tips.rhtml:15 -msgid "Type <strong><code>01/01/2008..14/01/2008</code></strong> to only show things that happened in the first two weeks of January." +#: app/views/request/new.rhtml:123 +msgid "" +"If you are thinking of using a pseudonym,\n" +" please <a href=\"%s\">read this first</a>." msgstr "" -#: app/views/general/_advanced_search_tips.rhtml:16 -msgid "<strong><code>tag:charity</code></strong> to find all public bodies or requests with a given tag. You can include multiple tags, \n and tag values, e.g. <code>tag:openlylocal AND tag:financial_transaction:335633</code>. Note that by default any of the tags\n can be present, you have to put <code>AND</code> explicitly if you only want results them all present." +#: app/views/request/show.rhtml:105 +msgid "If you are {{user_link}}, please" msgstr "" -#: app/views/general/_advanced_search_tips.rhtml:19 -msgid "Read about <a href=\"{{advanced_search_url}}\">advanced search operators</a>, such as proximity and wildcards." +#: app/views/user/bad_token.rhtml:7 +msgid "" +"If you can't click on it in the email, you'll have to <strong>select and " +"copy\n" +"it</strong> from the email. Then <strong>paste it into your browser</" +"strong>, into the place\n" +"you would type the address of any other webpage." msgstr "" -#: app/views/general/_advanced_search_tips.rhtml:22 -msgid "Table of statuses" +#: app/views/request/show_response.rhtml:47 +msgid "" +"If you can, scan in or photograph the response, and <strong>send us\n" +" a copy to upload</strong>." msgstr "" -#: app/views/general/_advanced_search_tips.rhtml:23 -msgid "All the options below can use <strong>status</strong> or <strong>latest_status</strong> before the colon. For example, <strong>status:not_held</strong> will match requests which have <em>ever</em> been marked as not held; <strong>latest_status:not_held</strong> will match only requests that are <em>currently</em> marked as not held." +#: app/views/outgoing_mailer/_followup_footer.rhtml:4 +msgid "" +"If you find this service useful as an FOI officer, please ask your web " +"manager to link to us from your organisation's FOI page." msgstr "" -#: app/views/general/_advanced_search_tips.rhtml:26 -msgid "Waiting for the public authority to reply" +#: app/views/user/bad_token.rhtml:13 +msgid "" +"If you got the email <strong>more than six months ago</strong>, then this " +"login link won't work any\n" +"more. Please try doing what you were doing from the beginning." msgstr "" -#: app/views/general/_advanced_search_tips.rhtml:27 -msgid "The public authority does not have the information requested" +#: app/controllers/request_controller.rb:477 +msgid "" +"If you have not done so already, please write a message below telling the " +"authority that you have withdrawn your request. Otherwise they will not know " +"it has been withdrawn." msgstr "" -#: app/views/general/_advanced_search_tips.rhtml:28 -msgid "The request was refused by the public authority" +#: app/views/user/rate_limited.rhtml:9 +msgid "" +"If you need to make more requests than this, <a href='%s'>get in touch</a> " +"and we’ll consider it." msgstr "" -#: app/views/general/_advanced_search_tips.rhtml:29 -msgid "Some of the information requested has been received" +#: app/views/user/signchangepassword_confirm.rhtml:10 +#: app/views/user/signchangeemail_confirm.rhtml:11 +msgid "" +"If you use web-based email or have \"junk mail\" filters, also check your\n" +"bulk/spam mail folders. Sometimes, our messages are marked that way." msgstr "" -#: app/views/general/_advanced_search_tips.rhtml:30 -msgid "All of the information requested has been received" +#: app/views/user/banned.rhtml:15 +msgid "" +"If you would like us to lift this ban, then you may politely\n" +"<a href=\"/help/contact\">contact us</a> giving reasons.\n" msgstr "" -#: app/views/general/_advanced_search_tips.rhtml:31 -msgid "The public authority would like part of the request explained" +#: app/views/user/_signup.rhtml:6 +msgid "If you're new to {{site_name}}" msgstr "" -#: app/views/general/_advanced_search_tips.rhtml:32 -msgid "The public authority would like to / has responded by post" +#: app/views/user/_signin.rhtml:7 +msgid "If you've used {{site_name}} before" msgstr "" -#: app/views/general/_advanced_search_tips.rhtml:33 -msgid "Waiting for the public authority to complete an internal review of their handling of the request" +#: app/views/user/no_cookies.rhtml:12 +msgid "" +"If your browser is set to accept cookies and you are seeing this message,\n" +"then there is probably a fault with our server." msgstr "" -#: app/views/general/_advanced_search_tips.rhtml:34 -msgid "Received an error message, such as delivery failure." +#: locale/model_attributes.rb:55 +msgid "IncomingMessage|Cached attachment text clipped" msgstr "" -#: app/views/general/_advanced_search_tips.rhtml:35 -msgid "A strange reponse, required attention by the {{site_name}} team" +#: locale/model_attributes.rb:56 +msgid "IncomingMessage|Cached main body text folded" msgstr "" -#: app/views/general/_advanced_search_tips.rhtml:36 -msgid "The requester has abandoned this request for some reason" +#: locale/model_attributes.rb:57 +msgid "IncomingMessage|Cached main body text unfolded" msgstr "" -#: app/views/general/_advanced_search_tips.rhtml:39 -msgid "Table of varieties" +#: locale/model_attributes.rb:61 +msgid "IncomingMessage|Last parsed" msgstr "" -#: app/views/general/_advanced_search_tips.rhtml:40 -msgid "All the options below can use <strong>variety</strong> or <strong>latest_variety</strong> before the colon. For example, <strong>variety:sent</strong> will match requests which have <em>ever</em> been sent; <strong>latest_variety:sent</strong> will match only requests that are <em>currently</em> marked as sent." +#: locale/model_attributes.rb:62 +msgid "IncomingMessage|Mail from" msgstr "" -#: app/views/general/_advanced_search_tips.rhtml:42 -msgid "Original request sent" +#: locale/model_attributes.rb:59 +msgid "IncomingMessage|Mail from domain" msgstr "" -#: app/views/general/_advanced_search_tips.rhtml:43 -msgid "Follow up message sent by requester" +#: locale/model_attributes.rb:63 +msgid "IncomingMessage|Sent at" msgstr "" -#: app/views/general/_advanced_search_tips.rhtml:44 -msgid "Response from a public authority" +#: locale/model_attributes.rb:58 +msgid "IncomingMessage|Subject" msgstr "" -#: app/views/general/_advanced_search_tips.rhtml:45 -msgid "Annotation added to request" +#: locale/model_attributes.rb:60 +msgid "IncomingMessage|Valid to reply to" msgstr "" -#: app/views/general/_advanced_search_tips.rhtml:46 -msgid "A public authority" +#: locale/model_attributes.rb:39 +msgid "InfoRequestEvent|Calculated state" msgstr "" -#: app/views/general/_advanced_search_tips.rhtml:47 -msgid "A {{site_name}} user" +#: locale/model_attributes.rb:38 +msgid "InfoRequestEvent|Described state" msgstr "" -#: app/views/general/_credits.rhtml:1 -msgid "Powered by <a href=\"http://www.alaveteli.org/\">Alaveteli</a>" +#: locale/model_attributes.rb:36 +msgid "InfoRequestEvent|Event type" msgstr "" -#: app/views/general/_footer.rhtml:2 -msgid "Contact {{site_name}}" +#: locale/model_attributes.rb:40 +msgid "InfoRequestEvent|Last described at" msgstr "" -#: app/views/general/_footer.rhtml:3 app/views/general/blog.rhtml:7 -msgid "Follow us on twitter" +#: locale/model_attributes.rb:37 +msgid "InfoRequestEvent|Params yaml" msgstr "" -#: app/views/general/_localised_datepicker.rhtml:4 -msgid "Done" +#: locale/model_attributes.rb:41 +msgid "InfoRequestEvent|Prominence" msgstr "" -#: app/views/general/_localised_datepicker.rhtml:5 -msgid "Prev" +#: locale/model_attributes.rb:102 +msgid "InfoRequest|Allow new responses from" msgstr "" -#: app/views/general/_localised_datepicker.rhtml:6 -msgid "Next" +#: locale/model_attributes.rb:98 +msgid "InfoRequest|Awaiting description" msgstr "" -#: app/views/general/_localised_datepicker.rhtml:7 -msgid "Today" +#: locale/model_attributes.rb:97 +msgid "InfoRequest|Described state" msgstr "" -#: app/views/general/_localised_datepicker.rhtml:13 -msgid "Wk" +#: locale/model_attributes.rb:103 +msgid "InfoRequest|Handle rejected responses" msgstr "" -#: app/views/general/_topnav.rhtml:3 -msgid "Home" +#: locale/model_attributes.rb:104 +msgid "InfoRequest|Idhash" msgstr "" -#: app/views/general/_topnav.rhtml:4 -msgid "Make a request" +#: locale/model_attributes.rb:101 +msgid "InfoRequest|Law used" msgstr "" -#: app/views/general/_topnav.rhtml:5 -msgid "View requests" +#: locale/model_attributes.rb:99 +msgid "InfoRequest|Prominence" msgstr "" -#: app/views/general/_topnav.rhtml:6 -msgid "View authorities" +#: locale/model_attributes.rb:96 +msgid "InfoRequest|Title" msgstr "" -#: app/views/general/_topnav.rhtml:7 -msgid "Read blog" +#: locale/model_attributes.rb:100 +msgid "InfoRequest|Url title" msgstr "" -#: app/views/general/_topnav.rhtml:8 -msgid "Help" +#: app/models/info_request.rb:787 +msgid "Information not held." msgstr "" -#: app/views/general/blog.rhtml:1 -msgid "{{site_name}} blog and tweets" +#: app/views/request/new.rhtml:69 +msgid "" +"Information on emissions and discharges (e.g. noise, energy,\n" +" radiation, waste materials)" msgstr "" -#: app/views/general/blog.rhtml:6 -msgid "Stay up to date" +#: app/models/info_request_event.rb:348 +msgid "Internal review request" msgstr "" -#: app/views/general/blog.rhtml:8 -msgid "Subscribe to blog" +#: app/views/outgoing_mailer/initial_request.rhtml:8 +msgid "" +"Is {{email_address}} the wrong address for {{type_of_request}} requests to " +"{{public_body_name}}? If so, please contact us using this form:" msgstr "" -#: app/views/general/blog.rhtml:53 -msgid "Posted on {{date}} by {{author}}" +#: app/views/user/no_cookies.rhtml:8 +msgid "" +"It may be that your browser is not set to accept a thing called \"cookies" +"\",\n" +"or cannot do so. If you can, please enable cookies, or try using a " +"different\n" +"browser. Then press refresh to have another go." msgstr "" -#: app/views/general/blog.rhtml:56 -msgid "{{number_of_comments}} comments" +#: app/views/user/_user_listing_single.rhtml:21 +msgid "Joined in" msgstr "" -#: app/views/general/exception_caught.rhtml:3 -msgid "Sorry, we couldn't find that page" +#: app/views/user/show.rhtml:67 +msgid "Joined {{site_name}} in" msgstr "" -#: app/views/general/exception_caught.rhtml:5 -msgid "The page doesn't exist. Things you can try now:" +#: app/views/request/new.rhtml:106 +msgid "" +"Keep it <strong>focused</strong>, you'll be more likely to get what you want " +"(<a href=\"%s\">why?</a>)." msgstr "" -#: app/views/general/exception_caught.rhtml:8 -msgid "Check for mistakes if you typed or copied the address." +#: app/views/request/_request_filter_form.rhtml:6 +msgid "Keywords" msgstr "" -#: app/views/general/exception_caught.rhtml:9 -msgid "Search the site to find what you were looking for." +#: lib/world_foi_websites.rb:9 +msgid "Kosovo" msgstr "" -#: app/views/general/exception_caught.rhtml:12 app/views/general/frontpage.rhtml:23 -#: app/views/general/search.rhtml:17 app/views/general/search.rhtml:32 app/views/general/search.rhtml:45 -#: app/views/public_body/list.rhtml:43 app/views/request/_request_filter_form.rhtml:49 -#: app/views/request/select_authority.rhtml:41 -msgid "Search" +#: app/views/contact_mailer/message.rhtml:10 +msgid "Last authority viewed: " msgstr "" -#: app/views/general/exception_caught.rhtml:17 -msgid "Sorry, there was a problem processing this page" +#: app/views/contact_mailer/message.rhtml:7 +msgid "Last request viewed: " msgstr "" -#: app/views/general/exception_caught.rhtml:18 -msgid "You have found a bug. Please <a href=\"{{contact_url}}\">contact us</a> to tell us about the problem" +#: app/views/user/no_cookies.rhtml:17 +msgid "" +"Let us know what you were doing when this message\n" +"appeared and your browser and operating system type and version." msgstr "" -#: app/views/general/exception_caught.rhtml:21 -msgid "Technical details" +#: app/views/request/_correspondence.rhtml:26 +#: app/views/request/_correspondence.rhtml:54 +msgid "Link to this" msgstr "" -#: app/views/general/exception_caught.rhtml:22 -msgid "Unknown" +#: app/views/public_body/list.rhtml:32 +msgid "List of all authorities (CSV)" msgstr "" -#: app/views/general/frontpage.rhtml:5 -msgid "Make a new<br/>\n <strong>Freedom <span>of</span><br/>\n Information<br/>\n request</strong>" +#: app/controllers/request_controller.rb:814 +msgid "Log in to download a zip file of {{info_request_title}}" msgstr "" -#: app/views/general/frontpage.rhtml:10 -msgid "Start now »" +#: app/models/info_request.rb:785 +msgid "Long overdue." msgstr "" -#: app/views/general/frontpage.rhtml:15 -msgid "Search over<br/>\n <strong>{{number_of_requests}} requests</strong> <span>and</span><br/>\n <strong>{{number_of_authorities}} authorities</strong>" +#: app/views/request/_request_filter_form.rhtml:23 +#: app/views/general/search.rhtml:108 +msgid "Made between" msgstr "" -#: app/views/general/frontpage.rhtml:37 -msgid "Who can I request information from?" +#: app/views/public_body/show.rhtml:52 +msgid "Make a new <strong>Environmental Information</strong> request" msgstr "" -#: app/views/general/frontpage.rhtml:38 -msgid "{{site_name}} covers requests to {{number_of_authorities}} authorities, including:" +#: app/views/public_body/show.rhtml:54 +msgid "" +"Make a new <strong>Freedom of Information</strong> request to {{public_body}}" msgstr "" -#: app/views/general/frontpage.rhtml:43 -msgid "%d request" -msgid_plural "%d requests" -msgstr[0] "" -msgstr[1] "" +#: app/views/general/frontpage.rhtml:5 +msgid "" +"Make a new<br/>\n" +" <strong>Freedom <span>of</span><br/>\n" +" Information<br/>\n" +" request</strong>" +msgstr "" -#: app/views/general/frontpage.rhtml:48 -msgid "Browse all authorities..." +#: app/views/general/_topnav.rhtml:4 +msgid "Make a request" msgstr "" -#: app/views/general/frontpage.rhtml:54 -msgid "What information has been released?" +#: app/views/request/new.rhtml:20 +msgid "Make an {{law_used_short}} request to '{{public_body_name}}'" msgstr "" -#: app/views/general/frontpage.rhtml:55 -msgid "{{site_name}} users have made {{number_of_requests}} requests, including:" +#: app/views/layouts/default.rhtml:8 app/views/layouts/no_chrome.rhtml:8 +msgid "Make and browse Freedom of Information (FOI) requests" msgstr "" -#: app/views/general/frontpage.rhtml:60 -msgid "answered a request about" +#: app/views/public_body/_body_listing_single.rhtml:23 +msgid "Make your own request" msgstr "" -#: app/views/general/frontpage.rhtml:62 -msgid "{{length_of_time}} ago" +#: app/views/contact_mailer/message.rhtml:4 +msgid "Message sent using {{site_name}} contact form, " +msgstr "" + +#: app/views/request/new_bad_contact.rhtml:1 +msgid "Missing contact details for '" +msgstr "" + +#: app/views/public_body/show.rhtml:10 +msgid "More about this authority" +msgstr "" + +#: app/views/request/_sidebar.rhtml:29 +msgid "More similar requests" msgstr "" #: app/views/general/frontpage.rhtml:67 msgid "More successful requests..." msgstr "" -#: app/views/general/search.rhtml:8 -msgid "Search Freedom of Information requests, public authorities and users" +#: app/views/layouts/default.rhtml:106 +msgid "My profile" msgstr "" -#: app/views/general/search.rhtml:10 app/views/public_body/show.rhtml:109 -msgid "There were no requests matching your query." +#: app/views/request/_describe_state.rhtml:64 +msgid "My request has been <strong>refused</strong>" msgstr "" -#: app/views/general/search.rhtml:12 -msgid "Results page {{page_number}}" +#: app/views/layouts/default.rhtml:105 +msgid "My requests" msgstr "" -#: app/views/general/search.rhtml:19 -msgid "Search results" +#: app/models/public_body.rb:36 +msgid "Name can't be blank" msgstr "" -#: app/views/general/search.rhtml:24 -msgid "To use the advanced search, combine phrases and labels as described in the search tips below." +#: app/models/public_body.rb:40 +msgid "Name is already taken" msgstr "" -#: app/views/general/search.rhtml:33 -msgid "Simple search" +#: app/models/track_thing.rb:214 app/models/track_thing.rb:215 +msgid "New Freedom of Information requests" msgstr "" -#: app/views/general/search.rhtml:46 -msgid "Advanced search" +#: lib/world_foi_websites.rb:21 +msgid "New Zealand" msgstr "" -#: app/views/general/search.rhtml:51 app/views/request/_request_filter_form.rhtml:29 -msgid "Showing" +#: app/views/user/signchangeemail.rhtml:20 +msgid "New e-mail:" msgstr "" -#: app/views/general/search.rhtml:56 -msgid "everything" +#: app/models/change_email_validator.rb:54 +msgid "New email doesn't look like a valid address" msgstr "" -#: app/views/general/search.rhtml:75 -msgid "Tags (separated by a space):" +#: app/views/user/signchangepassword.rhtml:15 +msgid "New password:" msgstr "" -#: app/views/general/search.rhtml:87 -msgid "Restrict to" +#: app/views/user/signchangepassword.rhtml:20 +msgid "New password: (again)" msgstr "" -#: app/views/general/search.rhtml:88 app/views/request/_request_filter_form.rhtml:31 -msgid "successful requests" +#: app/models/request_mailer.rb:68 +msgid "New response to your FOI request - " msgstr "" -#: app/views/general/search.rhtml:89 app/views/request/_request_filter_form.rhtml:32 -msgid "unsuccessful requests" +#: app/views/request/show_response.rhtml:60 +msgid "New response to your request" msgstr "" -#: app/views/general/search.rhtml:90 app/views/request/_request_filter_form.rhtml:33 -msgid "unresolved requests" +#: app/views/request/show_response.rhtml:66 +msgid "New response to {{law_used_short}} request" msgstr "" -#: app/views/general/search.rhtml:91 -msgid "internal reviews" +#: app/models/track_thing.rb:198 app/models/track_thing.rb:199 +msgid "New updates for the request '{{request_title}}'" msgstr "" -#: app/views/general/search.rhtml:100 -msgid "Search in" +#: app/views/general/search.rhtml:127 +msgid "Newest results first" msgstr "" -#: app/views/general/search.rhtml:101 app/views/request/_request_filter_form.rhtml:12 -msgid "messages from users" +#: app/views/general/_localised_datepicker.rhtml:6 +msgid "Next" msgstr "" -#: app/views/general/search.rhtml:102 app/views/request/_request_filter_form.rhtml:13 -msgid "messages from authorities" +#: app/views/user/set_draft_profile_photo.rhtml:32 +msgid "Next, crop your photo >>" msgstr "" -#: app/views/general/search.rhtml:112 app/views/request/_request_filter_form.rhtml:23 -msgid "Made between" +#: app/views/request/list.rhtml:19 +msgid "No requests of this sort yet." msgstr "" -#: app/views/general/search.rhtml:114 app/views/request/_request_filter_form.rhtml:25 -msgid "and" +#: app/views/request/select_authority.rhtml:53 +#: app/views/public_body/_search_ahead.rhtml:9 +msgid "No results found." msgstr "" -#: app/views/general/search.rhtml:121 -msgid "Filter" +#: app/views/request/similar.rhtml:7 +msgid "No similar requests found." msgstr "" -#: app/views/general/search.rhtml:129 -msgid "Show most relevant results first" +#: app/views/public_body/show.rhtml:77 +msgid "" +"Nobody has made any Freedom of Information requests to {{public_body_name}} " +"using this site yet." msgstr "" -#: app/views/general/search.rhtml:131 -msgid "Newest results first" +#: app/views/request/_request_listing.rhtml:2 +#: app/views/public_body/_body_listing.rhtml:3 +msgid "None found." msgstr "" -#: app/views/general/search.rhtml:133 -msgid "Recently described results first" +#: app/views/user/show.rhtml:175 app/views/user/show.rhtml:197 +msgid "None made." msgstr "" -#: app/views/general/search.rhtml:141 -msgid "Track this search" +#: app/views/user/signchangepassword_confirm.rhtml:1 +#: app/views/user/signchangepassword_confirm.rhtml:3 +#: app/views/user/signchangeemail_confirm.rhtml:3 +msgid "Now check your email!" msgstr "" -#: app/views/general/search.rhtml:156 -msgid "One public authority found" +#: app/views/comment/preview.rhtml:5 +msgid "Now preview your annotation" msgstr "" -#: app/views/general/search.rhtml:158 -msgid "Public authorities {{start_count}} to {{end_count}} of {{total_count}}" +#: app/views/request/followup_preview.rhtml:10 +msgid "Now preview your follow up" msgstr "" -#: app/views/general/search.rhtml:169 -msgid "No public authorities found" +#: app/views/request/followup_preview.rhtml:8 +msgid "Now preview your message asking for an internal review" msgstr "" -#: app/views/general/search.rhtml:171 -msgid "Did you mean: {{correction}}" +#: app/views/user/set_draft_profile_photo.rhtml:46 +msgid "OR remove the existing photo" msgstr "" -#: app/views/general/search.rhtml:173 -msgid "<a href=\"%s\">Browse all</a> or <a href=\"%s\">ask us to add one</a>." +#: app/controllers/request_controller.rb:454 +msgid "" +"Oh no! Sorry to hear that your request was refused. Here is what to do now." msgstr "" -#: app/views/general/search.rhtml:180 -msgid "One person found" +#: app/views/user/signchangeemail.rhtml:15 +msgid "Old e-mail:" msgstr "" -#: app/views/general/search.rhtml:182 -msgid "People {{start_count}} to {{end_count}} of {{total_count}}" +#: app/models/change_email_validator.rb:45 +msgid "" +"Old email address isn't the same as the address of the account you are " +"logged in with" msgstr "" -#: app/views/general/search.rhtml:196 +#: app/models/change_email_validator.rb:40 +msgid "Old email doesn't look like a valid address" +msgstr "" + +#: app/views/user/show.rhtml:39 +msgid "On this page" +msgstr "" + +#: app/views/general/search.rhtml:193 msgid "One FOI request found" msgstr "" -#: app/views/general/search.rhtml:198 -msgid "FOI requests {{start_count}} to {{end_count}} of {{total_count}}" +#: app/views/general/search.rhtml:175 +msgid "One person found" msgstr "" -#: app/views/help/alaveteli.rhtml:6 -msgid "Would you like to see a website like this in your country?" +#: app/views/general/search.rhtml:152 +msgid "One public authority found" msgstr "" -#: app/views/layouts/default.rhtml:8 app/views/layouts/no_chrome.rhtml:8 -msgid "Make and browse Freedom of Information (FOI) requests" +#: app/views/public_body/show.rhtml:111 +msgid "Only requests made using {{site_name}} are shown." msgstr "" -#: app/views/layouts/default.rhtml:102 -msgid "Hello, {{username}}!" +#: app/models/info_request.rb:399 +msgid "" +"Only the authority can reply to this request, and I don't recognise the " +"address this reply was sent from" msgstr "" -#: app/views/layouts/default.rhtml:105 -msgid "My profile" +#: app/models/info_request.rb:395 +msgid "" +"Only the authority can reply to this request, but there is no \"From\" " +"address to check against" msgstr "" -#: app/views/layouts/default.rhtml:109 -msgid "Sign out" +#: app/views/request/_search_ahead.rhtml:11 +msgid "Or search in their website for this information." msgstr "" -#: app/views/layouts/default.rhtml:111 -msgid "Sign in or sign up" +#: app/views/general/_advanced_search_tips.rhtml:42 +msgid "Original request sent" msgstr "" -#: app/views/layouts/default.rhtml:152 -msgid "Paste this link into emails, tweets, and anywhere else:" +#: app/views/request/_describe_state.rhtml:71 +msgid "Other:" msgstr "" -#: app/views/outgoing_mailer/_followup_footer.rhtml:1 -msgid "Disclaimer: This message and any reply that you make will be published on the internet. Our privacy and copyright policies:" +#: locale/model_attributes.rb:26 +msgid "OutgoingMessage|Body" msgstr "" -#: app/views/outgoing_mailer/_followup_footer.rhtml:4 -msgid "If you find this service useful as an FOI officer, please ask your web manager to link to us from your organisation's FOI page." +#: locale/model_attributes.rb:29 +msgid "OutgoingMessage|Last sent at" msgstr "" -#: app/views/outgoing_mailer/followup.rhtml:6 app/views/outgoing_mailer/initial_request.rhtml:5 -msgid "Please use this email address for all replies to this request:" +#: locale/model_attributes.rb:28 +msgid "OutgoingMessage|Message type" msgstr "" -#: app/views/outgoing_mailer/initial_request.rhtml:8 -msgid "Is {{email_address}} the wrong address for {{type_of_request}} requests to {{public_body_name}}? If so, please contact us using this form:" +#: locale/model_attributes.rb:27 +msgid "OutgoingMessage|Status" msgstr "" -#: app/views/public_body/_body_listing.rhtml:3 app/views/request/_request_listing.rhtml:2 -msgid "None found." +#: locale/model_attributes.rb:30 +msgid "OutgoingMessage|What doing" msgstr "" -#: app/views/public_body/_body_listing_single.rhtml:12 -msgid "Also called {{other_name}}." +#: app/models/info_request.rb:791 +msgid "Partially successful." msgstr "" -#: app/views/public_body/_body_listing_single.rhtml:21 -msgid "%d request made." -msgid_plural "%d requests made." -msgstr[0] "" -msgstr[1] "" +#: app/models/change_email_validator.rb:48 +msgid "Password is not correct" +msgstr "" -#: app/views/public_body/_body_listing_single.rhtml:23 -msgid "Make your own request" +#: app/views/user/_signup.rhtml:30 app/views/user/_signin.rhtml:16 +msgid "Password:" msgstr "" -#: app/views/public_body/_body_listing_single.rhtml:27 -msgid "Added on {{date}}" +#: app/views/user/_signup.rhtml:35 +msgid "Password: (again)" msgstr "" -#: app/views/public_body/_search_ahead.rhtml:3 app/views/request/select_authority.rhtml:47 -msgid "Top search results:" +#: app/views/layouts/default.rhtml:153 +msgid "Paste this link into emails, tweets, and anywhere else:" msgstr "" -#: app/views/public_body/_search_ahead.rhtml:5 app/views/request/select_authority.rhtml:49 -msgid "Select one to see more information about the authority." +#: app/views/general/search.rhtml:177 +msgid "People {{start_count}} to {{end_count}} of {{total_count}}" msgstr "" -#: app/views/public_body/_search_ahead.rhtml:8 app/views/request/select_authority.rhtml:52 -msgid "No results found." +#: app/views/user/set_draft_profile_photo.rhtml:13 +msgid "Photo of you:" msgstr "" -#: app/views/public_body/list.rhtml:2 -msgid "Show only..." +#: app/views/request/new.rhtml:74 +msgid "Plans and administrative measures that affect these matters" msgstr "" -#: app/views/public_body/list.rhtml:4 -msgid "Beginning with" +#: app/controllers/request_game_controller.rb:42 +msgid "Play the request categorisation game" msgstr "" -#: app/views/public_body/list.rhtml:29 -msgid "<a href=\"%s\">Are we missing a public authority?</a>." +#: app/views/request_game/play.rhtml:1 app/views/request_game/play.rhtml:30 +msgid "Play the request categorisation game!" msgstr "" -#: app/views/public_body/list.rhtml:32 -msgid "List of all authorities (CSV)" +#: app/views/request/show.rhtml:101 +msgid "Please" msgstr "" -#: app/views/public_body/list.rhtml:36 -msgid "Public authorities - {{description}}" +#: app/views/user/no_cookies.rhtml:15 +msgid "Please <a href=\"%s\">get in touch</a> with us so we can fix it." msgstr "" -#: app/views/public_body/list.rhtml:38 -msgid "Public authorities" +#: app/views/request/show.rhtml:52 +msgid "" +"Please <strong>answer the question above</strong> so we know whether the " msgstr "" -#: app/views/public_body/list.rhtml:47 -msgid "Found {{count}} public bodies {{description}}" +#: app/views/user/show.rhtml:16 +msgid "" +"Please <strong>go to the following requests</strong>, and let us\n" +" know if there was information in the recent responses to them." msgstr "" -#: app/views/public_body/list.rhtml:51 -msgid "<a href=\"%s\">Can't find the one you want?</a>" +#: app/views/request/_followup.rhtml:54 +msgid "" +"Please <strong>only</strong> write messages directly relating to your " +"request {{request_link}}. If you would like to ask for information that was " +"not in your original request, then <a href=\"{{new_request_link}}\">file a " +"new request</a>." msgstr "" -#: app/views/public_body/show.rhtml:1 -msgid " - view and make Freedom of Information requests" +#: app/views/request/new.rhtml:58 +msgid "Please ask for environmental information only" msgstr "" -#: app/views/public_body/show.rhtml:4 -msgid "Follow this authority" +#: app/views/user/bad_token.rhtml:2 +msgid "" +"Please check the URL (i.e. the long code of letters and numbers) is copied\n" +"correctly from your email." msgstr "" -#: app/views/public_body/show.rhtml:7 -msgid "There is %d person following this authority" -msgid_plural "There are %d people following this authority" -msgstr[0] "" -msgstr[1] "" +#: app/models/profile_photo.rb:91 +msgid "Please choose a file containing your photo." +msgstr "" -#: app/views/public_body/show.rhtml:10 -msgid "More about this authority" +#: app/models/outgoing_message.rb:163 +msgid "Please choose what sort of reply you are making." msgstr "" -#: app/views/public_body/show.rhtml:12 -msgid "Home page of authority" +#: app/controllers/request_controller.rb:386 +msgid "" +"Please choose whether or not you got some of the information that you wanted." msgstr "" -#: app/views/public_body/show.rhtml:15 -msgid "Publication scheme" +#: app/views/track_mailer/event_digest.rhtml:63 +msgid "Please click on the link below to cancel or alter these emails." msgstr "" -#: app/views/public_body/show.rhtml:20 app/views/public_body/show.rhtml:22 -msgid "Charity registration" +#: app/views/user_mailer/changeemail_confirm.rhtml:3 +msgid "" +"Please click on the link below to confirm that you want to \n" +"change the email address that you use for {{site_name}}\n" +"from {{old_email}} to {{new_email}}" msgstr "" -#: app/views/public_body/show.rhtml:26 -msgid "View FOI email address" +#: app/views/user_mailer/confirm_login.rhtml:3 +msgid "Please click on the link below to confirm your email address." msgstr "" -#: app/views/public_body/show.rhtml:30 -msgid "Freedom of information requests to" +#: app/models/info_request.rb:120 +msgid "" +"Please describe more what the request is about in the subject. There is no " +"need to say it is an FOI request, we add that on anyway." msgstr "" -#: app/views/public_body/show.rhtml:35 -msgid "also called {{public_body_short_name}}" +#: app/views/user/set_draft_profile_photo.rhtml:22 +msgid "" +"Please don't upload offensive pictures. We will take down images\n" +" that we consider inappropriate." msgstr "" -#: app/views/public_body/show.rhtml:37 -msgid "admin" +#: app/views/user/no_cookies.rhtml:3 +msgid "Please enable \"cookies\" to carry on" msgstr "" -#: app/views/public_body/show.rhtml:46 -msgid "You can only request information about the environment from this authority." +#: app/models/user.rb:42 +msgid "Please enter a password" msgstr "" -#: app/views/public_body/show.rhtml:52 -msgid "Make a new <strong>Environmental Information</strong> request" +#: app/models/contact_validator.rb:30 +msgid "Please enter a subject" msgstr "" -#: app/views/public_body/show.rhtml:54 -msgid "Make a new <strong>Freedom of Information</strong> request to {{public_body}}" +#: app/models/info_request.rb:28 +msgid "Please enter a summary of your request" msgstr "" -#: app/views/public_body/show.rhtml:56 -msgid "<a class=\"link_button_green\" href=\"{{url}}\">{{text}}</a>" +#: app/models/user.rb:119 +msgid "Please enter a valid email address" msgstr "" -#: app/views/public_body/show.rhtml:56 -msgid "Start" +#: app/models/contact_validator.rb:31 +msgid "Please enter the message you want to send" msgstr "" -#: app/views/public_body/show.rhtml:60 -msgid "Freedom of Information law does not apply to this authority, so you cannot make\n a request to it." +#: app/models/user.rb:53 +msgid "Please enter the same password twice" msgstr "" -#: app/views/public_body/show.rhtml:63 -msgid "This authority no longer exists, so you cannot make a request to it." +#: app/models/comment.rb:60 +msgid "Please enter your annotation" msgstr "" -#: app/views/public_body/show.rhtml:65 -msgid "For an unknown reason, it is not possible to make a request to this authority." +#: app/models/contact_validator.rb:29 app/models/user.rb:38 +msgid "Please enter your email address" msgstr "" -#: app/views/public_body/show.rhtml:73 -msgid "Environmental Information Regulations requests made using this site" +#: app/models/outgoing_message.rb:148 +msgid "Please enter your follow up message" msgstr "" -#: app/views/public_body/show.rhtml:76 -msgid "Freedom of Information requests made using this site" +#: app/models/outgoing_message.rb:151 +msgid "Please enter your letter requesting information" msgstr "" -#: app/views/public_body/show.rhtml:77 -msgid "Nobody has made any Freedom of Information requests to {{public_body_name}} using this site yet." +#: app/models/contact_validator.rb:28 app/models/user.rb:40 +msgid "Please enter your name" msgstr "" -#: app/views/public_body/show.rhtml:85 -msgid "Search within the %d Freedom of Information requests to %s" -msgid_plural "Search within the %d Freedom of Information requests made to %s" -msgstr[0] "" -msgstr[1] "" +#: app/models/user.rb:122 +msgid "Please enter your name, not your email address, in the name field." +msgstr "" -#: app/views/public_body/show.rhtml:87 -msgid "%d Freedom of Information request to %s" -msgid_plural "%d Freedom of Information requests to %s" -msgstr[0] "" -msgstr[1] "" +#: app/models/change_email_validator.rb:31 +msgid "Please enter your new email address" +msgstr "" -#: app/views/public_body/show.rhtml:111 -msgid "Only requests made using {{site_name}} are shown." +#: app/models/change_email_validator.rb:30 +msgid "Please enter your old email address" msgstr "" -#: app/views/public_body/show.rhtml:116 -msgid "Environmental Information Regulations requests made" +#: app/models/change_email_validator.rb:32 +msgid "Please enter your password" msgstr "" -#: app/views/public_body/show.rhtml:118 -msgid "Freedom of Information requests made" +#: app/models/outgoing_message.rb:146 +msgid "Please give details explaining why you want a review" msgstr "" -#: app/views/public_body/show.rhtml:120 -msgid "The search index is currently offline, so we can't show the Freedom of Information requests that have been made to this authority." +#: app/models/about_me_validator.rb:24 +msgid "Please keep it shorter than 500 characters" msgstr "" -#: app/views/public_body/view_email.rhtml:3 -msgid "FOI email address for {{public_body}}" +#: app/models/info_request.rb:117 +msgid "" +"Please keep the summary short, like in the subject of an email. You can use " +"a phrase, rather than a full sentence." msgstr "" -#: app/views/public_body/view_email.rhtml:7 -msgid "{{site_name}} sends new requests to <strong>{{request_email}}</strong> for this authority." +#: app/views/request/new.rhtml:77 +msgid "" +"Please only request information that comes under those categories, " +"<strong>do not waste your\n" +" time</strong> or the time of the public authority by requesting " +"unrelated information." msgstr "" -#: app/views/public_body/view_email.rhtml:10 -msgid "Freedom of Information law no longer applies to this authority.Follow up messages to existing requests are sent to " +#: app/views/request/new_please_describe.rhtml:5 +msgid "" +"Please select each of these requests in turn, and <strong>let everyone know</" +"strong>\n" +"if they are successful yet or not." msgstr "" -#: app/views/public_body/view_email.rhtml:14 -msgid "Follow up messages to existing requests are sent to " +#: app/models/outgoing_message.rb:157 +msgid "" +"Please sign at the bottom with your name, or alter the \"%{signoff}\" " +"signature" msgstr "" -#: app/views/public_body/view_email.rhtml:17 -msgid "We do not have a working request email address for this authority." +#: app/views/user/sign.rhtml:8 +msgid "Please sign in as " msgstr "" -#: app/views/public_body/view_email.rhtml:28 -msgid "If the address is wrong, or you know a better address, please <a href=\"%s\">contact us</a>." +#: app/controllers/request_controller.rb:783 +msgid "Please type a message and/or choose a file containing your response." msgstr "" -#: app/views/public_body/view_email.rhtml:30 -msgid " If you know the address to use, then please <a href=\"%s\">send it to us</a>.\n You may be able to find the address on their website, or by phoning them up and asking." +#: app/controllers/request_controller.rb:474 +msgid "Please use the form below to tell us more." msgstr "" -#: app/views/public_body/view_email_captcha.rhtml:1 -msgid "View FOI email address for '{{public_body_name}}'" +#: app/views/outgoing_mailer/initial_request.rhtml:5 +#: app/views/outgoing_mailer/followup.rhtml:6 +msgid "Please use this email address for all replies to this request:" msgstr "" -#: app/views/public_body/view_email_captcha.rhtml:3 -msgid "View FOI email address for {{public_body_name}}" +#: app/models/info_request.rb:29 +msgid "Please write a summary with some text in it" msgstr "" -#: app/views/public_body/view_email_captcha.rhtml:5 -msgid "To view the email address that we use to send FOI requests to {{public_body_name}}, please enter these words." +#: app/models/info_request.rb:114 +msgid "" +"Please write the summary using a mixture of capital and lower case letters. " +"This makes it easier for others to read." msgstr "" -#: app/views/public_body/view_email_captcha.rhtml:12 -msgid "View email" +#: app/models/comment.rb:63 +msgid "" +"Please write your annotation using a mixture of capital and lower case " +"letters. This makes it easier for others to read." msgstr "" -#: app/views/request/_after_actions.rhtml:3 -msgid "Things to do with this request" +#: app/controllers/request_controller.rb:463 +msgid "" +"Please write your follow up message containing the necessary clarifications " +"below." msgstr "" -#: app/views/request/_after_actions.rhtml:6 -msgid "Anyone:" +#: app/models/outgoing_message.rb:160 +msgid "" +"Please write your message using a mixture of capital and lower case letters. " +"This makes it easier for others to read." msgstr "" -#: app/views/request/_after_actions.rhtml:9 -msgid "<a href=\"%s\">Add an annotation</a> (to help the requester or others)" +#: app/views/comment/new.rhtml:42 +msgid "" +"Point to <strong>related information</strong>, campaigns or forums which may " +"be useful." msgstr "" -#: app/views/request/_after_actions.rhtml:13 app/views/request/_after_actions.rhtml:35 -msgid "Update the status of this request" +#: app/views/request/_search_ahead.rhtml:4 +msgid "Possibly related requests:" msgstr "" -#: app/views/request/_after_actions.rhtml:17 -msgid "Download a zip file of all correspondence" +#: app/views/comment/preview.rhtml:21 +msgid "Post annotation" msgstr "" -#: app/views/request/_after_actions.rhtml:23 -msgid "{{info_request_user_name}} only:" +#: locale/model_attributes.rb:53 +msgid "PostRedirect|Circumstance" msgstr "" -#: app/views/request/_after_actions.rhtml:28 -msgid "Send a followup" +#: locale/model_attributes.rb:51 +msgid "PostRedirect|Email token" msgstr "" -#: app/views/request/_after_actions.rhtml:30 -msgid "Write a reply" +#: locale/model_attributes.rb:50 +msgid "PostRedirect|Post params yaml" msgstr "" -#: app/views/request/_after_actions.rhtml:39 -msgid "Request an internal review" +#: locale/model_attributes.rb:52 +msgid "PostRedirect|Reason params yaml" msgstr "" -#: app/views/request/_after_actions.rhtml:45 -msgid "{{public_body_name}} only:" +#: locale/model_attributes.rb:48 +msgid "PostRedirect|Token" msgstr "" -#: app/views/request/_after_actions.rhtml:48 -msgid "Respond to request" +#: locale/model_attributes.rb:49 +msgid "PostRedirect|Uri" msgstr "" -#: app/views/request/_correspondence.rhtml:12 app/views/request/_correspondence.rhtml:36 -#: app/views/request/simple_correspondence.rhtml:14 app/views/request/simple_correspondence.rhtml:27 -msgid "From:" +#: app/views/general/blog.rhtml:53 +msgid "Posted on {{date}} by {{author}}" msgstr "" -#: app/views/request/_correspondence.rhtml:26 app/views/request/_correspondence.rhtml:54 -msgid "Link to this" +#: app/views/general/_credits.rhtml:1 +msgid "Powered by <a href=\"http://www.alaveteli.org/\">Alaveteli</a>" msgstr "" -#: app/views/request/_describe_state.rhtml:4 -msgid "What best describes the status of this request now?" +#: app/views/general/_localised_datepicker.rhtml:5 +msgid "Prev" msgstr "" -#: app/views/request/_describe_state.rhtml:7 app/views/request/_other_describe_state.rhtml:10 -msgid "This request is still in progress:" +#: app/views/request/followup_preview.rhtml:1 +msgid "Preview follow up to '" msgstr "" -#: app/views/request/_describe_state.rhtml:11 -msgid "I'm still <strong>waiting</strong> for my information\n <small>(maybe you got an acknowledgement)</small>" +#: app/views/comment/preview.rhtml:1 +msgid "Preview new annotation on '{{info_request_title}}'" msgstr "" -#: app/views/request/_describe_state.rhtml:18 -msgid "I'm still <strong>waiting</strong> for the internal review" +#: app/views/comment/_comment_form.rhtml:15 +msgid "Preview your annotation" msgstr "" -#: app/views/request/_describe_state.rhtml:25 -msgid "I've been asked to <strong>clarify</strong> my request" +#: app/views/request/_followup.rhtml:123 +msgid "Preview your message" msgstr "" -#: app/views/request/_describe_state.rhtml:32 -msgid "I'm waiting for an <strong>internal review</strong> response" +#: app/views/request/new.rhtml:143 +msgid "Preview your public request" msgstr "" -#: app/views/request/_describe_state.rhtml:38 -msgid "They are going to reply <strong>by post</strong>" +#: locale/model_attributes.rb:15 +msgid "ProfilePhoto|Data" msgstr "" -#: app/views/request/_describe_state.rhtml:44 app/views/request/_other_describe_state.rhtml:40 -msgid "This particular request is finished:" +#: locale/model_attributes.rb:16 +msgid "ProfilePhoto|Draft" msgstr "" -#: app/views/request/_describe_state.rhtml:47 app/views/request/_other_describe_state.rhtml:43 -msgid "The <strong>review has finished</strong> and overall:" +#: app/views/public_body/list.rhtml:38 +msgid "Public authorities" msgstr "" -#: app/views/request/_describe_state.rhtml:52 -msgid "They do <strong>not have</strong> the information <small>(maybe they say who does)</small>" +#: app/views/public_body/list.rhtml:36 +msgid "Public authorities - {{description}}" msgstr "" -#: app/views/request/_describe_state.rhtml:56 -msgid "I've received <strong>some of the information</strong>" +#: app/views/general/search.rhtml:154 +msgid "Public authorities {{start_count}} to {{end_count}} of {{total_count}}" msgstr "" -#: app/views/request/_describe_state.rhtml:60 -msgid "I've received <strong>all the information" +#: locale/model_attributes.rb:12 +msgid "PublicBody|First letter" msgstr "" -#: app/views/request/_describe_state.rhtml:64 -msgid "My request has been <strong>refused</strong>" +#: locale/model_attributes.rb:10 +msgid "PublicBody|Home page" msgstr "" -#: app/views/request/_describe_state.rhtml:71 -msgid "Other:" +#: locale/model_attributes.rb:8 +msgid "PublicBody|Last edit comment" msgstr "" -#: app/views/request/_describe_state.rhtml:76 -msgid "I've received an <strong>error message</strong>" +#: locale/model_attributes.rb:7 +msgid "PublicBody|Last edit editor" msgstr "" -#: app/views/request/_describe_state.rhtml:84 -msgid "This request <strong>requires administrator attention</strong>" +#: locale/model_attributes.rb:3 +msgid "PublicBody|Name" msgstr "" -#: app/views/request/_describe_state.rhtml:91 -msgid "I would like to <strong>withdraw this request</strong>" +#: locale/model_attributes.rb:11 +msgid "PublicBody|Notes" msgstr "" -#: app/views/request/_describe_state.rhtml:101 -msgid "Submit status" +#: locale/model_attributes.rb:13 +msgid "PublicBody|Publication scheme" msgstr "" -#: app/views/request/_describe_state.rhtml:101 -msgid "and we'll suggest <strong>what to do next</strong>" +#: locale/model_attributes.rb:5 +msgid "PublicBody|Request email" msgstr "" -#: app/views/request/_describe_state.rhtml:107 -msgid "We don't know whether the most recent response to this request contains\n information or not\n –\n if you are {{user_link}} please <a href=\"{{url}}\">sign in</a> and let everyone know." +#: locale/model_attributes.rb:4 +msgid "PublicBody|Short name" msgstr "" -#: app/views/request/_followup.rhtml:3 -msgid "the main FOI contact at {{public_body}}" +#: locale/model_attributes.rb:9 +msgid "PublicBody|Url name" msgstr "" -#: app/views/request/_followup.rhtml:8 -msgid "Request an internal review from {{person_or_body}}" +#: locale/model_attributes.rb:6 +msgid "PublicBody|Version" msgstr "" -#: app/views/request/_followup.rhtml:11 -msgid "Send a public follow up message to {{person_or_body}}" +#: app/views/public_body/show.rhtml:15 +msgid "Publication scheme" msgstr "" -#: app/views/request/_followup.rhtml:14 -msgid "Send a public reply to {{person_or_body}}" +#: app/views/track/_tracking_links.rhtml:26 +msgid "RSS feed" msgstr "" -#: app/views/request/_followup.rhtml:19 -msgid "Don't want to address your message to {{person_or_body}}? You can also write to:" +#: app/views/track/_tracking_links.rhtml:26 +msgid "RSS feed of updates" msgstr "" -#: app/views/request/_followup.rhtml:23 app/views/request/_followup.rhtml:28 -#: app/views/request/_followup.rhtml:34 -msgid "the main FOI contact address for {{public_body}}" +#: app/views/comment/preview.rhtml:20 +msgid "Re-edit this annotation" msgstr "" -#: app/views/request/_followup.rhtml:43 -msgid "Follow ups and new responses to this request have been stopped to prevent spam. Please <a href=\"{{url}}\">contact us</a> if you are {{user_link}} and need to send a follow up." +#: app/views/request/followup_preview.rhtml:49 +msgid "Re-edit this message" msgstr "" -#: app/views/request/_followup.rhtml:47 -msgid "If you are dissatisfied by the response you got from\n the public authority, you have the right to\n complain (<a href=\"%s\">details</a>)." +#: app/views/general/_advanced_search_tips.rhtml:19 +msgid "" +"Read about <a href=\"{{advanced_search_url}}\">advanced search operators</" +"a>, such as proximity and wildcards." msgstr "" -#: app/views/request/_followup.rhtml:54 -msgid "Please <strong>only</strong> write messages directly relating to your request {{request_link}}. If you would like to ask for information that was not in your original request, then <a href=\"{{new_request_link}}\">file a new request</a>." +#: app/views/general/_topnav.rhtml:7 +msgid "Read blog" msgstr "" -#: app/views/request/_followup.rhtml:59 -msgid "The response to your request has been <strong>delayed</strong>. You can say that, \n by law, the authority should normally have responded\n <strong>promptly</strong> and" +#: app/views/general/_advanced_search_tips.rhtml:34 +msgid "Received an error message, such as delivery failure." msgstr "" -#: app/views/request/_followup.rhtml:63 app/views/request/show.rhtml:70 app/views/request/show.rhtml:80 -msgid "in term time" +#: app/views/general/search.rhtml:129 +msgid "Recently described results first" msgstr "" -#: app/views/request/_followup.rhtml:65 -msgid "by <strong>{{date}}</strong>" +#: app/models/info_request.rb:789 +msgid "Refused." msgstr "" -#: app/views/request/_followup.rhtml:66 app/views/request/_followup.rhtml:73 -#: app/views/request/show.rhtml:83 app/views/request/show.rhtml:87 -msgid "<a href=\"%s\">details</a>" +#: app/views/user/_signin.rhtml:26 +msgid "" +"Remember me</label> (keeps you signed in longer;\n" +" do not use on a public computer) " msgstr "" -#: app/views/request/_followup.rhtml:71 -msgid "The response to your request is <strong>long overdue</strong>. You can say that, by \n law, under all circumstances, the authority should have responded\n by now" +#: app/views/comment/_single_comment.rhtml:24 +msgid "Report abuse" msgstr "" -#: app/views/request/_followup.rhtml:85 -msgid "What are you doing?" +#: app/views/request/_after_actions.rhtml:39 +msgid "Request an internal review" msgstr "" -#: app/views/request/_followup.rhtml:95 -msgid "I am asking for <strong>new information</strong>" +#: app/views/request/_followup.rhtml:8 +msgid "Request an internal review from {{person_or_body}}" msgstr "" -#: app/views/request/_followup.rhtml:100 -msgid "I am requesting an <strong>internal review</strong>" +#: app/views/request/hidden.rhtml:1 +msgid "Request has been removed" msgstr "" -#: app/views/request/_followup.rhtml:101 -msgid "<a href=\"%s\">what's that?</a>" +#: app/views/request/_request_listing_via_event.rhtml:20 +msgid "" +"Request sent to {{public_body_name}} by {{info_request_user}} on {{date}}." msgstr "" -#: app/views/request/_followup.rhtml:106 -msgid "<strong>Anything else</strong>, such as clarifying, prompting, thanking" +#: app/views/request/_request_listing_via_event.rhtml:28 +msgid "" +"Request to {{public_body_name}} by {{info_request_user}}. Annotated by " +"{{event_comment_user}} on {{date}}." msgstr "" -#: app/views/request/_followup.rhtml:112 -msgid "Edit and add <strong>more details</strong> to the message above,\n explaining why you are dissatisfied with their response." +#: app/views/request/_request_listing_single.rhtml:12 +msgid "" +"Requested from {{public_body_name}} by {{info_request_user}} on {{date}}" msgstr "" -#: app/views/request/_followup.rhtml:123 -msgid "Preview your message" +#: app/views/request/_sidebar_request_listing.rhtml:13 +msgid "Requested on {{date}}" msgstr "" -#: app/views/request/_hidden_correspondence.rhtml:10 -msgid "This response has been hidden. See annotations to find out why.\n If you are the requester, then you may <a href=\"%s\">sign in</a> to view the response." +#: app/models/track_thing.rb:281 app/models/track_thing.rb:282 +msgid "Requests or responses matching your saved search" msgstr "" -#: app/views/request/_hidden_correspondence.rhtml:17 -msgid "This outgoing message has been hidden. See annotations to\n find out why. If you are the requester, then you may <a href=\"%s\">sign in</a> to view the response." +#: app/views/request/upload_response.rhtml:11 +msgid "Respond by email" msgstr "" -#: app/views/request/_hidden_correspondence.rhtml:23 -msgid "This comment has been hidden. See annotations to\n find out why. If you are the requester, then you may <a href=\"%s\">sign in</a> to view the response." +#: app/views/request/_after_actions.rhtml:48 +msgid "Respond to request" msgstr "" -#: app/views/request/_hidden_correspondence.rhtml:32 -msgid "unexpected prominence on request event" +#: app/views/request/upload_response.rhtml:5 +msgid "Respond to the FOI request" msgstr "" -#: app/views/request/_other_describe_state.rhtml:4 -msgid "Hi! We need your help. The person who made the following request\n hasn't told us whether or not it was successful. Would you mind taking\n a moment to read it and help us keep the place tidy for everyone?\n Thanks." +#: app/views/request/upload_response.rhtml:21 +msgid "Respond using the web" msgstr "" -#: app/views/request/_other_describe_state.rhtml:14 -msgid "<strong>No response</strong> has been received\n <small>(maybe there's just an acknowledgement)</small>" +#: app/models/info_request_event.rb:341 +msgid "Response" msgstr "" -#: app/views/request/_other_describe_state.rhtml:21 -msgid "Still awaiting an <strong>internal review</strong>" +#: app/views/general/_advanced_search_tips.rhtml:44 +msgid "Response from a public authority" msgstr "" -#: app/views/request/_other_describe_state.rhtml:28 -msgid "<strong>Clarification</strong> has been requested" +#: app/views/request/show.rhtml:77 +msgid "Response to this request is <strong>delayed</strong>." msgstr "" -#: app/views/request/_other_describe_state.rhtml:34 -msgid "A response will be sent <strong>by post</strong>" +#: app/views/request/show.rhtml:85 +msgid "Response to this request is <strong>long overdue</strong>." msgstr "" -#: app/views/request/_other_describe_state.rhtml:48 -msgid "The authority do <strong>not have</strong> the information <small>(maybe they say who does)" +#: app/views/request/show_response.rhtml:62 +msgid "Response to your request" msgstr "" -#: app/views/request/_other_describe_state.rhtml:52 -msgid "<strong>Some of the information</strong> has been sent " +#: app/views/request/upload_response.rhtml:28 +msgid "Response:" msgstr "" -#: app/views/request/_other_describe_state.rhtml:56 -msgid "<strong>All the information</strong> has been sent" +#: app/views/general/search.rhtml:83 +msgid "Restrict to" msgstr "" -#: app/views/request/_other_describe_state.rhtml:60 -msgid "The request has been <strong>refused</strong>" +#: app/views/general/search.rhtml:12 +msgid "Results page {{page_number}}" msgstr "" -#: app/views/request/_other_describe_state.rhtml:70 -msgid "An <strong>error message</strong> has been received" +#: app/views/user/set_profile_about_me.rhtml:35 +msgid "Save" msgstr "" -#: app/views/request/_request_filter_form.rhtml:6 -msgid "Keywords" +#: app/views/request/select_authority.rhtml:42 +#: app/views/request/_request_filter_form.rhtml:49 +#: app/views/general/search.rhtml:17 app/views/general/search.rhtml:32 +#: app/views/general/search.rhtml:45 +#: app/views/general/exception_caught.rhtml:12 +#: app/views/general/frontpage.rhtml:23 app/views/public_body/list.rhtml:43 +msgid "Search" +msgstr "" + +#: app/views/general/search.rhtml:8 +msgid "Search Freedom of Information requests, public authorities and users" +msgstr "" + +#: app/views/user/show.rhtml:134 +msgid "Search contributions by this person" msgstr "" #: app/views/request/_request_filter_form.rhtml:11 msgid "Search for words in:" msgstr "" -#: app/views/request/_request_filter_form.rhtml:30 -msgid "all requests" +#: app/views/general/search.rhtml:96 +msgid "Search in" msgstr "" -#: app/views/request/_request_listing_short_via_event.rhtml:9 -msgid "To {{public_body_link_absolute}}" +#: app/views/general/frontpage.rhtml:15 +msgid "" +"Search over<br/>\n" +" <strong>{{number_of_requests}} requests</strong> <span>and</" +"span><br/>\n" +" <strong>{{number_of_authorities}} authorities</strong>" msgstr "" -#: app/views/request/_request_listing_short_via_event.rhtml:10 -msgid "by {{user_link_absolute}}" +#: app/views/general/search.rhtml:19 +msgid "Search results" msgstr "" -#: app/views/request/_request_listing_single.rhtml:12 -msgid "Requested from {{public_body_name}} by {{info_request_user}} on {{date}}" +#: app/views/general/exception_caught.rhtml:9 +msgid "Search the site to find what you were looking for." msgstr "" -#: app/views/request/_request_listing_via_event.rhtml:20 -msgid "Request sent to {{public_body_name}} by {{info_request_user}} on {{date}}." +#: app/views/public_body/show.rhtml:85 +msgid "Search within the %d Freedom of Information requests to %s" +msgid_plural "Search within the %d Freedom of Information requests made to %s" +msgstr[0] "" +msgstr[1] "" + +#: app/views/user/show.rhtml:132 +msgid "Search your contributions" msgstr "" -#: app/views/request/_request_listing_via_event.rhtml:23 -msgid "sent to {{public_body_name}} by {{info_request_user}} on {{date}}." +#: app/views/request/select_authority.rhtml:50 +#: app/views/public_body/_search_ahead.rhtml:6 +msgid "Select one to see more information about the authority." msgstr "" -#: app/views/request/_request_listing_via_event.rhtml:26 -msgid "by {{public_body_name}} to {{info_request_user}} on {{date}}." +#: app/views/request/select_authority.rhtml:28 +msgid "Select the authority to write to" msgstr "" -#: app/views/request/_request_listing_via_event.rhtml:28 -msgid "Request to {{public_body_name}} by {{info_request_user}}. Annotated by {{event_comment_user}} on {{date}}." +#: app/views/request/_after_actions.rhtml:28 +msgid "Send a followup" msgstr "" -#: app/views/request/_request_listing_via_event.rhtml:30 -msgid "unknown event type indexed " +#: app/controllers/user_controller.rb:363 +msgid "Send a message to " msgstr "" -#: app/views/request/_search_ahead.rhtml:3 -msgid "Possibly related requests:" +#: app/views/request/_followup.rhtml:11 +msgid "Send a public follow up message to {{person_or_body}}" msgstr "" -#: app/views/request/_search_ahead.rhtml:10 -msgid "Or search in their website for this information." +#: app/views/request/_followup.rhtml:14 +msgid "Send a public reply to {{person_or_body}}" msgstr "" -#: app/views/request/_sidebar.rhtml:2 -msgid "Follow this request" +#: app/views/request/followup_preview.rhtml:50 +msgid "Send message" msgstr "" -#: app/views/request/_sidebar.rhtml:5 -msgid "There is %d person following this request" -msgid_plural "There are %d people following this request" -msgstr[0] "" -msgstr[1] "" +#: app/views/user/show.rhtml:74 +msgid "Send message to " +msgstr "" -#: app/views/request/_sidebar.rhtml:8 -msgid "Act on what you've learnt" +#: app/views/request/preview.rhtml:41 +msgid "Send request" msgstr "" -#: app/views/request/_sidebar.rhtml:13 -msgid "Tweet this request" +#: app/views/user/show.rhtml:58 +msgid "Set your profile photo" msgstr "" -#: app/views/request/_sidebar.rhtml:17 -msgid "Start your own blog" +#: app/models/public_body.rb:39 +msgid "Short name is already taken" msgstr "" -#: app/views/request/_sidebar.rhtml:24 -msgid "Similar requests" +#: app/views/general/search.rhtml:125 +msgid "Show most relevant results first" msgstr "" -#: app/views/request/_sidebar.rhtml:29 -msgid "More similar requests" +#: app/views/public_body/list.rhtml:2 +msgid "Show only..." msgstr "" -#: app/views/request/_sidebar.rhtml:35 -msgid "Event history details" +#: app/views/request/_request_filter_form.rhtml:29 +#: app/views/general/search.rhtml:51 +msgid "Showing" msgstr "" -#: app/views/request/_sidebar.rhtml:39 -msgid "<a href=\"%s\">Are you the owner of\n any commercial copyright on this page?</a>" +#: app/views/user/sign.rhtml:2 app/views/user/sign.rhtml:24 +#: app/views/user/_signin.rhtml:32 +msgid "Sign in" msgstr "" -#: app/views/request/_sidebar_request_listing.rhtml:13 -msgid "Requested on {{date}}" +#: app/views/user/sign.rhtml:20 +msgid "Sign in or make a new account" msgstr "" -#: app/views/request/_view_html_prefix.rhtml:6 -msgid "Download original attachment" +#: app/views/layouts/default.rhtml:112 +msgid "Sign in or sign up" msgstr "" -#: app/views/request/_view_html_prefix.rhtml:9 -msgid "This is an HTML version of an attachment to the Freedom of Information request" +#: app/views/layouts/default.rhtml:110 +msgid "Sign out" msgstr "" -#: app/views/request/details.rhtml:1 app/views/request/details.rhtml:2 -msgid "Details of request '" +#: app/views/user/_signup.rhtml:46 app/views/user/sign.rhtml:31 +msgid "Sign up" msgstr "" -#: app/views/request/details.rhtml:4 -msgid "Event history" +#: app/views/request/_sidebar.rhtml:24 +msgid "Similar requests" msgstr "" -#: app/views/request/details.rhtml:6 -msgid "This table shows the technical details of the internal events that happened\nto this request on {{site_name}}. This could be used to generate information about\nthe speed with which authorities respond to requests, the number of requests\nwhich require a postal response and much more." +#: app/views/general/search.rhtml:33 +msgid "Simple search" msgstr "" -#: app/views/request/details.rhtml:12 -msgid "<strong>Caveat emptor!</strong> To use this data in an honourable way, you will need \na good internal knowledge of user behaviour on {{site_name}}. How, \nwhy and by whom requests are categorised is not straightforward, and there will\nbe user error and ambiguity. You will also need to understand FOI law, and the\nway authorities use it. Plus you'll need to be an elite statistician. Please\n<a href=\"{{contact_path}}\">contact us</a> with questions." +#: app/models/request_mailer.rb:178 +msgid "Some notes have been added to your FOI request - " msgstr "" -#: app/views/request/details.rhtml:50 -msgid "Here <strong>described</strong> means when a user selected a status for the request, and\nthe most recent event had its status updated to that value. <strong>calculated</strong> is then inferred by\n{{site_name}} for intermediate events, which weren't given an explicit\ndescription by a user. See the <a href=\"{{search_path}}\">search tips</a> for description of the states." +#: app/views/general/_advanced_search_tips.rhtml:29 +msgid "Some of the information requested has been received" msgstr "" -#: app/views/request/details.rhtml:58 -msgid "You can get this page in computer-readable format as part of the main JSON\npage for the request. See the <a href=\"{{api_path}}\">API documentation</a>." +#: app/views/request_game/play.rhtml:31 +msgid "" +"Some people who've made requests haven't let us know whether they were\n" +"successful or not. We need <strong>your</strong> help –\n" +"choose one of these requests, read it, and let everyone know whether or not " +"the\n" +"information has been provided. Everyone'll be exceedingly grateful." msgstr "" -#: app/views/request/followup_bad.rhtml:2 -msgid "Unable to send follow up message to {{username}}" +#: app/models/request_mailer.rb:169 +msgid "Somebody added a note to your FOI request - " msgstr "" -#: app/views/request/followup_bad.rhtml:4 -msgid "Unable to send a reply to {{username}}" +#: app/views/user_mailer/changeemail_already_used.rhtml:1 +msgid "" +"Someone, perhaps you, just tried to change their email address on\n" +"{{site_name}} from {{old_email}} to {{new_email}}." msgstr "" -#: app/views/request/followup_bad.rhtml:11 -msgid "Freedom of Information law no longer applies to" +#: app/views/user/wrong_user.rhtml:2 +msgid "Sorry, but only {{user_name}} is allowed to do that." msgstr "" -#: app/views/request/followup_bad.rhtml:12 -msgid "From the request page, try replying to a particular message, rather than sending\n a general followup. If you need to make a general followup, and know\n an email which will go to the right place, please <a href=\"%s\">send it to us</a>." +#: app/views/general/exception_caught.rhtml:17 +msgid "Sorry, there was a problem processing this page" msgstr "" -#: app/views/request/followup_bad.rhtml:18 -msgid "no longer exists. If you are trying to make\n From the request page, try replying to a particular message, rather than sending\n a general followup. If you need to make a general followup, and know\n an email which will go to the right place, please <a href=\"%s\">send it to us</a>." +#: app/views/general/exception_caught.rhtml:3 +msgid "Sorry, we couldn't find that page" msgstr "" -#: app/views/request/followup_bad.rhtml:24 -msgid "We do not have a working {{law_used_full}} address for {{public_body_name}}." +#: app/views/request/new.rhtml:52 +msgid "Special note for this authority!" msgstr "" -#: app/views/request/followup_bad.rhtml:24 -msgid "You may be able to find\n one on their website, or by phoning them up and asking. If you manage\n to find one, then please <a href=\"%s\">send it to us</a>." +#: app/views/public_body/show.rhtml:56 +msgid "Start" msgstr "" -#: app/views/request/followup_bad.rhtml:29 -msgid "unknown reason " +#: app/views/general/frontpage.rhtml:10 +msgid "Start now »" msgstr "" -#: app/views/request/followup_preview.rhtml:1 -msgid "Preview follow up to '" +#: app/views/request/_sidebar.rhtml:17 +msgid "Start your own blog" msgstr "" -#: app/views/request/followup_preview.rhtml:8 -msgid "Now preview your message asking for an internal review" +#: app/views/general/blog.rhtml:6 +msgid "Stay up to date" msgstr "" -#: app/views/request/followup_preview.rhtml:10 -msgid "Now preview your follow up" +#: app/views/request/_other_describe_state.rhtml:21 +msgid "Still awaiting an <strong>internal review</strong>" msgstr "" -#: app/views/request/followup_preview.rhtml:14 app/views/request/preview.rhtml:7 -msgid "Check you haven't included any <strong>personal information</strong>." +#: app/views/request/followup_preview.rhtml:23 +#: app/views/request/preview.rhtml:18 +msgid "Subject:" msgstr "" -#: app/views/request/followup_preview.rhtml:15 -msgid "Your message will appear in <strong>search engines</strong>" +#: app/views/user/signchangepassword_send_confirm.rhtml:26 +msgid "Submit" msgstr "" -#: app/views/request/followup_preview.rhtml:22 app/views/request/new.rhtml:40 app/views/request/preview.rhtml:17 -#: app/views/request/simple_correspondence.rhtml:16 app/views/request/simple_correspondence.rhtml:28 -msgid "To:" +#: app/views/request/_describe_state.rhtml:101 +msgid "Submit status" msgstr "" -#: app/views/request/followup_preview.rhtml:23 app/views/request/preview.rhtml:18 -msgid "Subject:" +#: app/views/general/blog.rhtml:8 +msgid "Subscribe to blog" msgstr "" -#: app/views/request/followup_preview.rhtml:37 -msgid "<strong>Privacy warning:</strong> Your message, and any response\n to it, will be displayed publicly on this website." +#: app/models/track_thing.rb:230 app/models/track_thing.rb:231 +msgid "Successful Freedom of Information requests" msgstr "" -#: app/views/request/followup_preview.rhtml:49 -msgid "Re-edit this message" +#: app/models/info_request.rb:793 +msgid "Successful." msgstr "" -#: app/views/request/followup_preview.rhtml:50 -msgid "Send message" +#: app/views/comment/new.rhtml:39 +msgid "" +"Suggest how the requester can find the <strong>rest of the information</" +"strong>." msgstr "" -#: app/views/request/hidden.rhtml:1 -msgid "Request has been removed" +#: app/views/request/new.rhtml:84 +msgid "Summary:" msgstr "" -#: app/views/request/hidden.rhtml:9 -msgid "The request you have tried to view has been removed. There are\nvarious reasons why we might have done this, sorry we can't be more specific here. Please <a\n href=\"%s\">contact us</a> if you have any questions." +#: app/views/general/_advanced_search_tips.rhtml:22 +msgid "Table of statuses" msgstr "" -#: app/views/request/hidden.rhtml:15 -msgid "If you are the requester, then you may <a href=\"%s\">sign in</a> to view the request." +#: app/views/general/_advanced_search_tips.rhtml:39 +msgid "Table of varieties" msgstr "" -#: app/views/request/list.rhtml:8 -msgid "Follow these requests" +#: app/views/general/search.rhtml:71 +msgid "Tags (separated by a space):" msgstr "" -#: app/views/request/list.rhtml:19 -msgid "No requests of this sort yet." +#: app/views/request/preview.rhtml:45 +msgid "Tags:" msgstr "" -#: app/views/request/list.rhtml:21 -msgid "{{count}} FOI requests found" +#: app/views/general/exception_caught.rhtml:21 +msgid "Technical details" msgstr "" -#: app/views/request/list.rhtml:27 -msgid "Unexpected search result type" +#: app/controllers/request_game_controller.rb:52 +msgid "Thank you for helping us keep the site tidy!" msgstr "" -#: app/views/request/new.rhtml:20 -msgid "Make an {{law_used_short}} request to '{{public_body_name}}'" +#: app/controllers/comment_controller.rb:62 +msgid "Thank you for making an annotation!" msgstr "" -#: app/views/request/new.rhtml:22 -msgid "2. Ask for Information" +#: app/controllers/request_controller.rb:789 +msgid "" +"Thank you for responding to this FOI request! Your response has been " +"published below, and a link to your response has been emailed to " msgstr "" -#: app/views/request/new.rhtml:27 -msgid "{{existing_request_user}} already\n created the same request on {{date}}. You can either view the <a href=\"{{existing_request}}\">existing request</a>,\n or edit the details below to make a new but similar request." +#: app/controllers/request_controller.rb:418 +msgid "" +"Thank you for updating the status of the request '<a href=\"{{url}}\">" +"{{info_request_title}}</a>'. There are some more requests below for you to " +"classify." msgstr "" -#: app/views/request/new.rhtml:44 -msgid "Browse <a href='{{url}}'>other requests</a> to '{{public_body_name}}' for examples of how to word your request." +#: app/controllers/request_controller.rb:421 +msgid "Thank you for updating this request!" msgstr "" -#: app/views/request/new.rhtml:46 -msgid "Browse <a href='{{url}}'>other requests</a> for examples of how to word your request." +#: app/controllers/user_controller.rb:430 +#: app/controllers/user_controller.rb:446 +msgid "Thank you for updating your profile photo" msgstr "" -#: app/views/request/new.rhtml:52 -msgid "Special note for this authority!" +#: app/views/request_game/play.rhtml:42 +msgid "" +"Thanks for helping - your work will make it easier for everyone to find " +"successful\n" +"responses, and maybe even let us make league tables..." msgstr "" -#: app/views/request/new.rhtml:58 -msgid "Please ask for environmental information only" +#: app/views/user/show.rhtml:24 +msgid "" +"Thanks very much - this will help others find useful stuff. We'll\n" +" also, if you need it, give advice on what to do next about your\n" +" requests." msgstr "" -#: app/views/request/new.rhtml:60 -msgid "The Freedom of Information Act <strong>does not apply</strong> to" +#: app/views/request/new_please_describe.rhtml:20 +msgid "" +"Thanks very much for helping keep everything <strong>neat and organised</" +"strong>.\n" +" We'll also, if you need it, give you advice on what to do next about " +"each of your\n" +" requests." msgstr "" -#: app/views/request/new.rhtml:61 -msgid "However, you have the right to request environmental\n information under a different law" +#: app/controllers/user_controller.rb:221 +msgid "" +"That doesn't look like a valid email address. Please check you have typed it " +"correctly." msgstr "" -#: app/views/request/new.rhtml:63 -msgid "This covers a very wide spectrum of information about the state of\n the <strong>natural and built environment</strong>, such as:" +#: app/views/request/_describe_state.rhtml:47 +#: app/views/request/_other_describe_state.rhtml:43 +msgid "The <strong>review has finished</strong> and overall:" msgstr "" -#: app/views/request/new.rhtml:67 -msgid "Air, water, soil, land, flora and fauna (including how these effect\n human beings)" +#: app/views/request/new.rhtml:60 +msgid "The Freedom of Information Act <strong>does not apply</strong> to" msgstr "" -#: app/views/request/new.rhtml:69 -msgid "Information on emissions and discharges (e.g. noise, energy,\n radiation, waste materials)" +#: app/views/user_mailer/changeemail_already_used.rhtml:8 +msgid "The accounts have been left as they previously were." msgstr "" -#: app/views/request/new.rhtml:71 -msgid "Human health and safety" +#: app/views/request/_other_describe_state.rhtml:48 +msgid "" +"The authority do <strong>not have</strong> the information <small>(maybe " +"they say who does)" msgstr "" -#: app/views/request/new.rhtml:72 -msgid "Cultural sites and built structures (as they may be affected by the\n environmental factors listed above)" +#: app/views/request/show_response.rhtml:26 +msgid "" +"The authority only has a <strong>paper copy</strong> of the information." msgstr "" -#: app/views/request/new.rhtml:74 -msgid "Plans and administrative measures that affect these matters" +#: app/views/request/show_response.rhtml:18 +msgid "" +"The authority say that they <strong>need a postal\n" +" address</strong>, not just an email, for it to be a valid FOI " +"request" msgstr "" -#: app/views/request/new.rhtml:77 -msgid "Please only request information that comes under those categories, <strong>do not waste your\n time</strong> or the time of the public authority by requesting unrelated information." +#: app/views/request/show.rhtml:109 +msgid "" +"The authority would like to / has <strong>responded by post</strong> to this " +"request." msgstr "" -#: app/views/request/new.rhtml:84 -msgid "Summary:" +#: app/views/request_mailer/stopped_responses.rhtml:1 +msgid "" +"The email that you, on behalf of {{public_body}}, sent to\n" +"{{user}} to reply to an {{law_used_short}}\n" +"request has not been delivered." msgstr "" -#: app/views/request/new.rhtml:88 -msgid "a one line summary of the information you are requesting, \n e.g." +#: app/views/general/exception_caught.rhtml:5 +msgid "The page doesn't exist. Things you can try now:" msgstr "" -#: app/views/request/new.rhtml:90 -msgid "'Pollution levels over time for the River Tyne'" +#: app/views/general/_advanced_search_tips.rhtml:27 +msgid "The public authority does not have the information requested" msgstr "" -#: app/views/request/new.rhtml:92 -msgid "'Crime statistics by ward level for Wales'" +#: app/views/general/_advanced_search_tips.rhtml:31 +msgid "The public authority would like part of the request explained" msgstr "" -#: app/views/request/new.rhtml:104 -msgid "Write your request in <strong>simple, precise language</strong>." +#: app/views/general/_advanced_search_tips.rhtml:32 +msgid "The public authority would like to / has responded by post" msgstr "" -#: app/views/request/new.rhtml:105 -msgid "Ask for <strong>specific</strong> documents or information, this site is not suitable for general enquiries." +#: app/views/request/_other_describe_state.rhtml:60 +msgid "The request has been <strong>refused</strong>" msgstr "" -#: app/views/request/new.rhtml:106 -msgid "Keep it <strong>focused</strong>, you'll be more likely to get what you want (<a href=\"%s\">why?</a>)." +#: app/controllers/request_controller.rb:392 +msgid "" +"The request has been updated since you originally loaded this page. Please " +"check for any new incoming messages below, and try again." msgstr "" -#: app/views/request/new.rhtml:113 -msgid "Your request:" +#: app/views/request/show.rhtml:104 +msgid "The request is <strong>waiting for clarification</strong>." msgstr "" -#: app/views/request/new.rhtml:120 -msgid "Everything that you enter on this page, including <strong>your name</strong>, \n will be <strong>displayed publicly</strong> on\n this website forever (<a href=\"%s\">why?</a>)." +#: app/views/request/show.rhtml:97 +msgid "The request was <strong>partially successful</strong>." msgstr "" -#: app/views/request/new.rhtml:123 -msgid "If you are thinking of using a pseudonym,\n please <a href=\"%s\">read this first</a>." +#: app/views/request/show.rhtml:93 +msgid "The request was <strong>refused</strong> by" msgstr "" -#: app/views/request/new.rhtml:128 -msgid "Everything that you enter on this page \n will be <strong>displayed publicly</strong> on\n this website forever (<a href=\"%s\">why?</a>)." +#: app/views/request/show.rhtml:95 +msgid "The request was <strong>successful</strong>." msgstr "" -#: app/views/request/new.rhtml:135 -msgid "<strong> Can I request information about myself?</strong>\n <a href=\"%s\">No! (Click here for details)</a>" +#: app/views/general/_advanced_search_tips.rhtml:28 +msgid "The request was refused by the public authority" msgstr "" -#: app/views/request/new.rhtml:143 -msgid "Preview your public request" +#: app/views/request/hidden.rhtml:9 +msgid "" +"The request you have tried to view has been removed. There are\n" +"various reasons why we might have done this, sorry we can't be more specific " +"here. Please <a\n" +" href=\"%s\">contact us</a> if you have any questions." msgstr "" -#: app/views/request/new_bad_contact.rhtml:1 -msgid "Missing contact details for '" +#: app/views/general/_advanced_search_tips.rhtml:36 +msgid "The requester has abandoned this request for some reason" msgstr "" -#: app/views/request/new_bad_contact.rhtml:5 -msgid "Unfortunately, we do not have a working {{info_request_law_used_full}}\naddress for" +#: app/views/request/_followup.rhtml:59 +msgid "" +"The response to your request has been <strong>delayed</strong>. You can say " +"that, \n" +" by law, the authority should normally have responded\n" +" <strong>promptly</strong> and" msgstr "" -#: app/views/request/new_bad_contact.rhtml:6 -msgid "You may be able to find\none on their website, or by phoning them up and asking. If you manage\nto find one, then please <a href=\"{{help_url}}\">send it to us</a>." +#: app/views/request/_followup.rhtml:71 +msgid "" +"The response to your request is <strong>long overdue</strong>. You can say " +"that, by \n" +" law, under all circumstances, the authority should have " +"responded\n" +" by now" msgstr "" -#: app/views/request/new_please_describe.rhtml:5 -msgid "Please select each of these requests in turn, and <strong>let everyone know</strong>\nif they are successful yet or not." +#: app/views/public_body/show.rhtml:120 +msgid "" +"The search index is currently offline, so we can't show the Freedom of " +"Information requests that have been made to this authority." msgstr "" -#: app/views/request/new_please_describe.rhtml:16 -msgid "When you're done, <strong>come back here</strong>, <a href=\"%s\">reload this page</a> and file your new request." +#: app/views/user/show.rhtml:165 +msgid "" +"The search index is currently offline, so we can't show the Freedom of " +"Information requests this person has made." msgstr "" -#: app/views/request/new_please_describe.rhtml:20 -msgid "Thanks very much for helping keep everything <strong>neat and organised</strong>.\n We'll also, if you need it, give you advice on what to do next about each of your\n requests." +#: app/controllers/track_controller.rb:151 +msgid "Then you can cancel the alert." msgstr "" -#: app/views/request/preview.rhtml:5 -msgid "3. Now check your request" +#: app/controllers/track_controller.rb:181 +msgid "Then you can cancel the alerts." msgstr "" -#: app/views/request/preview.rhtml:8 -msgid "Your name, request and any responses will appear in <strong>search engines</strong>\n (<a href=\"%s\">details</a>)." +#: app/controllers/user_controller.rb:281 +msgid "Then you can change your email address used on {{site_name}}" msgstr "" -#: app/views/request/preview.rhtml:31 -msgid "<strong>Privacy note:</strong> If you want to request private information about\n yourself then <a href=\"%s\">click here</a>." +#: app/controllers/user_controller.rb:235 +msgid "Then you can change your password on {{site_name}}" msgstr "" -#: app/views/request/preview.rhtml:40 -msgid "Edit this request" +#: app/controllers/request_controller.rb:378 +msgid "Then you can classify the FOI response you have got from " msgstr "" -#: app/views/request/preview.rhtml:41 -msgid "Send request" +#: app/controllers/request_controller.rb:813 +msgid "Then you can download a zip file of {{info_request_title}}." msgstr "" -#: app/views/request/preview.rhtml:45 -msgid "Tags:" +#: app/controllers/request_game_controller.rb:41 +msgid "Then you can play the request categorisation game." msgstr "" -#: app/views/request/select_authority.rhtml:27 -msgid "Select the authority to write to" +#: app/controllers/user_controller.rb:362 +msgid "Then you can send a message to " msgstr "" -#: app/views/request/select_authority.rhtml:29 -msgid "1. Select an authority" +#: app/controllers/user_controller.rb:556 +msgid "Then you can sign in to {{site_name}}" msgstr "" -#: app/views/request/select_authority.rhtml:35 -msgid "First, type in the <strong>name of the UK public authority</strong> you'd \n <br>like information from. <strong>By law, they have to respond</strong>\n (<a href=\"%s\">why?</a>)." +#: app/controllers/request_controller.rb:84 +msgid "Then you can update the status of your request to " msgstr "" -#: app/views/request/show.rhtml:5 -msgid "This request has prominence 'hidden'. You can only see it because you are logged\n in as a super user." +#: app/controllers/request_controller.rb:754 +msgid "Then you can upload an FOI response. " msgstr "" -#: app/views/request/show.rhtml:11 -msgid "This request is hidden, so that only you the requester can see it. Please\n <a href=\"%s\">contact us</a> if you are not sure why." +#: app/controllers/request_controller.rb:585 +msgid "Then you can write follow up message to " msgstr "" -#: app/views/request/show.rhtml:36 -msgid "{{user}} (<a href=\"{{user_admin_url}}\">admin</a>) made this {{law_used_full}} request (<a href=\"{{request_admin_url}}\">admin</a>) to {{public_body_link}} (<a href=\"{{public_body_admin_url}}\">admin</a>)" +#: app/controllers/request_controller.rb:586 +msgid "Then you can write your reply to " msgstr "" -#: app/views/request/show.rhtml:44 -msgid "{{user}} made this {{law_used_full}} request" +#: app/models/track_thing.rb:269 +msgid "" +"Then you will be emailed whenever '{{user_name}}' requests something or gets " +"a response." msgstr "" -#: app/views/request/show.rhtml:45 -msgid "to {{public_body}}" +#: app/models/track_thing.rb:285 +msgid "" +"Then you will be emailed whenever a new request or response matches your " +"search." msgstr "" -#: app/views/request/show.rhtml:52 -msgid "Please <strong>answer the question above</strong> so we know whether the " +#: app/models/track_thing.rb:234 +msgid "Then you will be emailed whenever an FOI request succeeds." msgstr "" -#: app/views/request/show.rhtml:53 -msgid "useful information." +#: app/models/track_thing.rb:218 +msgid "Then you will be emailed whenever anyone makes a new FOI request." msgstr "" -#: app/views/request/show.rhtml:55 -msgid "This request has an <strong>unknown status</strong>." +#: app/models/track_thing.rb:253 +msgid "" +"Then you will be emailed whenever someone requests something or gets a " +"response from '{{public_body_name}}'." msgstr "" -#: app/views/request/show.rhtml:57 -msgid "We're waiting for someone to read" +#: app/models/track_thing.rb:202 +msgid "" +"Then you will be emailed whenever the request '{{request_title}}' is updated." msgstr "" -#: app/views/request/show.rhtml:59 -msgid "and update the status accordingly. Perhaps <strong>you</strong> might like to help out by doing that?" +#: app/controllers/request_controller.rb:35 +msgid "Then you'll be allowed to send FOI requests." msgstr "" -#: app/views/request/show.rhtml:61 -msgid "We're waiting for" +#: app/controllers/request_controller.rb:338 +msgid "Then your FOI request to {{public_body_name}} will be sent." msgstr "" -#: app/views/request/show.rhtml:62 -msgid "to read" +#: app/controllers/comment_controller.rb:56 +msgid "Then your annotation to {{info_request_title}} will be posted." msgstr "" -#: app/views/request/show.rhtml:64 -msgid "and update the status." +#: app/views/request_mailer/comment_on_alert_plural.rhtml:1 +msgid "" +"There are {{count}} new annotations on your {{info_request}} request. Follow " +"this link to see what they wrote." msgstr "" -#: app/views/request/show.rhtml:68 -msgid "Currently <strong>waiting for a response</strong> from {{public_body_link}}, they must respond promptly and" +#: app/views/public_body/show.rhtml:7 +msgid "There is %d person following this authority" +msgid_plural "There are %d people following this authority" +msgstr[0] "" +msgstr[1] "" + +#: app/views/request/_sidebar.rhtml:5 +msgid "There is %d person following this request" +msgid_plural "There are %d people following this request" +msgstr[0] "" +msgstr[1] "" + +#: app/views/user/show.rhtml:8 +msgid "" +"There is <strong>more than one person</strong> who uses this site and has " +"this name. \n" +" One of them is shown below, you may mean a different one:" msgstr "" -#: app/views/request/show.rhtml:72 -msgid "normally" +#: app/views/user/rate_limited.rhtml:5 +msgid "" +"There is a limit on the number of requests that you can make in any one day. " +"You can make more requests tomorrow." msgstr "" -#: app/views/request/show.rhtml:74 -msgid "no later than" +#: app/views/request/show.rhtml:113 +msgid "" +"There was a <strong>delivery error</strong> or similar, which needs fixing " +"by the {{site_name}} team." msgstr "" -#: app/views/request/show.rhtml:77 -msgid "Response to this request is <strong>delayed</strong>." +#: app/controllers/user_controller.rb:154 +#: app/controllers/public_body_controller.rb:83 +msgid "There was an error with the words you entered, please try again." msgstr "" -#: app/views/request/show.rhtml:78 -msgid "By law, {{public_body_link}} should normally have responded <strong>promptly</strong> and" +#: app/views/public_body/show.rhtml:109 +msgid "There were no requests matching your query." msgstr "" -#: app/views/request/show.rhtml:82 -msgid "by" +#: app/views/general/search.rhtml:10 +msgid "There were no results matching your query." msgstr "" -#: app/views/request/show.rhtml:85 -msgid "Response to this request is <strong>long overdue</strong>." +#: app/views/request/_describe_state.rhtml:38 +msgid "They are going to reply <strong>by post</strong>" msgstr "" -#: app/views/request/show.rhtml:86 -msgid "By law, under all circumstances, {{public_body_link}} should have responded by now" +#: app/views/request/_describe_state.rhtml:52 +msgid "" +"They do <strong>not have</strong> the information <small>(maybe they say who " +"does)</small>" msgstr "" -#: app/views/request/show.rhtml:88 -msgid "You can <strong>complain</strong> by" +#: app/views/user/show.rhtml:88 +msgid "They have been given the following explanation:" msgstr "" -#: app/views/request/show.rhtml:89 -msgid "requesting an internal review" +#: app/views/request_mailer/overdue_alert.rhtml:3 +msgid "" +"They have not replied to your {{law_used_short}} request {{title}} promptly, " +"as normally required by law" msgstr "" -#: app/views/request/show.rhtml:91 -msgid "<strong>did not have</strong> the information requested." +#: app/views/request_mailer/very_overdue_alert.rhtml:3 +msgid "" +"They have not replied to your {{law_used_short}} request {{title}}, \n" +"as required by law" msgstr "" -#: app/views/request/show.rhtml:93 -msgid "The request was <strong>refused</strong> by" +#: app/views/request/_after_actions.rhtml:3 +msgid "Things to do with this request" msgstr "" -#: app/views/request/show.rhtml:95 -msgid "The request was <strong>successful</strong>." +#: app/views/public_body/show.rhtml:63 +msgid "This authority no longer exists, so you cannot make a request to it." msgstr "" -#: app/views/request/show.rhtml:97 -msgid "The request was <strong>partially successful</strong>." +#: app/views/request/_hidden_correspondence.rhtml:23 +msgid "" +"This comment has been hidden. See annotations to\n" +" find out why. If you are the requester, then you may <a href=" +"\"%s\">sign in</a> to view the response." msgstr "" -#: app/views/request/show.rhtml:100 -msgid "is <strong>waiting for your clarification</strong>." +#: app/views/request/new.rhtml:63 +msgid "" +"This covers a very wide spectrum of information about the state of\n" +" the <strong>natural and built environment</strong>, such as:" msgstr "" -#: app/views/request/show.rhtml:101 -msgid "Please" +#: app/views/request/simple_correspondence.rhtml:1 +msgid "" +"This is a plain-text version of the Freedom of Information request " +"\"{{request_title}}\". The latest, full version is available online at " +"{{full_url}}" msgstr "" -#: app/views/request/show.rhtml:102 -msgid "send a follow up message" +#: app/views/request/_view_html_prefix.rhtml:9 +msgid "" +"This is an HTML version of an attachment to the Freedom of Information " +"request" msgstr "" -#: app/views/request/show.rhtml:104 -msgid "The request is <strong>waiting for clarification</strong>." +#: app/views/request_mailer/stopped_responses.rhtml:5 +msgid "" +"This is because {{title}} is an old request that has been\n" +"marked to no longer receive responses." msgstr "" -#: app/views/request/show.rhtml:105 -msgid "If you are {{user_link}}, please" +#: app/views/track/_tracking_links.rhtml:8 +msgid "" +"This is your own request, so you will be automatically emailed when new " +"responses arrive." msgstr "" -#: app/views/request/show.rhtml:106 -msgid "sign in" +#: app/views/request/_hidden_correspondence.rhtml:17 +msgid "" +"This outgoing message has been hidden. See annotations to\n" +"\t\t\t\t\t\tfind out why. If you are the requester, then you may <a href=" +"\"%s\">sign in</a> to view the response." msgstr "" -#: app/views/request/show.rhtml:106 -msgid "to send a follow up message." +#: app/views/request/_describe_state.rhtml:44 +#: app/views/request/_other_describe_state.rhtml:40 +msgid "This particular request is finished:" msgstr "" -#: app/views/request/show.rhtml:109 -msgid "The authority would like to / has <strong>responded by post</strong> to this request." +#: app/views/user/show.rhtml:144 +msgid "" +"This person has made no Freedom of Information requests using this site." msgstr "" -#: app/views/request/show.rhtml:111 -msgid "Waiting for an <strong>internal review</strong> by {{public_body_link}} of their handling of this request." +#: app/views/user/show.rhtml:149 +msgid "This person's %d Freedom of Information request" +msgid_plural "This person's %d Freedom of Information requests" +msgstr[0] "" +msgstr[1] "" + +#: app/views/user/show.rhtml:179 +msgid "This person's %d annotation" +msgid_plural "This person's %d annotations" +msgstr[0] "" +msgstr[1] "" + +#: app/views/user/show.rhtml:172 +msgid "This person's annotations" msgstr "" -#: app/views/request/show.rhtml:113 -msgid "There was a <strong>delivery error</strong> or similar, which needs fixing by the {{site_name}} team." +#: app/views/request/_describe_state.rhtml:84 +msgid "This request <strong>requires administrator attention</strong>" msgstr "" -#: app/views/request/show.rhtml:115 -msgid "This request has had an unusual response, and <strong>requires attention</strong> from the {{site_name}} team." +#: app/views/request/show.rhtml:55 +msgid "This request has an <strong>unknown status</strong>." msgstr "" #: app/views/request/show.rhtml:117 -msgid "This request has been <strong>withdrawn</strong> by the person who made it. \n There may be an explanation in the correspondence below." +msgid "" +"This request has been <strong>withdrawn</strong> by the person who made " +"it. \n" +" \t There may be an explanation in the correspondence below." msgstr "" -#: app/views/request/show_response.rhtml:13 -msgid "Which of these is happening?" +#: app/models/info_request.rb:389 +msgid "" +"This request has been set by an administrator to \"allow new responses from " +"nobody\"" msgstr "" -#: app/views/request/show_response.rhtml:18 -msgid "The authority say that they <strong>need a postal\n address</strong>, not just an email, for it to be a valid FOI request" +#: app/views/request/show.rhtml:115 +msgid "" +"This request has had an unusual response, and <strong>requires attention</" +"strong> from the {{site_name}} team." msgstr "" -#: app/views/request/show_response.rhtml:26 -msgid "The authority only has a <strong>paper copy</strong> of the information." +#: app/views/request/show.rhtml:5 +msgid "" +"This request has prominence 'hidden'. You can only see it because you are " +"logged\n" +" in as a super user." msgstr "" -#: app/views/request/show_response.rhtml:29 -msgid "At the bottom of this page, write a reply to them trying to persuade them to scan it in\n (<a href=\"%s\">more details</a>)." +#: app/views/request/show.rhtml:11 +msgid "" +"This request is hidden, so that only you the requester can see it. Please\n" +" <a href=\"%s\">contact us</a> if you are not sure why." msgstr "" -#: app/views/request/show_response.rhtml:34 -msgid "You want to <strong>give your postal address</strong> to the authority in private." +#: app/views/request/_describe_state.rhtml:7 +#: app/views/request/_other_describe_state.rhtml:10 +msgid "This request is still in progress:" msgstr "" -#: app/views/request/show_response.rhtml:37 -msgid "To do that please send a private email to " +#: app/views/request/_hidden_correspondence.rhtml:10 +msgid "" +"This response has been hidden. See annotations to find out why.\n" +" If you are the requester, then you may <a href=\"%s\">sign in</" +"a> to view the response." msgstr "" -#: app/views/request/show_response.rhtml:39 -msgid "containing your postal address, and asking them to reply to this request.\n Or you could phone them." +#: app/views/request/details.rhtml:6 +msgid "" +"This table shows the technical details of the internal events that happened\n" +"to this request on {{site_name}}. This could be used to generate information " +"about\n" +"the speed with which authorities respond to requests, the number of " +"requests\n" +"which require a postal response and much more." msgstr "" -#: app/views/request/show_response.rhtml:42 -msgid "When you receive the paper response, please help\n others find out what it says:" +#: app/views/user/show.rhtml:84 +msgid "This user has been banned from {{site_name}} " msgstr "" -#: app/views/request/show_response.rhtml:45 -msgid "Add an annotation to your request with choice quotes, or\n a <strong>summary of the response</strong>." +#: app/views/user_mailer/changeemail_already_used.rhtml:5 +msgid "" +"This was not possible because there is already an account using \n" +"the email address {{email}}." msgstr "" -#: app/views/request/show_response.rhtml:47 -msgid "If you can, scan in or photograph the response, and <strong>send us\n a copy to upload</strong>." +#: app/models/track_thing.rb:217 +msgid "To be emailed about any new requests" msgstr "" -#: app/views/request/show_response.rhtml:60 -msgid "New response to your request" +#: app/models/track_thing.rb:233 +msgid "To be emailed about any successful requests" msgstr "" -#: app/views/request/show_response.rhtml:62 -msgid "Response to your request" +#: app/models/track_thing.rb:268 +msgid "To be emailed about requests by '{{user_name}}'" msgstr "" -#: app/views/request/show_response.rhtml:66 -msgid "New response to {{law_used_short}} request" +#: app/models/track_thing.rb:252 +msgid "" +"To be emailed about requests made using {{site_name}} to the public " +"authority '{{public_body_name}}'" msgstr "" -#: app/views/request/similar.rhtml:7 -msgid "No similar requests found." +#: app/controllers/track_controller.rb:180 +msgid "To cancel these alerts" msgstr "" -#: app/views/request/similar.rhtml:18 -msgid "Unexpected search result type " +#: app/controllers/track_controller.rb:150 +msgid "To cancel this alert" msgstr "" -#: app/views/request/simple_correspondence.rhtml:1 -msgid "This is a plain-text version of the Freedom of Information request \"{{request_title}}\". The latest, full version is available online at {{full_url}}" +#: app/views/user/no_cookies.rhtml:5 +msgid "" +"To carry on, you need to sign in or make an account. Unfortunately, there\n" +"was a technical problem trying to do this." msgstr "" -#: app/views/request/simple_correspondence.rhtml:17 app/views/request/simple_correspondence.rhtml:29 -#: app/views/request/simple_correspondence.rhtml:36 -msgid "Date:" +#: app/controllers/user_controller.rb:280 +msgid "To change your email address used on {{site_name}}" msgstr "" -#: app/views/request/simple_correspondence.rhtml:21 -msgid "Attachment:" +#: app/controllers/request_controller.rb:377 +msgid "To classify the response to this FOI request" msgstr "" -#: app/views/request/simple_correspondence.rhtml:42 -msgid "{{username}} left an annotation:" +#: app/views/request/show_response.rhtml:37 +msgid "To do that please send a private email to " msgstr "" -#: app/views/request/upload_response.rhtml:5 -msgid "Respond to the FOI request" +#: app/views/request_mailer/not_clarified_alert.rhtml:2 +msgid "To do this, first click on the link below." msgstr "" -#: app/views/request/upload_response.rhtml:5 -msgid " made by " +#: app/controllers/request_controller.rb:812 +msgid "To download the zip file" msgstr "" -#: app/views/request/upload_response.rhtml:8 -msgid "Your response will <strong>appear on the Internet</strong>, <a href=\"%s\">read why</a> and answers to other questions." +#: app/models/track_thing.rb:284 +msgid "To follow requests and responses matching your search" msgstr "" -#: app/views/request/upload_response.rhtml:11 -msgid "Respond by email" +#: app/models/track_thing.rb:201 +msgid "To follow updates to the request '{{request_title}}'" msgstr "" -#: app/views/request/upload_response.rhtml:13 -msgid "You should have received a copy of the request by email, and you can respond\nby <strong>simply replying</strong> to that email. For your convenience, here is the address:" +#: app/views/request_mailer/old_unclassified_updated.rhtml:1 +msgid "" +"To help us keep the site tidy, someone else has updated the status of the \n" +"{{law_used_full}} request {{title}} that you made to {{public_body}}, to " +"\"{{display_status}}\" If you disagree with their categorisation, please " +"update the status again yourself to what you believe to be more accurate." msgstr "" -#: app/views/request/upload_response.rhtml:16 -msgid "You may <strong>include attachments</strong>. If you would like to attach a\nfile too large for email, use the form below." +#: app/views/request_mailer/new_response_reminder_alert.rhtml:1 +msgid "To let us know, follow this link and then select the appropriate box." msgstr "" -#: app/views/request/upload_response.rhtml:21 -msgid "Respond using the web" +#: app/controllers/request_game_controller.rb:40 +msgid "To play the request categorisation game" msgstr "" -#: app/views/request/upload_response.rhtml:23 -msgid "Enter your response below. You may attach one file (use email, or \n<a href=\"%s\">contact us</a> if you need more)." +#: app/controllers/comment_controller.rb:55 +msgid "To post your annotation" msgstr "" -#: app/views/request/upload_response.rhtml:28 -msgid "Response:" +#: app/controllers/request_controller.rb:583 +msgid "To reply to " msgstr "" -#: app/views/request/upload_response.rhtml:33 -msgid "Attachment (optional):" +#: app/controllers/request_controller.rb:582 +msgid "To send a follow up message to " msgstr "" -#: app/views/request/upload_response.rhtml:40 -msgid " (<strong>patience</strong>, especially for large files, it may take a while!)" +#: app/controllers/user_controller.rb:361 +msgid "To send a message to " msgstr "" -#: app/views/request_game/play.rhtml:1 app/views/request_game/play.rhtml:30 -msgid "Play the request categorisation game!" +#: app/controllers/request_controller.rb:34 +#: app/controllers/request_controller.rb:337 +msgid "To send your FOI request" msgstr "" -#: app/views/request_game/play.rhtml:31 -msgid "Some people who've made requests haven't let us know whether they were\nsuccessful or not. We need <strong>your</strong> help –\nchoose one of these requests, read it, and let everyone know whether or not the\ninformation has been provided. Everyone'll be exceedingly grateful." +#: app/controllers/request_controller.rb:83 +msgid "To update the status of this FOI request" msgstr "" -#: app/views/request_game/play.rhtml:39 -msgid "I don't like these ones — give me some more!" +#: app/controllers/request_controller.rb:753 +msgid "" +"To upload a response, you must be logged in using an email address from " msgstr "" -#: app/views/request_game/play.rhtml:40 -msgid "I don't want to do any more tidying now!" +#: app/views/general/search.rhtml:24 +msgid "" +"To use the advanced search, combine phrases and labels as described in the " +"search tips below." msgstr "" -#: app/views/request_game/play.rhtml:42 -msgid "Thanks for helping - your work will make it easier for everyone to find successful\nresponses, and maybe even let us make league tables..." +#: app/views/public_body/view_email_captcha.rhtml:5 +msgid "" +"To view the email address that we use to send FOI requests to " +"{{public_body_name}}, please enter these words." msgstr "" -#: app/views/request_mailer/comment_on_alert.rhtml:1 -msgid "{{user_name}} has annotated your {{law_used_short}} \nrequest. Follow this link to see what they wrote." +#: app/views/request_mailer/new_response.rhtml:5 +msgid "To view the response, click on the link below." msgstr "" -#: app/views/request_mailer/comment_on_alert.rhtml:6 app/views/request_mailer/comment_on_alert_plural.rhtml:5 -#: app/views/request_mailer/new_response.rhtml:15 app/views/request_mailer/new_response_reminder_alert.rhtml:8 -#: app/views/request_mailer/not_clarified_alert.rhtml:9 app/views/request_mailer/old_unclassified_updated.rhtml:8 -#: app/views/request_mailer/overdue_alert.rhtml:9 app/views/request_mailer/stopped_responses.rhtml:16 -#: app/views/request_mailer/very_overdue_alert.rhtml:11 app/views/track_mailer/event_digest.rhtml:66 -#: app/views/user_mailer/already_registered.rhtml:11 app/views/user_mailer/changeemail_already_used.rhtml:10 -#: app/views/user_mailer/changeemail_confirm.rhtml:13 app/views/user_mailer/confirm_login.rhtml:11 -msgid "the {{site_name}} team" +#: app/views/request/_request_listing_short_via_event.rhtml:9 +msgid "To {{public_body_link_absolute}}" msgstr "" -#: app/views/request_mailer/comment_on_alert_plural.rhtml:1 -msgid "There are {{count}} new annotations on your {{info_request}} request. Follow this link to see what they wrote." +#: app/views/request/simple_correspondence.rhtml:16 +#: app/views/request/simple_correspondence.rhtml:28 +#: app/views/request/followup_preview.rhtml:22 app/views/request/new.rhtml:40 +#: app/views/request/preview.rhtml:17 +msgid "To:" msgstr "" -#: app/views/request_mailer/new_response.rhtml:1 -msgid "You have a new response to the {{law_used_full}} request " +#: app/views/general/_localised_datepicker.rhtml:7 +msgid "Today" msgstr "" -#: app/views/request_mailer/new_response.rhtml:2 -msgid "that you made to" +#: app/views/request/select_authority.rhtml:48 +#: app/views/public_body/_search_ahead.rhtml:4 +msgid "Top search results:" msgstr "" -#: app/views/request_mailer/new_response.rhtml:5 -msgid "To view the response, click on the link below." +#: app/models/track_thing.rb:246 +msgid "Track requests to {{public_body_name}} by email" msgstr "" -#: app/views/request_mailer/new_response.rhtml:9 -msgid "When you get there, please update the status to say if the response \ncontains any useful information." +#: app/models/track_thing.rb:278 +msgid "Track things matching this search by email" msgstr "" -#: app/views/request_mailer/new_response.rhtml:12 -msgid "Although all responses are automatically published, we depend on\nyou, the original requester, to evaluate them." +#: app/views/user/show.rhtml:35 +msgid "Track this person" msgstr "" -#: app/views/request_mailer/new_response_reminder_alert.rhtml:1 -msgid "To let us know, follow this link and then select the appropriate box." +#: app/models/track_thing.rb:262 +msgid "Track this person by email" msgstr "" -#: app/views/request_mailer/new_response_reminder_alert.rhtml:5 -msgid "Your request was called {{info_request}}. Letting everyone know whether you got the information will help us keep tabs on" +#: app/models/track_thing.rb:195 +msgid "Track this request by email" msgstr "" -#: app/views/request_mailer/not_clarified_alert.rhtml:1 -msgid "request." +#: app/views/general/search.rhtml:137 +msgid "Track this search" msgstr "" -#: app/views/request_mailer/not_clarified_alert.rhtml:2 -msgid "To do this, first click on the link below." +#: locale/model_attributes.rb:33 +msgid "TrackThing|Track medium" msgstr "" -#: app/views/request_mailer/not_clarified_alert.rhtml:6 -msgid "You will only get an answer to your request if you follow up\nwith the clarification." +#: locale/model_attributes.rb:32 +msgid "TrackThing|Track query" msgstr "" -#: app/views/request_mailer/old_unclassified_updated.rhtml:1 -msgid "To help us keep the site tidy, someone else has updated the status of the \n{{law_used_full}} request {{title}} that you made to {{public_body}}, to \"{{display_status}}\" If you disagree with their categorisation, please update the status again yourself to what you believe to be more accurate." +#: locale/model_attributes.rb:34 +msgid "TrackThing|Track type" msgstr "" -#: app/views/request_mailer/old_unclassified_updated.rhtml:4 -msgid "Follow this link to see the request:" +#: app/views/request/_sidebar.rhtml:13 +msgid "Tweet this request" msgstr "" -#: app/views/request_mailer/overdue_alert.rhtml:1 -msgid "have delayed." +#: app/views/general/_advanced_search_tips.rhtml:15 +msgid "" +"Type <strong><code>01/01/2008..14/01/2008</code></strong> to only show " +"things that happened in the first two weeks of January." msgstr "" -#: app/views/request_mailer/overdue_alert.rhtml:3 -msgid "They have not replied to your {{law_used_short}} request {{title}} promptly, as normally required by law" +#: app/models/public_body.rb:37 +msgid "URL name can't be blank" msgstr "" -#: app/views/request_mailer/overdue_alert.rhtml:3 -msgid "during term time" +#: app/models/user_mailer.rb:45 +msgid "Unable to change email address on {{site_name}}" msgstr "" -#: app/views/request_mailer/overdue_alert.rhtml:5 -msgid "Click on the link below to send a message to {{public_body}} reminding them to reply to your request." +#: app/views/request/followup_bad.rhtml:4 +msgid "Unable to send a reply to {{username}}" msgstr "" -#: app/views/request_mailer/requires_admin.rhtml:2 -msgid "has reported an" +#: app/views/request/followup_bad.rhtml:2 +msgid "Unable to send follow up message to {{username}}" msgstr "" -#: app/views/request_mailer/requires_admin.rhtml:3 -msgid "response as needing administrator attention. Take a look, and reply to this\nemail to let them know what you are going to do about it." +#: app/views/request/list.rhtml:27 +msgid "Unexpected search result type" msgstr "" -#: app/views/request_mailer/requires_admin.rhtml:9 -msgid "Administration URL:" +#: app/views/request/similar.rhtml:18 +msgid "Unexpected search result type " msgstr "" -#: app/views/request_mailer/stopped_responses.rhtml:1 -msgid "The email that you, on behalf of {{public_body}}, sent to\n{{user}} to reply to an {{law_used_short}}\nrequest has not been delivered." +#: app/views/user/wrong_user_unknown_email.rhtml:3 +msgid "" +"Unfortunately we don't know the FOI\n" +"email address for that authority, so we can't validate this.\n" +"Please <a href=\"%s\">contact us</a> to sort it out." msgstr "" -#: app/views/request_mailer/stopped_responses.rhtml:5 -msgid "This is because {{title}} is an old request that has been\nmarked to no longer receive responses." +#: app/views/request/new_bad_contact.rhtml:5 +msgid "" +"Unfortunately, we do not have a working {{info_request_law_used_full}}\n" +"address for" msgstr "" -#: app/views/request_mailer/stopped_responses.rhtml:10 -msgid "If this is incorrect, or you would like to send a late response to the request\nor an email on another subject to {{user}}, then please\nemail {{contact_email}} for help." +#: lib/world_foi_websites.rb:5 +msgid "United Kingdom" msgstr "" -#: app/views/request_mailer/stopped_responses.rhtml:14 -msgid "Your original message is attached." +#: lib/world_foi_websites.rb:17 +msgid "United States of America" msgstr "" -#: app/views/request_mailer/very_overdue_alert.rhtml:1 -msgid "are long overdue." +#: app/views/general/exception_caught.rhtml:22 +msgid "Unknown" msgstr "" -#: app/views/request_mailer/very_overdue_alert.rhtml:3 -msgid "They have not replied to your {{law_used_short}} request {{title}}, \nas required by law" +#: app/models/info_request.rb:803 +msgid "Unusual response." msgstr "" -#: app/views/request_mailer/very_overdue_alert.rhtml:4 -msgid "even during holidays" +#: app/views/request/_after_actions.rhtml:13 +#: app/views/request/_after_actions.rhtml:35 +msgid "Update the status of this request" msgstr "" -#: app/views/request_mailer/very_overdue_alert.rhtml:6 -msgid "Click on the link below to send a message to {{public_body_name}} telling them to reply to your request. You might like to ask for an internal\nreview, asking them to find out why response to the request has been so slow." +#: app/controllers/request_controller.rb:85 +msgid "Update the status of your request to " msgstr "" -#: app/views/track/_tracking_links.rhtml:8 -msgid "This is your own request, so you will be automatically emailed when new responses arrive." +#: app/views/general/_advanced_search_tips.rhtml:6 +msgid "" +"Use OR (in capital letters) where you don't mind which word, e.g. " +"<strong><code>commons OR lords</code></strong>" msgstr "" -#: app/views/track/_tracking_links.rhtml:21 -msgid "Follow by email" +#: app/views/general/_advanced_search_tips.rhtml:7 +msgid "" +"Use quotes when you want to find an exact phrase, e.g. <strong><code>" +"\"Liverpool City Council\"</code></strong>" msgstr "" -#: app/views/track/_tracking_links.rhtml:26 -msgid "RSS feed of updates" +#: locale/model_attributes.rb:94 +msgid "UserInfoRequestSentAlert|Alert type" msgstr "" -#: app/views/track/_tracking_links.rhtml:26 -msgid "RSS feed" +#: locale/model_attributes.rb:80 +msgid "User|About me" msgstr "" -#: app/views/track_mailer/event_digest.rhtml:21 -msgid "{{public_body}} sent a response to {{user_name}}" +#: locale/model_attributes.rb:78 +msgid "User|Admin level" msgstr "" -#: app/views/track_mailer/event_digest.rhtml:24 -msgid "{{user_name}} sent a follow up message to {{public_body}}" +#: locale/model_attributes.rb:79 +msgid "User|Ban text" msgstr "" -#: app/views/track_mailer/event_digest.rhtml:28 -msgid "{{user_name}} sent a request to {{public_body}}" +#: locale/model_attributes.rb:71 +msgid "User|Email" msgstr "" -#: app/views/track_mailer/event_digest.rhtml:31 -msgid "{{user_name}} added an annotation" +#: locale/model_attributes.rb:83 +msgid "User|Email bounce message" msgstr "" -#: app/views/track_mailer/event_digest.rhtml:60 -msgid "Alter your subscription" +#: locale/model_attributes.rb:82 +msgid "User|Email bounced at" msgstr "" -#: app/views/track_mailer/event_digest.rhtml:63 -msgid "Please click on the link below to cancel or alter these emails." +#: locale/model_attributes.rb:75 +msgid "User|Email confirmed" msgstr "" -#: app/views/user/_signin.rhtml:7 -msgid "If you've used {{site_name}} before" +#: locale/model_attributes.rb:73 +msgid "User|Hashed password" msgstr "" -#: app/views/user/_signin.rhtml:11 app/views/user/_signup.rhtml:9 -#: app/views/user/signchangepassword_send_confirm.rhtml:13 -msgid "Your e-mail:" +#: locale/model_attributes.rb:77 +msgid "User|Last daily track email" msgstr "" -#: app/views/user/_signin.rhtml:16 app/views/user/_signup.rhtml:30 -msgid "Password:" +#: locale/model_attributes.rb:81 +msgid "User|Locale" msgstr "" -#: app/views/user/_signin.rhtml:21 -msgid "Forgotten your password?" +#: locale/model_attributes.rb:72 +msgid "User|Name" msgstr "" -#: app/views/user/_signin.rhtml:26 -msgid "Remember me</label> (keeps you signed in longer;\n do not use on a public computer) " +#: locale/model_attributes.rb:84 +msgid "User|No limit" msgstr "" -#: app/views/user/_signin.rhtml:32 app/views/user/sign.rhtml:2 app/views/user/sign.rhtml:33 -msgid "Sign in" +#: locale/model_attributes.rb:74 +msgid "User|Salt" msgstr "" -#: app/views/user/_signup.rhtml:6 -msgid "If you're new to {{site_name}}" +#: locale/model_attributes.rb:76 +msgid "User|Url name" msgstr "" -#: app/views/user/_signup.rhtml:13 -msgid "We will not reveal your email address to anybody unless you or\n the law tell us to (<a href=\"%s\">details</a>). " +#: app/views/public_body/show.rhtml:26 +msgid "View FOI email address" msgstr "" -#: app/views/user/_signup.rhtml:18 -msgid "Your name:" +#: app/views/public_body/view_email_captcha.rhtml:1 +msgid "View FOI email address for '{{public_body_name}}'" msgstr "" -#: app/views/user/_signup.rhtml:22 -msgid "Your <strong>name will appear publicly</strong> \n (<a href=\"%s\">why?</a>)\n on this website and in search engines. If you\n are thinking of using a pseudonym, please \n <a href=\"%s\">read this first</a>." +#: app/views/public_body/view_email_captcha.rhtml:3 +msgid "View FOI email address for {{public_body_name}}" msgstr "" -#: app/views/user/_signup.rhtml:35 -msgid "Password: (again)" +#: app/views/contact_mailer/user_message.rhtml:10 +msgid "View Freedom of Information requests made by {{user_name}}:" msgstr "" -#: app/views/user/_signup.rhtml:46 app/views/user/sign.rhtml:40 -msgid "Sign up" +#: app/controllers/request_controller.rb:169 +msgid "View and search requests" msgstr "" -#: app/views/user/_user_listing_single.rhtml:19 app/views/user/_user_listing_single.rhtml:20 -msgid "made." +#: app/views/general/_topnav.rhtml:6 +msgid "View authorities" msgstr "" -#: app/views/user/_user_listing_single.rhtml:21 -msgid "Joined in" +#: app/views/public_body/view_email_captcha.rhtml:12 +msgid "View email" msgstr "" -#: app/views/user/bad_token.rhtml:2 -msgid "Please check the URL (i.e. the long code of letters and numbers) is copied\ncorrectly from your email." +#: app/views/general/_topnav.rhtml:5 +msgid "View requests" msgstr "" -#: app/views/user/bad_token.rhtml:7 -msgid "If you can't click on it in the email, you'll have to <strong>select and copy\nit</strong> from the email. Then <strong>paste it into your browser</strong>, into the place\nyou would type the address of any other webpage." +#: app/models/info_request.rb:795 +msgid "Waiting clarification." msgstr "" -#: app/views/user/bad_token.rhtml:13 -msgid "If you got the email <strong>more than six months ago</strong>, then this login link won't work any\nmore. Please try doing what you were doing from the beginning." +#: app/views/request/show.rhtml:111 +msgid "" +"Waiting for an <strong>internal review</strong> by {{public_body_link}} of " +"their handling of this request." msgstr "" -#: app/views/user/banned.rhtml:9 -msgid "You will be unable to make new requests, send follow ups, add annotations or\nsend messages to other users. You may continue to view other requests, and set\nup\nemail alerts." +#: app/views/general/_advanced_search_tips.rhtml:33 +msgid "" +"Waiting for the public authority to complete an internal review of their " +"handling of the request" msgstr "" -#: app/views/user/banned.rhtml:15 -msgid "If you would like us to lift this ban, then you may politely\n<a href=\"/help/contact\">contact us</a> giving reasons.\n" +#: app/views/general/_advanced_search_tips.rhtml:26 +msgid "Waiting for the public authority to reply" msgstr "" -#: app/views/user/confirm.rhtml:6 -msgid "We've sent you an email, and you'll need to click the link in it before you can\ncontinue." +#: app/models/request_mailer.rb:126 +msgid "Was the response you got to your FOI request any good?" msgstr "" -#: app/views/user/confirm.rhtml:11 -msgid "<small>If you use web-based email or have \"junk mail\" filters, also check your\nbulk/spam mail folders. Sometimes, our messages are marked that way.</small>\n</p>" +#: app/views/public_body/view_email.rhtml:17 +msgid "We do not have a working request email address for this authority." msgstr "" -#: app/views/user/contact.rhtml:32 -msgid "<strong>Note:</strong> You're sending a message to yourself, presumably\n to try out how it works." +#: app/views/request/followup_bad.rhtml:24 +msgid "" +"We do not have a working {{law_used_full}} address for {{public_body_name}}." msgstr "" -#: app/views/user/contact.rhtml:35 -msgid " <strong>Privacy note:</strong> Your email address will be given to" +#: app/views/request/_describe_state.rhtml:107 +msgid "" +"We don't know whether the most recent response to this request contains\n" +" information or not\n" +" –\n" +"\tif you are {{user_link}} please <a href=\"{{url}}\">sign in</a> and let " +"everyone know." msgstr "" -#: app/views/user/contact.rhtml:36 -msgid " when you send this message." +#: app/views/user_mailer/confirm_login.rhtml:8 +msgid "" +"We will not reveal your email address to anybody unless you\n" +"or the law tell us to." msgstr "" -#: app/views/user/no_cookies.rhtml:3 -msgid "Please enable \"cookies\" to carry on" +#: app/views/user/_signup.rhtml:13 +msgid "" +"We will not reveal your email address to anybody unless you or\n" +" the law tell us to (<a href=\"%s\">details</a>). " msgstr "" -#: app/views/user/no_cookies.rhtml:5 -msgid "To carry on, you need to sign in or make an account. Unfortunately, there\nwas a technical problem trying to do this." +#: app/views/user_mailer/changeemail_confirm.rhtml:10 +msgid "" +"We will not reveal your email addresses to anybody unless you\n" +"or the law tell us to." msgstr "" -#: app/views/user/no_cookies.rhtml:8 -msgid "It may be that your browser is not set to accept a thing called \"cookies\",\nor cannot do so. If you can, please enable cookies, or try using a different\nbrowser. Then press refresh to have another go." +#: app/views/request/show.rhtml:61 +msgid "We're waiting for" msgstr "" -#: app/views/user/no_cookies.rhtml:12 -msgid "If your browser is set to accept cookies and you are seeing this message,\nthen there is probably a fault with our server." +#: app/views/request/show.rhtml:57 +msgid "We're waiting for someone to read" msgstr "" -#: app/views/user/no_cookies.rhtml:15 -msgid "Please <a href=\"%s\">get in touch</a> with us so we can fix it." +#: app/views/user/signchangeemail_confirm.rhtml:6 +msgid "" +"We've sent an email to your new email address. You'll need to click the link " +"in\n" +"it before your email address will be changed." msgstr "" -#: app/views/user/no_cookies.rhtml:17 -msgid "Let us know what you were doing when this message\nappeared and your browser and operating system type and version." +#: app/views/user/confirm.rhtml:6 +msgid "" +"We've sent you an email, and you'll need to click the link in it before you " +"can\n" +"continue." msgstr "" -#: app/views/user/no_cookies.rhtml:20 -msgid "If you are still having trouble, please <a href=\"%s\">contact us</a>." +#: app/views/user/signchangepassword_confirm.rhtml:6 +msgid "" +"We've sent you an email, click the link in it, then you can change your " +"password." msgstr "" -#: app/views/user/set_crop_profile_photo.rhtml:1 app/views/user/show.rhtml:104 -msgid "Change profile photo" +#: app/views/request/_followup.rhtml:85 +msgid "What are you doing?" msgstr "" -#: app/views/user/set_crop_profile_photo.rhtml:6 -msgid "Crop your profile photo" +#: app/views/request/_describe_state.rhtml:4 +msgid "What best describes the status of this request now?" msgstr "" -#: app/views/user/set_crop_profile_photo.rhtml:35 -msgid "<strong>Privacy note:</strong> Your photo will be shown in public on the Internet, \n wherever you do something on {{site_name}}." +#: app/views/general/frontpage.rhtml:54 +msgid "What information has been released?" msgstr "" -#: app/views/user/set_draft_profile_photo.rhtml:5 -msgid "Choose your profile photo" +#: app/views/request_mailer/new_response.rhtml:9 +msgid "" +"When you get there, please update the status to say if the response \n" +"contains any useful information." msgstr "" -#: app/views/user/set_draft_profile_photo.rhtml:13 -msgid "Photo of you:" +#: app/views/request/show_response.rhtml:42 +msgid "" +"When you receive the paper response, please help\n" +" others find out what it says:" msgstr "" -#: app/views/user/set_draft_profile_photo.rhtml:18 -msgid "Your photo will be shown in public <strong>on the Internet</strong>, \n wherever you do something on {{site_name}}." +#: app/views/request/new_please_describe.rhtml:16 +msgid "" +"When you're done, <strong>come back here</strong>, <a href=\"%s\">reload " +"this page</a> and file your new request." msgstr "" -#: app/views/user/set_draft_profile_photo.rhtml:22 -msgid "Please don't upload offensive pictures. We will take down images\n that we consider inappropriate." +#: app/views/request/show_response.rhtml:13 +msgid "Which of these is happening?" msgstr "" -#: app/views/user/set_draft_profile_photo.rhtml:32 -msgid "Next, crop your photo >>" +#: app/views/general/frontpage.rhtml:37 +msgid "Who can I request information from?" msgstr "" -#: app/views/user/set_draft_profile_photo.rhtml:46 -msgid "OR remove the existing photo" +#: app/models/info_request.rb:805 +msgid "Withdrawn by the requester." msgstr "" -#: app/views/user/set_draft_profile_photo.rhtml:55 -msgid "Cancel, return to your profile page" +#: app/views/general/_localised_datepicker.rhtml:13 +msgid "Wk" msgstr "" -#: app/views/user/set_profile_about_me.rhtml:1 -msgid "Change the text about you on your profile at {{site_name}}" +#: app/views/help/alaveteli.rhtml:6 +msgid "Would you like to see a website like this in your country?" msgstr "" -#: app/views/user/set_profile_about_me.rhtml:3 app/views/user/signchangeemail.rhtml:3 -msgid "internal error" +#: app/views/request/_after_actions.rhtml:30 +msgid "Write a reply" msgstr "" -#: app/views/user/set_profile_about_me.rhtml:9 -msgid "Edit text about you" +#: app/controllers/request_controller.rb:589 +msgid "Write a reply to " msgstr "" -#: app/views/user/set_profile_about_me.rhtml:11 -msgid " What are you investigating using Freedom of Information? " +#: app/controllers/request_controller.rb:588 +msgid "Write your FOI follow up message to " msgstr "" -#: app/views/user/set_profile_about_me.rhtml:14 -msgid " This will appear on your {{site_name}} profile, to make it\n easier for others to get involved with what you're doing." +#: app/views/request/new.rhtml:104 +msgid "Write your request in <strong>simple, precise language</strong>." msgstr "" -#: app/views/user/set_profile_about_me.rhtml:20 -msgid "About you:" +#: app/views/comment/_single_comment.rhtml:10 +msgid "You" msgstr "" -#: app/views/user/set_profile_about_me.rhtml:26 -msgid " Include relevant links, such as to a campaign page, your blog or a\n twitter account. They will be made clickable. \n e.g." +#: app/controllers/track_controller.rb:105 +msgid "You are already being emailed updates about " msgstr "" -#: app/views/user/set_profile_about_me.rhtml:35 -msgid "Save" +#: app/models/track_thing.rb:247 +msgid "You are already tracking requests to {{public_body_name}} by email" msgstr "" -#: app/views/user/show.rhtml:4 -msgid "There is <strong>more than one person</strong> who uses this site and has this name. \n One of them is shown below, you may mean a different one:" +#: app/models/track_thing.rb:279 +msgid "You are already tracking things matching this search by email" msgstr "" -#: app/views/user/show.rhtml:12 -msgid "Please <strong>go to the following requests</strong>, and let us\n know if there was information in the recent responses to them." +#: app/models/track_thing.rb:263 +msgid "You are already tracking this person by email" msgstr "" -#: app/views/user/show.rhtml:20 -msgid "Thanks very much - this will help others find useful stuff. We'll\n also, if you need it, give advice on what to do next about your\n requests." +#: app/models/track_thing.rb:196 +msgid "You are already tracking this request by email" msgstr "" -#: app/views/user/show.rhtml:29 -msgid "Track this person" +#: app/models/track_thing.rb:228 +msgid "You are being emailed about any new successful responses" msgstr "" -#: app/views/user/show.rhtml:32 -msgid "On this page" +#: app/models/track_thing.rb:212 +msgid "You are being emailed when there are new requests" msgstr "" -#: app/views/user/show.rhtml:33 -msgid "FOI requests" +#: app/views/request/show.rhtml:88 +msgid "You can <strong>complain</strong> by" msgstr "" -#: app/views/user/show.rhtml:34 -msgid "Annotations" +#: app/views/request/details.rhtml:58 +msgid "" +"You can get this page in computer-readable format as part of the main JSON\n" +"page for the request. See the <a href=\"{{api_path}}\">API documentation</" +"a>." msgstr "" -#: app/views/user/show.rhtml:36 -msgid "Email subscriptions" +#: app/views/public_body/show.rhtml:46 +msgid "" +"You can only request information about the environment from this authority." msgstr "" -#: app/views/user/show.rhtml:53 -msgid "Set your profile photo" +#: app/views/request_mailer/new_response.rhtml:1 +msgid "You have a new response to the {{law_used_full}} request " msgstr "" -#: app/views/user/show.rhtml:59 -msgid " (you)" +#: app/views/general/exception_caught.rhtml:18 +msgid "" +"You have found a bug. Please <a href=\"{{contact_url}}\">contact us</a> to " +"tell us about the problem" msgstr "" -#: app/views/user/show.rhtml:62 -msgid "Joined {{site_name}} in" +#: app/views/user/show.rhtml:144 +msgid "You have made no Freedom of Information requests using this site." msgstr "" -#: app/views/user/show.rhtml:69 -msgid "Send message to " +#: app/controllers/user_controller.rb:525 +msgid "You have now changed the text about you on your profile." msgstr "" -#: app/views/user/show.rhtml:71 -msgid "just to see how it works" +#: app/controllers/user_controller.rb:342 +msgid "You have now changed your email address used on {{site_name}}" msgstr "" -#: app/views/user/show.rhtml:79 -msgid "This user has been banned from {{site_name}} " +#: app/views/user_mailer/already_registered.rhtml:3 +msgid "" +"You just tried to sign up to {{site_name}}, when you\n" +"already have an account. Your name and password have been\n" +"left as they previously were.\n" +"\n" +"Please click on the link below." msgstr "" -#: app/views/user/show.rhtml:83 -msgid "They have been given the following explanation:" +#: app/views/comment/new.rhtml:60 +msgid "" +"You know what caused the error, and can <strong>suggest a solution</strong>, " +"such as a working email address." msgstr "" -#: app/views/user/show.rhtml:96 -msgid "edit text about you" +#: app/views/request/upload_response.rhtml:16 +msgid "" +"You may <strong>include attachments</strong>. If you would like to attach a\n" +"file too large for email, use the form below." msgstr "" -#: app/views/user/show.rhtml:106 -msgid "Change your password" +#: app/views/request/followup_bad.rhtml:24 +msgid "" +"You may be able to find\n" +" one on their website, or by phoning them up and asking. If you manage\n" +" to find one, then please <a href=\"%s\">send it to us</a>." msgstr "" -#: app/views/user/show.rhtml:107 -msgid "Change your email" +#: app/views/request/new_bad_contact.rhtml:6 +msgid "" +"You may be able to find\n" +"one on their website, or by phoning them up and asking. If you manage\n" +"to find one, then please <a href=\"{{help_url}}\">send it to us</a>." msgstr "" -#: app/views/user/show.rhtml:113 -msgid "<a href=\"%s\">Sign in</a> to change password, subscriptions and more ({{user_name}} only)" +#: app/controllers/user_controller.rb:503 +msgid "You need to be logged in to change the text about you on your profile." msgstr "" -#: app/views/user/show.rhtml:123 -msgid "Search your contributions" +#: app/controllers/user_controller.rb:403 +msgid "You need to be logged in to change your profile photo." msgstr "" -#: app/views/user/show.rhtml:125 -msgid "Search contributions by this person" +#: app/controllers/user_controller.rb:465 +msgid "You need to be logged in to clear your profile photo." msgstr "" -#: app/views/user/show.rhtml:136 -msgid "You have made no Freedom of Information requests using this site." +#: app/controllers/request_controller.rb:599 +msgid "You previously submitted that exact follow up message for this request." msgstr "" -#: app/views/user/show.rhtml:136 -msgid "This person has made no Freedom of Information requests using this site." +#: app/views/request/upload_response.rhtml:13 +msgid "" +"You should have received a copy of the request by email, and you can " +"respond\n" +"by <strong>simply replying</strong> to that email. For your convenience, " +"here is the address:" msgstr "" -#: app/views/user/show.rhtml:141 -msgid "Your %d Freedom of Information request" -msgid_plural "Your %d Freedom of Information requests" -msgstr[0] "" -msgstr[1] "" +#: app/views/request/show_response.rhtml:34 +msgid "" +"You want to <strong>give your postal address</strong> to the authority in " +"private." +msgstr "" -#: app/views/user/show.rhtml:141 -msgid "This person's %d Freedom of Information request" -msgid_plural "This person's %d Freedom of Information requests" -msgstr[0] "" -msgstr[1] "" +#: app/views/user/banned.rhtml:9 +msgid "" +"You will be unable to make new requests, send follow ups, add annotations " +"or\n" +"send messages to other users. You may continue to view other requests, and " +"set\n" +"up\n" +"email alerts." +msgstr "" -#: app/views/user/show.rhtml:155 -msgid "Freedom of Information requests made by you" +#: app/controllers/track_controller.rb:161 +msgid "You will no longer be emailed updates about " msgstr "" -#: app/views/user/show.rhtml:155 -msgid "Freedom of Information requests made by this person" +#: app/controllers/track_controller.rb:190 +msgid "You will no longer be emailed updates for those alerts" msgstr "" -#: app/views/user/show.rhtml:156 -msgid "The search index is currently offline, so we can't show the Freedom of Information requests this person has made." +#: app/controllers/track_controller.rb:118 +msgid "You will now be emailed updates about " msgstr "" -#: app/views/user/show.rhtml:162 -msgid "Your annotations" +#: app/views/request_mailer/not_clarified_alert.rhtml:6 +msgid "" +"You will only get an answer to your request if you follow up\n" +"with the clarification." msgstr "" -#: app/views/user/show.rhtml:162 -msgid "This person's annotations" +#: app/models/request_mailer.rb:106 +msgid "You're long overdue a response to your FOI request - " msgstr "" -#: app/views/user/show.rhtml:165 app/views/user/show.rhtml:185 -msgid "None made." +#: app/controllers/user_controller.rb:474 +msgid "You've now cleared your profile photo" msgstr "" -#: app/views/user/show.rhtml:169 -msgid "Your %d annotation" -msgid_plural "Your %d annotations" +#: app/views/user/show.rhtml:149 +msgid "Your %d Freedom of Information request" +msgid_plural "Your %d Freedom of Information requests" msgstr[0] "" msgstr[1] "" -#: app/views/user/show.rhtml:169 -msgid "This person's %d annotation" -msgid_plural "This person's %d annotations" +#: app/views/user/show.rhtml:179 +msgid "Your %d annotation" +msgid_plural "Your %d annotations" msgstr[0] "" msgstr[1] "" -#: app/views/user/show.rhtml:184 +#: app/views/user/_signup.rhtml:22 +msgid "" +"Your <strong>name will appear publicly</strong> \n" +" (<a href=\"%s\">why?</a>)\n" +" on this website and in search engines. If you\n" +" are thinking of using a pseudonym, please \n" +" <a href=\"%s\">read this first</a>." +msgstr "" + +#: app/views/user/show.rhtml:172 +msgid "Your annotations" +msgstr "" + +#: app/views/contact_mailer/user_message.rhtml:3 +msgid "" +"Your details have not been given to anyone, unless you choose to reply to " +"this\n" +"message, which will then go directly to the person who wrote the message." +msgstr "" + +#: app/views/user/_signup.rhtml:9 app/views/user/_signin.rhtml:11 +#: app/views/user/signchangepassword_send_confirm.rhtml:13 +msgid "Your e-mail:" +msgstr "" + +#: app/views/user/show.rhtml:196 msgid "Your email subscriptions" msgstr "" -#: app/views/user/show.rhtml:187 -msgid "email subscription" +#: app/controllers/request_controller.rb:596 +msgid "" +"Your follow up has not been sent because this request has been stopped to " +"prevent spam. Please <a href=\"%s\">contact us</a> if you really want to " +"send a follow up message." msgstr "" -#: app/views/user/show.rhtml:196 app/views/user/show.rhtml:210 -msgid "unsubscribe all" +#: app/controllers/request_controller.rb:624 +msgid "Your follow up message has been sent on its way." msgstr "" -#: app/views/user/show.rhtml:224 -msgid "unsubscribe" +#: app/controllers/request_controller.rb:622 +msgid "Your internal review request has been sent on its way." msgstr "" -#: app/views/user/sign.rhtml:8 -msgid "Please sign in as " +#: app/controllers/help_controller.rb:63 +msgid "" +"Your message has been sent. Thank you for getting in touch! We'll get back " +"to you soon." msgstr "" -#: app/views/user/sign.rhtml:11 -msgid "please sign in as " +#: app/controllers/user_controller.rb:381 +msgid "Your message to {{recipient_user_name}} has been sent!" msgstr "" -#: app/views/user/sign.rhtml:20 -msgid "Sign in or make a new account" +#: app/views/request/followup_preview.rhtml:15 +msgid "Your message will appear in <strong>search engines</strong>" msgstr "" -#: app/views/user/sign.rhtml:26 -msgid " Please sign in or make a new account." +#: app/views/comment/preview.rhtml:10 +msgid "" +"Your name and annotation will appear in <strong>search engines</strong>." msgstr "" -#: app/views/user/sign.rhtml:28 -msgid "please sign in or make a new account." +#: app/views/request/preview.rhtml:8 +msgid "" +"Your name, request and any responses will appear in <strong>search engines</" +"strong>\n" +" (<a href=\"%s\">details</a>)." msgstr "" -#: app/views/user/sign.rhtml:37 -msgid "- or -" +#: app/views/user/_signup.rhtml:18 +msgid "Your name:" msgstr "" -#: app/views/user/signchangeemail.rhtml:15 -msgid "Old e-mail:" +#: app/views/request_mailer/stopped_responses.rhtml:14 +msgid "Your original message is attached." msgstr "" -#: app/views/user/signchangeemail.rhtml:20 -msgid "New e-mail:" +#: app/controllers/user_controller.rb:263 +msgid "Your password has been changed." msgstr "" #: app/views/user/signchangeemail.rhtml:25 msgid "Your password:" msgstr "" -#: app/views/user/signchangeemail.rhtml:30 -msgid "<strong>Note:</strong>\n We will send an email to your new email address. Follow the\n instructions in it to confirm changing your email." +#: app/views/user/set_draft_profile_photo.rhtml:18 +msgid "" +"Your photo will be shown in public <strong>on the Internet</strong>, \n" +" wherever you do something on {{site_name}}." msgstr "" -#: app/views/user/signchangeemail.rhtml:37 -msgid "Change email on {{site_name}}" +#: app/views/request_mailer/new_response_reminder_alert.rhtml:5 +msgid "" +"Your request was called {{info_request}}. Letting everyone know whether you " +"got the information will help us keep tabs on" msgstr "" -#: app/views/user/signchangeemail_confirm.rhtml:3 app/views/user/signchangepassword_confirm.rhtml:1 -#: app/views/user/signchangepassword_confirm.rhtml:3 -msgid "Now check your email!" +#: app/views/request/new.rhtml:113 +msgid "Your request:" msgstr "" -#: app/views/user/signchangeemail_confirm.rhtml:6 -msgid "We've sent an email to your new email address. You'll need to click the link in\nit before your email address will be changed." +#: app/views/request/upload_response.rhtml:8 +msgid "" +"Your response will <strong>appear on the Internet</strong>, <a href=\"%s" +"\">read why</a> and answers to other questions." msgstr "" -#: app/views/user/signchangeemail_confirm.rhtml:11 app/views/user/signchangepassword_confirm.rhtml:10 -msgid "If you use web-based email or have \"junk mail\" filters, also check your\nbulk/spam mail folders. Sometimes, our messages are marked that way." +#: app/views/comment/new.rhtml:63 +msgid "" +"Your thoughts on what the {{site_name}} <strong>administrators</strong> " +"should do about the request." msgstr "" -#: app/views/user/signchangepassword.rhtml:1 app/views/user/signchangepassword.rhtml:11 -#: app/views/user/signchangepassword_send_confirm.rhtml:1 app/views/user/signchangepassword_send_confirm.rhtml:9 -msgid "Change your password on {{site_name}}" +#: app/models/track_mailer.rb:25 +msgid "Your {{site_name}} email alert" msgstr "" -#: app/views/user/signchangepassword.rhtml:15 -msgid "New password:" +#: app/models/outgoing_message.rb:70 +msgid "Yours faithfully," msgstr "" -#: app/views/user/signchangepassword.rhtml:20 -msgid "New password: (again)" +#: app/models/outgoing_message.rb:68 +msgid "Yours sincerely," msgstr "" -#: app/views/user/signchangepassword.rhtml:27 -msgid "Change password on {{site_name}}" +#: app/views/request/new.rhtml:88 +msgid "" +"a one line summary of the information you are requesting, \n" +"\t\t\te.g." msgstr "" -#: app/views/user/signchangepassword_confirm.rhtml:6 -msgid "We've sent you an email, click the link in it, then you can change your password." +#: app/views/public_body/show.rhtml:37 +msgid "admin" msgstr "" -#: app/views/user/signchangepassword_send_confirm.rhtml:18 -msgid " <strong>Note:</strong>\n We will send you an email. Follow the instructions in it to change\n your password." +#: app/views/request/_request_filter_form.rhtml:30 +msgid "all requests" msgstr "" -#: app/views/user/signchangepassword_send_confirm.rhtml:26 -msgid "Submit" +#: app/views/public_body/show.rhtml:35 +msgid "also called {{public_body_short_name}}" msgstr "" -#: app/views/user/wrong_user.rhtml:2 -msgid "Sorry, but only {{user_name}} is allowed to do that." +#: app/views/request/_request_filter_form.rhtml:25 +#: app/views/general/search.rhtml:110 +msgid "and" msgstr "" -#: app/views/user/wrong_user_unknown_email.rhtml:3 -msgid "Unfortunately we don't know the FOI\nemail address for that authority, so we can't validate this.\nPlease <a href=\"%s\">contact us</a> to sort it out." +#: app/views/request/show.rhtml:59 +msgid "" +"and update the status accordingly. Perhaps <strong>you</strong> might like " +"to help out by doing that?" msgstr "" -#: app/views/user_mailer/already_registered.rhtml:3 -msgid "You just tried to sign up to {{site_name}}, when you\nalready have an account. Your name and password have been\nleft as they previously were.\n\nPlease click on the link below." +#: app/views/request/show.rhtml:64 +msgid "and update the status." msgstr "" -#: app/views/user_mailer/changeemail_already_used.rhtml:1 -msgid "Someone, perhaps you, just tried to change their email address on\n{{site_name}} from {{old_email}} to {{new_email}}." +#: app/views/request/_describe_state.rhtml:101 +msgid "and we'll suggest <strong>what to do next</strong>" msgstr "" -#: app/views/user_mailer/changeemail_already_used.rhtml:5 -msgid "This was not possible because there is already an account using \nthe email address {{email}}." +#: app/views/general/frontpage.rhtml:60 +msgid "answered a request about" msgstr "" -#: app/views/user_mailer/changeemail_already_used.rhtml:8 -msgid "The accounts have been left as they previously were." +#: app/models/track_thing.rb:210 +msgid "any <a href=\"/list\">new requests</a>" msgstr "" -#: app/views/user_mailer/changeemail_confirm.rhtml:3 -msgid "Please click on the link below to confirm that you want to \nchange the email address that you use for {{site_name}}\nfrom {{old_email}} to {{new_email}}" +#: app/models/track_thing.rb:226 +msgid "any <a href=\"/list/successful\">successful requests</a>" msgstr "" -#: app/views/user_mailer/changeemail_confirm.rhtml:10 -msgid "We will not reveal your email addresses to anybody unless you\nor the law tell us to." +#: app/models/track_thing.rb:115 +msgid "anything" msgstr "" -#: app/views/user_mailer/confirm_login.rhtml:3 -msgid "Please click on the link below to confirm your email address." +#: app/views/request_mailer/very_overdue_alert.rhtml:1 +msgid "are long overdue." msgstr "" -#: app/views/user_mailer/confirm_login.rhtml:8 -msgid "We will not reveal your email address to anybody unless you\nor the law tell us to." +#: app/models/track_thing.rb:88 app/views/general/search.rhtml:55 +msgid "authorities" msgstr "" -#: lib/world_foi_websites.rb:5 -msgid "United Kingdom" +#: app/models/track_thing.rb:103 +msgid "awaiting a response" msgstr "" -#: lib/world_foi_websites.rb:9 -msgid "Kosovo" +#: app/controllers/public_body_controller.rb:125 +msgid "beginning with ‘{{first_letter}}’" msgstr "" -#: lib/world_foi_websites.rb:13 -msgid "European Union" +#: app/models/track_thing.rb:94 +msgid "between two dates" msgstr "" -#: lib/world_foi_websites.rb:17 -msgid "United States of America" +#: app/views/request/show.rhtml:82 +msgid "by" msgstr "" -#: lib/world_foi_websites.rb:21 -msgid "New Zealand" +#: app/views/request/_followup.rhtml:65 +msgid "by <strong>{{date}}</strong>" msgstr "" -#: lib/world_foi_websites.rb:25 -msgid "Germany" +#: app/views/request/_request_listing_via_event.rhtml:26 +msgid "by {{public_body_name}} to {{info_request_user}} on {{date}}." msgstr "" -#: lib/world_foi_websites.rb:29 -msgid "Chile" +#: app/views/request/_request_listing_short_via_event.rhtml:10 +msgid "by {{user_link_absolute}}" msgstr "" -#: locale/model_attributes.rb:2 -msgid "public body" +#: locale/model_attributes.rb:42 +msgid "censor rule" msgstr "" -#: locale/model_attributes.rb:3 -msgid "PublicBody|Name" +#: locale/model_attributes.rb:20 +msgid "comment" msgstr "" -#: locale/model_attributes.rb:4 -msgid "PublicBody|Short name" +#: app/models/track_thing.rb:85 +#: app/views/request/_request_filter_form.rhtml:14 +#: app/views/general/search.rhtml:99 +msgid "comments" msgstr "" -#: locale/model_attributes.rb:5 -msgid "PublicBody|Request email" +#: app/views/request/show_response.rhtml:39 +msgid "" +"containing your postal address, and asking them to reply to this request.\n" +" Or you could phone them." msgstr "" -#: locale/model_attributes.rb:6 -msgid "PublicBody|Version" +#: app/models/info_request_event.rb:358 +msgid "display_status only works for incoming and outgoing messages right now" msgstr "" -#: locale/model_attributes.rb:7 -msgid "PublicBody|Last edit editor" +#: app/views/request_mailer/overdue_alert.rhtml:3 +msgid "during term time" msgstr "" -#: locale/model_attributes.rb:8 -msgid "PublicBody|Last edit comment" +#: app/views/user/show.rhtml:101 +msgid "edit text about you" msgstr "" -#: locale/model_attributes.rb:9 -msgid "PublicBody|Url name" +#: app/views/user/show.rhtml:199 +msgid "email subscription" msgstr "" -#: locale/model_attributes.rb:10 -msgid "PublicBody|Home page" +#: app/views/request_mailer/very_overdue_alert.rhtml:4 +msgid "even during holidays" msgstr "" -#: locale/model_attributes.rb:11 -msgid "PublicBody|Notes" +#: app/views/general/search.rhtml:56 +msgid "everything" msgstr "" -#: locale/model_attributes.rb:12 -msgid "PublicBody|First letter" +#: locale/model_attributes.rb:17 +msgid "exim log" msgstr "" -#: locale/model_attributes.rb:13 -msgid "PublicBody|Publication scheme" +#: locale/model_attributes.rb:67 +msgid "exim log done" msgstr "" -#: locale/model_attributes.rb:14 -msgid "profile photo" +#: locale/model_attributes.rb:85 +msgid "foi attachment" msgstr "" -#: locale/model_attributes.rb:15 -msgid "ProfilePhoto|Data" +#: app/views/request_mailer/requires_admin.rhtml:2 +msgid "has reported an" msgstr "" -#: locale/model_attributes.rb:16 -msgid "ProfilePhoto|Draft" +#: app/views/request_mailer/overdue_alert.rhtml:1 +msgid "have delayed." msgstr "" -#: locale/model_attributes.rb:17 -msgid "exim log" +#: locale/model_attributes.rb:64 +msgid "holiday" msgstr "" -#: locale/model_attributes.rb:18 -msgid "EximLog|Order" +#: app/views/request/_followup.rhtml:63 app/views/request/show.rhtml:70 +#: app/views/request/show.rhtml:80 +msgid "in term time" msgstr "" -#: locale/model_attributes.rb:19 -msgid "EximLog|Line" +#: app/controllers/public_body_controller.rb:131 +msgid "in the category ‘{{category_name}}’" msgstr "" -#: locale/model_attributes.rb:20 -msgid "comment" +#: locale/model_attributes.rb:54 +msgid "incoming message" msgstr "" -#: locale/model_attributes.rb:21 -msgid "Comment|Comment type" +#: locale/model_attributes.rb:95 +msgid "info request" msgstr "" -#: locale/model_attributes.rb:22 -msgid "Comment|Body" +#: locale/model_attributes.rb:35 +msgid "info request event" msgstr "" -#: locale/model_attributes.rb:23 -msgid "Comment|Visible" +#: app/views/user/set_profile_about_me.rhtml:3 +#: app/views/user/signchangeemail.rhtml:3 +msgid "internal error" msgstr "" -#: locale/model_attributes.rb:24 -msgid "Comment|Locale" +#: app/views/general/search.rhtml:87 +msgid "internal reviews" msgstr "" -#: locale/model_attributes.rb:25 -msgid "outgoing message" +#: app/views/request/show.rhtml:100 +msgid "is <strong>waiting for your clarification</strong>." msgstr "" -#: locale/model_attributes.rb:26 -msgid "OutgoingMessage|Body" +#: app/views/user/show.rhtml:76 +msgid "just to see how it works" msgstr "" -#: locale/model_attributes.rb:27 -msgid "OutgoingMessage|Status" +#: app/views/comment/_single_comment.rhtml:10 +msgid "left an annotation" msgstr "" -#: locale/model_attributes.rb:28 -msgid "OutgoingMessage|Message type" +#: app/views/user/_user_listing_single.rhtml:19 +#: app/views/user/_user_listing_single.rhtml:20 +msgid "made." msgstr "" -#: locale/model_attributes.rb:29 -msgid "OutgoingMessage|Last sent at" +#: app/controllers/public_body_controller.rb:129 +msgid "matching the tag ‘{{tag_name}}’" msgstr "" -#: locale/model_attributes.rb:30 -msgid "OutgoingMessage|What doing" +#: app/views/request/_request_filter_form.rhtml:13 +#: app/views/general/search.rhtml:98 +msgid "messages from authorities" msgstr "" -#: locale/model_attributes.rb:31 -msgid "track thing" +#: app/views/request/_request_filter_form.rhtml:12 +#: app/views/general/search.rhtml:97 +msgid "messages from users" msgstr "" -#: locale/model_attributes.rb:32 -msgid "TrackThing|Track query" +#: app/views/request/show.rhtml:74 +msgid "no later than" msgstr "" -#: locale/model_attributes.rb:33 -msgid "TrackThing|Track medium" +#: app/views/request/followup_bad.rhtml:18 +msgid "" +"no longer exists. If you are trying to make\n" +" From the request page, try replying to a particular message, rather than " +"sending\n" +" a general followup. If you need to make a general followup, and know\n" +" an email which will go to the right place, please <a href=\"%s\">send it " +"to us</a>." msgstr "" -#: locale/model_attributes.rb:34 -msgid "TrackThing|Track type" +#: app/views/request/show.rhtml:72 +msgid "normally" msgstr "" -#: locale/model_attributes.rb:35 -msgid "censor rule" +#: locale/model_attributes.rb:25 +msgid "outgoing message" msgstr "" -#: locale/model_attributes.rb:36 -msgid "CensorRule|Text" +#: app/views/user/sign.rhtml:11 +msgid "please sign in as " msgstr "" -#: locale/model_attributes.rb:37 -msgid "CensorRule|Replacement" +#: locale/model_attributes.rb:47 +msgid "post redirect" msgstr "" -#: locale/model_attributes.rb:38 -msgid "CensorRule|Last edit editor" +#: locale/model_attributes.rb:14 +msgid "profile photo" msgstr "" -#: locale/model_attributes.rb:39 -msgid "CensorRule|Last edit comment" +#: locale/model_attributes.rb:2 +msgid "public body" msgstr "" -#: locale/model_attributes.rb:40 -msgid "info request event" +#: app/views/request_mailer/not_clarified_alert.rhtml:1 +msgid "request." msgstr "" -#: locale/model_attributes.rb:41 -msgid "InfoRequestEvent|Event type" +#: app/views/request/show.rhtml:89 +msgid "requesting an internal review" msgstr "" -#: locale/model_attributes.rb:42 -msgid "InfoRequestEvent|Params yaml" +#: app/models/track_thing.rb:91 app/models/track_thing.rb:110 +#: app/models/track_thing.rb:112 app/views/general/search.rhtml:53 +msgid "requests" msgstr "" -#: locale/model_attributes.rb:43 -msgid "InfoRequestEvent|Described state" +#: app/models/track_thing.rb:111 +msgid "requests which are {{list_of_statuses}}" msgstr "" -#: locale/model_attributes.rb:44 -msgid "InfoRequestEvent|Calculated state" +#: app/views/request_mailer/requires_admin.rhtml:3 +msgid "" +"response as needing administrator attention. Take a look, and reply to this\n" +"email to let them know what you are going to do about it." msgstr "" -#: locale/model_attributes.rb:45 -msgid "InfoRequestEvent|Last described at" +#: app/views/request/show.rhtml:102 +msgid "send a follow up message" msgstr "" -#: locale/model_attributes.rb:46 -msgid "InfoRequestEvent|Prominence" +#: app/views/request/_request_listing_via_event.rhtml:23 +msgid "sent to {{public_body_name}} by {{info_request_user}} on {{date}}." msgstr "" -#: locale/model_attributes.rb:47 -msgid "post redirect" +#: app/views/request/show.rhtml:106 +msgid "sign in" msgstr "" -#: locale/model_attributes.rb:48 -msgid "PostRedirect|Token" +#: app/models/track_thing.rb:100 +msgid "successful" msgstr "" -#: locale/model_attributes.rb:49 -msgid "PostRedirect|Uri" +#: app/views/request/_request_filter_form.rhtml:31 +#: app/views/general/search.rhtml:84 +msgid "successful requests" msgstr "" -#: locale/model_attributes.rb:50 -msgid "PostRedirect|Post params yaml" +#: app/views/request_mailer/new_response.rhtml:2 +msgid "that you made to" msgstr "" -#: locale/model_attributes.rb:51 -msgid "PostRedirect|Email token" +#: app/views/request/_followup.rhtml:23 app/views/request/_followup.rhtml:28 +#: app/views/request/_followup.rhtml:34 +msgid "the main FOI contact address for {{public_body}}" msgstr "" -#: locale/model_attributes.rb:52 -msgid "PostRedirect|Reason params yaml" +#: app/views/request/_followup.rhtml:3 +msgid "the main FOI contact at {{public_body}}" msgstr "" -#: locale/model_attributes.rb:53 -msgid "PostRedirect|Circumstance" +#: app/views/track_mailer/event_digest.rhtml:66 +#: app/views/request_mailer/stopped_responses.rhtml:16 +#: app/views/request_mailer/new_response.rhtml:15 +#: app/views/request_mailer/new_response_reminder_alert.rhtml:8 +#: app/views/request_mailer/comment_on_alert.rhtml:6 +#: app/views/request_mailer/comment_on_alert_plural.rhtml:5 +#: app/views/request_mailer/old_unclassified_updated.rhtml:8 +#: app/views/request_mailer/overdue_alert.rhtml:9 +#: app/views/request_mailer/not_clarified_alert.rhtml:9 +#: app/views/request_mailer/very_overdue_alert.rhtml:11 +#: app/views/user_mailer/changeemail_already_used.rhtml:10 +#: app/views/user_mailer/confirm_login.rhtml:11 +#: app/views/user_mailer/changeemail_confirm.rhtml:13 +#: app/views/user_mailer/already_registered.rhtml:11 +msgid "the {{site_name}} team" msgstr "" -#: locale/model_attributes.rb:54 -msgid "holiday" +#: app/views/request/show.rhtml:62 +msgid "to read" msgstr "" -#: locale/model_attributes.rb:55 -msgid "Holiday|Day" +#: app/views/request/show.rhtml:106 +msgid "to send a follow up message." msgstr "" -#: locale/model_attributes.rb:56 -msgid "Holiday|Description" +#: app/views/request/show.rhtml:45 +msgid "to {{public_body}}" msgstr "" -#: locale/model_attributes.rb:57 -msgid "exim log done" +#: locale/model_attributes.rb:31 +msgid "track thing" msgstr "" -#: locale/model_attributes.rb:58 -msgid "EximLogDone|Filename" +#: app/views/request/_hidden_correspondence.rhtml:32 +msgid "unexpected prominence on request event" msgstr "" -#: locale/model_attributes.rb:59 -msgid "EximLogDone|Last stat" +#: app/views/request/followup_bad.rhtml:29 +msgid "unknown reason " msgstr "" -#: locale/model_attributes.rb:60 -msgid "incoming message" +#: app/models/info_request.rb:810 app/models/info_request_event.rb:353 +msgid "unknown status " msgstr "" -#: locale/model_attributes.rb:61 -msgid "IncomingMessage|Cached attachment text clipped" +#: app/views/request/_request_filter_form.rhtml:33 +#: app/views/general/search.rhtml:86 +msgid "unresolved requests" msgstr "" -#: locale/model_attributes.rb:62 -msgid "IncomingMessage|Cached main body text folded" +#: app/views/user/show.rhtml:236 +msgid "unsubscribe" msgstr "" -#: locale/model_attributes.rb:63 -msgid "IncomingMessage|Cached main body text unfolded" +#: app/views/user/show.rhtml:208 app/views/user/show.rhtml:222 +msgid "unsubscribe all" msgstr "" -#: locale/model_attributes.rb:64 -msgid "IncomingMessage|Sent at" +#: app/models/track_thing.rb:97 +msgid "unsuccessful" msgstr "" -#: locale/model_attributes.rb:65 -msgid "IncomingMessage|Subject" +#: app/views/request/_request_filter_form.rhtml:32 +#: app/views/general/search.rhtml:85 +msgid "unsuccessful requests" msgstr "" -#: locale/model_attributes.rb:66 -msgid "IncomingMessage|Safe mail from" +#: app/views/request/show.rhtml:53 +msgid "useful information." msgstr "" -#: locale/model_attributes.rb:67 -msgid "IncomingMessage|Mail from domain" +#: locale/model_attributes.rb:70 +msgid "user" msgstr "" -#: locale/model_attributes.rb:68 -msgid "IncomingMessage|Valid to reply to" +#: locale/model_attributes.rb:93 +msgid "user info request sent alert" msgstr "" -#: locale/model_attributes.rb:69 -msgid "user info request sent alert" +#: app/models/track_thing.rb:82 app/views/general/search.rhtml:54 +msgid "users" msgstr "" -#: locale/model_attributes.rb:70 -msgid "UserInfoRequestSentAlert|Alert type" +#: app/views/request/list.rhtml:21 +msgid "{{count}} FOI requests found" msgstr "" -#: locale/model_attributes.rb:71 -msgid "user" +#: app/views/request/new.rhtml:27 +msgid "" +"{{existing_request_user}} already\n" +" created the same request on {{date}}. You can either view the <a href=" +"\"{{existing_request}}\">existing request</a>,\n" +" or edit the details below to make a new but similar request." msgstr "" -#: locale/model_attributes.rb:72 -msgid "User|Email" +#: app/views/request/_after_actions.rhtml:23 +msgid "{{info_request_user_name}} only:" msgstr "" -#: locale/model_attributes.rb:73 -msgid "User|Name" +#: app/models/info_request.rb:239 +msgid "{{law_used_full}} request - {{title}}" msgstr "" -#: locale/model_attributes.rb:74 -msgid "User|Hashed password" +#: app/models/info_request.rb:237 +msgid "{{law_used_full}} request GQ - {{title}}" msgstr "" -#: locale/model_attributes.rb:75 -msgid "User|Salt" +#: app/views/general/frontpage.rhtml:62 +msgid "{{length_of_time}} ago" msgstr "" -#: locale/model_attributes.rb:76 -msgid "User|Email confirmed" +#: app/models/track_thing.rb:121 +msgid "{{list_of_things}} matching text '{{search_query}}'" msgstr "" -#: locale/model_attributes.rb:77 -msgid "User|Url name" +#: app/views/general/blog.rhtml:56 +msgid "{{number_of_comments}} comments" msgstr "" -#: locale/model_attributes.rb:78 -msgid "User|Last daily track email" +#: app/views/request/_after_actions.rhtml:45 +msgid "{{public_body_name}} only:" msgstr "" -#: locale/model_attributes.rb:79 -msgid "User|Admin level" +#: app/views/track_mailer/event_digest.rhtml:21 +msgid "{{public_body}} sent a response to {{user_name}}" msgstr "" -#: locale/model_attributes.rb:80 -msgid "User|Ban text" +#: app/controllers/user_controller.rb:54 +msgid "{{search_results}} matching '{{query}}'" msgstr "" -#: locale/model_attributes.rb:81 -msgid "User|About me" +#: app/views/general/blog.rhtml:1 +msgid "{{site_name}} blog and tweets" msgstr "" -#: locale/model_attributes.rb:82 -msgid "info request" +#: app/views/general/frontpage.rhtml:38 +msgid "" +"{{site_name}} covers requests to {{number_of_authorities}} authorities, " +"including:" msgstr "" -#: locale/model_attributes.rb:83 -msgid "InfoRequest|Title" +#: app/views/public_body/view_email.rhtml:7 +msgid "" +"{{site_name}} sends new requests to <strong>{{request_email}}</strong> for " +"this authority." msgstr "" -#: locale/model_attributes.rb:84 -msgid "InfoRequest|Described state" +#: app/views/general/frontpage.rhtml:55 +msgid "" +"{{site_name}} users have made {{number_of_requests}} requests, including:" msgstr "" -#: locale/model_attributes.rb:85 -msgid "InfoRequest|Awaiting description" +#: app/models/user.rb:135 +msgid "{{user_name}} (Account suspended)" msgstr "" -#: locale/model_attributes.rb:86 -msgid "InfoRequest|Prominence" +#: app/views/track_mailer/event_digest.rhtml:31 +msgid "{{user_name}} added an annotation" msgstr "" -#: locale/model_attributes.rb:87 -msgid "InfoRequest|Url title" +#: app/views/request_mailer/comment_on_alert.rhtml:1 +msgid "" +"{{user_name}} has annotated your {{law_used_short}} \n" +"request. Follow this link to see what they wrote." msgstr "" -#: locale/model_attributes.rb:88 -msgid "InfoRequest|Law used" +#: app/views/contact_mailer/user_message.rhtml:2 +msgid "{{user_name}} has used {{site_name}} to send you the message below." msgstr "" -#: locale/model_attributes.rb:89 -msgid "InfoRequest|Allow new responses from" +#: app/views/track_mailer/event_digest.rhtml:24 +msgid "{{user_name}} sent a follow up message to {{public_body}}" msgstr "" -#: locale/model_attributes.rb:90 -msgid "InfoRequest|Handle rejected responses" +#: app/views/track_mailer/event_digest.rhtml:28 +msgid "{{user_name}} sent a request to {{public_body}}" msgstr "" -#: locale/model_attributes.rb:91 -msgid "InfoRequest|Idhash" +#: app/views/request/simple_correspondence.rhtml:42 +msgid "{{username}} left an annotation:" +msgstr "" + +#: app/views/request/show.rhtml:36 +msgid "" +"{{user}} (<a href=\"{{user_admin_url}}\">admin</a>) made this " +"{{law_used_full}} request (<a href=\"{{request_admin_url}}\">admin</a>) to " +"{{public_body_link}} (<a href=\"{{public_body_admin_url}}\">admin</a>)" +msgstr "" + +#: app/views/request/show.rhtml:44 +msgid "{{user}} made this {{law_used_full}} request" msgstr "" diff --git a/locale/cy/app.po b/locale/cy/app.po index 954f20f9f..617f7bbff 100644 --- a/locale/cy/app.po +++ b/locale/cy/app.po @@ -3908,7 +3908,7 @@ msgid "" msgstr "" #: app/models/user.rb:122 -msgid "{{user_name}} (Banned)" +msgid "{{user_name}} (Account suspended)" msgstr "" #: app/views/request_mailer/comment_on_alert.rhtml:1 diff --git a/locale/de/app.po b/locale/de/app.po index 81ce9ab75..da1a55b11 100644 --- a/locale/de/app.po +++ b/locale/de/app.po @@ -3,15 +3,16 @@ # This file is distributed under the same license as the PACKAGE package. # # Translators: +# David Cabo <david.cabo@gmail.com>, 2012. # <kersti@access-info.org>, 2011. # stefanw <stefanwehrmeyer@gmail.com>, 2011. msgid "" msgstr "" "Project-Id-Version: alaveteli\n" "Report-Msgid-Bugs-To: http://github.com/sebbacon/alaveteli/issues\n" -"POT-Creation-Date: 2011-09-27 15:58+0200\n" -"PO-Revision-Date: 2011-09-27 14:01+0000\n" -"Last-Translator: dcabo <david.cabo@gmail.com>\n" +"POT-Creation-Date: 2011-11-10 14:28+0100\n" +"PO-Revision-Date: 2012-01-06 18:43+0000\n" +"Last-Translator: David Cabo <david.cabo@gmail.com>\n" "Language-Team: LANGUAGE <LL@li.org>\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -19,215 +20,284 @@ msgstr "" "Language: de\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" -#: app/controllers/application_controller.rb:298 +#: app/models/incoming_message.rb:859 msgid "" -"<p>{{site_name}} is currently in maintenance. You can only view existing " -"requests. You cannot make new ones, add followups or annotations, or " -"otherwise change the database.</p> <p>{{read_only}}</p>" +"\n" +"\n" +"[ {{site_name}} note: The above text was badly encoded, and has had strange characters removed. ]" msgstr "" -"<p>{{site_name}} wird gerade überarbeitet. Sie können ausschließlich " -"existierende Anfragen ansehen. Sie können keine neuen Anfragen stellen, " -"Follow-ups oder Anmerkungen hinzufügen oder andere Änderungen an der " -"Datenbank vornehmen.</p> <p>{{read_only}}</p>" - -#: app/controllers/comment_controller.rb:55 -msgid "To post your annotation" -msgstr "Um Ihre Anmerkung zu senden" - -#: app/controllers/comment_controller.rb:56 -msgid "Then your annotation to {{info_request_title}} will be posted." -msgstr "Dann wird Ihr Kommentar zu {{info_request_title}} gesendet." +"\n" +"\n" +"[ {{site_name}} Anmerkung: Der obenstehende Text war schlecht kodiert und merkwürdige Zeichen wurden entfernt. ]" -#: app/controllers/comment_controller.rb:57 -msgid "Confirm your annotation to {{info_request_title}}" -msgstr "Bestätigen Sie Ihre Anmerkung zu {{info_request_title}}" +#: app/views/user/set_profile_about_me.rhtml:14 +msgid "" +" This will appear on your {{site_name}} profile, to make it\n" +" easier for others to get involved with what you're doing." +msgstr "" +" Diese Information wird auf Ihrem {{site_name}} -profil angezeigt werden, um" +" andere Nutzer über Ihre Aktivitäten zu informieren. " -#: app/controllers/comment_controller.rb:62 -msgid "Thank you for making an annotation!" -msgstr "Vielen Dank für Ihre Anmerkung" +#: app/views/comment/_comment_form.rhtml:16 +msgid "" +" (<strong>no ranty</strong> politics, read our <a href=\"%s\">moderation " +"policy</a>)" +msgstr "<a href=\"%s\">Moderationsregeln</a>)" -#: app/controllers/comment_controller.rb:73 -msgid " You will also be emailed updates about the request." +#: app/views/request/upload_response.rhtml:40 +msgid "" +" (<strong>patience</strong>, especially for large files, it may take a " +"while!)" msgstr "" -"Aktualisierungen zu dieser Anfrage werden Ihnen auch per Email übermittelt. " +" (<strong>Geduld</strong>, speziell für größere Dateien kann es einen Moment" +" dauern!)" -#: app/controllers/comment_controller.rb:75 -msgid " You are already being emailed updates about the request." +#: app/views/user/show.rhtml:59 +msgid " (you)" +msgstr " (Sie)" + +#: app/views/public_body/show.rhtml:1 +msgid " - view and make Freedom of Information requests" msgstr "" -"Sie haben bereits Aktualisierungen zu dieser Anfrage per Email erhalten. " -#: app/controllers/help_controller.rb:63 +#: app/views/user/signchangepassword_send_confirm.rhtml:18 msgid "" -"Your message has been sent. Thank you for getting in touch! We'll get back " -"to you soon." +" <strong>Note:</strong>\n" +" We will send you an email. Follow the instructions in it to change\n" +" your password." msgstr "" -"Ihre Nachricht wurde gesendet. Vielen Dank für die Kontaktaufnahme! Wir " -"werden uns in Kürze mit Ihnen in Verbindung senden. " +"<strong>Note:</strong>⏎ Sie werden in Kürze eine Email erhalten. Folgen Sie " +"der Anleitung, um Ihr Passwort⏎ zu ändern." -#: app/controllers/public_body_controller.rb:82 -#: app/controllers/user_controller.rb:140 -msgid "There was an error with the words you entered, please try again." +#: app/views/user/contact.rhtml:35 +msgid " <strong>Privacy note:</strong> Your email address will be given to" msgstr "" -"Mit den von Ihren eingegebenen Worten ist etwas schiefgegangen. Versuchen " -"Sie es erneut. " - -#: app/controllers/public_body_controller.rb:123 -msgid "beginning with" -msgstr "mit Anfangsbuchstabe " - -#: app/controllers/request_controller.rb:31 -#: app/controllers/request_controller.rb:303 -msgid "To send your FOI request" -msgstr "Um Ihre IFG-Anfrage zu senden" - -#: app/controllers/request_controller.rb:32 -msgid "Then you'll be allowed to send FOI requests." -msgstr "Dann ist es Ihnen gestattet eine IFG-Anfrage zu senden. " - -#: app/controllers/request_controller.rb:33 -msgid "Confirm your email address" -msgstr "Bestätigen Sie Ihre Email-Adresse" - -#: app/controllers/request_controller.rb:81 -msgid "To update the status of this FOI request" -msgstr "Um den Status dieser IFG-Anfrage zu aktualisieren" +" <strong>Datenschutzerklärung:</strong> Ihre Emailadresse wird " +"weitergeleitet an: " -#: app/controllers/request_controller.rb:82 -msgid "Then you can update the status of your request to " -msgstr "Dann können Sie den Status Ihrer Nachricht aktualisieren" +#: app/views/comment/new.rhtml:34 +msgid " <strong>Summarise</strong> the content of any information returned. " +msgstr "Fassen Sie den Inhalt jeglicher erhaltenen Information zusammen. " -#: app/controllers/request_controller.rb:83 -msgid "Update the status of your request to " -msgstr "Aktualisieren Sie den Status Ihrer Anfrage an" +#: app/views/comment/new.rhtml:24 +msgid " Advise on how to <strong>best clarify</strong> the request." +msgstr " Hilfe zur Erstellung einer guten Informationsanfrage. " -#: app/controllers/request_controller.rb:155 -msgid "View and search requests" -msgstr "Ansehen und Suchen von Anfragen" +#: app/views/comment/new.rhtml:50 +msgid "" +" Ideas on what <strong>other documents to request</strong> which the " +"authority may hold. " +msgstr "" +" Ideas on what <strong>other documents to request</strong> which the " +"authority may hold. " -#: app/controllers/request_controller.rb:285 +#: app/views/public_body/view_email.rhtml:30 msgid "" -"<p>You do not need to include your email in the request in order to get a " -"reply, as we will ask for it on the next screen (<a " -"href=\"%s\">details</a>).</p>" +" If you know the address to use, then please <a href=\"%s\">send it to us</a>.\n" +" You may be able to find the address on their website, or by phoning them up and asking." msgstr "" -"<p>Um eine Antwort zu erhalten, müssen Sie Ihre Email-Adresse nicht in Ihre " -"Anfrage einfügen, da wir diese auf der folgenden Seite erfragen werden (<a " -"href=\"%s\">Details</a>).</p>" +"Sollten Sie die korrekte Adresse kennen, <a href=\"%s\">senden Sie sie uns</a>.\n" +" Sie können die Adresse wahrscheinlich auf der Webseite oder durch einen Anruf bei der Behörde herausfinden. " -#: app/controllers/request_controller.rb:287 +#: app/views/user/set_profile_about_me.rhtml:26 msgid "" -"<p>You do not need to include your email in the request in order to get a " -"reply (<a href=\"%s\">details</a>).</p>" +" Include relevant links, such as to a campaign page, your blog or a\n" +" twitter account. They will be made clickable. \n" +" e.g." msgstr "" -"<p> Es ist nicht erfoderlich Ihre Emailadresse in der Anfrage zu nennen, um " -"eine Antwort zu erhalten (<a href=\"%s\">Details</a>).</p>" +"Fügen Sie relevanten Links ein, z.B. zu einer Kampagnenseite, Ihrem Blog " +"oder Twitterkonto. Die Links werden aktiviert widergegeben. z.B." -#: app/controllers/request_controller.rb:289 +#: app/views/comment/new.rhtml:28 msgid "" -"<p>We recommend that you edit your request and remove the email address.\n" -" If you leave it, the email address will be sent to the authority, but will not be displayed on the site.</p>" +" Link to the information requested, if it is <strong>already " +"available</strong> on the Internet. " msgstr "" -"<p>Wir empfehlen Ihnen Ihre Anfrage zu bearbeiten und Ihre Emailadresse zu entfernen.\n" -" Sollten Sie die Emaildresse nicht entfernen, wir diese an die entsprechende Behörde gesendet, jedoch nicht auf der Seite angezeigt.</p>" +" Link zur angefragten Information,falls bereits online " +"<strong>verfügbar</strong>. " -#: app/controllers/request_controller.rb:293 +#: app/views/comment/new.rhtml:30 msgid "" -"<p>Your request contains a <strong>postcode</strong>. Unless it directly " -"relates to the subject of your request, please remove any address as it will" -" <strong>appear publicly on the Internet</strong>.</p>" +" Offer better ways of <strong>wording the request</strong> to get the " +"information. " msgstr "" -"<p>Ihre Anfrage enthält eine <strong>Postleitzahl</strong>. Sollte diese " -"nicht unmittelbar in Zusammenhang mit Ihrer Anfrage stehen, empfehlen wir " -"diese zu entfern en, da diese ansonsten<strong>im Internet veröffentlicht " -"wird </strong>.</p>" +" Machen Sie bessere <strong>Formulierungsvorschläge</strong>, um die " +"gewünschten Informationen zu erhalten. " -#: app/controllers/request_controller.rb:304 -msgid "Then your FOI request to {{public_body_name}} will be sent." -msgstr "Dann wird Ihre OFG-Anfrage an {{public_body_name}} gesendet. " +#: app/views/user/sign.rhtml:26 +msgid " Please sign in or make a new account." +msgstr "Bitte melden Sie sich an oder erstellen Sie ein neues Benutzerkonto." -#: app/controllers/request_controller.rb:305 -msgid "Confirm your FOI request to " -msgstr "Bestätigen Sie Ihre IFG-Anfrage " +#: app/views/comment/new.rhtml:35 +msgid "" +" Say how you've <strong>used the information</strong>, with links if " +"possible." +msgstr "" +"Teilen Sie uns mit, <strong>wie Sie die Informationen verwendet " +"haben</strong> - falls möglich mit Link." -#: app/controllers/request_controller.rb:316 +#: app/views/comment/new.rhtml:29 msgid "" -"<p>Your {{law_used_full}} request has been <strong>sent on its way</strong>!</p>\n" -" <p><strong>We will email you</strong> when there is a response, or after {{late_number_of_days}} working days if the authority still hasn't\n" -" replied by then.</p>\n" -" <p>If you write about this request (for example in a forum or a blog) please link to this page, and add an \n" -" annotation below telling people about your writing.</p>" +" Suggest <strong>where else</strong> the requester might find the " +"information. " msgstr "" +"Machen Sie Vorschläge wo sonst die gewünschte Information eventuell zu " +"finden ist " -#: app/controllers/request_controller.rb:343 -msgid "To classify the response to this FOI request" -msgstr "Um die Antwort auf diese IFG-Anfrage zu klassifizieren" +#: app/views/user/set_profile_about_me.rhtml:11 +msgid " What are you investigating using Freedom of Information? " +msgstr " Was recherchieren im Rahmen der Informationsfreiheit?" -#: app/controllers/request_controller.rb:344 -msgid "Then you can classify the FOI response you have got from " +#: app/controllers/comment_controller.rb:75 +msgid " You are already being emailed updates about the request." msgstr "" -"Dann klassifizieren Sie die IFG-Anfrage welche Sie erhalten haben, von" +"Sie haben bereits Aktualisierungen zu dieser Anfrage per Email erhalten. " -#: app/controllers/request_controller.rb:345 -msgid "Classify an FOI response from " -msgstr "Klassifizieren Sie eine IFG-Anfrage von" +#: app/controllers/comment_controller.rb:73 +msgid " You will also be emailed updates about the request." +msgstr "" +"Aktualisierungen zu dieser Anfrage werden Ihnen auch per Email übermittelt. " -#: app/controllers/request_controller.rb:352 +#: app/views/request/upload_response.rhtml:5 +msgid " made by " +msgstr "erstellt durch" + +#: app/models/track_thing.rb:112 app/models/track_thing.rb:120 +msgid " or " +msgstr " oder " + +#: app/views/user/contact.rhtml:36 +msgid " when you send this message." +msgstr "wenn Sie diese Nachricht senden. " + +#: app/views/public_body/show.rhtml:95 +msgid "%d Freedom of Information request to %s" +msgid_plural "%d Freedom of Information requests to %s" +msgstr[0] "%d Informationsfreiheitsanfrage an %s" +msgstr[1] "%d Informationsfreiheitsanfragen an %s" + +#: app/views/general/frontpage.rhtml:43 +msgid "%d request" +msgid_plural "%d requests" +msgstr[0] "%d Anfrage" +msgstr[1] "%d Anfragen" + +#: app/views/public_body/_body_listing_single.rhtml:21 +msgid "%d request made." +msgid_plural "%d requests made." +msgstr[0] "%d Anfragen gestellt." +msgstr[1] "%d Anfragen gestellt." + +#: app/views/request/new.rhtml:92 +msgid "'Crime statistics by ward level for Wales'" +msgstr "´Kriminalitätsrate auf Länderebene´" + +#: app/views/request/new.rhtml:90 +msgid "'Pollution levels over time for the River Tyne'" +msgstr "'Verschmutzungsgrades des Tyne Flusses im Zeitverlauf'" + +#: app/models/track_thing.rb:246 +msgid "'{{link_to_authority}}', a public authority" +msgstr "'{{link_to_authority}}', eine Behörde" + +#: app/models/track_thing.rb:195 +msgid "'{{link_to_request}}', a request" +msgstr "'{{link_to_request}}', eine Anfrage" + +#: app/models/track_thing.rb:262 +msgid "'{{link_to_user}}', a person" +msgstr "'{{link_to_user}}', eine Person" + +#: app/controllers/user_controller.rb:373 msgid "" -"Please choose whether or not you got some of the information that you " -"wanted." +",\n" +"\n" +"\n" +"\n" +"Yours,\n" +"\n" +"{{user_name}}" msgstr "" -"Bitte wählen Sie ob Sie einige der erwünschten Informationen erhalten haben " -"oder ob dies nicht der Fall ist. " +",\n" +"\n" +"\n" +"\n" +"Mit freundlichem Gruß,\n" +"\n" +"{{user_name}}" -#: app/controllers/request_controller.rb:358 -msgid "" -"The request has been updated since you originally loaded this page. Please " -"check for any new incoming messages below, and try again." +#: app/views/user/sign.rhtml:37 +msgid "- or -" msgstr "" -"Die Anfrage wurde seit Ihrem letzten Besuch auf dieser Seite aktualisiert. " -"Bitte checken Sie unten nach neu eingegangenen Nachrichten, nud versuchen " -"Sie es erneut." -#: app/controllers/request_controller.rb:384 -msgid "" -"Thank you for updating the status of the request '<a " -"href=\"{{url}}\">{{info_request_title}}</a>'. There are some more requests " -"below for you to classify." +#: app/views/request/select_authority.rhtml:29 +msgid "1. Select an authority" +msgstr "1. Behörde auswählen" + +#: app/views/request/new.rhtml:22 +msgid "2. Ask for Information" +msgstr "2. Informationen anfragen" + +#: app/views/request/preview.rhtml:5 +msgid "3. Now check your request" +msgstr "3. Überprüfen Sie nun Ihre Anfrage" + +#: app/views/public_body/show.rhtml:64 +msgid "<a class=\"link_button_green\" href=\"{{url}}\">{{text}}</a>" +msgstr "<a class=\"link_button_green\" href=\"{{url}}\">{{text}}</a>" + +#: app/views/request/_after_actions.rhtml:9 +msgid "<a href=\"%s\">Add an annotation</a> (to help the requester or others)" msgstr "" -"Herzlichen Dank für die Aktualisierung der Anfrage '<a " -"href=\"{{url}}\">{{info_request_title}}</a>'. Untenstehend finden Sie einige" -" weitere Anfragen, welche durch Sie zugeordnet werden sollten." +"<a href=\"%s\">Kommentar hinzufügen</a> (um den Anfragensteller oder andere " +"Nutzern zu unterstützen)" -#: app/controllers/request_controller.rb:387 -msgid "Thank you for updating this request!" -msgstr "Vielen Dank für die Aktualisierung dieser Anfrage!" +#: app/views/public_body/list.rhtml:29 +msgid "<a href=\"%s\">Are we missing a public authority?</a>." +msgstr "<a href=\"%s\">Fehlt eine Behörde?</a>." -#: app/controllers/request_controller.rb:395 +#: app/views/request/_sidebar.rhtml:39 msgid "" -"<p>Thank you! Hopefully your wait isn't too long.</p> <p>By law, you should get a response promptly, and normally before the end of <strong>\n" -"{{date_response_required_by}}</strong>.</p>" +"<a href=\"%s\">Are you the owner of\n" +" any commercial copyright on this page?</a>" +msgstr "<a href=\"%s\">Halten Sie die Urheberrechte dieser Seite?</a>" + +#: app/views/general/search.rhtml:173 +msgid "<a href=\"%s\">Browse all</a> or <a href=\"%s\">ask us to add one</a>." msgstr "" -"<p>Vielen Dank! Wir hoffen Sie müssen nicht zu lange warten.</p> <p>Nach " -"gesetzlicher Vorschrift hätten Sie sofort oder vor Ende " -"<strong>{{date_response_required_by}}</strong> erhalten sollen. </p>" +"<a href=\"%s\">Alle durchsuchen</a> or <a href=\"%s\">bitten Sie uns eine " +"hinzuzufügen</a>." -#: app/controllers/request_controller.rb:399 +#: app/views/public_body/list.rhtml:51 +msgid "<a href=\"%s\">Can't find the one you want?</a>" +msgstr "<a href=\"%s\">Gewünschte Behörde nicht gefunden?</a>" + +#: app/views/user/show.rhtml:113 msgid "" -"<p>Thank you! Hope you don't have to wait much longer.</p> <p>By law, you " -"should have got a response promptly, and normally before the end of " -"<strong>{{date_response_required_by}}</strong>.</p>" +"<a href=\"%s\">Sign in</a> to change password, subscriptions and more " +"({{user_name}} only)" msgstr "" -"<p>Vielen Dank! Wir hoffen Sie müssen nicht viel länger warten.</p> <p>Nach " -"gesetzlicher Vorschrift hätten Sie sofort oder vor Ende " -"<strong>{{date_response_required_by}}</strong> erhalten sollen. </p>" +"<a href=\"%s\">Melden Sie sich an,</a> um Ihr Passwort und weitere " +"Einstellungen zu ändern (auschließlich {{user_name}})" -#: app/controllers/request_controller.rb:402 +#: app/views/request/_followup.rhtml:66 app/views/request/_followup.rhtml:73 +#: app/views/request/show.rhtml:83 app/views/request/show.rhtml:87 +msgid "<a href=\"%s\">details</a>" +msgstr "<a href=\"%s\">Details</a>" + +#: app/views/request/_followup.rhtml:101 +msgid "<a href=\"%s\">what's that?</a>" +msgstr "<a href=\"%s\">Was ist das?</a>" + +#: app/controllers/request_game_controller.rb:23 msgid "" -"<p>Thank you! Your request is long overdue, by more than " -"{{very_late_number_of_days}} working days. Most requests should be answered " -"within {{late_number_of_days}} working days. You might like to complain " -"about this, see below.</p>" +"<p>All done! Thank you very much for your help.</p><p>There are <a " +"href=\"{{helpus_url}}\">more things you can do</a> to help " +"{{site_name}}.</p>" msgstr "" +"<p>Fertig! Ganz herzlichen Dank für Ihre Hilfe.</p><p>Es gibt <a " +"href=\"{{helpus_url}}\">noch mehr womit Sie uns helfen " +"können</a>{{site_name}}.</p>" #: app/controllers/request_controller.rb:405 msgid "" @@ -253,12 +323,78 @@ msgstr "" " </li>\n" " </ul>" -#: app/controllers/request_controller.rb:420 +#: app/controllers/request_controller.rb:399 msgid "" -"Oh no! Sorry to hear that your request was refused. Here is what to do now." +"<p>Thank you! Hope you don't have to wait much longer.</p> <p>By law, you " +"should have got a response promptly, and normally before the end of " +"<strong>{{date_response_required_by}}</strong>.</p>" msgstr "" -"Oh nein! Es tut uns leid zu hören, dass Ihre Anfrage abgelehnt wurde. Lesen " -"Sie hier was Sie nun tun können. " +"<p>Vielen Dank! Wir hoffen Sie müssen nicht viel länger warten.</p> <p>Nach " +"gesetzlicher Vorschrift hätten Sie sofort oder vor Ende " +"<strong>{{date_response_required_by}}</strong> erhalten sollen. </p>" + +#: app/controllers/request_controller.rb:395 +msgid "" +"<p>Thank you! Hopefully your wait isn't too long.</p> <p>By law, you should get a response promptly, and normally before the end of <strong>\n" +"{{date_response_required_by}}</strong>.</p>" +msgstr "" +"<p>Vielen Dank! Wir hoffen Sie müssen nicht zu lange warten.</p> <p>Nach " +"gesetzlicher Vorschrift hätten Sie sofort oder vor Ende " +"<strong>{{date_response_required_by}}</strong> erhalten sollen. </p>" + +#: app/controllers/request_controller.rb:434 +msgid "" +"<p>Thank you! Hopefully your wait isn't too long.</p><p>You should get a " +"response within {{late_number_of_days}} days, or be told if it will take " +"longer (<a href=\"{{review_url}}\">details</a>).</p>" +msgstr "" +"<p>Vielen Dank! Hoffentlich mussten Sie nicht zu lange warten.</p><p>Sie " +"sollten innerhalb {{late_number_of_days}} Tagen eine Antwort erhalten, oder " +"eine Nachricht, dass es länger dauern kann (<a " +"href=\"{{review_url}}\">Details</a>).</p>" + +#: app/controllers/request_controller.rb:437 +msgid "" +"<p>Thank you! We'll look into what happened and try and fix it up.</p><p>If " +"the error was a delivery failure, and you can find an up to date FOI email " +"address for the authority, please tell us using the form below.</p>" +msgstr "" +"<p>Vielen Dank! Wir überprüfen das Problem und werden versuchen es zu " +"beheben.</p><p>Sollte es sich um einen Übertragungsfehler gehandelt haben " +"und Sie können eine aktuelle IFG Email-Adresse dieser Behörde finden, teilen" +" Sie uns diese bitte mit Hilfe des unten angezeigten Formulars mit.</p>" + +#: app/controllers/request_controller.rb:402 +msgid "" +"<p>Thank you! Your request is long overdue, by more than " +"{{very_late_number_of_days}} working days. Most requests should be answered " +"within {{late_number_of_days}} working days. You might like to complain " +"about this, see below.</p>" +msgstr "" + +#: app/controllers/user_controller.rb:513 +msgid "" +"<p>Thanks for changing the text about you on your profile.</p>\n" +" <p><strong>Next...</strong> You can upload a profile photograph too.</p>" +msgstr "" +"<p>Vielen Dank für die Änderung Ihres Profiltextes.</p>\n" +" <p><strong>Weiter...</strong> Sie können auch ein Profilbild hochladen.</p>" + +#: app/controllers/user_controller.rb:435 +msgid "" +"<p>Thanks for updating your profile photo.</p>\n" +" <p><strong>Next...</strong> You can put some text about you and your research on your profile.</p>" +msgstr "" +"<p>Danke für die Aktualisierung Ihres Profilbildes.</p>\n" +" <p><strong>Nächster Schritt...</strong> Sie können Informationen zu Ihrer Person und Ihrer Suchanfrage zu Ihrem Profil hinzufügen.</p>" + +#: app/controllers/request_controller.rb:289 +msgid "" +"<p>We recommend that you edit your request and remove the email address.\n" +" If you leave it, the email address will be sent to the authority, but will not be displayed on the site.</p>" +msgstr "" +"<p>Wir empfehlen Ihnen Ihre Anfrage zu bearbeiten und Ihre Emailadresse zu entfernen.\n" +" Sollten Sie die Emaildresse nicht entfernen, wir diese an die entsprechende Behörde gesendet, jedoch nicht auf der Seite angezeigt.</p>" #: app/controllers/request_controller.rb:423 msgid "" @@ -289,605 +425,675 @@ msgstr "" "hinter dieser Seite.</p><p>Falls Sie versuchen möchten den Rest der " "Information zu erhalten, schauen Sie hier was Sie tun können.</p>" -#: app/controllers/request_controller.rb:429 +#: app/controllers/request_controller.rb:287 msgid "" -"Please write your follow up message containing the necessary clarifications " -"below." +"<p>You do not need to include your email in the request in order to get a " +"reply (<a href=\"%s\">details</a>).</p>" msgstr "" -"Bitte geben Sie unten Ihre Follow-up Nachricht mit den nötigen " -"Klärungsdetails ein. " +"<p> Es ist nicht erfoderlich Ihre Emailadresse in der Anfrage zu nennen, um " +"eine Antwort zu erhalten (<a href=\"%s\">Details</a>).</p>" -#: app/controllers/request_controller.rb:434 +#: app/controllers/request_controller.rb:285 msgid "" -"<p>Thank you! Hopefully your wait isn't too long.</p><p>You should get a " -"response within {{late_number_of_days}} days, or be told if it will take " -"longer (<a href=\"{{review_url}}\">details</a>).</p>" +"<p>You do not need to include your email in the request in order to get a " +"reply, as we will ask for it on the next screen (<a " +"href=\"%s\">details</a>).</p>" msgstr "" -"<p>Vielen Dank! Hoffentlich mussten Sie nicht zu lange warten.</p><p>Sie " -"sollten innerhalb {{late_number_of_days}} Tagen eine Antwort erhalten, oder " -"eine Nachricht, dass es länger dauern kann (<a " -"href=\"{{review_url}}\">Details</a>).</p>" +"<p>Um eine Antwort zu erhalten, müssen Sie Ihre Email-Adresse nicht in Ihre " +"Anfrage einfügen, da wir diese auf der folgenden Seite erfragen werden (<a " +"href=\"%s\">Details</a>).</p>" -#: app/controllers/request_controller.rb:437 +#: app/controllers/request_controller.rb:293 msgid "" -"<p>Thank you! We'll look into what happened and try and fix it up.</p><p>If " -"the error was a delivery failure, and you can find an up to date FOI email " -"address for the authority, please tell us using the form below.</p>" +"<p>Your request contains a <strong>postcode</strong>. Unless it directly " +"relates to the subject of your request, please remove any address as it will" +" <strong>appear publicly on the Internet</strong>.</p>" msgstr "" -"<p>Vielen Dank! Wir überprüfen das Problem und werden versuchen es zu " -"beheben.</p><p>Sollte es sich um einen Übertragungsfehler gehandelt haben " -"und Sie können eine aktuelle IFG Email-Adresse dieser Behörde finden, teilen" -" Sie uns diese bitte mit Hilfe des unten angezeigten Formulars mit.</p>" +"<p>Ihre Anfrage enthält eine <strong>Postleitzahl</strong>. Sollte diese " +"nicht unmittelbar in Zusammenhang mit Ihrer Anfrage stehen, empfehlen wir " +"diese zu entfern en, da diese ansonsten<strong>im Internet veröffentlicht " +"wird </strong>.</p>" -#: app/controllers/request_controller.rb:440 -msgid "Please use the form below to tell us more." -msgstr "Bitte nutzen Sie das Formular, um uns ausführlicher zu informieren. " +#: app/controllers/request_controller.rb:316 +msgid "" +"<p>Your {{law_used_full}} request has been <strong>sent on its way</strong>!</p>\n" +" <p><strong>We will email you</strong> when there is a response, or after {{late_number_of_days}} working days if the authority still hasn't\n" +" replied by then.</p>\n" +" <p>If you write about this request (for example in a forum or a blog) please link to this page, and add an \n" +" annotation below telling people about your writing.</p>" +msgstr "" -#: app/controllers/request_controller.rb:443 +#: app/controllers/application_controller.rb:298 msgid "" -"If you have not done so already, please write a message below telling the " -"authority that you have withdrawn your request. Otherwise they will not know" -" it has been withdrawn." +"<p>{{site_name}} is currently in maintenance. You can only view existing " +"requests. You cannot make new ones, add followups or annotations, or " +"otherwise change the database.</p> <p>{{read_only}}</p>" msgstr "" -"Falls noch nicht geschehen, senden Sie bitte eine Nachricht, um die Behörde " -"zu informieren, dass Sie Ihre Anfrage zurückgezogen haben. Anderenfalls " -"weiss diese nicht, dass dies geschehen ist. " +"<p>{{site_name}} wird gerade überarbeitet. Sie können ausschließlich " +"existierende Anfragen ansehen. Sie können keine neuen Anfragen stellen, " +"Follow-ups oder Anmerkungen hinzufügen oder andere Änderungen an der " +"Datenbank vornehmen.</p> <p>{{read_only}}</p>" -#: app/controllers/request_controller.rb:548 -msgid "To send a follow up message to " -msgstr "Um eine Nachfrage zu senden" +#: app/views/user/confirm.rhtml:11 +msgid "" +"<small>If you use web-based email or have \"junk mail\" filters, also check your\n" +"bulk/spam mail folders. Sometimes, our messages are marked that way.</small>\n" +"</p>" +msgstr "" +"Sollten Sie eine webbasierten Emailanbieter oder ´Junk-mail´ Filter nutzen, " +"prüfen Sie Ihren Spamordner. Es kommt vor, dass unsere Nachrichten dort " +"landen. " -#: app/controllers/request_controller.rb:549 -msgid "To reply to " -msgstr "Um eine Antwort zu senden an" +#: app/views/request/new.rhtml:135 +msgid "" +"<strong> Can I request information about myself?</strong>\n" +"\t\t\t<a href=\"%s\">No! (Click here for details)</a>" +msgstr "" +"<strong> Kann ich Informationen zu meiner eigenen Person anfragen?</strong>\n" +"<span class=\"whitespace other\" title=\"Tab\">»</span><span class=\"whitespace other\" title=\"Tab\">»</span><span class=\"whitespace other\" title=\"Tab\">»</span><a href=\"%s\">Nein! (Weitere Informationen)</a>" -#: app/controllers/request_controller.rb:551 -msgid "Then you can write follow up message to " -msgstr "Dann können Sie eine Nachfrage senden an" +#: app/views/general/_advanced_search_tips.rhtml:12 +msgid "" +"<strong><code>commented_by:tony_bowden</code></strong> to search annotations" +" made by Tony Bowden, typing the name as in the URL." +msgstr "" +"<strong><code>kommentiert_durch:tony_bowden</code></strong> um Kommentare " +"von Tony Bowden zu suche, den Namen wie in der URL eingebend." -#: app/controllers/request_controller.rb:552 -msgid "Then you can write your reply to " -msgstr "Dann können Sie Ihre Antwort schreiben an" +#: app/views/general/_advanced_search_tips.rhtml:14 +msgid "" +"<strong><code>filetype:pdf</code></strong> to find all responses with PDF " +"attachments. Or try these: <code>{{list_of_file_extensions}}</code>" +msgstr "" +"<strong><code>Dateityp:PDF</code></strong> um alle Antworten mit PDF-Anhang " +"zu finden. Oder versuchen Sie es hiermit: " +"<code>{{list_of_file_extensions}}</code>" -#: app/controllers/request_controller.rb:554 -msgid "Write your FOI follow up message to " -msgstr "Senden Sie Ihre Follow-Up Nachricht an " +#: app/views/general/_advanced_search_tips.rhtml:13 +msgid "" +"<strong><code>request:</code></strong> to restrict to a specific request, " +"typing the title as in the URL." +msgstr "" +"<strong><code>Anfrage:</code></strong> um die Suchanfrage zu begrenzen, " +"geben Sie den Titel wie in der URL ein." -#: app/controllers/request_controller.rb:555 -msgid "Write a reply to " -msgstr "Antwort senden" +#: app/views/general/_advanced_search_tips.rhtml:11 +msgid "" +"<strong><code>requested_by:julian_todd</code></strong> to search requests " +"made by Julian Todd, typing the name as in the URL." +msgstr "" +"<strong><code>angefragt_durch:julian_todd</code></strong>um Anfragen von " +"Julian Todd zu suchen, den Namen wie in der URL eingebend." -#: app/controllers/request_controller.rb:562 +#: app/views/general/_advanced_search_tips.rhtml:10 msgid "" -"Your follow up has not been sent because this request has been stopped to " -"prevent spam. Please <a href=\"%s\">contact us</a> if you really want to " -"send a follow up message." +"<strong><code>requested_from:home_office</code></strong> to search requests " +"from the Home Office, typing the name as in the URL." msgstr "" -"Ihre Nachfrage wurde nicht gesendet, da Sie durch unseren Spamfilter " -"gestoppt wurde. Bitte <a href=\"%s\">kontaktieren Sie uns</a> wenn Sie " -"wirklich eine Nachfrage senden möchten. " +"<strong><code>angefragt durch:home_office</code></strong>um Anfragen vom " +"Home Office zu suchen, den Namen wie in der URL eingebend." -#: app/controllers/request_controller.rb:565 +#: app/views/general/_advanced_search_tips.rhtml:8 msgid "" -"You previously submitted that exact follow up message for this request." +"<strong><code>status:</code></strong> to select based on the status or " +"historical status of the request, see the <a href=\"{{statuses_url}}\">table" +" of statuses</a> below." msgstr "" -"Sie haben kürzlich dieselbe Follow-up Nachricht für diese Anfrage gesendet. " +"<strong><code>Status:</code></strong> um eine Auswahl nach Status oder " +"historischem Status der Anfrage zu treffen, gehen Sie zur unten " +"angezeigten<a href=\"{{statuses_url}}\">Statusübersicht</a> ." -#: app/controllers/request_controller.rb:588 -msgid "Your internal review request has been sent on its way." -msgstr "Ihre Anfrage zur internen Überprüfung wurde gesendet. " +#: app/views/general/_advanced_search_tips.rhtml:16 +msgid "" +"<strong><code>tag:charity</code></strong> to find all public bodies or requests with a given tag. You can include multiple tags, \n" +" and tag values, e.g. <code>tag:openlylocal AND tag:financial_transaction:335633</code>. Note that by default any of the tags\n" +" can be present, you have to put <code>AND</code> explicitly if you only want results them all present." +msgstr "" +"<strong><code>markieren Sie:Karitas</code></strong>, um alle Behörden oder Anfragen mit dieser Markierung zu finden. Sie können mehrere Markierungen, \n" +" and tag values, e.g. <code>tag:openlylocal AND tag:financial_transaction:335633</code>. Note that by default any of the tags\n" +" can be present, you have to put <code>AND</code> explicitly if you only want results them all present." -#: app/controllers/request_controller.rb:590 -msgid "Your follow up message has been sent on its way." -msgstr "Ihre Follow-up Nachricht wurde gesendet." +#: app/views/general/_advanced_search_tips.rhtml:9 +msgid "" +"<strong><code>variety:</code></strong> to select type of thing to search " +"for, see the <a href=\"{{varieties_url}}\">table of varieties</a> below." +msgstr "" +"<strong><code>variety:</code></strong> um Mögliche Suchoptionen zu wählen, " +"gehen Sie zur unten angezeigten <a " +"href=\"{{varieties_url}}\">Auswahlansich</a> ." -#: app/controllers/request_controller.rb:712 +#: app/views/comment/new.rhtml:57 msgid "" -"To upload a response, you must be logged in using an email address from " +"<strong>Advice</strong> on how to get a response that will satisfy the " +"requester. </li>" msgstr "" -"Um eine Antwort hochzuladen müssen Sie angemeldet sein und dafür eine " -"folgende Email-Adresse benutzen:" +"<strong>Ratschlag</strong> bzgl. Antworten, welche den Anfragesteller " +"zufriedenstellen. </li>" -#: app/controllers/request_controller.rb:713 -msgid "Then you can upload an FOI response. " -msgstr "Dann können Sie eine IFG-Antwort hochladen. " +#: app/views/request/_other_describe_state.rhtml:56 +msgid "<strong>All the information</strong> has been sent" +msgstr "Informationen wurden vollständig gesendet" -#: app/controllers/request_controller.rb:714 -#: app/controllers/user_controller.rb:542 -msgid "Confirm your account on {{site_name}}" -msgstr "Bestätigen Sie Ihr Nutzerkonto auf {{site_name}}" +#: app/views/request/_followup.rhtml:106 +msgid "" +"<strong>Anything else</strong>, such as clarifying, prompting, thanking" +msgstr "<strong>Alles andere</strong>, z.B. Klärungen, Hinweise, Danksagungen" -#: app/controllers/request_controller.rb:741 -msgid "Please type a message and/or choose a file containing your response." +#: app/views/request/details.rhtml:12 +msgid "" +"<strong>Caveat emptor!</strong> To use this data in an honourable way, you will need \n" +"a good internal knowledge of user behaviour on {{site_name}}. How, \n" +"why and by whom requests are categorised is not straightforward, and there will\n" +"be user error and ambiguity. You will also need to understand FOI law, and the\n" +"way authorities use it. Plus you'll need to be an elite statistician. Please\n" +"<a href=\"{{contact_path}}\">contact us</a> with questions." msgstr "" -"Bitte geben Sie eine Nachricht ein und / oder wählen Sie eine Datei aus, " -"welche Ihre Antwort enthält" +"<strong>Gewährleistungsausschluss!</strong>Um diese Daten ehrenhaft zu nutzen, benötigen Sie gute interne Kenntnisse des Nutzerverhaltens auf {{site_name}}. Es ist nicht überschaubar wie, warum und von wem Anfragen kategorisiert werden und es sind Nutzerfehler und Unklarheiten zu erwarten. Ein gutes Verständnis der Informationsfreiheits-Gesetzgebung und die Art und Weise der Anwendung durch Behörden ist ebenso wichtig. Ferner benötigen Sie herausragende Statisikkenntnisse. Für Fragen nehmen Sie bitte\n" +"<a href=\"{{contact_path}}\">Kontakt</a> mit uns auf." -#: app/controllers/request_controller.rb:747 +#: app/views/request/_other_describe_state.rhtml:28 +msgid "<strong>Clarification</strong> has been requested" +msgstr "Klärung der Angelegenheit wurde angefragt" + +#: app/views/request/_other_describe_state.rhtml:14 msgid "" -"Thank you for responding to this FOI request! Your response has been " -"published below, and a link to your response has been emailed to " +"<strong>No response</strong> has been received\n" +" <small>(maybe there's just an acknowledgement)</small>" msgstr "" -"Vielen Dank für Ihre IFG-Anfrage! Ihre Antwort wird unten angezeigt und ein " -"Link zu Ihrer Antwort wurde gesendet an" +"Es wurde <strong>Keine Antwort</strong> empfangen\n" +" <small>(vielleicht gab es nur eine Bestätigung)</small>" -#: app/controllers/request_controller.rb:773 -msgid "To download the zip file" -msgstr "Um die Zip-Datei herunterzuladen" +#: app/views/user/signchangeemail.rhtml:30 +msgid "" +"<strong>Note:</strong>\n" +" We will send an email to your new email address. Follow the\n" +" instructions in it to confirm changing your email." +msgstr "" +"<strong>Note:</strong>\n" +" Es wird eine Email an Ihre neue Emailadresse versendet. Folgen Sie den darin angegebenen Schritten, um die Änderung Ihrer Emailadresse zu bestätigen." -#: app/controllers/request_controller.rb:774 -msgid "Then you can download a zip file of {{info_request_title}}." +#: app/views/user/contact.rhtml:32 +msgid "" +"<strong>Note:</strong> You're sending a message to yourself, presumably\n" +" to try out how it works." msgstr "" -"Dann können Sie eine Zip-Datei von {{info_request_title}} herunterladen. " +"<strong>Achtung:</strong> Sie senden eine Nachricht an sich selbst, " +"vermutlich um herauszufinden, wie es funktioniert. " -#: app/controllers/request_controller.rb:775 -msgid "Log in to download a zip file of {{info_request_title}}" +#: app/views/request/preview.rhtml:31 +msgid "" +"<strong>Privacy note:</strong> If you want to request private information about\n" +" yourself then <a href=\"%s\">click here</a>." msgstr "" -"Melden Sie sich an, um eine Zip-Datei von {{info_request_title}} " -"herunterzuladen" +"<strong>Privacy note:</strong> Falls Sie Informationen zu Ihrer eingenen " +"Person erfragen wollen <a href=\"%s\">Klicken Sie hier</a>." -#: app/controllers/request_game_controller.rb:23 +#: app/views/user/set_crop_profile_photo.rhtml:35 msgid "" -"<p>All done! Thank you very much for your help.</p><p>There are <a " -"href=\"{{helpus_url}}\">more things you can do</a> to help " -"{{site_name}}.</p>" +"<strong>Privacy note:</strong> Your photo will be shown in public on the Internet, \n" +" wherever you do something on {{site_name}}." msgstr "" -"<p>Fertig! Ganz herzlichen Dank für Ihre Hilfe.</p><p>Es gibt <a " -"href=\"{{helpus_url}}\">noch mehr womit Sie uns helfen " -"können</a>{{site_name}}.</p>" +"<strong>Datenschutzhinweis:</strong> Ihr Photo wird öffentlich im Internet angezeigt werden\n" +" wo immer Sie {{site_name}} nutzen." -#: app/controllers/request_game_controller.rb:40 -msgid "To play the request categorisation game" -msgstr "Um uns mit der Kategorisierung von Anfragen zu unterstützen" +#: app/views/request/followup_preview.rhtml:37 +msgid "" +"<strong>Privacy warning:</strong> Your message, and any response\n" +" to it, will be displayed publicly on this website." +msgstr "" +"<strong>Datenschutzhinweis:</strong> Ihre Nachricht als auch alle " +"entsprechenden Reaktionen werden auf dieser Webseite veröffentlicht." -#: app/controllers/request_game_controller.rb:41 -msgid "Then you can play the request categorisation game." -msgstr "Dann können Sie die helden einige Anfraggen zuzuordnen. " +#: app/views/request/_other_describe_state.rhtml:52 +msgid "<strong>Some of the information</strong> has been sent " +msgstr "Information wurde teilweise gesendet" -#: app/controllers/request_game_controller.rb:42 -msgid "Play the request categorisation game" -msgstr "Helfen Sie uns ausstehende Anfragen zuzuordnen" +#: app/views/comment/new.rhtml:36 +msgid "<strong>Thank</strong> the public authority or " +msgstr "<strong>Danken Sie</strong> der Behörde oder " -#: app/controllers/request_game_controller.rb:52 -msgid "Thank you for helping us keep the site tidy!" -msgstr "vielen Dank für die Ihre Mithilfe die Seite aktuell zu halten. " +#: app/views/request/show.rhtml:91 +msgid "<strong>did not have</strong> the information requested." +msgstr "Die angefragten Informationen waren <strong>nicht vorhanden</strong>." -#: app/controllers/services_controller.rb:21 +#: app/views/comment/new.rhtml:46 msgid "" -"Hello! You can make Freedom of Information requests within {{country_name}} " -"at {{link_to_website}}" +"A <strong>summary</strong> of the response if you have received it by post. " msgstr "" -"Hallo! IFG-Anfragen innerhalb von {{country_name}} können Sie hier stellen: " -"{{link_to_website}} " - -#: app/controllers/track_controller.rb:98 -msgid "You are already being emailed updates about " -msgstr "Sie erhielten bereits Aktualisierungen zu" - -#: app/controllers/track_controller.rb:111 -msgid "You will now be emailed updates about " -msgstr "Sie erhalten nun Email-Aktualisierungen über" - -#: app/controllers/track_controller.rb:143 -msgid "To cancel this alert" -msgstr "Um diese Benachrichtigung zu löschen" +"Eine <strong>Zusammenfassung</strong> of the response if you have received " +"it by post. " -#: app/controllers/track_controller.rb:144 -msgid "Then you can cancel the alert." -msgstr "Dann können Sie die Statusnachricht abmelden " +#: app/models/info_request.rb:290 +msgid "A Freedom of Information request" +msgstr "" -#: app/controllers/track_controller.rb:145 -msgid "Cancel a {{site_name}} alert" -msgstr "Benachrichtigung für {{site_name}} abbestellen" +#: app/views/general/_advanced_search_tips.rhtml:46 +msgid "A public authority" +msgstr "Eine Behörde" -#: app/controllers/track_controller.rb:154 -msgid "You will no longer be emailed updates about " -msgstr "Sie erhalten keinen weiteren Aktualisierungen über" +#: app/views/request/_other_describe_state.rhtml:34 +msgid "A response will be sent <strong>by post</strong>" +msgstr "Antwort wird <strong>postalisch</strong> zugestellt" -#: app/controllers/track_controller.rb:173 -msgid "To cancel these alerts" -msgstr "Um diese Benachrichtigungen zu löschen" +#: app/views/general/_advanced_search_tips.rhtml:35 +msgid "A strange reponse, required attention by the {{site_name}} team" +msgstr "" +"Eine merkwürdige Antwort benötigte die Aufmerksamkeit des {{site_name}} " +"Teams" -#: app/controllers/track_controller.rb:174 -msgid "Then you can cancel the alerts." -msgstr "Dann können Sie die Statusnachrichten abmelden" +#: app/views/general/_advanced_search_tips.rhtml:47 +msgid "A {{site_name}} user" +msgstr "Ein/Eine {{site_name}} Benutzer/in" -#: app/controllers/track_controller.rb:175 -msgid "Cancel some {{site_name}} alerts" -msgstr "Einige Benachrichtigungen für {{site_name}} abbestellen" +#: app/views/user/set_profile_about_me.rhtml:20 +msgid "About you:" +msgstr "Zu Ihrer Person:" -#: app/controllers/track_controller.rb:183 -msgid "You will no longer be emailed updates for those alerts" -msgstr "Sie werden keine weiteren Aktualisierungen zu diesen Alerts erhalten" +#: app/views/request/_sidebar.rhtml:8 +msgid "Act on what you've learnt" +msgstr "Handel aus Deinen Erfahrungen" -#: app/controllers/user_controller.rb:43 -msgid "{{search_results}} matching '{{query}}'" -msgstr "{{search_results}} passen zu '{{query}}'" +#: app/views/comment/new.rhtml:14 +msgid "Add an annotation" +msgstr "Fügen Sie einee Anmerkung bei" -#: app/controllers/user_controller.rb:207 +#: app/views/request/show_response.rhtml:45 msgid "" -"That doesn't look like a valid email address. Please check you have typed it" -" correctly." +"Add an annotation to your request with choice quotes, or\n" +" a <strong>summary of the response</strong>." msgstr "" -"Dies sieht nicht nach einer gültigen Emailadresse aus. Bitte überprüfen Sie " -"Ihre Eingabe. " - -#: app/controllers/user_controller.rb:221 -msgid "Then you can change your password on {{site_name}}" -msgstr "Dann können Sie Ihr Passwort unter {{site_name}} ändern" +"Fügen Sie Ihrer Anfrage einen Kommentar mit Wahlzitat oder, " +"eine<strong>Zusammenfassung Ihrer Antwort</strong>hinzu. " -#: app/controllers/user_controller.rb:222 -msgid "Change your password {{site_name}}" -msgstr "Passwort ändern{{site_name}}" +#: app/views/public_body/_body_listing_single.rhtml:27 +msgid "Added on {{date}}" +msgstr "Hinzugefügt am {{date}}" -#: app/controllers/user_controller.rb:249 -msgid "Your password has been changed." -msgstr "Ihr Passwort wurde geändert." +#: app/models/user.rb:56 +msgid "Admin level is not included in list" +msgstr "Administrative Ebene ist in Liste nicht enthalten" -#: app/controllers/user_controller.rb:266 -msgid "To change your email address used on {{site_name}}" -msgstr "Um Ihre auf {{site_name}} verwendete Email-Adresse zu ändern" +#: app/views/request_mailer/requires_admin.rhtml:9 +msgid "Administration URL:" +msgstr "Administrator URL" -#: app/controllers/user_controller.rb:267 -msgid "Then you can change your email address used on {{site_name}}" -msgstr "können Sie Ihre auf {{site_name}} verwendete Email-Adresse beenden" +#: app/views/general/search.rhtml:46 +msgid "Advanced search" +msgstr "Erweiterte Suche" -#: app/controllers/user_controller.rb:268 -#: app/views/user/signchangeemail.rhtml:1 -#: app/views/user/signchangeemail.rhtml:11 -msgid "Change your email address used on {{site_name}}" -msgstr "Ändern Sie die unter {{site_name}} genutzte Email-Adresse" +#: app/views/general/_advanced_search_tips.rhtml:3 +msgid "Advanced search tips" +msgstr "Tipps zur erweiterten Suchanfrage" -#: app/controllers/user_controller.rb:328 -msgid "You have now changed your email address used on {{site_name}}" +#: app/views/comment/new.rhtml:53 +msgid "" +"Advise on whether the <strong>refusal is legal</strong>, and how to complain" +" about it if not." msgstr "" -"Sie haben die aud der Seite {{site_name}} verwendete Email-Adresse nun " -"geändert" - -#: app/controllers/user_controller.rb:347 -msgid "To send a message to " -msgstr "Um eine Nachricht zu senden an " - -#: app/controllers/user_controller.rb:348 -msgid "Then you can send a message to " -msgstr "Dann können Sie eine Nachricht senden an" - -#: app/controllers/user_controller.rb:349 -msgid "Send a message to " -msgstr "Nachricht senden an" - -#: app/controllers/user_controller.rb:367 -msgid "Your message to {{recipient_user_name}} has been sent!" -msgstr "Ihre Nachricht an {{recipient_user_name}} wurde versendet!" +"Beratung zur <strong>Rechtsgültigkeit der Ablehnung</strong> und wie Sie " +"dagene angehen können." -#: app/controllers/user_controller.rb:373 +#: app/views/request/new.rhtml:67 msgid "" -",\n" -"\n" -"\n" -"\n" -"Yours,\n" -"\n" -"{{user_name}}" +"Air, water, soil, land, flora and fauna (including how these effect\n" +" human beings)" msgstr "" -",\n" -"\n" -"\n" -"\n" -"Mit freundlichem Gruß,\n" -"\n" -"{{user_name}}" - -#: app/controllers/user_controller.rb:389 -msgid "You need to be logged in to change your profile photo." -msgstr "Sie müssen angemeldet sein, um Ihren Profilbild zu ändern. " +"Luft, Wasser, Erde, Land, Flora und Fauna (einschliesslich deren Einfluss " +"auf den Menschen)" -#: app/controllers/user_controller.rb:416 -#: app/controllers/user_controller.rb:432 -msgid "Thank you for updating your profile photo" -msgstr "Vielen Dank für die Aktualisierung Ihres Profilbildes" +#: app/views/general/_advanced_search_tips.rhtml:30 +msgid "All of the information requested has been received" +msgstr "Die angefragten Informationen wurden vollständig empfangen" -#: app/controllers/user_controller.rb:435 +#: app/views/general/_advanced_search_tips.rhtml:23 msgid "" -"<p>Thanks for updating your profile photo.</p>\n" -" <p><strong>Next...</strong> You can put some text about you and your research on your profile.</p>" +"All the options below can use <strong>status</strong> or " +"<strong>latest_status</strong> before the colon. For example, " +"<strong>status:not_held</strong> will match requests which have " +"<em>ever</em> been marked as not held; " +"<strong>latest_status:not_held</strong> will match only requests that are " +"<em>currently</em> marked as not held." msgstr "" -"<p>Danke für die Aktualisierung Ihres Profilbildes.</p>\n" -" <p><strong>Nächster Schritt...</strong> Sie können Informationen zu Ihrer Person und Ihrer Suchanfrage zu Ihrem Profil hinzufügen.</p>" -#: app/controllers/user_controller.rb:451 -msgid "You need to be logged in to clear your profile photo." -msgstr "Sie müssen angemeldet sein, um Ihren Profilbild zu löschen." - -#: app/controllers/user_controller.rb:460 -msgid "You've now cleared your profile photo" -msgstr "Sie haben Ihr Profilbild nun gelöscht" +#: app/views/general/_advanced_search_tips.rhtml:40 +msgid "" +"All the options below can use <strong>variety</strong> or " +"<strong>latest_variety</strong> before the colon. For example, " +"<strong>variety:sent</strong> will match requests which have <em>ever</em> " +"been sent; <strong>latest_variety:sent</strong> will match only requests " +"that are <em>currently</em> marked as sent." +msgstr "" -#: app/controllers/user_controller.rb:488 -msgid "You need to be logged in to change the text about you on your profile." -msgstr "Sie müssen angemeldet sein, um Ihren Profiltext zu ändern. " +#: app/views/public_body/_body_listing_single.rhtml:12 +msgid "Also called {{other_name}}." +msgstr "Auch {{other_name}} genannt." -#: app/controllers/user_controller.rb:510 -msgid "You have now changed the text about you on your profile." -msgstr "Sie haben den Text zu Ihrer Person in Ihrem Profil nun geändert. " +#: app/views/track_mailer/event_digest.rhtml:60 +msgid "Alter your subscription" +msgstr "Ändern Sie Ihre Registrierung" -#: app/controllers/user_controller.rb:513 +#: app/views/request_mailer/new_response.rhtml:12 msgid "" -"<p>Thanks for changing the text about you on your profile.</p>\n" -" <p><strong>Next...</strong> You can upload a profile photograph too.</p>" +"Although all responses are automatically published, we depend on\n" +"you, the original requester, to evaluate them." msgstr "" -"<p>Vielen Dank für die Änderung Ihres Profiltextes.</p>\n" -" <p><strong>Weiter...</strong> Sie können auch ein Profilbild hochladen.</p>" - -#: app/controllers/user_controller.rb:541 -msgid "Then you can sign in to {{site_name}}" -msgstr "Dann können Sie sich auf {{site_name}} einloggen. " - -#: app/models/about_me_validator.rb:24 -msgid "Please keep it shorter than 500 characters" -msgstr "Bitte bleiben Sie unter 500 Zeichen" +"Obwould alle Antworten automatisch veröffentlicht werden, sind wir auf Sie " +"als ursprünglichen Antragsteller angewiesen, um diese zu bewerten" -#: app/models/change_email_validator.rb:29 -msgid "Please enter your old email address" -msgstr "Bitte geben Sie Ihre alte E-Mail-Adresse ein" +#: app/views/request/_other_describe_state.rhtml:70 +msgid "An <strong>error message</strong> has been received" +msgstr "Eine <strong>Fehlermeldung</strong> wurde empfangen" -#: app/models/change_email_validator.rb:30 -msgid "Please enter your new email address" -msgstr "Bitte geben Sie Ihre neue Email-Adresse ein" +#: app/models/info_request.rb:292 +msgid "An Environmental Information Regulations request" +msgstr "" -#: app/models/change_email_validator.rb:31 -msgid "Please enter your password" -msgstr "Bitte geben Sie Ihr Passwort ein" +#: app/views/general/_advanced_search_tips.rhtml:45 +msgid "Annotation added to request" +msgstr "Anfrage wurde kommentiert" -#: app/models/change_email_validator.rb:39 -msgid "Old email doesn't look like a valid address" -msgstr "Alte Email sieht nicht nach gültiger Adresse aus" +#: app/views/user/show.rhtml:34 +msgid "Annotations" +msgstr "Kommentare" -#: app/models/change_email_validator.rb:44 +#: app/views/comment/new.rhtml:18 msgid "" -"Old email address isn't the same as the address of the account you are " -"logged in with" +"Annotations are so anyone, including you, can help the requester with their " +"request. For example:" msgstr "" -"Die alte Email-Adresse stimmt nicht mit der Adresse des Kontos, über welches" -" Sie eingeloggt sind überein" - -#: app/models/change_email_validator.rb:47 -msgid "Password is not correct" -msgstr "falsches Passwort" +"Anmerkungen helfen Ihnen, sowie weiteren Benutzern bei der Erstellungen " +"einer neuer Anfrage. Zum Beispiel:" -#: app/models/change_email_validator.rb:53 -msgid "New email doesn't look like a valid address" -msgstr "Die neue Email-Adresse scheint ungültig" +#: app/views/comment/new.rhtml:70 +msgid "" +"Annotations will be posted publicly here, and are \n" +" <strong>not</strong> sent to {{public_body_name}}." +msgstr "" +"Anmerkungen werden hier veröffentlicht, und werden \n" +" <strong>nicht</strong> an {{public_body_name}} gesendet." -#: app/models/comment.rb:59 -msgid "Please enter your annotation" -msgstr "Bitte geben Sie Ihre Anmerkung ein" +#: app/views/request/_after_actions.rhtml:6 +msgid "Anyone:" +msgstr "Jedermann:" -#: app/models/comment.rb:62 +#: app/views/request/new.rhtml:105 msgid "" -"Please write your annotation using a mixture of capital and lower case " -"letters. This makes it easier for others to read." +"Ask for <strong>specific</strong> documents or information, this site is not" +" suitable for general enquiries." msgstr "" -"Bitte nutzen Sie eine Mischung aus Groß- und Kleinschreibung für Ihre " -"Anmerkung. Dies vereinfacht das Lesen für andere." - -#: app/models/contact_validator.rb:28 app/models/user.rb:38 -msgid "Please enter your name" -msgstr "Bitte geben Sie Ihren Namen ein" +"Fragen Sie nach <strong>spezifischen</strong> Dokumenten oder Informationen." +" Diese Seite ist nicht für generelle Anfragen vorgesehen. " -#: app/models/contact_validator.rb:29 app/models/user.rb:36 -msgid "Please enter your email address" -msgstr "Bitte geben Sie Ihre E-Mail Adresse ein" +#: app/views/request/show_response.rhtml:29 +msgid "" +"At the bottom of this page, write a reply to them trying to persuade them to scan it in\n" +" (<a href=\"%s\">more details</a>)." +msgstr "" +"Am Ende der Seite können Sie eine Antwort mit der Aufforderung das Dokument einzuscannen senden\n" +" (<a href=\"%s\">weitere Details</a>)." -#: app/models/contact_validator.rb:30 -msgid "Please enter a subject" -msgstr "Bitte geben Sie einen Betreff ein" +#: app/views/request/upload_response.rhtml:33 +msgid "Attachment (optional):" +msgstr "Anhang (freiwillig)" -#: app/models/contact_validator.rb:31 -msgid "Please enter the message you want to send" -msgstr "Bitte geben Sie die Nachricht ein, die Sie senden wollen" +#: app/views/request/simple_correspondence.rhtml:21 +msgid "Attachment:" +msgstr "Anhang:" -#: app/models/contact_validator.rb:34 -msgid "Email doesn't look like a valid address" -msgstr "Dies sieht nicht nach einer gültigen Email-Adresse aus" +#: app/models/info_request.rb:785 +msgid "Awaiting classification." +msgstr "Zuordnung wird erwartet. " -#: app/models/incoming_message.rb:867 -msgid "" -"\n" -"\n" -"[ {{site_name}} note: The above text was badly encoded, and has had strange characters removed. ]" -msgstr "" -"\n" -"\n" -"[ {{site_name}} Anmerkung: Der obenstehende Text war schlecht kodiert und merkwürdige Zeichen wurden entfernt. ]" +#: app/models/info_request.rb:805 +msgid "Awaiting internal review." +msgstr "Interne Prüfung ausstehend." -#: app/models/info_request.rb:34 -msgid "Please enter a summary of your request" -msgstr "Bitte geben Sie eine Zusammenfassung Ihrer Anfrage ein" +#: app/models/info_request.rb:787 +msgid "Awaiting response." +msgstr "Antwort ausstehend. " -#: app/models/info_request.rb:35 -msgid "Please write a summary with some text in it" -msgstr "Bitte schreiben Sie eine Zusammenfassung mit etwas Text" +#: app/views/public_body/list.rhtml:4 +msgid "Beginning with" +msgstr "Mit Anfangsbuchstabe" -#: app/models/info_request.rb:120 +#: app/views/request/new.rhtml:46 msgid "" -"Please write the summary using a mixture of capital and lower case letters. " -"This makes it easier for others to read." +"Browse <a href='{{url}}'>other requests</a> for examples of how to word your" +" request." msgstr "" -"Bitte nutzen Sie eine Mischung aus Groß- und Kleinschreibung für die " -"Zusammenfassung. Dies vereinfacht das Lesen für andere." +"Durchsuchen Sie <a href='{{url}}'>andere Anfragen</a>für " +"Formulierungsbeispiele für Ihre Anfrage." -#: app/models/info_request.rb:123 +#: app/views/request/new.rhtml:44 msgid "" -"Please keep the summary short, like in the subject of an email. You can use " -"a phrase, rather than a full sentence." +"Browse <a href='{{url}}'>other requests</a> to '{{public_body_name}}' for " +"examples of how to word your request." msgstr "" -"Bitte halten Sie die Zusammenfassung kurz, wie in der Betreffzeile einer " -"E-Mail. Sie können eine Phrase, sondern als ein ganzer Satz." +"Schauen Sie <a href='{{url}}'>andere Anfragen</a> an '{{public_body_name}}' " +"für Formulierungsbeispiele an. " -#: app/models/info_request.rb:126 -msgid "" -"Please describe more what the request is about in the subject. There is no " -"need to say it is an FOI request, we add that on anyway." -msgstr "" -"Bitte beschreiben Sie im Betreff, um was es in der Anfrage geht. Sie " -"brauchen nicht sagen, dass es eine IFG-Anfrage ist, dies wird automatisch " -"hinzugefügt." +#: app/views/general/frontpage.rhtml:48 +msgid "Browse all authorities..." +msgstr "Durchsuchen Sie alle Behörden" -#: app/models/info_request.rb:395 +#: app/views/request/show.rhtml:86 msgid "" -"This request has been set by an administrator to \"allow new responses from " -"nobody\"" +"By law, under all circumstances, {{public_body_link}} should have responded " +"by now" msgstr "" +"Nach gesetzlicher Vorschrift sollte {{public_body_link}} Ihnen inzwischen " +"unter allen Umständen geantwortet haben. " -#: app/models/info_request.rb:401 +#: app/views/request/show.rhtml:78 msgid "" -"Only the authority can reply to this request, but there is no \"From\" " -"address to check against" +"By law, {{public_body_link}} should normally have responded " +"<strong>promptly</strong> and" msgstr "" -"Diese Anfrage kann ausschliesslich von der Behörde beantwortet werden, " -"jedoch besteht keine ´von´ Adresse zum Vergleich. " +"Nach gesetzlicher Vorschrift sollte {{public_body_link}} " +"<strong>umgehend</strong> geantwortet haben und" -#: app/models/info_request.rb:405 -msgid "" -"Only the authority can reply to this request, and I don't recognise the " -"address this reply was sent from" -msgstr "" -"Die Beantwortung dieser Anfrage ist ausschliesslich der Behörde gewährt und " -"die Adresse dieser Antwort ist mir nicht bekannt. " +#: app/controllers/track_controller.rb:145 +msgid "Cancel a {{site_name}} alert" +msgstr "Benachrichtigung für {{site_name}} abbestellen" -#: app/models/info_request.rb:785 -msgid "Awaiting classification." -msgstr "Zuordnung wird erwartet. " +#: app/controllers/track_controller.rb:175 +msgid "Cancel some {{site_name}} alerts" +msgstr "Einige Benachrichtigungen für {{site_name}} abbestellen" -#: app/models/info_request.rb:787 -msgid "Awaiting response." -msgstr "Antwort ausstehend. " +#: app/views/user/set_draft_profile_photo.rhtml:55 +msgid "Cancel, return to your profile page" +msgstr "Abbrechen, zurück zur Profilseite" -#: app/models/info_request.rb:789 -msgid "Delayed." -msgstr "Verzögert." +#: locale/model_attributes.rb:39 +msgid "CensorRule|Last edit comment" +msgstr "CensorRule|Last edit comment" -#: app/models/info_request.rb:791 -msgid "Long overdue." -msgstr "Stark verspätet." +#: locale/model_attributes.rb:38 +msgid "CensorRule|Last edit editor" +msgstr "CensorRule|Last edit editor" -#: app/models/info_request.rb:793 -msgid "Information not held." -msgstr "Information nicht verfügbr" +#: locale/model_attributes.rb:37 +msgid "CensorRule|Replacement" +msgstr "CensorRule|Replacement" -#: app/models/info_request.rb:795 -msgid "Refused." -msgstr "Abgelehnt." +#: locale/model_attributes.rb:36 +msgid "CensorRule|Text" +msgstr "CensorRule|Text" -#: app/models/info_request.rb:797 -msgid "Partially successful." -msgstr "Teilweise erfolgreich. " +#: app/views/user/signchangeemail.rhtml:37 +msgid "Change email on {{site_name}}" +msgstr "Email ändern auf {{site_name}}" -#: app/models/info_request.rb:799 -msgid "Successful." -msgstr "Erfolgreich." +#: app/views/user/signchangepassword.rhtml:27 +msgid "Change password on {{site_name}}" +msgstr "Passwort ändern: {{site_name}}" -#: app/models/info_request.rb:801 -msgid "Waiting clarification." -msgstr "Klärung wird erwartet. " +#: app/views/user/show.rhtml:104 app/views/user/set_crop_profile_photo.rhtml:1 +msgid "Change profile photo" +msgstr "Profilbild ändern" -#: app/models/info_request.rb:803 -msgid "Handled by post." -msgstr "Postalisch bearbeitet." +#: app/views/user/set_profile_about_me.rhtml:1 +msgid "Change the text about you on your profile at {{site_name}}" +msgstr "" +"Ändern Sie den Text zu Ihrer Person in Ihrem Nutzerprofil auf {{site_name}}" -#: app/models/info_request.rb:805 -msgid "Awaiting internal review." -msgstr "Interne Prüfung ausstehend." +#: app/views/user/show.rhtml:107 +msgid "Change your email" +msgstr "Emailadresse ändern" -#: app/models/info_request.rb:807 -msgid "Delivery error" -msgstr "Übertragungsfehler" +#: app/controllers/user_controller.rb:268 +#: app/views/user/signchangeemail.rhtml:1 +#: app/views/user/signchangeemail.rhtml:11 +msgid "Change your email address used on {{site_name}}" +msgstr "Ändern Sie die unter {{site_name}} genutzte Email-Adresse" -#: app/models/info_request.rb:809 -msgid "Unusual response." -msgstr "Ungewöhnliche Antwort." +#: app/views/user/show.rhtml:106 +msgid "Change your password" +msgstr "Passwort ändern" -#: app/models/info_request.rb:811 -msgid "Withdrawn by the requester." -msgstr "Vom Antragsteller zurückgezogen" +#: app/views/user/signchangepassword_send_confirm.rhtml:1 +#: app/views/user/signchangepassword_send_confirm.rhtml:9 +#: app/views/user/signchangepassword.rhtml:1 +#: app/views/user/signchangepassword.rhtml:11 +msgid "Change your password on {{site_name}}" +msgstr "Ändern Sie Ihr Passwort: {{site_name}}" -#: app/models/info_request.rb:816 app/models/info_request_event.rb:318 -msgid "unknown status " -msgstr "unbekannter Status" +#: app/controllers/user_controller.rb:222 +msgid "Change your password {{site_name}}" +msgstr "Passwort ändern{{site_name}}" -#: app/models/info_request_event.rb:306 -msgid "Response" -msgstr "Antwort" +#: app/views/public_body/show.rhtml:28 app/views/public_body/show.rhtml:30 +msgid "Charity registration" +msgstr "Charity Registrierung" -#: app/models/info_request_event.rb:313 -msgid "Internal review request" -msgstr "Anfrage zur internen Prüfung" +#: app/views/general/exception_caught.rhtml:8 +msgid "Check for mistakes if you typed or copied the address." +msgstr "" +"Sollten Sie die Adresse eingegeben oder kopiert haben, überprüfen Sie diese " +"auf Fehler." + +#: app/views/request/preview.rhtml:7 +#: app/views/request/followup_preview.rhtml:14 +msgid "Check you haven't included any <strong>personal information</strong>." +msgstr "" +"Stellen Sie sicher, dass Sie keine <strong> persönlichen Informationen " +"</strong> verwendet haben." + +#: lib/world_foi_websites.rb:29 +msgid "Chile" +msgstr "Chile" + +#: app/views/user/set_draft_profile_photo.rhtml:5 +msgid "Choose your profile photo" +msgstr "Wählen Sie Ihr Profilbild" #: app/models/info_request_event.rb:316 msgid "Clarification" msgstr "Klärung" -#: app/models/info_request_event.rb:320 -msgid "Follow up" -msgstr "Follow-up" +#: app/controllers/request_controller.rb:345 +msgid "Classify an FOI response from " +msgstr "Klassifizieren Sie eine IFG-Anfrage von" -#: app/models/info_request_event.rb:323 -msgid "display_status only works for incoming and outgoing messages right now" +#: app/views/request_mailer/very_overdue_alert.rhtml:6 +msgid "" +"Click on the link below to send a message to {{public_body_name}} telling them to reply to your request. You might like to ask for an internal\n" +"review, asking them to find out why response to the request has been so slow." msgstr "" -"Anzeigestatus funktioniert momentan nur für ein- und ausgehende Nachrichten" - -#: app/models/outgoing_message.rb:63 -msgid "Dear {{public_body_name}}," -msgstr "Sehr geehrte / Sehr geehrter {{public_body_name}}," +"Klickeb Suin Sie auf den unten aufgeführten Link, um eine Nachricht an " +"{{public_body_name}} zu senden. Sie möchten eventuell eine interne Prüfung " +"anfragen, um zu fragen warum die Beantwortung der Anfrage so lange dauert." -#: app/models/outgoing_message.rb:68 -msgid "Yours sincerely," -msgstr "Mit freundlichem Gruß, " +#: app/views/request_mailer/overdue_alert.rhtml:5 +msgid "" +"Click on the link below to send a message to {{public_body}} reminding them " +"to reply to your request." +msgstr "" +"Klicken Sie auf den unten aufgeführten Link an {{public_body}}, um eine " +"Anfrageerinnerung zu versenden." -#: app/models/outgoing_message.rb:70 -msgid "Yours faithfully," -msgstr "Mit freundlichem Gruß, " +#: locale/model_attributes.rb:22 +msgid "Comment|Body" +msgstr "Comment|Body" -#: app/models/outgoing_message.rb:74 -msgid "GIVE DETAILS ABOUT YOUR COMPLAINT HERE" -msgstr "HINTELASSEN SIE HIER DETAILS ZU IHRER BESCHWERDE" +#: locale/model_attributes.rb:21 +msgid "Comment|Comment type" +msgstr "Comment|Comment type" -#: app/models/outgoing_message.rb:146 -msgid "Please give details explaining why you want a review" -msgstr "Bitte machen Sie Angaben, warum Sie eine Durchsicht möchten" +#: locale/model_attributes.rb:24 +msgid "Comment|Locale" +msgstr "Comment|Locale" -#: app/models/outgoing_message.rb:148 -msgid "Please enter your follow up message" -msgstr "Bitte geben Sie Ihre Follow-Up-Nachricht ein" +#: locale/model_attributes.rb:23 +msgid "Comment|Visible" +msgstr "Comment|Visible" -#: app/models/outgoing_message.rb:151 -msgid "Please enter your letter requesting information" -msgstr "Bitte geben Sie Ihre Briefanfrage-Informationen ein" +#: app/models/track_thing.rb:220 +msgid "Confirm you want to be emailed about new requests" +msgstr "" +"Bitte bestätigen Sie, dass Sie über neue Anfragen informiert werden möchten" -#: app/models/outgoing_message.rb:157 +#: app/models/track_thing.rb:287 msgid "" -"Please sign at the bottom with your name, or alter the \"%{signoff}\" " -"signature" +"Confirm you want to be emailed about new requests or responses matching your" +" search" msgstr "" -"Bitte unterschreiben Sie unten mit Ihrem Namen oder ändern Sie Ihre \"% " -"{signoff}\" Signatur" +"Bestätigen Sie, dass Sie zu Ihrer Suche passende Anfragen und Antworten per " +"Email erhalten möchten" -#: app/models/outgoing_message.rb:160 +#: app/models/track_thing.rb:271 +msgid "Confirm you want to be emailed about requests by '{{user_name}}'" +msgstr "" +"Bitte bestätigen Sie, dass Sie über neue Anfragen von '{{user_name}}' " +"informiert werden möchten" + +#: app/models/track_thing.rb:255 msgid "" -"Please write your message using a mixture of capital and lower case letters." -" This makes it easier for others to read." +"Confirm you want to be emailed about requests to '{{public_body_name}}'" msgstr "" -"Bitte nutzen Sie eine Mischung aus Groß- und Kleinschreibung für Ihre " -"Nachricht. Dies vereinfacht das Lesen für andere." +"Bitte bestätigen Sie, dass Sie über neue Anfragen an '{{public_body_name}}' " +"informiert werden möchten" -#: app/models/outgoing_message.rb:163 -msgid "Please choose what sort of reply you are making." -msgstr "Bitte wählen Sie, welche Art von Antwort Sie geben." +#: app/models/track_thing.rb:236 +msgid "Confirm you want to be emailed when an FOI request succeeds" +msgstr "" +"Bestätigen Sie, dass Sie bei erfolgreicher IFG-Anfrage eine Emailbestätigung" +" erhalten möchten" -#: app/models/profile_photo.rb:91 -msgid "Please choose a file containing your photo." -msgstr "Bitte wählen Sie eine Datei mit Ihrem Foto." +#: app/models/track_thing.rb:204 +msgid "Confirm you want to follow updates to the request '{{request_title}}'" +msgstr "" +"Bestätigen Sie, dass Sie Aktualsierungen der folgenden Anfrage erhalten " +"möchten: '{{request_title}}'" + +#: app/controllers/request_controller.rb:305 +msgid "Confirm your FOI request to " +msgstr "Bestätigen Sie Ihre IFG-Anfrage " + +#: app/controllers/request_controller.rb:714 +#: app/controllers/user_controller.rb:542 +msgid "Confirm your account on {{site_name}}" +msgstr "Bestätigen Sie Ihr Nutzerkonto auf {{site_name}}" + +#: app/controllers/comment_controller.rb:57 +msgid "Confirm your annotation to {{info_request_title}}" +msgstr "Bestätigen Sie Ihre Anmerkung zu {{info_request_title}}" + +#: app/controllers/request_controller.rb:33 +msgid "Confirm your email address" +msgstr "Bestätigen Sie Ihre Email-Adresse" + +#: app/models/user_mailer.rb:34 +msgid "Confirm your new email address on {{site_name}}" +msgstr "Confirm your new email address on {{site_name}}" + +#: app/views/general/_footer.rhtml:2 +msgid "Contact {{site_name}}" +msgstr "Kontaktieren Sie {{site_name}}" + +#: app/models/request_mailer.rb:218 +msgid "Could not identify the request from the email address" +msgstr "Die Email-Adresse der Anfragen konnte nicht identifiziert werden" #: app/models/profile_photo.rb:96 msgid "" @@ -897,890 +1103,872 @@ msgstr "" "Konnte die hochgeladene Bilddatei nicht verarbeiten. PNG, JPEG, GIF und " "viele andere gängige Bildformate werden unterstützt." -#: app/models/profile_photo.rb:101 -msgid "Failed to convert image to a PNG" -msgstr "Konnte Bild nicht in ein PNG konvertieren" +#: app/views/user/set_crop_profile_photo.rhtml:6 +msgid "Crop your profile photo" +msgstr "Bearbeiten Sie Ihr Profilbild" -#: app/models/profile_photo.rb:105 +#: app/views/request/new.rhtml:72 msgid "" -"Failed to convert image to the correct size: at %{cols}x%{rows}, need " -"%{width}x%{height}" +"Cultural sites and built structures (as they may be affected by the\n" +" environmental factors listed above)" msgstr "" -"Konnte Bild nicht in die richtige Größe umwandeln: %{cols} x %{rows}, " -"brauche %{width} x %{height}" - -#: app/models/public_body.rb:36 -msgid "Name can't be blank" -msgstr "Name muss eingegeben werden " - -#: app/models/public_body.rb:37 -msgid "URL name can't be blank" -msgstr "URL muss angegeben werden" - -#: app/models/public_body.rb:39 -msgid "Short name is already taken" -msgstr "Nutzername bereits vergeben " - -#: app/models/public_body.rb:40 -msgid "Name is already taken" -msgstr "Benutzername vergeben" +"Kulturelle Seiten und erstellte Strukturen (da diese durch die oben " +"gelisteten Umweltfaktoren beeinträchtigt sein könnten)" -#: app/models/request_mailer.rb:218 -msgid "Could not identify the request from the email address" -msgstr "Die Email-Adresse der Anfragen konnte nicht identifiziert werden" +#: app/views/request/show.rhtml:68 +msgid "" +"Currently <strong>waiting for a response</strong> from {{public_body_link}}," +" they must respond promptly and" +msgstr "" +"<strong>Antwort</strong> von {{public_body_link}} wird erwartet. Sie sollten" +" in Kürze eine Antwort erhalten und" -#: app/models/track_mailer.rb:25 -msgid "Your {{site_name}} email alert" -msgstr "Ihr {{site_name}} Email Alarm" +#: app/views/request/simple_correspondence.rhtml:17 +#: app/views/request/simple_correspondence.rhtml:29 +#: app/views/request/simple_correspondence.rhtml:36 +msgid "Date:" +msgstr "Datum:" -#: app/models/track_thing.rb:83 app/views/general/search.rhtml:54 -msgid "users" -msgstr "Nutzer" +#: app/models/outgoing_message.rb:63 +msgid "Dear {{public_body_name}}," +msgstr "Sehr geehrte / Sehr geehrter {{public_body_name}}," -#: app/models/track_thing.rb:86 app/views/general/search.rhtml:103 -#: app/views/request/_request_filter_form.rhtml:14 -msgid "comments" -msgstr "Anmerkungen" +#: app/models/request_mailer.rb:86 +msgid "Delayed response to your FOI request - " +msgstr "" -#: app/models/track_thing.rb:89 app/views/general/search.rhtml:55 -msgid "authorities" -msgstr "Behörden" +#: app/models/info_request.rb:789 +msgid "Delayed." +msgstr "Verzögert." -#: app/models/track_thing.rb:92 app/models/track_thing.rb:111 -#: app/models/track_thing.rb:113 app/views/general/search.rhtml:53 -msgid "requests" -msgstr "Anfragen" +#: app/models/info_request.rb:807 +msgid "Delivery error" +msgstr "Übertragungsfehler" -#: app/models/track_thing.rb:95 -msgid "between two dates" -msgstr "zwischen zwei Datum" +#: app/views/request/details.rhtml:1 app/views/request/details.rhtml:2 +msgid "Details of request '" +msgstr "Anfragedetails" -#: app/models/track_thing.rb:98 -msgid "unsuccessful" -msgstr "nicht erfolgreich" +#: app/views/general/search.rhtml:171 +msgid "Did you mean: {{correction}}" +msgstr "Meinten Sie: {{correction}}" -#: app/models/track_thing.rb:101 -msgid "successful" -msgstr "erfolgreich" +#: app/views/outgoing_mailer/_followup_footer.rhtml:1 +msgid "" +"Disclaimer: This message and any reply that you make will be published on " +"the internet. Our privacy and copyright policies:" +msgstr "" +"Haftungsausschluss: Diese Nachricht und alle Antworten werden im Internet veröffentlicht. \t\n" +"Nutzungsbedingungen und Datenschutz:" -#: app/models/track_thing.rb:104 -msgid "awaiting a response" -msgstr "eine Antwort erwartend" +#: app/views/request/_followup.rhtml:19 +msgid "" +"Don't want to address your message to {{person_or_body}}? You can also " +"write to:" +msgstr "" +"Möchten Sie Ihre Nachricht nicht an {{person_or_body}} senden? Schreiben " +"Sie alternativ an:" -#: app/models/track_thing.rb:112 -msgid "requests which are {{list_of_statuses}}" -msgstr "Anfragen mit dem Status {{list_of_statuses}} " +#: app/views/general/_localised_datepicker.rhtml:4 +msgid "Done" +msgstr "Erledigt" -#: app/models/track_thing.rb:112 app/models/track_thing.rb:120 -msgid " or " -msgstr " oder " +#: app/views/request/_after_actions.rhtml:17 +msgid "Download a zip file of all correspondence" +msgstr "Laden Sie eine Zip-Datei des gesamten Schriftverkehrs herunter." -#: app/models/track_thing.rb:116 -msgid "anything" -msgstr "alles" +#: app/views/request/_view_html_prefix.rhtml:6 +msgid "Download original attachment" +msgstr "Originalanhang herunterladen" -#: app/models/track_thing.rb:122 -msgid "{{list_of_things}} matching text '{{search_query}}'" -msgstr "{{list_of_things}} passen zum Text '{{search_query}}'" +#: app/models/info_request.rb:274 +msgid "EIR" +msgstr "" -#: app/models/track_thing.rb:195 -msgid "'{{link_to_request}}', a request" -msgstr "'{{link_to_request}}', eine Anfrage" +#: app/views/request/_followup.rhtml:112 +msgid "" +"Edit and add <strong>more details</strong> to the message above,\n" +" explaining why you are dissatisfied with their response." +msgstr "" +"Bearbeiten Sie Ihre Anfrage und fügen Sie <strong>weitere Details</strong> hinzu,\n" +" explaining why you are dissatisfied with their response." -#: app/models/track_thing.rb:196 -msgid "Track this request by email" -msgstr "Diese Anfrage via Email verfolgen" +#: app/views/admin_public_body/_locale_selector.rhtml:2 +msgid "Edit language version:" +msgstr "Sprachauswahl ändern:" -#: app/models/track_thing.rb:197 -msgid "You are already tracking this request by email" -msgstr "Sie folgen dieser Anfrage bereits via Email" +#: app/views/user/set_profile_about_me.rhtml:9 +msgid "Edit text about you" +msgstr "Profiltext ändern" -#: app/models/track_thing.rb:199 app/models/track_thing.rb:200 -msgid "New updates for the request '{{request_title}}'" -msgstr "Neue Aktualisierungen der Anfrage '{{request_title}}'" +#: app/views/request/preview.rhtml:40 +msgid "Edit this request" +msgstr "Anfrage bearbeiten" -#: app/models/track_thing.rb:202 -msgid "To follow updates to the request '{{request_title}}'" -msgstr "Um Aktualisierungen der Anfrage '{{request_title}}' zu folgen" +#: app/models/user.rb:146 +msgid "Either the email or password was not recognised, please try again." +msgstr "" +"Passwort oder emailadresse wurde nicht erkannt. Bitte versuchen Sie es " +"erneut. " -#: app/models/track_thing.rb:203 +#: app/models/user.rb:148 msgid "" -"Then you will be emailed whenever the request '{{request_title}}' is " -"updated." +"Either the email or password was not recognised, please try again. Or create" +" a new account using the form on the right." msgstr "" -"Dann erhalten Sie jedesmal eine Email, wenn die Anfrage '{{request_title}}' " -"aktualisiert wird." +"Emailadresse oder Passwort ungültig. Bitte versuchen Sie es erneut oder " +"erstellen Sie ein neues Benutzerkonto mit dem Formular auf der rechten " +"Seite. " -#: app/models/track_thing.rb:204 -msgid "Confirm you want to follow updates to the request '{{request_title}}'" +#: app/models/contact_validator.rb:34 +msgid "Email doesn't look like a valid address" +msgstr "Dies sieht nicht nach einer gültigen Email-Adresse aus" + +#: app/views/comment/_comment_form.rhtml:8 +msgid "Email me future updates to this request" msgstr "" -"Bestätigen Sie, dass Sie Aktualsierungen der folgenden Anfrage erhalten " -"möchten: '{{request_title}}'" +"Informieren Sie mich über zukünftige Aktualisierungen zu dieser Anfrage" -#: app/models/track_thing.rb:211 -msgid "any <a href=\"/list\">new requests</a>" -msgstr "jegliche <a href=\"/list\">neue Anfragen</a>" +#: app/models/track_thing.rb:228 +msgid "Email me new successful responses " +msgstr "Neue erfolgreiche Anfragen per Email erhalten " #: app/models/track_thing.rb:212 msgid "Email me when there are new requests" msgstr "Informieren Sie mich per Email, wenn es neue Anfragen gibt" -#: app/models/track_thing.rb:213 -msgid "You are being emailed when there are new requests" -msgstr "Im Falle neuer Anfragen werden Sie per Email informiert werden" - -#: app/models/track_thing.rb:215 app/models/track_thing.rb:216 -msgid "New Freedom of Information requests" -msgstr "Neue IFG-Anfragen" +#: app/views/user/show.rhtml:36 +msgid "Email subscriptions" +msgstr "Email Abo" -#: app/models/track_thing.rb:218 -msgid "To be emailed about any new requests" -msgstr "Um Emails zu allen neuen Anfragen zu erhalten" +#: app/views/general/_advanced_search_tips.rhtml:5 +msgid "" +"Enter words that you want to find separated by spaces, e.g. <strong>climbing" +" lane</strong>" +msgstr "Trennen Sie Ihre Suchbegriffen durch Leerzeichen" -#: app/models/track_thing.rb:219 -msgid "Then you will be emailed whenever anyone makes a new FOI request." +#: app/views/request/upload_response.rhtml:23 +msgid "" +"Enter your response below. You may attach one file (use email, or \n" +"<a href=\"%s\">contact us</a> if you need more)." msgstr "" -"Sie werden dann per email informiert, sobald jemand eine neue IFG-Anfrage " -"stellt. " +"Geben Sie unten Ihre Antwort ein. Sie könne eine Datei anhängen (nutzen Sie Email, oder \n" +"<a href=\"%s\">kontaktieren Sie uns</a> falls Sie mehrere Anhänge benötigen)." -#: app/models/track_thing.rb:220 -msgid "Confirm you want to be emailed about new requests" +#: app/models/info_request.rb:265 app/models/info_request.rb:283 +msgid "Environmental Information Regulations" msgstr "" -"Bitte bestätigen Sie, dass Sie über neue Anfragen informiert werden möchten" -#: app/models/track_thing.rb:227 -msgid "any <a href=\"/list/successful\">successful requests</a>" -msgstr "jegliche <a href=\"/list/successful\">erfolgreiche Anfragen</a>" +#: app/views/public_body/show.rhtml:124 +msgid "Environmental Information Regulations requests made" +msgstr "" -#: app/models/track_thing.rb:228 -msgid "Email me new successful responses " -msgstr "Neue erfolgreiche Anfragen per Email erhalten " +#: app/views/public_body/show.rhtml:81 +msgid "Environmental Information Regulations requests made using this site" +msgstr "" -#: app/models/track_thing.rb:229 -msgid "You are being emailed about any new successful responses" -msgstr "Sie werden per Email über neue erfolgreiche Antworten informiert " +#: lib/world_foi_websites.rb:13 +msgid "European Union" +msgstr "Europäische Union" -#: app/models/track_thing.rb:231 app/models/track_thing.rb:232 -msgid "Successful Freedom of Information requests" -msgstr "Erfolgreiche Informationsfreiheitsanfrage" +#: app/views/request/details.rhtml:4 +msgid "Event history" +msgstr "Verlaufsübersicht" -#: app/models/track_thing.rb:234 -msgid "To be emailed about any successful requests" -msgstr "Um per Email über erfolgreiche Anfragen informiert zu werden" +#: app/views/request/_sidebar.rhtml:35 +msgid "Event history details" +msgstr "Details Verlaufsübersicht" -#: app/models/track_thing.rb:235 -msgid "Then you will be emailed whenever an FOI request succeeds." +#: app/views/request/new.rhtml:128 +msgid "" +"Everything that you enter on this page \n" +" will be <strong>displayed publicly</strong> on\n" +" this website forever (<a href=\"%s\">why?</a>)." msgstr "" -"Sie werden bei jeder erfolgreichen IFG-Anfrage per Email benachrichtigt. " +"Jegliche auf dieser Seite eingegebene Information wird\n" +" permanent auf dieser Internetseite <strong>veröffentlicht</strong>(<a href=\"%s\"> Warum?</a>)." -#: app/models/track_thing.rb:236 -msgid "Confirm you want to be emailed when an FOI request succeeds" +#: app/views/request/new.rhtml:120 +msgid "" +"Everything that you enter on this page, including <strong>your name</strong>, \n" +" will be <strong>displayed publicly</strong> on\n" +" this website forever (<a href=\"%s\">why?</a>)." msgstr "" -"Bestätigen Sie, dass Sie bei erfolgreicher IFG-Anfrage eine Emailbestätigung" -" erhalten möchten" +"Jegliche auf dieser Seite eingegebene Information, inklusive <strong>Ihrem Namen</strong>, ⏎ wird\n" +" permanent auf dieser Internetseite <strong>veröffentlicht</strong>(<a href=\"%s\"> Warum?</a>)." -#: app/models/track_thing.rb:246 -msgid "'{{link_to_authority}}', a public authority" -msgstr "'{{link_to_authority}}', eine Behörde" +#: locale/model_attributes.rb:58 +msgid "EximLogDone|Filename" +msgstr "EximLogDone|Filename" -#: app/models/track_thing.rb:247 -msgid "Track requests to {{public_body_name}} by email" -msgstr "An {{public_body_name}} gestellte Anfragen via Email verfolgen" +#: locale/model_attributes.rb:59 +msgid "EximLogDone|Last stat" +msgstr "EximLogDone|Last stat" -#: app/models/track_thing.rb:248 -msgid "You are already tracking requests to {{public_body_name}} by email" -msgstr "Sie verfolgen die Anfragen an {{public_body_name}} bereits via Email" +#: locale/model_attributes.rb:19 +msgid "EximLog|Line" +msgstr "EximLog|Line" -#: app/models/track_thing.rb:253 -msgid "" -"To be emailed about requests made using {{site_name}} to the public " -"authority '{{public_body_name}}'" -msgstr "" -"Um Emails bzgl. der durch {{site_name}} an die Behörde " -"'{{public_body_name}}' gestellte Anfragen" +#: locale/model_attributes.rb:18 +msgid "EximLog|Order" +msgstr "EximLog|Order" -#: app/models/track_thing.rb:254 -msgid "" -"Then you will be emailed whenever someone requests something or gets a " -"response from '{{public_body_name}}'." +#: app/models/info_request.rb:272 +msgid "FOI" msgstr "" -"Dann erhalten Sie eine Email sobald jemand eine Anfrage an die folgende " -"Behörde stellt oder eine Antwort von dieser erhält: '{{public_body_name}}'" -#: app/models/track_thing.rb:255 -msgid "" -"Confirm you want to be emailed about requests to '{{public_body_name}}'" -msgstr "" -"Bitte bestätigen Sie, dass Sie über neue Anfragen an '{{public_body_name}}' " -"informiert werden möchten" - -#: app/models/track_thing.rb:262 -msgid "'{{link_to_user}}', a person" -msgstr "'{{link_to_user}}', eine Person" +#: app/views/public_body/view_email.rhtml:1 +msgid "FOI email address for '{{public_body_name}}'" +msgstr "IFG-Emailadresse für '{{public_body_name}}'" -#: app/models/track_thing.rb:263 -msgid "Track this person by email" -msgstr "Dieser Person via Email folgen" +#: app/views/public_body/view_email.rhtml:3 +msgid "FOI email address for {{public_body}}" +msgstr "IFG-Emailadresse für {{public_body}}" -#: app/models/track_thing.rb:264 -msgid "You are already tracking this person by email" -msgstr "Sie folgen dieser Person bereits via Email" +#: app/views/user/show.rhtml:33 +msgid "FOI requests" +msgstr "IFG-Anfrage" #: app/models/track_thing.rb:266 app/models/track_thing.rb:267 msgid "FOI requests by '{{user_name}}'" msgstr "IFG-Anfrage von '{{user_name}}'" -#: app/models/track_thing.rb:269 -msgid "To be emailed about requests by '{{user_name}}'" -msgstr "Um Emails zu Anfragen von '{{user_name}}' zu erhalten" - -#: app/models/track_thing.rb:270 -msgid "" -"Then you will be emailed whenever '{{user_name}}' requests something or gets" -" a response." -msgstr "" -"Dann erhalten Sie eine Email sobald '{{user_name}}' eine Anfrage stellt oder" -" eine Antwort erhält. " +#: app/views/general/search.rhtml:198 +msgid "FOI requests {{start_count}} to {{end_count}} of {{total_count}}" +msgstr "IFG-Anfragen {{start_count}} bis {{end_count}} von {{total_count}}" -#: app/models/track_thing.rb:271 -msgid "Confirm you want to be emailed about requests by '{{user_name}}'" +#: app/models/request_mailer.rb:50 +msgid "FOI response requires admin - " msgstr "" -"Bitte bestätigen Sie, dass Sie über neue Anfragen von '{{user_name}}' " -"informiert werden möchten" - -#: app/models/track_thing.rb:279 -msgid "Track things matching this search by email" -msgstr "Folgen Sie ähnlichen Anfragen etc. per Email" - -#: app/models/track_thing.rb:280 -msgid "You are already tracking things matching this search by email" -msgstr "Sie folgen einer solchen Suchanfrage bereits per Email" -#: app/models/track_thing.rb:282 app/models/track_thing.rb:283 -msgid "Requests or responses matching your saved search" -msgstr "Zu Ihrer gespeicherten Suche passende Anfragen und Antworten" - -#: app/models/track_thing.rb:285 -msgid "To follow requests and responses matching your search" -msgstr "Um Ihrer Suchanfrage ähnelnten Anfragen und Antworten zu folgen" +#: app/models/profile_photo.rb:101 +msgid "Failed to convert image to a PNG" +msgstr "Konnte Bild nicht in ein PNG konvertieren" -#: app/models/track_thing.rb:286 +#: app/models/profile_photo.rb:105 msgid "" -"Then you will be emailed whenever a new request or response matches your " -"search." +"Failed to convert image to the correct size: at %{cols}x%{rows}, need " +"%{width}x%{height}" msgstr "" -"Dann werden Sie per Email über neue Anfragen oder Antworten informiert, die " -"auf Ihre Suche zutreffen. " +"Konnte Bild nicht in die richtige Größe umwandeln: %{cols} x %{rows}, " +"brauche %{width} x %{height}" -#: app/models/track_thing.rb:287 -msgid "" -"Confirm you want to be emailed about new requests or responses matching your" -" search" +#: app/views/general/search.rhtml:121 +msgid "Filter" msgstr "" -"Bestätigen Sie, dass Sie zu Ihrer Suche passende Anfragen und Antworten per " -"Email erhalten möchten" - -#: app/models/user.rb:40 -msgid "Please enter a password" -msgstr "Bitte geben Sie ein Passwort ein" -#: app/models/user.rb:51 -msgid "Please enter the same password twice" -msgstr "Bitte geben Sie das gleiche Passwort zweimal ein" - -#: app/models/user.rb:56 -msgid "Admin level is not included in list" -msgstr "Administrative Ebene ist in Liste nicht enthalten" +#: app/views/request/select_authority.rhtml:35 +msgid "" +"First, type in the <strong>name of the UK public authority</strong> you'd \n" +" <br>like information from. <strong>By law, they have to respond</strong>\n" +" (<a href=\"%s\">why?</a>)." +msgstr "" +"Zuerst, geben Sie <strong>EU Behörde</strong> ein, von welcher Sie \n" +" <br>Informationen anfragen möchten. <strong>Diese muss Ihnen wie gesetzlich vorgschrieben antworten</strong>\n" +" (<a href=\"%s\">warum?</a>)." -#: app/models/user.rb:117 -msgid "Please enter a valid email address" -msgstr "Bitte geben Sie eine gültige E-Mail-Adresse ein" +#: app/views/track/_tracking_links.rhtml:21 +msgid "Follow by email" +msgstr "Per Email folgen" -#: app/models/user.rb:120 -msgid "Please enter your name, not your email address, in the name field." -msgstr "" -"Bitte geben Sie Ihren Namen und nicht Ihre E-Mail-Adresse in das Name-Feld " -"ein." +#: app/views/request/list.rhtml:8 +msgid "Follow these requests" +msgstr "Diesen Anfragen folgen" -#: app/models/user.rb:133 -msgid "{{user_name}} (Banned)" -msgstr "{{user_name}} (Banned)" +#: app/views/public_body/show.rhtml:4 +msgid "Follow this authority" +msgstr "Dieser Behörde folgen" -#: app/models/user.rb:146 -msgid "Either the email or password was not recognised, please try again." -msgstr "" -"Passwort oder emailadresse wurde nicht erkannt. Bitte versuchen Sie es " -"erneut. " +#: app/views/request_mailer/old_unclassified_updated.rhtml:4 +msgid "Follow this link to see the request:" +msgstr "Folgen Sie diesem Link, um die Anfrage anzusehen:" -#: app/models/user.rb:148 -msgid "" -"Either the email or password was not recognised, please try again. Or create" -" a new account using the form on the right." -msgstr "" -"Emailadresse oder Passwort ungültig. Bitte versuchen Sie es erneut oder " -"erstellen Sie ein neues Benutzerkonto mit dem Formular auf der rechten " -"Seite. " +#: app/views/request/_sidebar.rhtml:2 +msgid "Follow this request" +msgstr "Dieser Anfrage folgen" -#: app/models/user_mailer.rb:34 -msgid "Confirm your new email address on {{site_name}}" -msgstr "Confirm your new email address on {{site_name}}" +#: app/models/info_request_event.rb:320 +msgid "Follow up" +msgstr "Follow-up" -#: app/models/user_mailer.rb:45 -msgid "Unable to change email address on {{site_name}}" -msgstr "Nicht in der Lage die Emailadresse auf {{site_name}} zu ändern" +#: app/views/general/_advanced_search_tips.rhtml:43 +msgid "Follow up message sent by requester" +msgstr "Nachfrage durch Anfragensteller gesendet" -#: app/views/admin_public_body/_locale_selector.rhtml:2 -msgid "Edit language version:" -msgstr "Sprachauswahl ändern:" +#: app/views/public_body/view_email.rhtml:14 +msgid "Follow up messages to existing requests are sent to " +msgstr "Nachfragen bzgl. bestehender anfragen werden weitergeleitet an:" -#: app/views/comment/_comment_form.rhtml:8 -msgid "Email me future updates to this request" +#: app/views/request/_followup.rhtml:43 +msgid "" +"Follow ups and new responses to this request have been stopped to prevent " +"spam. Please <a href=\"{{url}}\">contact us</a> if you are {{user_link}} and" +" need to send a follow up." msgstr "" -"Informieren Sie mich über zukünftige Aktualisierungen zu dieser Anfrage" +"Nachfragen und Antworten auf diese Anfrage wurden gestoppt, um Spam " +"vorzubeugen. Bitte <a href=\"{{url}}\">kontaktieren Sie uns</a> falls Sie " +"{{user_link}} sind und eine Nachfrage senden müssen." -#: app/views/comment/_comment_form.rhtml:15 -msgid "Preview your annotation" -msgstr "Überprüfen Sie Ihren Kommentar" +#: app/views/general/_footer.rhtml:3 app/views/general/blog.rhtml:7 +msgid "Follow us on twitter" +msgstr "Folgen Sie uns auf Twitter" -#: app/views/comment/_comment_form.rhtml:16 +#: app/views/public_body/show.rhtml:73 msgid "" -" (<strong>no ranty</strong> politics, read our <a href=\"%s\">moderation " -"policy</a>)" -msgstr "<a href=\"%s\">Moderationsregeln</a>)" +"For an unknown reason, it is not possible to make a request to this " +"authority." +msgstr "" +"Aus unbekannten Gründen ist es nicht möglich eine Anfrage a diese Behörde zu" +" stellen. " -#: app/views/comment/_single_comment.rhtml:10 -msgid "You" -msgstr "Sie" +#: app/views/user/_signin.rhtml:21 +msgid "Forgotten your password?" +msgstr "Passwort vergessen?" -#: app/views/comment/_single_comment.rhtml:10 -msgid "left an annotation" -msgstr "Anmerkung hinterlassen" +#: app/views/public_body/list.rhtml:47 +msgid "Found {{count}} public bodies {{description}}" +msgstr " {{count}} Behörden {{description}} gefunden" -#: app/views/comment/_single_comment.rhtml:24 -msgid "Report abuse" -msgstr "Missbrauch melden" +#: app/models/info_request.rb:263 +msgid "Freedom of Information" +msgstr "" -#: app/views/comment/new.rhtml:14 -msgid "Add an annotation" -msgstr "Fügen Sie einee Anmerkung bei" +#: app/models/info_request.rb:281 +msgid "Freedom of Information Act" +msgstr "" -#: app/views/comment/new.rhtml:18 +#: app/views/public_body/show.rhtml:68 msgid "" -"Annotations are so anyone, including you, can help the requester with their " -"request. For example:" +"Freedom of Information law does not apply to this authority, so you cannot make\n" +" a request to it." msgstr "" -"Anmerkungen helfen Ihnen, sowie weiteren Benutzern bei der Erstellungen " -"einer neuer Anfrage. Zum Beispiel:" +"Das Informationsfreiheitsgesetz trifft auf diese Behörde nicht zu. Sie " +"können daher keine Anfrage stellen. " -#: app/views/comment/new.rhtml:24 -msgid " Advise on how to <strong>best clarify</strong> the request." -msgstr " Hilfe zur Erstellung einer guten Informationsanfrage. " +#: app/views/request/followup_bad.rhtml:11 +msgid "Freedom of Information law no longer applies to" +msgstr "Informationsfreiheitsgesetz ist nicht länger gültig für" -#: app/views/comment/new.rhtml:28 +#: app/views/public_body/view_email.rhtml:10 msgid "" -" Link to the information requested, if it is <strong>already " -"available</strong> on the Internet. " +"Freedom of Information law no longer applies to this authority.Follow up " +"messages to existing requests are sent to " msgstr "" -" Link zur angefragten Information,falls bereits online " -"<strong>verfügbar</strong>. " +"Das Informationsfreiheitsgesetz ist für diese Behörde nicht länger gültig. " +"Follow-up Nachrichten bestehnder Nachrichten wurden gesendet an" -#: app/views/comment/new.rhtml:29 -msgid "" -" Suggest <strong>where else</strong> the requester might find the " -"information. " -msgstr "" -"Machen Sie Vorschläge wo sonst die gewünschte Information eventuell zu " -"finden ist " +#: app/views/public_body/show.rhtml:126 +msgid "Freedom of Information requests made" +msgstr "Anfrage ausgeführt" -#: app/views/comment/new.rhtml:30 -msgid "" -" Offer better ways of <strong>wording the request</strong> to get the " -"information. " -msgstr "" -" Machen Sie bessere <strong>Formulierungsvorschläge</strong>, um die " -"gewünschten Informationen zu erhalten. " +#: app/views/user/show.rhtml:157 +msgid "Freedom of Information requests made by this person" +msgstr "Informationsfreiheits-Anfrage durch diese Person gestellt" -#: app/views/comment/new.rhtml:34 -msgid " <strong>Summarise</strong> the content of any information returned. " -msgstr "Fassen Sie den Inhalt jeglicher erhaltenen Information zusammen. " +#: app/views/user/show.rhtml:157 +msgid "Freedom of Information requests made by you" +msgstr "Von Ihnen gestellte IFG-Anfragen" -#: app/views/comment/new.rhtml:35 -msgid "" -" Say how you've <strong>used the information</strong>, with links if " -"possible." -msgstr "" -"Teilen Sie uns mit, <strong>wie Sie die Informationen verwendet " -"haben</strong> - falls möglich mit Link." +#: app/views/public_body/show.rhtml:84 +msgid "Freedom of Information requests made using this site" +msgstr "Anfrage über diese Seite gestellt" -#: app/views/comment/new.rhtml:36 -msgid "<strong>Thank</strong> the public authority or " -msgstr "<strong>Danken Sie</strong> der Behörde oder " +#: app/views/public_body/show.rhtml:38 +msgid "Freedom of information requests to" +msgstr "IFG-Anfrage an" -#: app/views/comment/new.rhtml:39 +#: app/views/request/followup_bad.rhtml:12 msgid "" -"Suggest how the requester can find the <strong>rest of the " -"information</strong>." +"From the request page, try replying to a particular message, rather than sending\n" +" a general followup. If you need to make a general followup, and know\n" +" an email which will go to the right place, please <a href=\"%s\">send it to us</a>." msgstr "" -"Schlagen Sie vor, wie der Anfragensteller <strong>den Rest der " -"Information</strong> finden kann." +"Von der Anfragen-Seite, versuchen Sie direkt auf spezifische Nachrichten zu " +"reagieren anstall eine generelle Nachfrage zu senden. Falls Sie eine " +"generelle Nachfrage stellen müssen und eine Emailadresse kennen, welche an " +"die richtige Stelle geht, sind Sie so freundlich uns <a href=\"%s\">diese zu" +" senden. " -#: app/views/comment/new.rhtml:42 -msgid "" -"Point to <strong>related information</strong>, campaigns or forums which may" -" be useful." -msgstr "" -"Weisen Sie auf ähnliche, evtl. nütziche Informationen, Kampagnen oder Foren " -"hin" +#: app/views/request/_correspondence.rhtml:12 +#: app/views/request/_correspondence.rhtml:36 +#: app/views/request/simple_correspondence.rhtml:14 +#: app/views/request/simple_correspondence.rhtml:27 +msgid "From:" +msgstr "Von:" -#: app/views/comment/new.rhtml:46 -msgid "" -"A <strong>summary</strong> of the response if you have received it by post. " -msgstr "" -"Eine <strong>Zusammenfassung</strong> of the response if you have received " -"it by post. " +#: app/models/outgoing_message.rb:74 +msgid "GIVE DETAILS ABOUT YOUR COMPLAINT HERE" +msgstr "HINTELASSEN SIE HIER DETAILS ZU IHRER BESCHWERDE" -#: app/views/comment/new.rhtml:50 -msgid "" -" Ideas on what <strong>other documents to request</strong> which the " -"authority may hold. " -msgstr "" -" Ideas on what <strong>other documents to request</strong> which the " -"authority may hold. " +#: lib/world_foi_websites.rb:25 +msgid "Germany" +msgstr "Deutschland" -#: app/views/comment/new.rhtml:53 -msgid "" -"Advise on whether the <strong>refusal is legal</strong>, and how to complain" -" about it if not." -msgstr "" -"Beratung zur <strong>Rechtsgültigkeit der Ablehnung</strong> und wie Sie " -"dagene angehen können." +#: app/models/info_request.rb:803 +msgid "Handled by post." +msgstr "Postalisch bearbeitet." -#: app/views/comment/new.rhtml:57 +#: app/controllers/services_controller.rb:21 msgid "" -"<strong>Advice</strong> on how to get a response that will satisfy the " -"requester. </li>" +"Hello! You can make Freedom of Information requests within {{country_name}} " +"at {{link_to_website}}" msgstr "" -"<strong>Ratschlag</strong> bzgl. Antworten, welche den Anfragesteller " -"zufriedenstellen. </li>" +"Hallo! IFG-Anfragen innerhalb von {{country_name}} können Sie hier stellen: " +"{{link_to_website}} " -#: app/views/comment/new.rhtml:60 -msgid "" -"You know what caused the error, and can <strong>suggest a solution</strong>," -" such as a working email address." -msgstr "" -"Sie kennen die Ursache des Fehlers und können eine <strong>Lösung " -"anbieten</strong>, wie z.B. eine funktionierende Email-Adresse. " +#: app/views/layouts/default.rhtml:104 +msgid "Hello, {{username}}!" +msgstr "Hallo, {{username}}!" -#: app/views/comment/new.rhtml:63 +#: app/views/general/_topnav.rhtml:8 +msgid "Help" +msgstr "Hilfe" + +#: app/views/request/details.rhtml:50 msgid "" -"Your thoughts on what the {{site_name}} <strong>administrators</strong> " -"should do about the request." +"Here <strong>described</strong> means when a user selected a status for the request, and\n" +"the most recent event had its status updated to that value. <strong>calculated</strong> is then inferred by\n" +"{{site_name}} for intermediate events, which weren't given an explicit\n" +"description by a user. See the <a href=\"{{search_path}}\">search tips</a> for description of the states." msgstr "" -"Ihre Meinung zu empfehlenswerten Schritte von {{site_name}} durch die " -"<strong>Administratoren</strong> bzgl. der Anfrage." -#: app/views/comment/new.rhtml:70 +#: app/views/request/_other_describe_state.rhtml:4 msgid "" -"Annotations will be posted publicly here, and are \n" -" <strong>not</strong> sent to {{public_body_name}}." +"Hi! We need your help. The person who made the following request\n" +" hasn't told us whether or not it was successful. Would you mind taking\n" +" a moment to read it and help us keep the place tidy for everyone?\n" +" Thanks." msgstr "" -"Anmerkungen werden hier veröffentlicht, und werden \n" -" <strong>nicht</strong> an {{public_body_name}} gesendet." +"Hallo! Wir brauchen Ihre Hilfe. Die Person, welche die folgende Anfrage " +"gestellt hat, hat uns nicht mitgeteilt ob diese erfolgreich war. Wäre es " +"okaz für Sie sich einen Moment Zeit zu nehmen, um die Anfrage zu lesen und " +"uns somit zu helfen die Zeite für jedermann aktuell zu halten?" -#: app/views/comment/preview.rhtml:1 -msgid "Preview new annotation on '{{info_request_title}}'" -msgstr "Sehen Sie den neuen Kommentar zu '{{info_request_title}}'" +#: locale/model_attributes.rb:55 +msgid "Holiday|Day" +msgstr "Holiday|Day" -#: app/views/comment/preview.rhtml:5 -msgid "Now preview your annotation" -msgstr "Überprüfen Sie nun Ihren Kommentar" +#: locale/model_attributes.rb:56 +msgid "Holiday|Description" +msgstr "Holiday|Description" -#: app/views/comment/preview.rhtml:10 +#: app/views/general/_topnav.rhtml:3 +msgid "Home" +msgstr "Home" + +#: app/views/public_body/show.rhtml:20 +msgid "Home page of authority" +msgstr "Offizielle Homepage der Behörde" + +#: app/views/request/new.rhtml:61 msgid "" -"Your name and annotation will appear in <strong>search engines</strong>." +"However, you have the right to request environmental\n" +" information under a different law" msgstr "" -"Ihr Name und Ihr Kommentar wird in <strong>Suchmaschinen</strong>.angezeigt " -"werden. " +"Nichtsdestrotrotz sind Sie berechtigt Umweltanfragen auf Basis eines anderen" +" Gesetzes zu stellen" -#: app/views/comment/preview.rhtml:20 -msgid "Re-edit this annotation" -msgstr "Anmerkung erneut bearbeiten" +#: app/views/request/new.rhtml:71 +msgid "Human health and safety" +msgstr "Gesundheit und Sicherheit" -#: app/views/comment/preview.rhtml:21 -msgid "Post annotation" -msgstr "Anmerkung hinzufügen" +#: app/views/request/_followup.rhtml:95 +msgid "I am asking for <strong>new information</strong>" +msgstr "Ich beantrage <strong>neue Informationen</strong>" -#: app/views/contact_mailer/message.rhtml:4 -msgid "Message sent using {{site_name}} contact form, " -msgstr "Nachricht gesendet über {{site_name}} Kontaktformular, " +#: app/views/request/_followup.rhtml:100 +msgid "I am requesting an <strong>internal review</strong>" +msgstr "Ich stelle eine Anfrage zur <strong>internen Prüfung</strong>" -#: app/views/contact_mailer/message.rhtml:7 -msgid "Last request viewed: " -msgstr "Zuletzt angesehene Anfrage:" +#: app/views/request_game/play.rhtml:39 +msgid "I don't like these ones — give me some more!" +msgstr "Ich würde gerne andere Anfragen erhalten!" -#: app/views/contact_mailer/message.rhtml:10 -msgid "Last authority viewed: " -msgstr "Zuletzt angesehene Behörde: " +#: app/views/request_game/play.rhtml:40 +msgid "I don't want to do any more tidying now!" +msgstr "Ich möchte gerade keine weiteren Anfragen bearbeiten!" -#: app/views/contact_mailer/user_message.rhtml:2 -msgid "{{user_name}} has used {{site_name}} to send you the message below." -msgstr "" -"{{user_name}} hat {{site_name}} verwendet, um Ihnen die unten angezeigte " -"Nachricht zu senden." +#: app/views/request/_describe_state.rhtml:91 +msgid "I would like to <strong>withdraw this request</strong>" +msgstr "Ich möchte diese <strong>Anfrage zurückziehen</strong>" -#: app/views/contact_mailer/user_message.rhtml:3 +#: app/views/request/_describe_state.rhtml:11 msgid "" -"Your details have not been given to anyone, unless you choose to reply to this\n" -"message, which will then go directly to the person who wrote the message." +"I'm still <strong>waiting</strong> for my information\n" +" <small>(maybe you got an acknowledgement)</small>" msgstr "" -"Ihre Details wurden nicht weitergegeben, ausser wenn Sie sich entschieden " -"haben auf diese Nachricht zu antworten. Ihre Antwort geht dann direkt an die" -" Person, welche die Nachricht geschrieben hat. " +"Ich <strong>warte</strong> noch immer auf meine Informationen\n" +" <small>(vielleicht haben Sie eine Bestätigung erhalten)</small>" -#: app/views/contact_mailer/user_message.rhtml:10 -msgid "View Freedom of Information requests made by {{user_name}}:" -msgstr "Sehen Sie die durch {{user_name}} gestellten IFG-Anfragen an:" +#: app/views/request/_describe_state.rhtml:18 +msgid "I'm still <strong>waiting</strong> for the internal review" +msgstr "Ich <strong>warte</strong> noch immer auf die interne Prüfung" -#: app/views/general/_advanced_search_tips.rhtml:3 -msgid "Advanced search tips" -msgstr "Tipps zur erweiterten Suchanfrage" +#: app/views/request/_describe_state.rhtml:32 +msgid "I'm waiting for an <strong>internal review</strong> response" +msgstr "Ich warte auf eine Antwort der <strong>internen Prüfung</strong>" -#: app/views/general/_advanced_search_tips.rhtml:5 -msgid "" -"Enter words that you want to find separated by spaces, e.g. <strong>climbing" -" lane</strong>" -msgstr "Trennen Sie Ihre Suchbegriffen durch Leerzeichen" +#: app/views/request/_describe_state.rhtml:25 +msgid "I've been asked to <strong>clarify</strong> my request" +msgstr "" +"Ich wurde gebeten meine Anfrage <strong>deutlicher zu erläutern</strong>" -#: app/views/general/_advanced_search_tips.rhtml:6 +#: app/views/request/_describe_state.rhtml:60 +msgid "I've received <strong>all the information" +msgstr "Angefragte Information <strong> vollständig erhalten" + +#: app/views/request/_describe_state.rhtml:56 +msgid "I've received <strong>some of the information</strong>" +msgstr "Angefragte Information <strong> teilweise erhalten </strong>" + +#: app/views/request/_describe_state.rhtml:76 +msgid "I've received an <strong>error message</strong>" +msgstr "Fehlerhafte Information <strong>erhalten</strong>" + +#: app/views/public_body/view_email.rhtml:28 msgid "" -"Use OR (in capital letters) where you don't mind which word, e.g. " -"<strong><code>commons OR lords</code></strong>" +"If the address is wrong, or you know a better address, please <a " +"href=\"%s\">contact us</a>." msgstr "" -"Nutzen Sie ODER (in Großbuchstaben) wo es Ihnen gleich ist, welches Wort " -"verwendet wird, z.B. <strong><code>Komission ODER Ausschuss</code></strong>" +"Sollte die Adresse falsch sein oder sollten Sie eine bessere Adresse kennen," +" so <a href=\"%s\">kontaktieren Sie uns</a>bitte." -#: app/views/general/_advanced_search_tips.rhtml:7 +#: app/views/request_mailer/stopped_responses.rhtml:10 msgid "" -"Use quotes when you want to find an exact phrase, e.g. " -"<strong><code>\"Liverpool City Council\"</code></strong>" +"If this is incorrect, or you would like to send a late response to the request\n" +"or an email on another subject to {{user}}, then please\n" +"email {{contact_email}} for help." msgstr "" -"Verwenden Sie Anführungszeichen, e.g. <strong><code>\"Europäischer " -"Bürgerbeauftragter\"</code></strong>" +"Falls dies falsch ist oder Sie eine späte Antwort auf diese Anfrage oder zu einem anderen Thema an {{user}} senden möchten, dann mailen Sie bitte\n" +" {{contact_email}} ffür weitere Hilfe." -#: app/views/general/_advanced_search_tips.rhtml:8 +#: app/views/request/_followup.rhtml:47 msgid "" -"<strong><code>status:</code></strong> to select based on the status or " -"historical status of the request, see the <a href=\"{{statuses_url}}\">table" -" of statuses</a> below." +"If you are dissatisfied by the response you got from\n" +" the public authority, you have the right to\n" +" complain (<a href=\"%s\">details</a>)." msgstr "" -"<strong><code>Status:</code></strong> um eine Auswahl nach Status oder " -"historischem Status der Anfrage zu treffen, gehen Sie zur unten " -"angezeigten<a href=\"{{statuses_url}}\">Statusübersicht</a> ." +"Sollten Sie mit den erhaltenen Informationen nicht zufrieden sein, haben Sie" +" das Recht eine Beschwerde einzureichen (<a href=\"%s\">Details</a>)." -#: app/views/general/_advanced_search_tips.rhtml:9 -msgid "" -"<strong><code>variety:</code></strong> to select type of thing to search " -"for, see the <a href=\"{{varieties_url}}\">table of varieties</a> below." +#: app/views/user/no_cookies.rhtml:20 +msgid "If you are still having trouble, please <a href=\"%s\">contact us</a>." msgstr "" -"<strong><code>variety:</code></strong> um Mögliche Suchoptionen zu wählen, " -"gehen Sie zur unten angezeigten <a " -"href=\"{{varieties_url}}\">Auswahlansich</a> ." +"Sollten weiterhin Probleme bestehen, bitte <a href=\"%s\">kontaktieren Sie " +"uns</a>." -#: app/views/general/_advanced_search_tips.rhtml:10 +#: app/views/request/hidden.rhtml:15 msgid "" -"<strong><code>requested_from:home_office</code></strong> to search requests " -"from the Home Office, typing the name as in the URL." +"If you are the requester, then you may <a href=\"%s\">sign in</a> to view " +"the request." msgstr "" -"<strong><code>angefragt durch:home_office</code></strong>um Anfragen vom " -"Home Office zu suchen, den Namen wie in der URL eingebend." +"Falls Sie der Antragsteller sind, <a href=\"%s\">loggen Sie sich ein</a>, um" +" die Anfrage anzusehen." -#: app/views/general/_advanced_search_tips.rhtml:11 +#: app/views/request/new.rhtml:123 msgid "" -"<strong><code>requested_by:julian_todd</code></strong> to search requests " -"made by Julian Todd, typing the name as in the URL." +"If you are thinking of using a pseudonym,\n" +" please <a href=\"%s\">read this first</a>." msgstr "" -"<strong><code>angefragt_durch:julian_todd</code></strong>um Anfragen von " -"Julian Todd zu suchen, den Namen wie in der URL eingebend." +"Wenn Sie ein Pseudonym als Benutzername verwenden möchten,\n" +" bitte <a href=\"%s\">lesen Sie hier</a>." -#: app/views/general/_advanced_search_tips.rhtml:12 +#: app/views/request/show.rhtml:105 +msgid "If you are {{user_link}}, please" +msgstr "Wenn Sie {{user_link}} sind, bitte" + +#: app/views/user/bad_token.rhtml:7 msgid "" -"<strong><code>commented_by:tony_bowden</code></strong> to search annotations" -" made by Tony Bowden, typing the name as in the URL." +"If you can't click on it in the email, you'll have to <strong>select and copy\n" +"it</strong> from the email. Then <strong>paste it into your browser</strong>, into the place\n" +"you would type the address of any other webpage." msgstr "" -"<strong><code>kommentiert_durch:tony_bowden</code></strong> um Kommentare " -"von Tony Bowden zu suche, den Namen wie in der URL eingebend." +"Falls Sie den link in Ihrer Email nicht anklicken können, müssen Sie diesen " +"<strong>auswählen und kopieren</strong>. <strong>Fügen Sie diesen dann in " +"Ihr Browserfenster ein</strong>, an der Stelle, an der Sie auch jede andere " +"Webadresse eingeben würden." -#: app/views/general/_advanced_search_tips.rhtml:13 +#: app/views/request/show_response.rhtml:47 msgid "" -"<strong><code>request:</code></strong> to restrict to a specific request, " -"typing the title as in the URL." +"If you can, scan in or photograph the response, and <strong>send us\n" +" a copy to upload</strong>." msgstr "" -"<strong><code>Anfrage:</code></strong> um die Suchanfrage zu begrenzen, " -"geben Sie den Titel wie in der URL ein." +"Fall möglich, scannen oder photographieren Sie die Antwort und<strong>senden" +" Sie uns eine Kopie zum Upload</strong>." -#: app/views/general/_advanced_search_tips.rhtml:14 +#: app/views/outgoing_mailer/_followup_footer.rhtml:4 msgid "" -"<strong><code>filetype:pdf</code></strong> to find all responses with PDF " -"attachments. Or try these: <code>{{list_of_file_extensions}}</code>" +"If you find this service useful as an FOI officer, please ask your web " +"manager to link to us from your organisation's FOI page." msgstr "" -"<strong><code>Dateityp:PDF</code></strong> um alle Antworten mit PDF-Anhang " -"zu finden. Oder versuchen Sie es hiermit: " -"<code>{{list_of_file_extensions}}</code>" +"Falls Sie als IFGler diesen Service nützlich finden, bitten Sie bitte Ihren " +"Webadministrator die IFG-Seite Ihrer Organisation mit uns zu verlinken." -#: app/views/general/_advanced_search_tips.rhtml:15 +#: app/views/user/bad_token.rhtml:13 msgid "" -"Type <strong><code>01/01/2008..14/01/2008</code></strong> to only show " -"things that happened in the first two weeks of January." +"If you got the email <strong>more than six months ago</strong>, then this login link won't work any\n" +"more. Please try doing what you were doing from the beginning." msgstr "" -"Geben Sie <strong><code>01/01/2008..14/01/2008</code></strong> ein, um " -"ausschliesslich Vorgänge aus diesem Zeitraum anzuzeigen." +"Wenn Sie diese Email <strong>vor mehr als sechs Monaten erhalten " +"haben</strong>, ist dieser Anmeldecode nichtmehr aktiv. Bitte nehmen Sie " +"eine neue Registrierung vor. " -#: app/views/general/_advanced_search_tips.rhtml:16 +#: app/controllers/request_controller.rb:443 msgid "" -"<strong><code>tag:charity</code></strong> to find all public bodies or requests with a given tag. You can include multiple tags, \n" -" and tag values, e.g. <code>tag:openlylocal AND tag:financial_transaction:335633</code>. Note that by default any of the tags\n" -" can be present, you have to put <code>AND</code> explicitly if you only want results them all present." +"If you have not done so already, please write a message below telling the " +"authority that you have withdrawn your request. Otherwise they will not know" +" it has been withdrawn." msgstr "" -"<strong><code>markieren Sie:Karitas</code></strong>, um alle Behörden oder Anfragen mit dieser Markierung zu finden. Sie können mehrere Markierungen, \n" -" and tag values, e.g. <code>tag:openlylocal AND tag:financial_transaction:335633</code>. Note that by default any of the tags\n" -" can be present, you have to put <code>AND</code> explicitly if you only want results them all present." +"Falls noch nicht geschehen, senden Sie bitte eine Nachricht, um die Behörde " +"zu informieren, dass Sie Ihre Anfrage zurückgezogen haben. Anderenfalls " +"weiss diese nicht, dass dies geschehen ist. " -#: app/views/general/_advanced_search_tips.rhtml:19 +#: app/views/user/signchangepassword_confirm.rhtml:10 +#: app/views/user/signchangeemail_confirm.rhtml:11 msgid "" -"Read about <a href=\"{{advanced_search_url}}\">advanced search " -"operators</a>, such as proximity and wildcards." +"If you use web-based email or have \"junk mail\" filters, also check your\n" +"bulk/spam mail folders. Sometimes, our messages are marked that way." msgstr "" -"Lesen Sie mehr über <a href=\"{{advanced_search_url}}\">Anbieter erweiterter" -" Suchfunktionen</a>, wie proximity and wildcards." - -#: app/views/general/_advanced_search_tips.rhtml:22 -msgid "Table of statuses" -msgstr "Statusliste" +"Sollten Sie ein webbasiertes Emailkonto oder Spamfilter benutzen, überrpüfen" +" Sie Ihre Bulk-, Spamordner. Unsere Nachrichten landen teilweise in diese " +"Ordnern. " -#: app/views/general/_advanced_search_tips.rhtml:23 +#: app/views/user/banned.rhtml:15 msgid "" -"All the options below can use <strong>status</strong> or " -"<strong>latest_status</strong> before the colon. For example, " -"<strong>status:not_held</strong> will match requests which have " -"<em>ever</em> been marked as not held; " -"<strong>latest_status:not_held</strong> will match only requests that are " -"<em>currently</em> marked as not held." +"If you would like us to lift this ban, then you may politely\n" +"<a href=\"/help/contact\">contact us</a> giving reasons.\n" msgstr "" +"Falls Sie möchten, dass wir diese Sperre aufheben, mögen Sie uns höflich\n" +"<a href=\"/help/contact\">kontaktieren</a> und einen Grund angeben.\n" -#: app/views/general/_advanced_search_tips.rhtml:26 -msgid "Waiting for the public authority to reply" -msgstr "Antwort der Behörde wird erwartet" +#: app/views/user/_signup.rhtml:6 +msgid "If you're new to {{site_name}}" +msgstr "Falls Sie neu auf {{site_name}} sind" -#: app/views/general/_advanced_search_tips.rhtml:27 -msgid "The public authority does not have the information requested" -msgstr "Der Behörde liegen die angefragten Informationen nicht vor. " +#: app/views/user/_signin.rhtml:7 +msgid "If you've used {{site_name}} before" +msgstr "Falls Sie {{site_name}} zuvor genutzt haben" -#: app/views/general/_advanced_search_tips.rhtml:28 -msgid "The request was refused by the public authority" -msgstr "Die Anfrage wurde von der Behörde abgelehnt" +#: app/views/user/no_cookies.rhtml:12 +msgid "" +"If your browser is set to accept cookies and you are seeing this message,\n" +"then there is probably a fault with our server." +msgstr "" +"Sollte Ihr Browser Cookies zulassen und Sie trotzdem diese Nachricht " +"erhalten, gibt es wahrscheinlich ein Problem mit unserem Server." -#: app/views/general/_advanced_search_tips.rhtml:29 -msgid "Some of the information requested has been received" -msgstr "Ein Teil der angefragten Informationen wurde erhalten." +#: locale/model_attributes.rb:61 +msgid "IncomingMessage|Cached attachment text clipped" +msgstr "IncomingMessage|Cached attachment text clipped" -#: app/views/general/_advanced_search_tips.rhtml:30 -msgid "All of the information requested has been received" -msgstr "Die angefragten Informationen wurden vollständig empfangen" +#: locale/model_attributes.rb:62 +msgid "IncomingMessage|Cached main body text folded" +msgstr "IncomingMessage|Cached main body text folded" -#: app/views/general/_advanced_search_tips.rhtml:31 -msgid "The public authority would like part of the request explained" -msgstr "" -"Die Behörde würde gerne weitere Erläuterungen zu einem Teil der Anfrage " -"erhalten." +#: locale/model_attributes.rb:63 +msgid "IncomingMessage|Cached main body text unfolded" +msgstr "IncomingMessage|Cached main body text unfolded" -#: app/views/general/_advanced_search_tips.rhtml:32 -msgid "The public authority would like to / has responded by post" -msgstr "Die Behörde würde gerne / hat Ihnen postalisch geantwortet" +#: locale/model_attributes.rb:67 +msgid "IncomingMessage|Mail from domain" +msgstr "IncomingMessage|Mail from domain" -#: app/views/general/_advanced_search_tips.rhtml:33 -msgid "" -"Waiting for the public authority to complete an internal review of their " -"handling of the request" -msgstr "" -"Die Fertigstellung einer internen Prüfung der Bearbeitungsweise Ihrer " -"Anfrage durch die Behörde wird erwartet" +#: locale/model_attributes.rb:66 +msgid "IncomingMessage|Safe mail from" +msgstr "IncomingMessage|Safe mail from" -#: app/views/general/_advanced_search_tips.rhtml:34 -msgid "Received an error message, such as delivery failure." -msgstr "Fehlermeldung, wie z.B. Sendefehler, erhalten. " +#: locale/model_attributes.rb:64 +msgid "IncomingMessage|Sent at" +msgstr "IncomingMessage|Sent at" -#: app/views/general/_advanced_search_tips.rhtml:35 -msgid "A strange reponse, required attention by the {{site_name}} team" -msgstr "" -"Eine merkwürdige Antwort benötigte die Aufmerksamkeit des {{site_name}} " -"Teams" +#: locale/model_attributes.rb:65 +msgid "IncomingMessage|Subject" +msgstr "IncomingMessage|Subject" -#: app/views/general/_advanced_search_tips.rhtml:36 -msgid "The requester has abandoned this request for some reason" -msgstr "" -"Der Anfragensteller hat die Anfrage aus unbekannten Gründen zurückgezogen. " +#: locale/model_attributes.rb:68 +msgid "IncomingMessage|Valid to reply to" +msgstr "IncomingMessage|Valid to reply to" -#: app/views/general/_advanced_search_tips.rhtml:39 -msgid "Table of varieties" -msgstr "" +#: locale/model_attributes.rb:44 +msgid "InfoRequestEvent|Calculated state" +msgstr "InfoRequestEvent|Calculated state" -#: app/views/general/_advanced_search_tips.rhtml:40 -msgid "" -"All the options below can use <strong>variety</strong> or " -"<strong>latest_variety</strong> before the colon. For example, " -"<strong>variety:sent</strong> will match requests which have <em>ever</em> " -"been sent; <strong>latest_variety:sent</strong> will match only requests " -"that are <em>currently</em> marked as sent." -msgstr "" +#: locale/model_attributes.rb:43 +msgid "InfoRequestEvent|Described state" +msgstr "InfoRequestEvent|Described state" -#: app/views/general/_advanced_search_tips.rhtml:42 -msgid "Original request sent" -msgstr "Ursprüngliche Anfrage gesendet" +#: locale/model_attributes.rb:41 +msgid "InfoRequestEvent|Event type" +msgstr "InfoRequestEvent|Event type" -#: app/views/general/_advanced_search_tips.rhtml:43 -msgid "Follow up message sent by requester" -msgstr "Nachfrage durch Anfragensteller gesendet" +#: locale/model_attributes.rb:45 +msgid "InfoRequestEvent|Last described at" +msgstr "InfoRequestEvent|Last described at" -#: app/views/general/_advanced_search_tips.rhtml:44 -msgid "Response from a public authority" -msgstr "Antwort von einer Behörde" +#: locale/model_attributes.rb:42 +msgid "InfoRequestEvent|Params yaml" +msgstr "InfoRequestEvent|Params yaml" -#: app/views/general/_advanced_search_tips.rhtml:45 -msgid "Annotation added to request" -msgstr "Anfrage wurde kommentiert" +#: locale/model_attributes.rb:46 +msgid "InfoRequestEvent|Prominence" +msgstr "InfoRequestEvent|Prominence" -#: app/views/general/_advanced_search_tips.rhtml:46 -msgid "A public authority" -msgstr "Eine Behörde" +#: locale/model_attributes.rb:89 +msgid "InfoRequest|Allow new responses from" +msgstr "InfoAnfrage | Neue Antworten zulassen von" -#: app/views/general/_advanced_search_tips.rhtml:47 -msgid "A {{site_name}} user" -msgstr "Ein/Eine {{site_name}} Benutzer/in" +#: locale/model_attributes.rb:85 +msgid "InfoRequest|Awaiting description" +msgstr "InfoAnfrage | Beschreibung wird erwartet" -#: app/views/general/_credits.rhtml:1 -msgid "Powered by <a href=\"http://www.alaveteli.org/\">Alaveteli</a>" -msgstr "Unterstützt von <a href=\"http://www.alaveteli.org/\">Alaveteli</a>" +#: locale/model_attributes.rb:84 +msgid "InfoRequest|Described state" +msgstr "InfoRequest|Described state" -#: app/views/general/_footer.rhtml:2 -msgid "Contact {{site_name}}" -msgstr "Kontaktieren Sie {{site_name}}" +#: locale/model_attributes.rb:90 +msgid "InfoRequest|Handle rejected responses" +msgstr "InfoRequest|Handle rejected responses" -#: app/views/general/_footer.rhtml:3 app/views/general/blog.rhtml:7 -msgid "Follow us on twitter" -msgstr "Folgen Sie uns auf Twitter" +#: locale/model_attributes.rb:91 +msgid "InfoRequest|Idhash" +msgstr "InfoRequest|Idhash" -#: app/views/general/_localised_datepicker.rhtml:4 -msgid "Done" -msgstr "Erledigt" +#: locale/model_attributes.rb:88 +msgid "InfoRequest|Law used" +msgstr "InfoRequest|Law used" -#: app/views/general/_localised_datepicker.rhtml:5 -msgid "Prev" -msgstr "" +#: locale/model_attributes.rb:86 +msgid "InfoRequest|Prominence" +msgstr "InfoRequest|Prominence" -#: app/views/general/_localised_datepicker.rhtml:6 -msgid "Next" -msgstr "Folgende/r" +#: locale/model_attributes.rb:83 +msgid "InfoRequest|Title" +msgstr "InfoRequest|Title" -#: app/views/general/_localised_datepicker.rhtml:7 -msgid "Today" -msgstr "Heute" +#: locale/model_attributes.rb:87 +msgid "InfoRequest|Url title" +msgstr "InfoRequest|Url title" -#: app/views/general/_localised_datepicker.rhtml:13 -msgid "Wk" +#: app/models/info_request.rb:793 +msgid "Information not held." +msgstr "Information nicht verfügbr" + +#: app/views/request/new.rhtml:69 +msgid "" +"Information on emissions and discharges (e.g. noise, energy,\n" +" radiation, waste materials)" msgstr "" +"Informationen bzg. Emissionen und Ablagerungen (e.g. Lärm, Energie,\n" +" Strahlung, Abfallmaterialien)" -#: app/views/general/_topnav.rhtml:3 -msgid "Home" -msgstr "Home" +#: app/models/info_request_event.rb:313 +msgid "Internal review request" +msgstr "Anfrage zur internen Prüfung" -#: app/views/general/_topnav.rhtml:4 -msgid "Make a request" -msgstr "Anfrage stellen" +#: app/views/outgoing_mailer/initial_request.rhtml:8 +msgid "" +"Is {{email_address}} the wrong address for {{type_of_request}} requests to " +"{{public_body_name}}? If so, please contact us using this form:" +msgstr "" +"Ist {{email_address}} die falsche Email-Adresse für {{type_of_request}} " +"Anfragen an {{public_body_name}}? Sollte dies der Fall sein, so kontaktieren" +" Sie uns bitte über dieses Formular:" -#: app/views/general/_topnav.rhtml:5 -msgid "View requests" -msgstr "Anfragen ansehen" +#: app/views/user/no_cookies.rhtml:8 +msgid "" +"It may be that your browser is not set to accept a thing called \"cookies\",\n" +"or cannot do so. If you can, please enable cookies, or try using a different\n" +"browser. Then press refresh to have another go." +msgstr "" +"Möglicherweise blockiert Ihr Browser keine sogenannten ´Cookies´. Bitte " +"erlauben Sie diese oder versuchen Sie es mit einem anderen Browser. Klicken " +"Sie anschliessend auf aktualisieren, um es erneut zu versuchen. " -#: app/views/general/_topnav.rhtml:6 -msgid "View authorities" -msgstr "Behörden ansehen" +#: app/views/user/_user_listing_single.rhtml:21 +msgid "Joined in" +msgstr "Angemeldet" -#: app/views/general/_topnav.rhtml:7 -msgid "Read blog" -msgstr "Blog lesen" +#: app/views/user/show.rhtml:62 +msgid "Joined {{site_name}} in" +msgstr "{{site_name}} beigetreten am" -#: app/views/general/_topnav.rhtml:8 -msgid "Help" -msgstr "Hilfe" +#: app/views/request/new.rhtml:106 +msgid "" +"Keep it <strong>focused</strong>, you'll be more likely to get what you want" +" (<a href=\"%s\">why?</a>)." +msgstr "" +"Machen Sie es <strong>kurz und bündig</strong>, die Wahrscheinlichkeit die " +"gewünschten Informationen zu erhalten ist somit größer(<a " +"href=\"%s\">Warum?</a>)." -#: app/views/general/blog.rhtml:1 -msgid "{{site_name}} blog and tweets" -msgstr "{{site_name}} Blog und Tweets" +#: app/views/request/_request_filter_form.rhtml:6 +msgid "Keywords" +msgstr "Stichwörter" -#: app/views/general/blog.rhtml:6 -msgid "Stay up to date" -msgstr "Bleiben Sie auf dem Laufenden" +#: lib/world_foi_websites.rb:9 +msgid "Kosovo" +msgstr "Kosovo" -#: app/views/general/blog.rhtml:8 -msgid "Subscribe to blog" -msgstr "Blog folgen" +#: app/views/contact_mailer/message.rhtml:10 +msgid "Last authority viewed: " +msgstr "Zuletzt angesehene Behörde: " -#: app/views/general/blog.rhtml:53 -msgid "Posted on {{date}} by {{author}}" -msgstr "Verfasst am {{date}} durch {{author}}" +#: app/views/contact_mailer/message.rhtml:7 +msgid "Last request viewed: " +msgstr "Zuletzt angesehene Anfrage:" -#: app/views/general/blog.rhtml:56 -msgid "{{number_of_comments}} comments" -msgstr "{{number_of_comments}} Kommentare" +#: app/views/user/no_cookies.rhtml:17 +msgid "" +"Let us know what you were doing when this message\n" +"appeared and your browser and operating system type and version." +msgstr "" +"Teilen Sie uns mit bei welchem Vorgang diese Nachricht angezeigt wurde, also" +" auch den Namen Ihres Browsers, und den Namen und die Version Ihres " +"Betriebssystems." -#: app/views/general/exception_caught.rhtml:3 -msgid "Sorry, we couldn't find that page" -msgstr "Diese Seite wurde leider nicht gefunden" +#: app/views/request/_correspondence.rhtml:26 +#: app/views/request/_correspondence.rhtml:54 +msgid "Link to this" +msgstr "Link erstellen" -#: app/views/general/exception_caught.rhtml:5 -msgid "The page doesn't exist. Things you can try now:" -msgstr "Die Seite existiert nicht. Was Sie nun versuchen können:" +#: app/views/public_body/list.rhtml:32 +msgid "List of all authorities (CSV)" +msgstr "Liste aller Behörden (CSV)" -#: app/views/general/exception_caught.rhtml:8 -msgid "Check for mistakes if you typed or copied the address." +#: app/controllers/request_controller.rb:775 +msgid "Log in to download a zip file of {{info_request_title}}" msgstr "" -"Sollten Sie die Adresse eingegeben oder kopiert haben, überprüfen Sie diese " -"auf Fehler." +"Melden Sie sich an, um eine Zip-Datei von {{info_request_title}} " +"herunterzuladen" -#: app/views/general/exception_caught.rhtml:9 -msgid "Search the site to find what you were looking for." -msgstr "" -"Duchsuchen Sie die Seite, um die von Ihnen gewünschten Informationen zu " -"finden. " +#: app/models/info_request.rb:791 +msgid "Long overdue." +msgstr "Stark verspätet." -#: app/views/general/exception_caught.rhtml:12 -#: app/views/general/frontpage.rhtml:23 app/views/general/search.rhtml:32 -#: app/views/general/search.rhtml:45 app/views/public_body/list.rhtml:42 -#: app/views/request/_request_filter_form.rhtml:49 -#: app/views/request/select_authority.rhtml:41 -msgid "Search" -msgstr "Suche" +#: app/views/request/_request_filter_form.rhtml:23 +#: app/views/general/search.rhtml:112 +msgid "Made between" +msgstr "Gestellt zwischen" -#: app/views/general/exception_caught.rhtml:17 -msgid "Sorry, there was a problem processing this page" -msgstr "Sorry, bei der Übermittlung dieser Seite sind Probleme aufgetreten" +#: app/views/public_body/show.rhtml:60 +msgid "Make a new <strong>Environmental Information</strong> request" +msgstr "Stellen Sie eine neue <strong>Umwelt-Anfrage</strong>" -#: app/views/general/exception_caught.rhtml:18 +#: app/views/public_body/show.rhtml:62 msgid "" -"You have found a bug. Please <a href=\"{{contact_url}}\">contact us</a> to " -"tell us about the problem" +"Make a new <strong>Freedom of Information</strong> request to " +"{{public_body}}" msgstr "" -"Sie haben einen Fehler gefunden. Bitte <a " -"href=\"{{contact_url}}\">kontaktieren Sie uns</a>, um uns das Problem zu " -"schildern" +"Stellen Sie eine neue <strong>Informationsfreiheitsanfrage</strong> an " +"{{public_body}}" -#: app/views/general/exception_caught.rhtml:21 -msgid "Technical details" -msgstr "Technische Details" +#: app/views/public_body/view_email.rhtml:38 +msgid "Make a new EIR request" +msgstr "" -#: app/views/general/exception_caught.rhtml:22 -msgid "Unknown" -msgstr "Unbekannt" +#: app/views/public_body/view_email.rhtml:40 +msgid "Make a new FOI request" +msgstr "" #: app/views/general/frontpage.rhtml:5 msgid "" @@ -1792,937 +1980,773 @@ msgstr "" "Stellen Sie eine neue<br/>\n" " <strong>Informationsfreiheitsanfrage</strong>" -#: app/views/general/frontpage.rhtml:10 -msgid "Start now »" -msgstr "" - -#: app/views/general/frontpage.rhtml:15 -msgid "" -"Search over<br/>\n" -" <strong>{{number_of_requests}} requests</strong> <span>and</span><br/>\n" -" <strong>{{number_of_authorities}} authorities</strong>" -msgstr "" -"Suchen Sie in mehr als<br/>\n" -" <strong>{{number_of_requests}} Anfragen</strong> <span>und</span><br/>\n" -" <strong>{{number_of_authorities}} Behörden</strong>" +#: app/views/general/_topnav.rhtml:4 +msgid "Make a request" +msgstr "Anfrage stellen" -#: app/views/general/frontpage.rhtml:37 -msgid "Who can I request information from?" -msgstr "Von wem kann ich Informationen anfragen?" +#: app/views/request/new.rhtml:20 +msgid "Make an {{law_used_short}} request to '{{public_body_name}}'" +msgstr "Stellen Sie einen {{law_used_short}} Antrag an '{{public_body_name}}'" -#: app/views/general/frontpage.rhtml:38 -msgid "" -"{{site_name}} covers requests to {{number_of_authorities}} authorities, " -"including:" +#: app/views/layouts/default.rhtml:8 app/views/layouts/no_chrome.rhtml:8 +msgid "Make and browse Freedom of Information (FOI) requests" msgstr "" -"{{site_name}} beinhaltet Anfragen an {{number_of_authorities}} Behörden, " -"einschliesslich:" - -#: app/views/general/frontpage.rhtml:43 -msgid "%d request" -msgid_plural "%d requests" -msgstr[0] "%d Anfrage" -msgstr[1] "%d Anfragen" +"Hier können Sie Anfragen an das Informationsgesetz (IFG)stellen und " +"bestehende Anfragen durchsuchen" -#: app/views/general/frontpage.rhtml:48 -msgid "Browse all authorities..." -msgstr "Durchsuchen Sie alle Behörden" +#: app/views/public_body/_body_listing_single.rhtml:23 +msgid "Make your own request" +msgstr "Eigene Anfrage stellen" -#: app/views/general/frontpage.rhtml:54 -msgid "What information has been released?" -msgstr "Welche Informationen wurden veröffentlicht?" +#: app/views/contact_mailer/message.rhtml:4 +msgid "Message sent using {{site_name}} contact form, " +msgstr "Nachricht gesendet über {{site_name}} Kontaktformular, " -#: app/views/general/frontpage.rhtml:55 -msgid "" -"{{site_name}} users have made {{number_of_requests}} requests, including:" -msgstr "" -"{{site_name}} Benutzer haben {{number_of_requests}} Anfragen gestellt, u.a.:" +#: app/views/request/new_bad_contact.rhtml:1 +msgid "Missing contact details for '" +msgstr "Folgende Kontaktdetails fehlen:" -#: app/views/general/frontpage.rhtml:60 -msgid "answered a request about" -msgstr "eine Anfrage beantwortet über" +#: app/views/public_body/show.rhtml:10 +msgid "More about this authority" +msgstr "Weitere Informationen zu dieser Behörde" -#: app/views/general/frontpage.rhtml:62 -msgid "{{length_of_time}} ago" -msgstr "vor {{length_of_time}} " +#: app/views/request/_sidebar.rhtml:29 +msgid "More similar requests" +msgstr "Weitere ähnliche Anfragen" #: app/views/general/frontpage.rhtml:67 msgid "More successful requests..." msgstr "Weitere erfolgreiche Anfragen" -#: app/views/general/search.rhtml:8 -msgid "Search Freedom of Information requests, public authorities and users" -msgstr "Suchen Sie nach Informationsfreiheitsanfragen, Behörden und Nutzern" - -#: app/views/general/search.rhtml:10 app/views/public_body/show.rhtml:109 -msgid "There were no requests matching your query." -msgstr "Es gab keine zu Ihrer Suche passenden Anfragen." - -#: app/views/general/search.rhtml:12 -msgid "Results page {{page_number}}" -msgstr "Ergebnisanzeige {{page_number}}" - -#: app/views/general/search.rhtml:24 -msgid "" -"To use the advanced search, combine phrases and labels as described in the " -"search tips below." -msgstr "" -"Um die erweiterte Suchoption zu nutzen, kombinieren Sie Formulierungen und " -"Kennzeichen, wie in den unten aufgeführten Suchhinweisen beschrieben. " - -#: app/views/general/search.rhtml:33 -msgid "Simple search" -msgstr "Einfache Suche" +#: app/views/layouts/default.rhtml:107 +msgid "My profile" +msgstr "Mein Profil" -#: app/views/general/search.rhtml:46 -msgid "Advanced search" -msgstr "Erweiterte Suche" +#: app/views/request/_describe_state.rhtml:64 +msgid "My request has been <strong>refused</strong>" +msgstr "Meine Anfrage wurde <strong>abgelehnt</strong>" -#: app/views/general/search.rhtml:51 -#: app/views/request/_request_filter_form.rhtml:29 -msgid "Showing" -msgstr "Anzeigen" +#: app/models/public_body.rb:36 +msgid "Name can't be blank" +msgstr "Name muss eingegeben werden " -#: app/views/general/search.rhtml:56 -msgid "everything" -msgstr "alles" +#: app/models/public_body.rb:40 +msgid "Name is already taken" +msgstr "Benutzername vergeben" -#: app/views/general/search.rhtml:75 -msgid "Tags (separated by a space):" -msgstr "Tags (mit Leerzeichen getrennt):" +#: app/models/track_thing.rb:215 app/models/track_thing.rb:216 +msgid "New Freedom of Information requests" +msgstr "Neue IFG-Anfragen" -#: app/views/general/search.rhtml:87 -msgid "Restrict to" -msgstr "Vorbehalten für" +#: lib/world_foi_websites.rb:21 +msgid "New Zealand" +msgstr "Neuseeland" -#: app/views/general/search.rhtml:88 -#: app/views/request/_request_filter_form.rhtml:31 -msgid "successful requests" -msgstr "erfolgreiche Anfragen" +#: app/views/user/signchangeemail.rhtml:20 +msgid "New e-mail:" +msgstr "Neue Email:" -#: app/views/general/search.rhtml:89 -#: app/views/request/_request_filter_form.rhtml:32 -msgid "unsuccessful requests" -msgstr "nicht erfolgreiche Anfragen" +#: app/models/change_email_validator.rb:53 +msgid "New email doesn't look like a valid address" +msgstr "Die neue Email-Adresse scheint ungültig" -#: app/views/general/search.rhtml:90 -#: app/views/request/_request_filter_form.rhtml:33 -msgid "unresolved requests" -msgstr "ungelöste Anfragen" +#: app/views/user/signchangepassword.rhtml:15 +msgid "New password:" +msgstr "Neues Passwort:" -#: app/views/general/search.rhtml:91 -msgid "internal reviews" -msgstr "interne Prüfung" +#: app/views/user/signchangepassword.rhtml:20 +msgid "New password: (again)" +msgstr "Neues Passwort: (erneut eingeben)" -#: app/views/general/search.rhtml:100 -msgid "Search in" -msgstr "Suchen Sie in" +#: app/models/request_mailer.rb:67 +msgid "New response to your FOI request - " +msgstr "" -#: app/views/general/search.rhtml:101 -#: app/views/request/_request_filter_form.rhtml:12 -msgid "messages from users" -msgstr "Nachrichten von Nutzern" +#: app/views/request/show_response.rhtml:60 +msgid "New response to your request" +msgstr "Neue Antwort auf Ihre Anfrage" -#: app/views/general/search.rhtml:102 -#: app/views/request/_request_filter_form.rhtml:13 -msgid "messages from authorities" -msgstr "Nachrichten von Behörden" +#: app/views/request/show_response.rhtml:66 +msgid "New response to {{law_used_short}} request" +msgstr "Neue Antwort auf {{law_used_short}} Anfrage" -#: app/views/general/search.rhtml:129 -msgid "Show most relevant results first" -msgstr "Relevanteste Suchergebnisse zuerst anzeigen " +#: app/models/track_thing.rb:199 app/models/track_thing.rb:200 +msgid "New updates for the request '{{request_title}}'" +msgstr "Neue Aktualisierungen der Anfrage '{{request_title}}'" #: app/views/general/search.rhtml:131 msgid "Newest results first" msgstr "Aktuellste Ergebnisse zuerst anzeigen" -#: app/views/general/search.rhtml:133 -msgid "Recently described results first" -msgstr "Kürzlich widergegebene Ergebnisse zuerst" - -#: app/views/general/search.rhtml:156 -msgid "One public authority found" -msgstr "Eine Behörde gefunden" +#: app/views/general/_localised_datepicker.rhtml:6 +msgid "Next" +msgstr "Folgende/r" -#: app/views/general/search.rhtml:158 -msgid "Public authorities {{start_count}} to {{end_count}} of {{total_count}}" -msgstr "Behörde {{start_count}} bis {{end_count}} von {{total_count}}" +#: app/views/user/set_draft_profile_photo.rhtml:32 +msgid "Next, crop your photo >>" +msgstr "Nächster Schritt: Passen Sie Ihr Photo an >>" #: app/views/general/search.rhtml:169 msgid "No public authorities found" msgstr "Keine Behörde gefunden" -#: app/views/general/search.rhtml:171 -msgid "Did you mean: {{correction}}" -msgstr "Meinten Sie: {{correction}}" - -#: app/views/general/search.rhtml:173 -msgid "<a href=\"%s\">Browse all</a> or <a href=\"%s\">ask us to add one</a>." -msgstr "" -"<a href=\"%s\">Alle durchsuchen</a> or <a href=\"%s\">bitten Sie uns eine " -"hinzuzufügen</a>." - -#: app/views/general/search.rhtml:180 -msgid "One person found" -msgstr "Eine Person gefunden" - -#: app/views/general/search.rhtml:182 -msgid "People {{start_count}} to {{end_count}} of {{total_count}}" -msgstr "Leute {{start_count}} bis {{end_count}} von {{total_count}}" +#: app/views/request/list.rhtml:19 +msgid "No requests of this sort yet." +msgstr "Es besteht noch keine Anfrage dieser Art." -#: app/views/general/search.rhtml:196 -msgid "One FOI request found" -msgstr "Eine IFG-Anfrage gefunden" +#: app/views/request/select_authority.rhtml:52 +#: app/views/public_body/_search_ahead.rhtml:8 +msgid "No results found." +msgstr "Keine Ergebnisse gefunden." -#: app/views/general/search.rhtml:198 -msgid "FOI requests {{start_count}} to {{end_count}} of {{total_count}}" -msgstr "IFG-Anfragen {{start_count}} bis {{end_count}} von {{total_count}}" +#: app/views/request/similar.rhtml:7 +msgid "No similar requests found." +msgstr "Keine vergleichbaren Anfragen gefunden. " -#: app/views/help/alaveteli.rhtml:6 -msgid "Would you like to see a website like this in your country?" +#: app/views/public_body/show.rhtml:85 +msgid "" +"Nobody has made any Freedom of Information requests to {{public_body_name}} " +"using this site yet." msgstr "" -"Würden Sie eine solche Internetseite gerne für Ihr eigenes Land sehen?" +"Bisher hat niemand eine Anfrage an {{public_body_name}} über diese Seite " +"gestellt." -#: app/views/layouts/default.rhtml:15 app/views/layouts/no_chrome.rhtml:8 -msgid "Make and browse Freedom of Information (FOI) requests" -msgstr "" -"Hier können Sie Anfragen an das Informationsgesetz (IFG)stellen und " -"bestehende Anfragen durchsuchen" +#: app/views/request/_request_listing.rhtml:2 +#: app/views/public_body/_body_listing.rhtml:3 +msgid "None found." +msgstr "Keine gefunden." -#: app/views/layouts/default.rhtml:102 -msgid "Hello, {{username}}!" -msgstr "Hallo, {{username}}!" +#: app/views/user/show.rhtml:167 app/views/user/show.rhtml:187 +msgid "None made." +msgstr "Keine gestellt." -#: app/views/layouts/default.rhtml:105 -msgid "My profile" -msgstr "Mein Profil" +#: app/views/user/confirm.rhtml:1 app/views/user/confirm.rhtml:3 +#: app/views/user/signchangepassword_confirm.rhtml:1 +#: app/views/user/signchangepassword_confirm.rhtml:3 +#: app/views/user/signchangeemail_confirm.rhtml:3 +msgid "Now check your email!" +msgstr "Rufen Sie nun Ihre Emails ab. " -#: app/views/layouts/default.rhtml:109 -msgid "Sign out" -msgstr "Ausloggen" +#: app/views/comment/preview.rhtml:5 +msgid "Now preview your annotation" +msgstr "Überprüfen Sie nun Ihren Kommentar" -#: app/views/layouts/default.rhtml:111 -msgid "Sign in or sign up" -msgstr "Amelden oder registrieren " +#: app/views/request/followup_preview.rhtml:10 +msgid "Now preview your follow up" +msgstr "Überprüfen Sie nun Ihr Follow-up" -#: app/views/layouts/default.rhtml:152 -msgid "Paste this link into emails, tweets, and anywhere else:" -msgstr "" -"Nutzen Sie diesen Link in Emails, tweets und beliebigen weiteren Optionen:" +#: app/views/request/followup_preview.rhtml:8 +msgid "Now preview your message asking for an internal review" +msgstr "Überprüfen Sie nun Ihre Anfrage zur internen Prüfung" -#: app/views/outgoing_mailer/_followup_footer.rhtml:1 -msgid "" -"Disclaimer: This message and any reply that you make will be published on " -"the internet. Our privacy and copyright policies:" -msgstr "" -"Haftungsausschluss: Diese Nachricht und alle Antworten werden im Internet veröffentlicht. \t\n" -"Nutzungsbedingungen und Datenschutz:" +#: app/views/user/set_draft_profile_photo.rhtml:46 +msgid "OR remove the existing photo" +msgstr "OR entfernen Sie das bestehende Photo" -#: app/views/outgoing_mailer/_followup_footer.rhtml:4 +#: app/controllers/request_controller.rb:420 msgid "" -"If you find this service useful as an FOI officer, please ask your web " -"manager to link to us from your organisation's FOI page." +"Oh no! Sorry to hear that your request was refused. Here is what to do now." msgstr "" -"Falls Sie als IFGler diesen Service nützlich finden, bitten Sie bitte Ihren " -"Webadministrator die IFG-Seite Ihrer Organisation mit uns zu verlinken." +"Oh nein! Es tut uns leid zu hören, dass Ihre Anfrage abgelehnt wurde. Lesen " +"Sie hier was Sie nun tun können. " -#: app/views/outgoing_mailer/followup.rhtml:6 -#: app/views/outgoing_mailer/initial_request.rhtml:5 -msgid "Please use this email address for all replies to this request:" -msgstr "" -"Bitte nutzen Sie diese Emailadresse für alle Antworten auf diese Anfrage:" +#: app/views/user/signchangeemail.rhtml:15 +msgid "Old e-mail:" +msgstr "Alte Emailadresse: " -#: app/views/outgoing_mailer/initial_request.rhtml:8 +#: app/models/change_email_validator.rb:44 msgid "" -"Is {{email_address}} the wrong address for {{type_of_request}} requests to " -"{{public_body_name}}? If so, please contact us using this form:" +"Old email address isn't the same as the address of the account you are " +"logged in with" msgstr "" -"Ist {{email_address}} die falsche Email-Adresse für {{type_of_request}} " -"Anfragen an {{public_body_name}}? Sollte dies der Fall sein, so kontaktieren" -" Sie uns bitte über dieses Formular:" - -#: app/views/public_body/_body_listing.rhtml:3 -#: app/views/request/_request_listing.rhtml:2 -msgid "None found." -msgstr "Keine gefunden." +"Die alte Email-Adresse stimmt nicht mit der Adresse des Kontos, über welches" +" Sie eingeloggt sind überein" -#: app/views/public_body/_body_listing_single.rhtml:12 -msgid "Also called {{other_name}}." -msgstr "Auch {{other_name}} genannt." +#: app/models/change_email_validator.rb:39 +msgid "Old email doesn't look like a valid address" +msgstr "Alte Email sieht nicht nach gültiger Adresse aus" -#: app/views/public_body/_body_listing_single.rhtml:21 -msgid "%d request made." -msgid_plural "%d requests made." -msgstr[0] "%d Anfragen gestellt." -msgstr[1] "%d Anfragen gestellt." +#: app/views/user/show.rhtml:32 +msgid "On this page" +msgstr "Auf dieser Seite" -#: app/views/public_body/_body_listing_single.rhtml:23 -msgid "Make your own request" -msgstr "Eigene Anfrage stellen" +#: app/views/general/search.rhtml:196 +msgid "One FOI request found" +msgstr "Eine IFG-Anfrage gefunden" -#: app/views/public_body/_body_listing_single.rhtml:27 -msgid "Added on {{date}}" -msgstr "Hinzugefügt am {{date}}" +#: app/views/general/search.rhtml:180 +msgid "One person found" +msgstr "Eine Person gefunden" -#: app/views/public_body/_search_ahead.rhtml:3 -#: app/views/request/select_authority.rhtml:47 -msgid "Top search results:" -msgstr "Beste Suchergebnisse:" +#: app/views/general/search.rhtml:156 +msgid "One public authority found" +msgstr "Eine Behörde gefunden" -#: app/views/public_body/_search_ahead.rhtml:5 -#: app/views/request/select_authority.rhtml:49 -msgid "Select one to see more information about the authority." +#: app/views/public_body/show.rhtml:119 +msgid "Only requests made using {{site_name}} are shown." msgstr "" -"Wählen Sie eine aus, um mehr Informationen über diese Behörde sehen zu " -"können. " +"Es werden ausschliesslich Anfragen zu folgendem Sucheintrag angezeigt: " +"{{site_name}} " -#: app/views/public_body/_search_ahead.rhtml:8 -#: app/views/request/select_authority.rhtml:52 -msgid "No results found." -msgstr "Keine Ergebnisse gefunden." +#: app/models/info_request.rb:405 +msgid "" +"Only the authority can reply to this request, and I don't recognise the " +"address this reply was sent from" +msgstr "" +"Die Beantwortung dieser Anfrage ist ausschliesslich der Behörde gewährt und " +"die Adresse dieser Antwort ist mir nicht bekannt. " -#: app/views/public_body/list.rhtml:2 -msgid "Show only..." -msgstr "Zeig mir nur..." +#: app/models/info_request.rb:401 +msgid "" +"Only the authority can reply to this request, but there is no \"From\" " +"address to check against" +msgstr "" +"Diese Anfrage kann ausschliesslich von der Behörde beantwortet werden, " +"jedoch besteht keine ´von´ Adresse zum Vergleich. " -#: app/views/public_body/list.rhtml:4 -msgid "Beginning with" -msgstr "Mit Anfangsbuchstabe" +#: app/views/request/_search_ahead.rhtml:10 +msgid "Or search in their website for this information." +msgstr "Oder suchen Sie auf deren Internetseite nach Informationen" -#: app/views/public_body/list.rhtml:28 -msgid "<a href=\"%s\">Are we missing a public authority?</a>." -msgstr "<a href=\"%s\">Fehlt eine Behörde?</a>." +#: app/views/general/_advanced_search_tips.rhtml:42 +msgid "Original request sent" +msgstr "Ursprüngliche Anfrage gesendet" -#: app/views/public_body/list.rhtml:31 -msgid "List of all authorities (CSV)" -msgstr "Liste aller Behörden (CSV)" +#: app/views/request/_describe_state.rhtml:71 +msgid "Other:" +msgstr "Andere/s:" -#: app/views/public_body/list.rhtml:35 -msgid "Public authorities - {{description}}" -msgstr "Behörden - {{description}}" +#: locale/model_attributes.rb:26 +msgid "OutgoingMessage|Body" +msgstr "OutgoingMessage|Body" -#: app/views/public_body/list.rhtml:37 -msgid "Public authorities" -msgstr "Behörden" +#: locale/model_attributes.rb:29 +msgid "OutgoingMessage|Last sent at" +msgstr "OutgoingMessage|Last sent at" -#: app/views/public_body/list.rhtml:46 -msgid "Found {{count}} public bodies {{description}}" -msgstr " {{count}} Behörden {{description}} gefunden" +#: locale/model_attributes.rb:28 +msgid "OutgoingMessage|Message type" +msgstr "OutgoingMessage|Message type" -#: app/views/public_body/list.rhtml:50 -msgid "<a href=\"%s\">Can't find the one you want?</a>" -msgstr "<a href=\"%s\">Gewünschte Behörde nicht gefunden?</a>" +#: locale/model_attributes.rb:27 +msgid "OutgoingMessage|Status" +msgstr "OutgoingMessage|Status" -#: app/views/public_body/show.rhtml:4 -msgid "Follow this authority" -msgstr "Dieser Behörde folgen" +#: locale/model_attributes.rb:30 +msgid "OutgoingMessage|What doing" +msgstr "OutgoingMessage|What doing" -#: app/views/public_body/show.rhtml:7 -msgid "There is %d person following this authority" -msgid_plural "There are %d people following this authority" -msgstr[0] "Diese Behörde wird von %d Person beobachtet" -msgstr[1] "Diese Behörde wird von %d Personen beobachtet." +#: app/models/info_request.rb:797 +msgid "Partially successful." +msgstr "Teilweise erfolgreich. " -#: app/views/public_body/show.rhtml:10 -msgid "More about this authority" -msgstr "Weitere Informationen zu dieser Behörde" +#: app/models/change_email_validator.rb:47 +msgid "Password is not correct" +msgstr "falsches Passwort" -#: app/views/public_body/show.rhtml:12 -msgid "Home page of authority" -msgstr "Offizielle Homepage der Behörde" +#: app/views/user/_signup.rhtml:30 app/views/user/_signin.rhtml:16 +msgid "Password:" +msgstr "Passwort:" -#: app/views/public_body/show.rhtml:15 -msgid "Publication scheme" -msgstr "Veröffentlichungsschema" +#: app/views/user/_signup.rhtml:35 +msgid "Password: (again)" +msgstr "Passwort: (nochmal eingeben)" -#: app/views/public_body/show.rhtml:20 app/views/public_body/show.rhtml:22 -msgid "Charity registration" -msgstr "Charity Registrierung" +#: app/views/layouts/default.rhtml:154 +msgid "Paste this link into emails, tweets, and anywhere else:" +msgstr "" +"Nutzen Sie diesen Link in Emails, tweets und beliebigen weiteren Optionen:" -#: app/views/public_body/show.rhtml:26 -msgid "View FOI email address" -msgstr "IFG-Emailadressen ansehen" +#: app/views/general/search.rhtml:182 +msgid "People {{start_count}} to {{end_count}} of {{total_count}}" +msgstr "Leute {{start_count}} bis {{end_count}} von {{total_count}}" -#: app/views/public_body/show.rhtml:30 -msgid "Freedom of information requests to" -msgstr "IFG-Anfrage an" +#: app/views/user/set_draft_profile_photo.rhtml:13 +msgid "Photo of you:" +msgstr "Ihr Profilbild:" -#: app/views/public_body/show.rhtml:35 -msgid "also called {{public_body_short_name}}" -msgstr "auch genannt: {{public_body_short_name}}" +#: app/views/request/new.rhtml:74 +msgid "Plans and administrative measures that affect these matters" +msgstr "Diese Aspekte beeinflussende Pläne und administrative Maßnahmen" -#: app/views/public_body/show.rhtml:37 -msgid "admin" -msgstr "Administration" +#: app/controllers/request_game_controller.rb:42 +msgid "Play the request categorisation game" +msgstr "Helfen Sie uns ausstehende Anfragen zuzuordnen" -#: app/views/public_body/show.rhtml:46 -msgid "" -"You can only request information about the environment from this authority." -msgstr "" -"Umweltanfragen können ausschliesslich über diese Behörde gestellt werden. " +#: app/views/request_game/play.rhtml:1 app/views/request_game/play.rhtml:30 +msgid "Play the request categorisation game!" +msgstr "Helfen Sie uns ausstehende Anfragen zu kategorisieren!" -#: app/views/public_body/show.rhtml:52 -msgid "Make a new <strong>Environmental Information</strong> request" -msgstr "Stellen Sie eine neue <strong>Umwelt-Anfrage</strong>" +#: app/views/request/show.rhtml:101 +msgid "Please" +msgstr "Bitte" -#: app/views/public_body/show.rhtml:54 -msgid "" -"Make a new <strong>Freedom of Information</strong> request to " -"{{public_body}}" +#: app/views/user/no_cookies.rhtml:15 +msgid "Please <a href=\"%s\">get in touch</a> with us so we can fix it." msgstr "" -"Stellen Sie eine neue <strong>Informationsfreiheitsanfrage</strong> an " -"{{public_body}}" - -#: app/views/public_body/show.rhtml:56 -msgid "<a class=\"link_button_green\" href=\"{{url}}\">{{text}}</a>" -msgstr "<a class=\"link_button_green\" href=\"{{url}}\">{{text}}</a>" - -#: app/views/public_body/show.rhtml:56 -msgid "Start" -msgstr "Start" +"Bitte<a href=\"%s\">nehmen Sie Kontakt mit uns auf</a>, damit wir das " +"Problem beheben können. " -#: app/views/public_body/show.rhtml:60 +#: app/views/request/show.rhtml:52 msgid "" -"Freedom of Information law does not apply to this authority, so you cannot make\n" -" a request to it." -msgstr "" -"Das Informationsfreiheitsgesetz trifft auf diese Behörde nicht zu. Sie " -"können daher keine Anfrage stellen. " - -#: app/views/public_body/show.rhtml:63 -msgid "This authority no longer exists, so you cannot make a request to it." +"Please <strong>answer the question above</strong> so we know whether the " msgstr "" -"Diese Behörde existiert nichtmehr. Es ist folglich nicht möglich eine " -"Anfrage zu stellen. " +"Bitte <strong>beantworten Sie die oben angezeigte Frage</strong>, damit wir " +"wissen ob" -#: app/views/public_body/show.rhtml:65 +#: app/views/user/show.rhtml:12 msgid "" -"For an unknown reason, it is not possible to make a request to this " -"authority." -msgstr "" -"Aus unbekannten Gründen ist es nicht möglich eine Anfrage a diese Behörde zu" -" stellen. " - -#: app/views/public_body/show.rhtml:73 -msgid "Environmental Information Regulations requests made using this site" +"Please <strong>go to the following requests</strong>, and let us\n" +" know if there was information in the recent responses to them." msgstr "" +"Bitte <strong>gehen Sie zu den folgende Anfragen</strong> und teilen Sie uns" +" mit, ob in den letzten Antworten Informationen enthalten waren." -#: app/views/public_body/show.rhtml:76 -msgid "Freedom of Information requests made using this site" -msgstr "Anfrage über diese Seite gestellt" - -#: app/views/public_body/show.rhtml:77 +#: app/views/request/_followup.rhtml:54 msgid "" -"Nobody has made any Freedom of Information requests to {{public_body_name}} " -"using this site yet." +"Please <strong>only</strong> write messages directly relating to your " +"request {{request_link}}. If you would like to ask for information that was " +"not in your original request, then <a href=\"{{new_request_link}}\">file a " +"new request</a>." msgstr "" -"Bisher hat niemand eine Anfrage an {{public_body_name}} über diese Seite " -"gestellt." - -#: app/views/public_body/show.rhtml:85 -msgid "Search within the %d Freedom of Information requests to %s" -msgid_plural "Search within the %d Freedom of Information requests made to %s" -msgstr[0] "Suchen Sie in den %d an %s gestellten IFG-Anfragen" -msgstr[1] "Suchen Sie in den %d an %s gestellten IFG-Anfragen" +"Bitte senden Sie <strong>ausschließlich</strong> Nachrichten, welche sich " +"direkt auf Ihre Anfrage beziehen {{request_link}}. Sollten Sie Informationen" +" anfragen wollen, welche nicht Teil Ihrer ursprünglichen Anfrage sind, dann " +"<a href=\"{{new_request_link}}\">stellen Sie eine neue Anfrage</a>." -#: app/views/public_body/show.rhtml:87 -msgid "%d Freedom of Information request to %s" -msgid_plural "%d Freedom of Information requests to %s" -msgstr[0] "%d Informationsfreiheitsanfrage an %s" -msgstr[1] "%d Informationsfreiheitsanfragen an %s" +#: app/views/request/new.rhtml:58 +msgid "Please ask for environmental information only" +msgstr "Bitte fragen Sie ausschliesslich nach Umweltinformationen" -#: app/views/public_body/show.rhtml:111 -msgid "Only requests made using {{site_name}} are shown." +#: app/views/user/bad_token.rhtml:2 +msgid "" +"Please check the URL (i.e. the long code of letters and numbers) is copied\n" +"correctly from your email." msgstr "" -"Es werden ausschliesslich Anfragen zu folgendem Sucheintrag angezeigt: " -"{{site_name}} " +"Bitte überprüfen Sie, ob Sie die URL (Webadresse) korrekt aus Ihrer Email " +"kopiert haben. " -#: app/views/public_body/show.rhtml:116 -msgid "Environmental Information Regulations requests made" -msgstr "" +#: app/models/profile_photo.rb:91 +msgid "Please choose a file containing your photo." +msgstr "Bitte wählen Sie eine Datei mit Ihrem Foto." -#: app/views/public_body/show.rhtml:118 -msgid "Freedom of Information requests made" -msgstr "Anfrage ausgeführt" +#: app/models/outgoing_message.rb:163 +msgid "Please choose what sort of reply you are making." +msgstr "Bitte wählen Sie, welche Art von Antwort Sie geben." -#: app/views/public_body/show.rhtml:120 +#: app/controllers/request_controller.rb:352 msgid "" -"The search index is currently offline, so we can't show the Freedom of " -"Information requests that have been made to this authority." +"Please choose whether or not you got some of the information that you " +"wanted." msgstr "" -"Da die Suchanzeige momentan offline ist, können wir die an diese Behörde " -"gestellten Informationsfreiheitsanfragen gerade leider nicht anzeigen. " - -#: app/views/public_body/view_email.rhtml:3 -msgid "FOI email address for {{public_body}}" -msgstr "IFG-Emailadresse für {{public_body}}" +"Bitte wählen Sie ob Sie einige der erwünschten Informationen erhalten haben " +"oder ob dies nicht der Fall ist. " -#: app/views/public_body/view_email.rhtml:7 -msgid "" -"{{site_name}} sends new requests to <strong>{{request_email}}</strong> for " -"this authority." +#: app/views/track_mailer/event_digest.rhtml:63 +msgid "Please click on the link below to cancel or alter these emails." msgstr "" +"Bitte klicken Sie auf den unten angezeigten Link, um diese Emails zu " +"annullieren oder ändern." -#: app/views/public_body/view_email.rhtml:10 +#: app/views/user_mailer/changeemail_confirm.rhtml:3 msgid "" -"Freedom of Information law no longer applies to this authority.Follow up " -"messages to existing requests are sent to " +"Please click on the link below to confirm that you want to \n" +"change the email address that you use for {{site_name}}\n" +"from {{old_email}} to {{new_email}}" msgstr "" -"Das Informationsfreiheitsgesetz ist für diese Behörde nicht länger gültig. " -"Follow-up Nachrichten bestehnder Nachrichten wurden gesendet an" - -#: app/views/public_body/view_email.rhtml:14 -msgid "Follow up messages to existing requests are sent to " -msgstr "Nachfragen bzgl. bestehender anfragen werden weitergeleitet an:" +"Bitte klicken Sie auf den unten angezeigten Link, um zu bestätigen, dass Sie \n" +"die für {{site_name}} verwendete Email-Adresse\n" +"von {{old_email}} in {{new_email}} ändern möchten" -#: app/views/public_body/view_email.rhtml:17 -msgid "We do not have a working request email address for this authority." +#: app/views/user_mailer/confirm_login.rhtml:3 +msgid "Please click on the link below to confirm your email address." msgstr "" -"Für diese Behörde ist keine funktionierende Emailadresse zur " -"Anfragenstellung verfügbar. " +"Klicken Sie auf den unten aufgeführten Link, um Ihre Emailadresse zu " +"bestätigen." -#: app/views/public_body/view_email.rhtml:28 +#: app/models/info_request.rb:126 msgid "" -"If the address is wrong, or you know a better address, please <a " -"href=\"%s\">contact us</a>." +"Please describe more what the request is about in the subject. There is no " +"need to say it is an FOI request, we add that on anyway." msgstr "" -"Sollte die Adresse falsch sein oder sollten Sie eine bessere Adresse kennen," -" so <a href=\"%s\">kontaktieren Sie uns</a>bitte." +"Bitte beschreiben Sie im Betreff, um was es in der Anfrage geht. Sie " +"brauchen nicht sagen, dass es eine IFG-Anfrage ist, dies wird automatisch " +"hinzugefügt." -#: app/views/public_body/view_email.rhtml:30 +#: app/views/user/set_draft_profile_photo.rhtml:22 msgid "" -" If you know the address to use, then please <a href=\"%s\">send it to us</a>.\n" -" You may be able to find the address on their website, or by phoning them up and asking." +"Please don't upload offensive pictures. We will take down images\n" +" that we consider inappropriate." msgstr "" -"Sollten Sie die korrekte Adresse kennen, <a href=\"%s\">senden Sie sie uns</a>.\n" -" Sie können die Adresse wahrscheinlich auf der Webseite oder durch einen Anruf bei der Behörde herausfinden. " - -#: app/views/public_body/view_email_captcha.rhtml:1 -msgid "View FOI email address for '{{public_body_name}}'" -msgstr "IFG-Emailadresse für {{public_body}} ansehen" +"Bitte verwenden Sie keine anstößigen Bilder. Alle unangemessenen Bilder " +"werden von uns entfernt." -#: app/views/public_body/view_email_captcha.rhtml:3 -msgid "View FOI email address for {{public_body_name}}" -msgstr "IFG-Emailadresse für {{public_body}} ansehen" +#: app/views/user/no_cookies.rhtml:3 +msgid "Please enable \"cookies\" to carry on" +msgstr "Bitte erlauben Sie Cookies, um fortzufahren" -#: app/views/public_body/view_email_captcha.rhtml:5 -msgid "" -"To view the email address that we use to send FOI requests to " -"{{public_body_name}}, please enter these words." -msgstr "" -"Geben Sie bitte diese Worte ein, um die Email-Adresse zu sehen, welche wir " -"verwenden, um IFG-Anfragen an {{public_body_name}} zu senden." +#: app/models/user.rb:40 +msgid "Please enter a password" +msgstr "Bitte geben Sie ein Passwort ein" -#: app/views/public_body/view_email_captcha.rhtml:12 -msgid "View email" -msgstr "Email ansehen" +#: app/models/contact_validator.rb:30 +msgid "Please enter a subject" +msgstr "Bitte geben Sie einen Betreff ein" -#: app/views/request/_after_actions.rhtml:3 -msgid "Things to do with this request" -msgstr "Weitere Möglichkeiten für diese Anfrage" +#: app/models/info_request.rb:34 +msgid "Please enter a summary of your request" +msgstr "Bitte geben Sie eine Zusammenfassung Ihrer Anfrage ein" -#: app/views/request/_after_actions.rhtml:6 -msgid "Anyone:" -msgstr "Jedermann:" +#: app/models/user.rb:117 +msgid "Please enter a valid email address" +msgstr "Bitte geben Sie eine gültige E-Mail-Adresse ein" -#: app/views/request/_after_actions.rhtml:9 -msgid "<a href=\"%s\">Add an annotation</a> (to help the requester or others)" -msgstr "" -"<a href=\"%s\">Kommentar hinzufügen</a> (um den Anfragensteller oder andere " -"Nutzern zu unterstützen)" +#: app/models/contact_validator.rb:31 +msgid "Please enter the message you want to send" +msgstr "Bitte geben Sie die Nachricht ein, die Sie senden wollen" -#: app/views/request/_after_actions.rhtml:13 -#: app/views/request/_after_actions.rhtml:35 -msgid "Update the status of this request" -msgstr "Status der Anfrage aktualisieren" +#: app/models/user.rb:51 +msgid "Please enter the same password twice" +msgstr "Bitte geben Sie das gleiche Passwort zweimal ein" -#: app/views/request/_after_actions.rhtml:17 -msgid "Download a zip file of all correspondence" -msgstr "Laden Sie eine Zip-Datei des gesamten Schriftverkehrs herunter." +#: app/models/comment.rb:59 +msgid "Please enter your annotation" +msgstr "Bitte geben Sie Ihre Anmerkung ein" -#: app/views/request/_after_actions.rhtml:23 -msgid "{{info_request_user_name}} only:" -msgstr "Nur {{info_request_user_name}}:" +#: app/models/user.rb:36 app/models/contact_validator.rb:29 +msgid "Please enter your email address" +msgstr "Bitte geben Sie Ihre E-Mail Adresse ein" -#: app/views/request/_after_actions.rhtml:28 -msgid "Send a followup" -msgstr "Nachfrage senden" +#: app/models/outgoing_message.rb:148 +msgid "Please enter your follow up message" +msgstr "Bitte geben Sie Ihre Follow-Up-Nachricht ein" -#: app/views/request/_after_actions.rhtml:30 -msgid "Write a reply" -msgstr "Schreiben Sie eine Antwort" +#: app/models/outgoing_message.rb:151 +msgid "Please enter your letter requesting information" +msgstr "Bitte geben Sie Ihre Briefanfrage-Informationen ein" -#: app/views/request/_after_actions.rhtml:39 -msgid "Request an internal review" -msgstr "Interne Prüfung anfragen" +#: app/models/user.rb:38 app/models/contact_validator.rb:28 +msgid "Please enter your name" +msgstr "Bitte geben Sie Ihren Namen ein" -#: app/views/request/_after_actions.rhtml:45 -msgid "{{public_body_name}} only:" -msgstr "Nur {{public_body_name}}:" +#: app/models/user.rb:120 +msgid "Please enter your name, not your email address, in the name field." +msgstr "" +"Bitte geben Sie Ihren Namen und nicht Ihre E-Mail-Adresse in das Name-Feld " +"ein." -#: app/views/request/_after_actions.rhtml:48 -msgid "Respond to request" -msgstr "Auf Anfrage reagieren" +#: app/models/change_email_validator.rb:30 +msgid "Please enter your new email address" +msgstr "Bitte geben Sie Ihre neue Email-Adresse ein" -#: app/views/request/_correspondence.rhtml:12 -#: app/views/request/_correspondence.rhtml:36 -#: app/views/request/simple_correspondence.rhtml:14 -#: app/views/request/simple_correspondence.rhtml:27 -msgid "From:" -msgstr "Von:" +#: app/models/change_email_validator.rb:29 +msgid "Please enter your old email address" +msgstr "Bitte geben Sie Ihre alte E-Mail-Adresse ein" -#: app/views/request/_correspondence.rhtml:26 -#: app/views/request/_correspondence.rhtml:54 -msgid "Link to this" -msgstr "Link erstellen" +#: app/models/change_email_validator.rb:31 +msgid "Please enter your password" +msgstr "Bitte geben Sie Ihr Passwort ein" -#: app/views/request/_describe_state.rhtml:4 -msgid "What best describes the status of this request now?" -msgstr "Was ist die beste Beschreibung für diese Anfrage?" +#: app/models/outgoing_message.rb:146 +msgid "Please give details explaining why you want a review" +msgstr "Bitte machen Sie Angaben, warum Sie eine Durchsicht möchten" -#: app/views/request/_describe_state.rhtml:7 -#: app/views/request/_other_describe_state.rhtml:10 -msgid "This request is still in progress:" -msgstr "Diese Anfrage ist noch in Bearbeitung" +#: app/models/about_me_validator.rb:24 +msgid "Please keep it shorter than 500 characters" +msgstr "Bitte bleiben Sie unter 500 Zeichen" -#: app/views/request/_describe_state.rhtml:11 +#: app/models/info_request.rb:123 msgid "" -"I'm still <strong>waiting</strong> for my information\n" -" <small>(maybe you got an acknowledgement)</small>" +"Please keep the summary short, like in the subject of an email. You can use " +"a phrase, rather than a full sentence." msgstr "" -"Ich <strong>warte</strong> noch immer auf meine Informationen\n" -" <small>(vielleicht haben Sie eine Bestätigung erhalten)</small>" - -#: app/views/request/_describe_state.rhtml:18 -msgid "I'm still <strong>waiting</strong> for the internal review" -msgstr "Ich <strong>warte</strong> noch immer auf die interne Prüfung" +"Bitte halten Sie die Zusammenfassung kurz, wie in der Betreffzeile einer " +"E-Mail. Sie können eine Phrase, sondern als ein ganzer Satz." -#: app/views/request/_describe_state.rhtml:25 -msgid "I've been asked to <strong>clarify</strong> my request" +#: app/views/request/new.rhtml:77 +msgid "" +"Please only request information that comes under those categories, <strong>do not waste your\n" +" time</strong> or the time of the public authority by requesting unrelated information." msgstr "" -"Ich wurde gebeten meine Anfrage <strong>deutlicher zu erläutern</strong>" - -#: app/views/request/_describe_state.rhtml:32 -msgid "I'm waiting for an <strong>internal review</strong> response" -msgstr "Ich warte auf eine Antwort der <strong>internen Prüfung</strong>" - -#: app/views/request/_describe_state.rhtml:38 -msgid "They are going to reply <strong>by post</strong>" -msgstr "Ich erhalte meine Antwort <strong>auf dem Postweg</strong>" - -#: app/views/request/_describe_state.rhtml:44 -#: app/views/request/_other_describe_state.rhtml:40 -msgid "This particular request is finished:" -msgstr "Diese Anfrage wurde abgeschlossen:" - -#: app/views/request/_describe_state.rhtml:47 -#: app/views/request/_other_describe_state.rhtml:43 -msgid "The <strong>review has finished</strong> and overall:" -msgstr "Die <strong>Prüfung wurde abgeschlossen</strong> und insgesamt:" +"Bitte fragen Sie ausschliesslich auf diese Kategorien zutreffende " +"Informationen an. <strong>Verschwenden Sie nicht Ihre⏎Zeit</strong> oder die" +" Zeit der Behörde, indem Sie nicht zutreffende Informationen anfragen." -#: app/views/request/_describe_state.rhtml:52 +#: app/views/request/new_please_describe.rhtml:5 msgid "" -"They do <strong>not have</strong> the information <small>(maybe they say who" -" does)</small>" +"Please select each of these requests in turn, and <strong>let everyone know</strong>\n" +"if they are successful yet or not." msgstr "" -"Die Informationen <strong>liegen nicht vor</strong> <small>(vielleicht " -"können sie Ihnen mitteilen von wem Sie die Informationen erhalten " -"können)</small>" - -#: app/views/request/_describe_state.rhtml:56 -msgid "I've received <strong>some of the information</strong>" -msgstr "Angefragte Information <strong> teilweise erhalten </strong>" - -#: app/views/request/_describe_state.rhtml:60 -msgid "I've received <strong>all the information" -msgstr "Angefragte Information <strong> vollständig erhalten" - -#: app/views/request/_describe_state.rhtml:64 -msgid "My request has been <strong>refused</strong>" -msgstr "Meine Anfrage wurde <strong>abgelehnt</strong>" - -#: app/views/request/_describe_state.rhtml:71 -msgid "Other:" -msgstr "Andere/s:" - -#: app/views/request/_describe_state.rhtml:76 -msgid "I've received an <strong>error message</strong>" -msgstr "Fehlerhafte Information <strong>erhalten</strong>" - -#: app/views/request/_describe_state.rhtml:84 -msgid "This request <strong>requires administrator attention</strong>" -msgstr "Diese Anfrage <strong>müsste einmal überprüft werden</strong>" - -#: app/views/request/_describe_state.rhtml:91 -msgid "I would like to <strong>withdraw this request</strong>" -msgstr "Ich möchte diese <strong>Anfrage zurückziehen</strong>" - -#: app/views/request/_describe_state.rhtml:101 -msgid "Submit status" -msgstr "Status senden" - -#: app/views/request/_describe_state.rhtml:101 -msgid "and we'll suggest <strong>what to do next</strong>" -msgstr "und wir werden <strong>nächstmögliche Schritte</strong> vorschlagen" +"Bitte wählen Sie diese Anfragen der Reihe nach aus und <strong>lassen Sie " +"jederman wissen</strong>, ob sie bereits erfolgreich waren oder noch nicht. " -#: app/views/request/_describe_state.rhtml:107 +#: app/models/outgoing_message.rb:157 msgid "" -"We don't know whether the most recent response to this request contains\n" -" information or not\n" -" –\n" -"\tif you are {{user_link}} please <a href=\"{{url}}\">sign in</a> and let everyone know." +"Please sign at the bottom with your name, or alter the \"%{signoff}\" " +"signature" msgstr "" -"Wir sind nicht sicher, ob die letzte Antwort auf diese Anfrage Informationen enthält\n" -" –\n" -"<span class=\"whitespace other\" title=\"Tab\">»</span>falls Sie {{user_link}} sind, bitte <a href=\"{{url}}\">melden Sich an</a> und lassen es uns wissen. " +"Bitte unterschreiben Sie unten mit Ihrem Namen oder ändern Sie Ihre \"% " +"{signoff}\" Signatur" -#: app/views/request/_followup.rhtml:3 -msgid "the main FOI contact at {{public_body}}" -msgstr "der Hauptkontakt für {{public_body}}" +#: app/views/user/sign.rhtml:8 +msgid "Please sign in as " +msgstr "Anmelden als" -#: app/views/request/_followup.rhtml:8 -msgid "Request an internal review from {{person_or_body}}" -msgstr "Interne Prüfung von {{person_or_body}} anfragen" +#: app/controllers/request_controller.rb:741 +msgid "Please type a message and/or choose a file containing your response." +msgstr "" +"Bitte geben Sie eine Nachricht ein und / oder wählen Sie eine Datei aus, " +"welche Ihre Antwort enthält" -#: app/views/request/_followup.rhtml:11 -msgid "Send a public follow up message to {{person_or_body}}" -msgstr "Öffentliche Nachfrage an {{person_or_body}} senden" +#: app/controllers/request_controller.rb:440 +msgid "Please use the form below to tell us more." +msgstr "Bitte nutzen Sie das Formular, um uns ausführlicher zu informieren. " -#: app/views/request/_followup.rhtml:14 -msgid "Send a public reply to {{person_or_body}}" -msgstr "Öffentliche Antwort an {{person_or_body}} senden" +#: app/views/outgoing_mailer/followup.rhtml:6 +#: app/views/outgoing_mailer/initial_request.rhtml:5 +msgid "Please use this email address for all replies to this request:" +msgstr "" +"Bitte nutzen Sie diese Emailadresse für alle Antworten auf diese Anfrage:" -#: app/views/request/_followup.rhtml:19 +#: app/models/info_request.rb:35 +msgid "Please write a summary with some text in it" +msgstr "Bitte schreiben Sie eine Zusammenfassung mit etwas Text" + +#: app/models/info_request.rb:120 msgid "" -"Don't want to address your message to {{person_or_body}}? You can also " -"write to:" +"Please write the summary using a mixture of capital and lower case letters. " +"This makes it easier for others to read." msgstr "" -"Möchten Sie Ihre Nachricht nicht an {{person_or_body}} senden? Schreiben " -"Sie alternativ an:" - -#: app/views/request/_followup.rhtml:23 app/views/request/_followup.rhtml:28 -#: app/views/request/_followup.rhtml:34 -msgid "the main FOI contact address for {{public_body}}" -msgstr "die Haupt-Kontaktadresse für {{public_body}}" +"Bitte nutzen Sie eine Mischung aus Groß- und Kleinschreibung für die " +"Zusammenfassung. Dies vereinfacht das Lesen für andere." -#: app/views/request/_followup.rhtml:43 +#: app/models/comment.rb:62 msgid "" -"Follow ups and new responses to this request have been stopped to prevent " -"spam. Please <a href=\"{{url}}\">contact us</a> if you are {{user_link}} and" -" need to send a follow up." +"Please write your annotation using a mixture of capital and lower case " +"letters. This makes it easier for others to read." msgstr "" -"Nachfragen und Antworten auf diese Anfrage wurden gestoppt, um Spam " -"vorzubeugen. Bitte <a href=\"{{url}}\">kontaktieren Sie uns</a> falls Sie " -"{{user_link}} sind und eine Nachfrage senden müssen." +"Bitte nutzen Sie eine Mischung aus Groß- und Kleinschreibung für Ihre " +"Anmerkung. Dies vereinfacht das Lesen für andere." -#: app/views/request/_followup.rhtml:47 +#: app/controllers/request_controller.rb:429 msgid "" -"If you are dissatisfied by the response you got from\n" -" the public authority, you have the right to\n" -" complain (<a href=\"%s\">details</a>)." +"Please write your follow up message containing the necessary clarifications " +"below." msgstr "" -"Sollten Sie mit den erhaltenen Informationen nicht zufrieden sein, haben Sie" -" das Recht eine Beschwerde einzureichen (<a href=\"%s\">Details</a>)." +"Bitte geben Sie unten Ihre Follow-up Nachricht mit den nötigen " +"Klärungsdetails ein. " -#: app/views/request/_followup.rhtml:54 +#: app/models/outgoing_message.rb:160 msgid "" -"Please <strong>only</strong> write messages directly relating to your " -"request {{request_link}}. If you would like to ask for information that was " -"not in your original request, then <a href=\"{{new_request_link}}\">file a " -"new request</a>." +"Please write your message using a mixture of capital and lower case letters." +" This makes it easier for others to read." msgstr "" -"Bitte senden Sie <strong>ausschließlich</strong> Nachrichten, welche sich " -"direkt auf Ihre Anfrage beziehen {{request_link}}. Sollten Sie Informationen" -" anfragen wollen, welche nicht Teil Ihrer ursprünglichen Anfrage sind, dann " -"<a href=\"{{new_request_link}}\">stellen Sie eine neue Anfrage</a>." +"Bitte nutzen Sie eine Mischung aus Groß- und Kleinschreibung für Ihre " +"Nachricht. Dies vereinfacht das Lesen für andere." -#: app/views/request/_followup.rhtml:59 +#: app/views/comment/new.rhtml:42 msgid "" -"The response to your request has been <strong>delayed</strong>. You can say that, \n" -" by law, the authority should normally have responded\n" -" <strong>promptly</strong> and" +"Point to <strong>related information</strong>, campaigns or forums which may" +" be useful." msgstr "" -"Die Beantwortung auf Ihre Anfrage ist verspätet. Nach gesetzlicher " -"Vorschrift sollte die Behörde unverzüglich geantwortet haben und" +"Weisen Sie auf ähnliche, evtl. nütziche Informationen, Kampagnen oder Foren " +"hin" -#: app/views/request/_followup.rhtml:63 app/views/request/show.rhtml:70 -#: app/views/request/show.rhtml:80 -msgid "in term time" -msgstr "während des Semesters" +#: app/views/request/_search_ahead.rhtml:3 +msgid "Possibly related requests:" +msgstr "Eventuell ähnliche Anfrage:" -#: app/views/request/_followup.rhtml:65 -msgid "by <strong>{{date}}</strong>" -msgstr "bis zum <strong>{{date}}</strong>" +#: app/views/comment/preview.rhtml:21 +msgid "Post annotation" +msgstr "Anmerkung hinzufügen" -#: app/views/request/_followup.rhtml:66 app/views/request/_followup.rhtml:73 -#: app/views/request/show.rhtml:83 app/views/request/show.rhtml:87 -msgid "<a href=\"%s\">details</a>" -msgstr "<a href=\"%s\">Details</a>" +#: locale/model_attributes.rb:53 +msgid "PostRedirect|Circumstance" +msgstr "PostRedirect|Circumstance" -#: app/views/request/_followup.rhtml:71 -msgid "" -"The response to your request is <strong>long overdue</strong>. You can say that, by \n" -" law, under all circumstances, the authority should have responded\n" -" by now" -msgstr "" -"The response to your request is <strong>long overdue</strong>. Nach " -"gesetzlicher Vorschrift sollte {{public_body_link}} Ihnen inzwischen unter " -"allen Umständen geantwortet haben. " +#: locale/model_attributes.rb:51 +msgid "PostRedirect|Email token" +msgstr "PostRedirect|Email token" -#: app/views/request/_followup.rhtml:85 -msgid "What are you doing?" -msgstr "Was machen Sie?" +#: locale/model_attributes.rb:50 +msgid "PostRedirect|Post params yaml" +msgstr "PostRedirect|Post params yaml" -#: app/views/request/_followup.rhtml:95 -msgid "I am asking for <strong>new information</strong>" -msgstr "Ich beantrage <strong>neue Informationen</strong>" +#: locale/model_attributes.rb:52 +msgid "PostRedirect|Reason params yaml" +msgstr "PostRedirect|Reason params yaml" -#: app/views/request/_followup.rhtml:100 -msgid "I am requesting an <strong>internal review</strong>" -msgstr "Ich stelle eine Anfrage zur <strong>internen Prüfung</strong>" +#: locale/model_attributes.rb:48 +msgid "PostRedirect|Token" +msgstr "PostRedirect|Token" -#: app/views/request/_followup.rhtml:101 -msgid "<a href=\"%s\">what's that?</a>" -msgstr "<a href=\"%s\">Was ist das?</a>" +#: locale/model_attributes.rb:49 +msgid "PostRedirect|Uri" +msgstr "PostRedirect|Uri" -#: app/views/request/_followup.rhtml:106 -msgid "" -"<strong>Anything else</strong>, such as clarifying, prompting, thanking" -msgstr "<strong>Alles andere</strong>, z.B. Klärungen, Hinweise, Danksagungen" +#: app/views/general/blog.rhtml:53 +msgid "Posted on {{date}} by {{author}}" +msgstr "Verfasst am {{date}} durch {{author}}" -#: app/views/request/_followup.rhtml:112 -msgid "" -"Edit and add <strong>more details</strong> to the message above,\n" -" explaining why you are dissatisfied with their response." +#: app/views/general/_credits.rhtml:1 +msgid "Powered by <a href=\"http://www.alaveteli.org/\">Alaveteli</a>" +msgstr "Unterstützt von <a href=\"http://www.alaveteli.org/\">Alaveteli</a>" + +#: app/views/general/_localised_datepicker.rhtml:5 +msgid "Prev" msgstr "" -"Bearbeiten Sie Ihre Anfrage und fügen Sie <strong>weitere Details</strong> hinzu,\n" -" explaining why you are dissatisfied with their response." + +#: app/views/request/followup_preview.rhtml:1 +msgid "Preview follow up to '" +msgstr "Überprüfen Sie die Nachfrage an" + +#: app/views/comment/preview.rhtml:1 +msgid "Preview new annotation on '{{info_request_title}}'" +msgstr "Sehen Sie den neuen Kommentar zu '{{info_request_title}}'" + +#: app/views/comment/_comment_form.rhtml:15 +msgid "Preview your annotation" +msgstr "Überprüfen Sie Ihren Kommentar" #: app/views/request/_followup.rhtml:123 msgid "Preview your message" msgstr "Anfrage ansehen" -#: app/views/request/_hidden_correspondence.rhtml:10 -msgid "" -"This response has been hidden. See annotations to find out why.\n" -" If you are the requester, then you may <a href=\"%s\">sign in</a> to view the response." -msgstr "" -"Dieser Kommentar wurde verborgen. Sehen Sie die Anmerkungen, um den Grund zu" -" erfahren. Falls Sie diese Anfrage gestellt haben können Sie sich <a " -"href=\"%s\">anmelden</a> um die Antwort zu lesen." +#: app/views/request/new.rhtml:143 +msgid "Preview your public request" +msgstr "Vorschau der Anfrage ansehen" -#: app/views/request/_hidden_correspondence.rhtml:17 -msgid "" -"This outgoing message has been hidden. See annotations to\n" -"\t\t\t\t\t\tfind out why. If you are the requester, then you may <a href=\"%s\">sign in</a> to view the response." -msgstr "" -"Dieser Kommentar wurde verborgen. Sehen Sie die Anmerkungen, um den Grund zu" -" erfahren. Falls Sie diese Anfrage gestellt haben können Sie sich <a " -"href=\"%s\">einloggen</a> um die Antwort zu lesen." +#: locale/model_attributes.rb:15 +msgid "ProfilePhoto|Data" +msgstr "ProfilePhoto|Data" -#: app/views/request/_hidden_correspondence.rhtml:23 -msgid "" -"This comment has been hidden. See annotations to\n" -" find out why. If you are the requester, then you may <a href=\"%s\">sign in</a> to view the response." -msgstr "" -"Dieser Kommentar wurde verborgen. Sehen Sie die Anmerkungen, um den Grund zu" -" erfahren. Falls Sie diese Anfrage gestellt haben können Sie sich <a " -"href=\"%s\">einloggen</a> um die Antwort zu lesen." +#: locale/model_attributes.rb:16 +msgid "ProfilePhoto|Draft" +msgstr "ProfilePhoto|Draft" -#: app/views/request/_hidden_correspondence.rhtml:32 -msgid "unexpected prominence on request event" -msgstr "" +#: app/views/public_body/list.rhtml:38 +msgid "Public authorities" +msgstr "Behörden" -#: app/views/request/_other_describe_state.rhtml:4 -msgid "" -"Hi! We need your help. The person who made the following request\n" -" hasn't told us whether or not it was successful. Would you mind taking\n" -" a moment to read it and help us keep the place tidy for everyone?\n" -" Thanks." -msgstr "" -"Hallo! Wir brauchen Ihre Hilfe. Die Person, welche die folgende Anfrage " -"gestellt hat, hat uns nicht mitgeteilt ob diese erfolgreich war. Wäre es " -"okaz für Sie sich einen Moment Zeit zu nehmen, um die Anfrage zu lesen und " -"uns somit zu helfen die Zeite für jedermann aktuell zu halten?" +#: app/views/public_body/list.rhtml:36 +msgid "Public authorities - {{description}}" +msgstr "Behörden - {{description}}" -#: app/views/request/_other_describe_state.rhtml:14 -msgid "" -"<strong>No response</strong> has been received\n" -" <small>(maybe there's just an acknowledgement)</small>" -msgstr "" -"Es wurde <strong>Keine Antwort</strong> empfangen\n" -" <small>(vielleicht gab es nur eine Bestätigung)</small>" +#: app/views/general/search.rhtml:158 +msgid "Public authorities {{start_count}} to {{end_count}} of {{total_count}}" +msgstr "Behörde {{start_count}} bis {{end_count}} von {{total_count}}" -#: app/views/request/_other_describe_state.rhtml:21 -msgid "Still awaiting an <strong>internal review</strong>" -msgstr "<strong>internal review</strong> weiterhin ausstehend" +#: locale/model_attributes.rb:12 +msgid "PublicBody|First letter" +msgstr "PublicBody|First letter" -#: app/views/request/_other_describe_state.rhtml:28 -msgid "<strong>Clarification</strong> has been requested" -msgstr "Klärung der Angelegenheit wurde angefragt" +#: locale/model_attributes.rb:10 +msgid "PublicBody|Home page" +msgstr "PublicBody|Home page" -#: app/views/request/_other_describe_state.rhtml:34 -msgid "A response will be sent <strong>by post</strong>" -msgstr "Antwort wird <strong>postalisch</strong> zugestellt" +#: locale/model_attributes.rb:8 +msgid "PublicBody|Last edit comment" +msgstr "PublicBody|Last edit comment" -#: app/views/request/_other_describe_state.rhtml:48 -msgid "" -"The authority do <strong>not have</strong> the information <small>(maybe " -"they say who does)" -msgstr "" -"Die Informationen <strong>liegen der Behörde nicht vor</strong> the " -"information <small>(vielleicht können sie Ihnen mitteilen von wem Sie die " -"Informationen erhalten können)" +#: locale/model_attributes.rb:7 +msgid "PublicBody|Last edit editor" +msgstr "PublicBody|Last edit editor" -#: app/views/request/_other_describe_state.rhtml:52 -msgid "<strong>Some of the information</strong> has been sent " -msgstr "Information wurde teilweise gesendet" +#: locale/model_attributes.rb:3 +msgid "PublicBody|Name" +msgstr "Behörde|Name" -#: app/views/request/_other_describe_state.rhtml:56 -msgid "<strong>All the information</strong> has been sent" -msgstr "Informationen wurden vollständig gesendet" +#: locale/model_attributes.rb:11 +msgid "PublicBody|Notes" +msgstr "Behörde|Anmerkung" -#: app/views/request/_other_describe_state.rhtml:60 -msgid "The request has been <strong>refused</strong>" -msgstr "Die Anfrage wurde <strong>abgelehnt</strong>" +#: locale/model_attributes.rb:13 +msgid "PublicBody|Publication scheme" +msgstr "PublicBody|Publication scheme" -#: app/views/request/_other_describe_state.rhtml:70 -msgid "An <strong>error message</strong> has been received" -msgstr "Eine <strong>Fehlermeldung</strong> wurde empfangen" +#: locale/model_attributes.rb:5 +msgid "PublicBody|Request email" +msgstr "Behörde|Email anfragen" -#: app/views/request/_request_filter_form.rhtml:6 -msgid "Keywords" -msgstr "Stichwörter" +#: locale/model_attributes.rb:4 +msgid "PublicBody|Short name" +msgstr "PublicBody|Short name" -#: app/views/request/_request_filter_form.rhtml:11 -msgid "Search for words in:" -msgstr "Suchen Sie nach Begriffen in:" +#: locale/model_attributes.rb:9 +msgid "PublicBody|Url name" +msgstr "Behörde|URL" -#: app/views/request/_request_filter_form.rhtml:23 -msgid "Made between" -msgstr "Gestellt zwischen" +#: locale/model_attributes.rb:6 +msgid "PublicBody|Version" +msgstr "Behörde|Version" -#: app/views/request/_request_filter_form.rhtml:25 -msgid "and" -msgstr "und" +#: app/views/public_body/show.rhtml:23 +msgid "Publication scheme" +msgstr "Veröffentlichungsschema" -#: app/views/request/_request_filter_form.rhtml:30 -msgid "all requests" -msgstr "alle Anfragen" +#: app/views/track/_tracking_links.rhtml:26 +msgid "RSS feed" +msgstr "RSS feed" -#: app/views/request/_request_listing_short_via_event.rhtml:9 -msgid "To {{public_body_link_absolute}}" -msgstr "An {{public_body_link_absolute}}" +#: app/views/track/_tracking_links.rhtml:26 +msgid "RSS feed of updates" +msgstr "RSS Feeds für Neuigkeiten" -#: app/views/request/_request_listing_short_via_event.rhtml:10 -msgid "by {{user_link_absolute}}" -msgstr "durch {{user_link_absolute}}" +#: app/views/comment/preview.rhtml:20 +msgid "Re-edit this annotation" +msgstr "Anmerkung erneut bearbeiten" -#: app/views/request/_request_listing_single.rhtml:12 +#: app/views/request/followup_preview.rhtml:49 +msgid "Re-edit this message" +msgstr "Nachricht ändern" + +#: app/views/general/_advanced_search_tips.rhtml:19 msgid "" -"Requested from {{public_body_name}} by {{info_request_user}} on {{date}}" +"Read about <a href=\"{{advanced_search_url}}\">advanced search " +"operators</a>, such as proximity and wildcards." msgstr "" -"Angefragt von {{public_body_name}} durch {{info_request_user}} am {{date}}" +"Lesen Sie mehr über <a href=\"{{advanced_search_url}}\">Anbieter erweiterter" +" Suchfunktionen</a>, wie proximity and wildcards." + +#: app/views/general/_topnav.rhtml:7 +msgid "Read blog" +msgstr "Blog lesen" + +#: app/views/general/_advanced_search_tips.rhtml:34 +msgid "Received an error message, such as delivery failure." +msgstr "Fehlermeldung, wie z.B. Sendefehler, erhalten. " + +#: app/views/general/search.rhtml:133 +msgid "Recently described results first" +msgstr "Kürzlich widergegebene Ergebnisse zuerst" + +#: app/models/info_request.rb:795 +msgid "Refused." +msgstr "Abgelehnt." + +#: app/views/user/_signin.rhtml:26 +msgid "" +"Remember me</label> (keeps you signed in longer;\n" +" do not use on a public computer) " +msgstr "" +"Login speichern</label> (Sie bleiben eingeloggt. Nutzen Sie diese Funktion " +"nicht an öffentlichen Computern) " + +#: app/views/comment/_single_comment.rhtml:24 +msgid "Report abuse" +msgstr "Missbrauch melden" + +#: app/views/request/_after_actions.rhtml:39 +msgid "Request an internal review" +msgstr "Interne Prüfung anfragen" + +#: app/views/request/_followup.rhtml:8 +msgid "Request an internal review from {{person_or_body}}" +msgstr "Interne Prüfung von {{person_or_body}} anfragen" + +#: app/views/request/hidden.rhtml:1 +msgid "Request has been removed" +msgstr "Anfrage wurde verweigert" #: app/views/request/_request_listing_via_event.rhtml:20 msgid "" @@ -2731,15 +2755,6 @@ msgstr "" "Anfrage gestellt an {{public_body_name}} durch {{info_request_user}} am " "{{date}}." -#: app/views/request/_request_listing_via_event.rhtml:23 -msgid "sent to {{public_body_name}} by {{info_request_user}} on {{date}}." -msgstr "" -"gesendet an {{public_body_name}} durch {{info_request_user}} am {{date}}." - -#: app/views/request/_request_listing_via_event.rhtml:26 -msgid "by {{public_body_name}} to {{info_request_user}} on {{date}}." -msgstr "von {{public_body_name}} an {{info_request_user}} am {{date}}." - #: app/views/request/_request_listing_via_event.rhtml:28 msgid "" "Request to {{public_body_name}} by {{info_request_user}}. Annotated by " @@ -2748,484 +2763,396 @@ msgstr "" "Anfrage an {{public_body_name}} durch {{info_request_user}}. Kommentiert " "durch {{event_comment_user}} am {{date}}." -#: app/views/request/_request_listing_via_event.rhtml:30 -msgid "unknown event type indexed " -msgstr "unbekannter Aktionstyp angezeigt" - -#: app/views/request/_search_ahead.rhtml:3 -msgid "Possibly related requests:" -msgstr "Eventuell ähnliche Anfrage:" - -#: app/views/request/_search_ahead.rhtml:10 -msgid "Or search in their website for this information." -msgstr "Oder suchen Sie auf deren Internetseite nach Informationen" - -#: app/views/request/_sidebar.rhtml:2 -msgid "Follow this request" -msgstr "Dieser Anfrage folgen" - -#: app/views/request/_sidebar.rhtml:5 -msgid "There is %d person following this request" -msgid_plural "There are %d people following this request" -msgstr[0] " %d Person verfolgen diese Anfrage" -msgstr[1] " %d Personen verfolgen diese Anfrage" +#: app/views/request/_request_listing_single.rhtml:12 +msgid "" +"Requested from {{public_body_name}} by {{info_request_user}} on {{date}}" +msgstr "" +"Angefragt von {{public_body_name}} durch {{info_request_user}} am {{date}}" -#: app/views/request/_sidebar.rhtml:8 -msgid "Act on what you've learnt" -msgstr "Handel aus Deinen Erfahrungen" +#: app/views/request/_sidebar_request_listing.rhtml:13 +msgid "Requested on {{date}}" +msgstr "Angefragt am {{date}}" -#: app/views/request/_sidebar.rhtml:13 -msgid "Tweet this request" -msgstr "Tweet diese Anfrage" +#: app/models/track_thing.rb:282 app/models/track_thing.rb:283 +msgid "Requests or responses matching your saved search" +msgstr "Zu Ihrer gespeicherten Suche passende Anfragen und Antworten" -#: app/views/request/_sidebar.rhtml:17 -msgid "Start your own blog" -msgstr "Starten Sie Ihren eigenen Blog" +#: app/views/request/upload_response.rhtml:11 +msgid "Respond by email" +msgstr "Email-Antwort senden" -#: app/views/request/_sidebar.rhtml:24 -msgid "Similar requests" -msgstr "Ähnliche Anfragen" +#: app/views/request/_after_actions.rhtml:48 +msgid "Respond to request" +msgstr "Auf Anfrage reagieren" -#: app/views/request/_sidebar.rhtml:29 -msgid "More similar requests" -msgstr "Weitere ähnliche Anfragen" +#: app/views/request/upload_response.rhtml:5 +msgid "Respond to the FOI request" +msgstr "IFG-Anfrage beantworten" -#: app/views/request/_sidebar.rhtml:35 -msgid "Event history details" -msgstr "Details Verlaufsübersicht" +#: app/views/request/upload_response.rhtml:21 +msgid "Respond using the web" +msgstr "Online antworten" -#: app/views/request/_sidebar.rhtml:39 -msgid "" -"<a href=\"%s\">Are you the owner of\n" -" any commercial copyright on this page?</a>" -msgstr "<a href=\"%s\">Halten Sie die Urheberrechte dieser Seite?</a>" +#: app/models/info_request_event.rb:306 +msgid "Response" +msgstr "Antwort" -#: app/views/request/_sidebar_request_listing.rhtml:13 -msgid "Requested on {{date}}" -msgstr "Angefragt am {{date}}" +#: app/views/general/_advanced_search_tips.rhtml:44 +msgid "Response from a public authority" +msgstr "Antwort von einer Behörde" -#: app/views/request/_view_html_prefix.rhtml:6 -msgid "Download original attachment" -msgstr "Originalanhang herunterladen" +#: app/views/request/show.rhtml:77 +msgid "Response to this request is <strong>delayed</strong>." +msgstr "Die Antwort auf diese Anfrage ist <strong>im Rückstand</strong>." -#: app/views/request/_view_html_prefix.rhtml:9 -msgid "" -"This is an HTML version of an attachment to the Freedom of Information " -"request" +#: app/views/request/show.rhtml:85 +msgid "Response to this request is <strong>long overdue</strong>." msgstr "" -"Dies ist eine HTML Version eines Anhanges der Informationsfreiheitsanfrage" +"Die Antwort auf diese Anfrage ist <strong>lange im Rückstand</strong>." -#: app/views/request/details.rhtml:1 app/views/request/details.rhtml:2 -msgid "Details of request '" -msgstr "Anfragedetails" +#: app/views/request/show_response.rhtml:62 +msgid "Response to your request" +msgstr "Reagieren Sie auf Ihre Anfrage" -#: app/views/request/details.rhtml:4 -msgid "Event history" -msgstr "Verlaufsübersicht" +#: app/views/request/upload_response.rhtml:28 +msgid "Response:" +msgstr "Antwort:" -#: app/views/request/details.rhtml:6 -msgid "" -"This table shows the technical details of the internal events that happened\n" -"to this request on {{site_name}}. This could be used to generate information about\n" -"the speed with which authorities respond to requests, the number of requests\n" -"which require a postal response and much more." -msgstr "" +#: app/views/general/search.rhtml:87 +msgid "Restrict to" +msgstr "Vorbehalten für" -#: app/views/request/details.rhtml:12 -msgid "" -"<strong>Caveat emptor!</strong> To use this data in an honourable way, you will need \n" -"a good internal knowledge of user behaviour on {{site_name}}. How, \n" -"why and by whom requests are categorised is not straightforward, and there will\n" -"be user error and ambiguity. You will also need to understand FOI law, and the\n" -"way authorities use it. Plus you'll need to be an elite statistician. Please\n" -"<a href=\"{{contact_path}}\">contact us</a> with questions." -msgstr "" -"<strong>Gewährleistungsausschluss!</strong>Um diese Daten ehrenhaft zu nutzen, benötigen Sie gute interne Kenntnisse des Nutzerverhaltens auf {{site_name}}. Es ist nicht überschaubar wie, warum und von wem Anfragen kategorisiert werden und es sind Nutzerfehler und Unklarheiten zu erwarten. Ein gutes Verständnis der Informationsfreiheits-Gesetzgebung und die Art und Weise der Anwendung durch Behörden ist ebenso wichtig. Ferner benötigen Sie herausragende Statisikkenntnisse. Für Fragen nehmen Sie bitte\n" -"<a href=\"{{contact_path}}\">Kontakt</a> mit uns auf." +#: app/views/general/search.rhtml:12 +msgid "Results page {{page_number}}" +msgstr "Ergebnisanzeige {{page_number}}" -#: app/views/request/details.rhtml:50 -msgid "" -"Here <strong>described</strong> means when a user selected a status for the request, and\n" -"the most recent event had its status updated to that value. <strong>calculated</strong> is then inferred by\n" -"{{site_name}} for intermediate events, which weren't given an explicit\n" -"description by a user. See the <a href=\"{{search_path}}\">search tips</a> for description of the states." -msgstr "" +#: app/views/user/set_profile_about_me.rhtml:35 +msgid "Save" +msgstr "Speichern" -#: app/views/request/details.rhtml:58 -msgid "" -"You can get this page in computer-readable format as part of the main JSON\n" -"page for the request. See the <a href=\"{{api_path}}\">API documentation</a>." -msgstr "" -"Im Rahmen der HauptJSON Seite können diese Seite in maschinenlesbarer Form erhalten. \n" -" Sehen Sie hier: <a href=\"{{api_path}}\">API Sokumentation</a>." +#: app/views/request/_request_filter_form.rhtml:49 +#: app/views/request/select_authority.rhtml:41 +#: app/views/public_body/list.rhtml:43 +#: app/views/general/exception_caught.rhtml:12 +#: app/views/general/frontpage.rhtml:23 app/views/general/search.rhtml:17 +#: app/views/general/search.rhtml:32 app/views/general/search.rhtml:45 +msgid "Search" +msgstr "Suche" -#: app/views/request/followup_bad.rhtml:2 -msgid "Unable to send follow up message to {{username}}" -msgstr "Nachfrage an {{username}} kann nicht gesendet werden" +#: app/views/general/search.rhtml:8 +msgid "Search Freedom of Information requests, public authorities and users" +msgstr "Suchen Sie nach Informationsfreiheitsanfragen, Behörden und Nutzern" -#: app/views/request/followup_bad.rhtml:4 -msgid "Unable to send a reply to {{username}}" -msgstr "Antwort an {{username}} kann nicht gesendet werden" +#: app/views/user/show.rhtml:127 +msgid "Search contributions by this person" +msgstr "Suchen Sie Beiträge dieser Person" -#: app/views/request/followup_bad.rhtml:11 -msgid "Freedom of Information law no longer applies to" -msgstr "Informationsfreiheitsgesetz ist nicht länger gültig für" +#: app/views/request/_request_filter_form.rhtml:11 +msgid "Search for words in:" +msgstr "Suchen Sie nach Begriffen in:" -#: app/views/request/followup_bad.rhtml:12 -msgid "" -"From the request page, try replying to a particular message, rather than sending\n" -" a general followup. If you need to make a general followup, and know\n" -" an email which will go to the right place, please <a href=\"%s\">send it to us</a>." -msgstr "" -"Von der Anfragen-Seite, versuchen Sie direkt auf spezifische Nachrichten zu " -"reagieren anstall eine generelle Nachfrage zu senden. Falls Sie eine " -"generelle Nachfrage stellen müssen und eine Emailadresse kennen, welche an " -"die richtige Stelle geht, sind Sie so freundlich uns <a href=\"%s\">diese zu" -" senden. " +#: app/views/general/search.rhtml:100 +msgid "Search in" +msgstr "Suchen Sie in" -#: app/views/request/followup_bad.rhtml:18 +#: app/views/general/frontpage.rhtml:15 msgid "" -"no longer exists. If you are trying to make\n" -" From the request page, try replying to a particular message, rather than sending\n" -" a general followup. If you need to make a general followup, and know\n" -" an email which will go to the right place, please <a href=\"%s\">send it to us</a>." +"Search over<br/>\n" +" <strong>{{number_of_requests}} requests</strong> <span>and</span><br/>\n" +" <strong>{{number_of_authorities}} authorities</strong>" msgstr "" -"besteht nicht mehr. Falls Sie versuchen \n" -" Von der Anfragen-Seite, versuchen Sie auf spezifische Nachrichten zu Antworten anstatt generelle Nachfragen zu versenden. Wenn Sie eine gnerelle Nachfrage stellen müssen und eine Email-Adresse kennen, die an die richtige Stelle geht, <a href=\"%s\">senden Sie uns diese</a> bitte zu." +"Suchen Sie in mehr als<br/>\n" +" <strong>{{number_of_requests}} Anfragen</strong> <span>und</span><br/>\n" +" <strong>{{number_of_authorities}} Behörden</strong>" -#: app/views/request/followup_bad.rhtml:24 -msgid "" -"We do not have a working {{law_used_full}} address for {{public_body_name}}." +#: app/views/general/search.rhtml:19 +msgid "Search results" msgstr "" -"Wir haben keine funktionierende {{law_used_full}} Adresse für " -"{{public_body_name}}." -#: app/views/request/followup_bad.rhtml:24 -msgid "" -"You may be able to find\n" -" one on their website, or by phoning them up and asking. If you manage\n" -" to find one, then please <a href=\"%s\">send it to us</a>." +#: app/views/general/exception_caught.rhtml:9 +msgid "Search the site to find what you were looking for." msgstr "" -"Es ist mögliche eine auf deren Internetseite zu finden oder sie telefonisch " -"zu erfragen. Sollten Sie sie herausfinden, <a href=\"%s\">senden sie sie uns" -" bitte zu</a>." - -#: app/views/request/followup_bad.rhtml:29 -msgid "unknown reason " -msgstr "unbekannte Ursache" - -#: app/views/request/followup_preview.rhtml:1 -msgid "Preview follow up to '" -msgstr "Überprüfen Sie die Nachfrage an" +"Duchsuchen Sie die Seite, um die von Ihnen gewünschten Informationen zu " +"finden. " -#: app/views/request/followup_preview.rhtml:8 -msgid "Now preview your message asking for an internal review" -msgstr "Überprüfen Sie nun Ihre Anfrage zur internen Prüfung" +#: app/views/public_body/show.rhtml:93 +msgid "Search within the %d Freedom of Information requests to %s" +msgid_plural "Search within the %d Freedom of Information requests made to %s" +msgstr[0] "Suchen Sie in den %d an %s gestellten IFG-Anfragen" +msgstr[1] "Suchen Sie in den %d an %s gestellten IFG-Anfragen" -#: app/views/request/followup_preview.rhtml:10 -msgid "Now preview your follow up" -msgstr "Überprüfen Sie nun Ihr Follow-up" +#: app/views/user/show.rhtml:125 +msgid "Search your contributions" +msgstr "Suchen Sie Ihre Beiträge" -#: app/views/request/followup_preview.rhtml:14 -#: app/views/request/preview.rhtml:7 -msgid "Check you haven't included any <strong>personal information</strong>." +#: app/views/request/select_authority.rhtml:49 +#: app/views/public_body/_search_ahead.rhtml:5 +msgid "Select one to see more information about the authority." msgstr "" -"Stellen Sie sicher, dass Sie keine <strong> persönlichen Informationen " -"</strong> verwendet haben." +"Wählen Sie eine aus, um mehr Informationen über diese Behörde sehen zu " +"können. " -#: app/views/request/followup_preview.rhtml:15 -msgid "Your message will appear in <strong>search engines</strong>" -msgstr "" -"Ihre Nachricht wird in <strong>Suchmaschinen</strong> angezeigt werden" +#: app/views/request/select_authority.rhtml:27 +msgid "Select the authority to write to" +msgstr "Wählen Sie die zu kontaktierende Behörde" -#: app/views/request/followup_preview.rhtml:22 app/views/request/new.rhtml:40 -#: app/views/request/preview.rhtml:17 -#: app/views/request/simple_correspondence.rhtml:16 -#: app/views/request/simple_correspondence.rhtml:28 -msgid "To:" -msgstr "An:" +#: app/views/request/_after_actions.rhtml:28 +msgid "Send a followup" +msgstr "Nachfrage senden" -#: app/views/request/followup_preview.rhtml:23 -#: app/views/request/preview.rhtml:18 -msgid "Subject:" -msgstr "Betreff:" +#: app/controllers/user_controller.rb:349 +msgid "Send a message to " +msgstr "Nachricht senden an" -#: app/views/request/followup_preview.rhtml:37 -msgid "" -"<strong>Privacy warning:</strong> Your message, and any response\n" -" to it, will be displayed publicly on this website." -msgstr "" -"<strong>Datenschutzhinweis:</strong> Ihre Nachricht als auch alle " -"entsprechenden Reaktionen werden auf dieser Webseite veröffentlicht." +#: app/views/request/_followup.rhtml:11 +msgid "Send a public follow up message to {{person_or_body}}" +msgstr "Öffentliche Nachfrage an {{person_or_body}} senden" -#: app/views/request/followup_preview.rhtml:49 -msgid "Re-edit this message" -msgstr "Nachricht ändern" +#: app/views/request/_followup.rhtml:14 +msgid "Send a public reply to {{person_or_body}}" +msgstr "Öffentliche Antwort an {{person_or_body}} senden" #: app/views/request/followup_preview.rhtml:50 msgid "Send message" msgstr "Nachricht senden" -#: app/views/request/hidden.rhtml:1 -msgid "Request has been removed" -msgstr "Anfrage wurde verweigert" +#: app/views/user/show.rhtml:69 +msgid "Send message to " +msgstr "Nachricht senden an" -#: app/views/request/hidden.rhtml:9 -msgid "" -"The request you have tried to view has been removed. There are\n" -"various reasons why we might have done this, sorry we can't be more specific here. Please <a\n" -" href=\"%s\">contact us</a> if you have any questions." -msgstr "" -"Die von Ihnen ausgewählte Anfrage wurde verweigert. Dies kann unterschiedliche Ursachen haben, welche an dieser Stelle leider nicht näher erläutert werden können. Bitte<a\n" -" href=\"%s\">kontaktieren Sie uns</a> für weitere Fragen. " +#: app/views/request/preview.rhtml:41 +msgid "Send request" +msgstr "Anfrage senden" -#: app/views/request/hidden.rhtml:15 -msgid "" -"If you are the requester, then you may <a href=\"%s\">sign in</a> to view " -"the request." -msgstr "" -"Falls Sie der Antragsteller sind, <a href=\"%s\">loggen Sie sich ein</a>, um" -" die Anfrage anzusehen." +#: app/views/user/show.rhtml:53 +msgid "Set your profile photo" +msgstr "Profilbild wählen" -#: app/views/request/list.rhtml:8 -msgid "Follow these requests" -msgstr "Diesen Anfragen folgen" +#: app/models/public_body.rb:39 +msgid "Short name is already taken" +msgstr "Nutzername bereits vergeben " -#: app/views/request/list.rhtml:19 -msgid "No requests of this sort yet." -msgstr "Es besteht noch keine Anfrage dieser Art." +#: app/views/general/search.rhtml:129 +msgid "Show most relevant results first" +msgstr "Relevanteste Suchergebnisse zuerst anzeigen " -#: app/views/request/list.rhtml:21 -msgid "{{count}} FOI requests found" -msgstr "{{count}} IFG-Anfragen gefunden" +#: app/views/public_body/list.rhtml:2 +msgid "Show only..." +msgstr "Zeig mir nur..." -#: app/views/request/list.rhtml:27 -msgid "Unexpected search result type" -msgstr "Unerwartetes Suchergebnis" +#: app/views/request/_request_filter_form.rhtml:29 +#: app/views/general/search.rhtml:51 +msgid "Showing" +msgstr "Anzeigen" -#: app/views/request/new.rhtml:20 -msgid "Make an {{law_used_short}} request to '{{public_body_name}}'" -msgstr "Stellen Sie einen {{law_used_short}} Antrag an '{{public_body_name}}'" +#: app/views/user/sign.rhtml:2 app/views/user/sign.rhtml:33 +#: app/views/user/_signin.rhtml:32 +msgid "Sign in" +msgstr "Anmelden" -#: app/views/request/new.rhtml:22 -msgid "2. Ask for Information" -msgstr "2. Informationen anfragen" +#: app/views/user/sign.rhtml:20 +msgid "Sign in or make a new account" +msgstr "Anmelden oder neues Benutzerkonto erstellen" -#: app/views/request/new.rhtml:27 -msgid "" -"{{existing_request_user}} already\n" -" created the same request on {{date}}. You can either view the <a href=\"{{existing_request}}\">existing request</a>,\n" -" or edit the details below to make a new but similar request." +#: app/views/layouts/default.rhtml:113 +msgid "Sign in or sign up" +msgstr "Amelden oder registrieren " + +#: app/views/layouts/default.rhtml:111 +msgid "Sign out" +msgstr "Ausloggen" + +#: app/views/user/sign.rhtml:40 app/views/user/_signup.rhtml:46 +msgid "Sign up" +msgstr "Benutzerkonto erstellen" + +#: app/views/request/_sidebar.rhtml:24 +msgid "Similar requests" +msgstr "Ähnliche Anfragen" + +#: app/views/general/search.rhtml:33 +msgid "Simple search" +msgstr "Einfache Suche" + +#: app/models/request_mailer.rb:177 +msgid "Some notes have been added to your FOI request - " msgstr "" -"{{existing_request_user}} already\n" -" created the same request on {{date}}. You can either view the <a href=\"{{existing_request}}\">existing request</a>,\n" -" or edit the details below to make a new but similar request." -#: app/views/request/new.rhtml:44 +#: app/views/general/_advanced_search_tips.rhtml:29 +msgid "Some of the information requested has been received" +msgstr "Ein Teil der angefragten Informationen wurde erhalten." + +#: app/views/request_game/play.rhtml:31 msgid "" -"Browse <a href='{{url}}'>other requests</a> to '{{public_body_name}}' for " -"examples of how to word your request." +"Some people who've made requests haven't let us know whether they were\n" +"successful or not. We need <strong>your</strong> help –\n" +"choose one of these requests, read it, and let everyone know whether or not the\n" +"information has been provided. Everyone'll be exceedingly grateful." msgstr "" -"Schauen Sie <a href='{{url}}'>andere Anfragen</a> an '{{public_body_name}}' " -"für Formulierungsbeispiele an. " +"Nicht alle Anfragensteller haben uns über den Erfolg Ihrer Anfragen " +"informiert. Wir sind auf <strong>Ihre</strong> Hilfe angewiesen. Wählen Sie " +"eine dieser Anfragen, lesen Sie sie und teilen Sie uns mit, ob die " +"gewünschte Information zur Verfügung gestellt wurde. Alle Nutzer wären Ihnen" +" ausgesprochen dankbar. " -#: app/views/request/new.rhtml:46 +#: app/models/request_mailer.rb:168 +msgid "Somebody added a note to your FOI request - " +msgstr "" + +#: app/views/user_mailer/changeemail_already_used.rhtml:1 msgid "" -"Browse <a href='{{url}}'>other requests</a> for examples of how to word your" -" request." +"Someone, perhaps you, just tried to change their email address on\n" +"{{site_name}} from {{old_email}} to {{new_email}}." msgstr "" -"Durchsuchen Sie <a href='{{url}}'>andere Anfragen</a>für " -"Formulierungsbeispiele für Ihre Anfrage." +"Jemand, evtl. Sie selber, hat soeben versucht seine/ihre Email-Adresse auf\n" +"{{site_name}} von{{old_email}} in {{new_email}} zu ändern." + +#: app/views/user/wrong_user.rhtml:2 +msgid "Sorry, but only {{user_name}} is allowed to do that." +msgstr "Sorry, aber dieser Vorgang ist {{user_name}} vorbehalten." + +#: app/views/general/exception_caught.rhtml:17 +msgid "Sorry, there was a problem processing this page" +msgstr "Sorry, bei der Übermittlung dieser Seite sind Probleme aufgetreten" + +#: app/views/general/exception_caught.rhtml:3 +msgid "Sorry, we couldn't find that page" +msgstr "Diese Seite wurde leider nicht gefunden" #: app/views/request/new.rhtml:52 msgid "Special note for this authority!" msgstr "Spezielle Nachricht and diese Behörde!" -#: app/views/request/new.rhtml:58 -msgid "Please ask for environmental information only" -msgstr "Bitte fragen Sie ausschliesslich nach Umweltinformationen" - -#: app/views/request/new.rhtml:60 -msgid "The Freedom of Information Act <strong>does not apply</strong> to" -msgstr "Das Informationsfreiheitsgesetz <strong>trifft nicht zu</strong> auf" +#: app/views/public_body/show.rhtml:64 +msgid "Start" +msgstr "Start" -#: app/views/request/new.rhtml:61 -msgid "" -"However, you have the right to request environmental\n" -" information under a different law" +#: app/views/general/frontpage.rhtml:10 +msgid "Start now »" msgstr "" -"Nichtsdestrotrotz sind Sie berechtigt Umweltanfragen auf Basis eines anderen" -" Gesetzes zu stellen" -#: app/views/request/new.rhtml:63 -msgid "" -"This covers a very wide spectrum of information about the state of\n" -" the <strong>natural and built environment</strong>, such as:" -msgstr "" +#: app/views/request/_sidebar.rhtml:17 +msgid "Start your own blog" +msgstr "Starten Sie Ihren eigenen Blog" -#: app/views/request/new.rhtml:67 -msgid "" -"Air, water, soil, land, flora and fauna (including how these effect\n" -" human beings)" -msgstr "" -"Luft, Wasser, Erde, Land, Flora und Fauna (einschliesslich deren Einfluss " -"auf den Menschen)" +#: app/views/general/blog.rhtml:6 +msgid "Stay up to date" +msgstr "Bleiben Sie auf dem Laufenden" -#: app/views/request/new.rhtml:69 -msgid "" -"Information on emissions and discharges (e.g. noise, energy,\n" -" radiation, waste materials)" -msgstr "" -"Informationen bzg. Emissionen und Ablagerungen (e.g. Lärm, Energie,\n" -" Strahlung, Abfallmaterialien)" +#: app/views/request/_other_describe_state.rhtml:21 +msgid "Still awaiting an <strong>internal review</strong>" +msgstr "<strong>internal review</strong> weiterhin ausstehend" -#: app/views/request/new.rhtml:71 -msgid "Human health and safety" -msgstr "Gesundheit und Sicherheit" +#: app/views/request/preview.rhtml:18 +#: app/views/request/followup_preview.rhtml:23 +msgid "Subject:" +msgstr "Betreff:" -#: app/views/request/new.rhtml:72 -msgid "" -"Cultural sites and built structures (as they may be affected by the\n" -" environmental factors listed above)" -msgstr "" -"Kulturelle Seiten und erstellte Strukturen (da diese durch die oben " -"gelisteten Umweltfaktoren beeinträchtigt sein könnten)" +#: app/views/user/signchangepassword_send_confirm.rhtml:26 +msgid "Submit" +msgstr "Senden" -#: app/views/request/new.rhtml:74 -msgid "Plans and administrative measures that affect these matters" -msgstr "Diese Aspekte beeinflussende Pläne und administrative Maßnahmen" +#: app/views/request/_describe_state.rhtml:101 +msgid "Submit status" +msgstr "Status senden" -#: app/views/request/new.rhtml:77 +#: app/views/general/blog.rhtml:8 +msgid "Subscribe to blog" +msgstr "Blog folgen" + +#: app/models/track_thing.rb:231 app/models/track_thing.rb:232 +msgid "Successful Freedom of Information requests" +msgstr "Erfolgreiche Informationsfreiheitsanfrage" + +#: app/models/info_request.rb:799 +msgid "Successful." +msgstr "Erfolgreich." + +#: app/views/comment/new.rhtml:39 msgid "" -"Please only request information that comes under those categories, <strong>do not waste your\n" -" time</strong> or the time of the public authority by requesting unrelated information." +"Suggest how the requester can find the <strong>rest of the " +"information</strong>." msgstr "" -"Bitte fragen Sie ausschliesslich auf diese Kategorien zutreffende " -"Informationen an. <strong>Verschwenden Sie nicht Ihre⏎Zeit</strong> oder die" -" Zeit der Behörde, indem Sie nicht zutreffende Informationen anfragen." +"Schlagen Sie vor, wie der Anfragensteller <strong>den Rest der " +"Information</strong> finden kann." #: app/views/request/new.rhtml:84 msgid "Summary:" msgstr "Zusammenfassung:" -#: app/views/request/new.rhtml:88 -msgid "" -"a one line summary of the information you are requesting, \n" -"\t\t\te.g." -msgstr "" -"Einzeilige Zusammenfassung der von Ihnen angefragten Information, \n" -"<span class=\"whitespace other\" title=\"Tab\">»</span><span class=\"whitespace other\" title=\"Tab\">»</span><span class=\"whitespace other\" title=\"Tab\">»</span>e.g." - -#: app/views/request/new.rhtml:90 -msgid "'Pollution levels over time for the River Tyne'" -msgstr "'Verschmutzungsgrades des Tyne Flusses im Zeitverlauf'" - -#: app/views/request/new.rhtml:92 -msgid "'Crime statistics by ward level for Wales'" -msgstr "´Kriminalitätsrate auf Länderebene´" +#: app/views/general/_advanced_search_tips.rhtml:22 +msgid "Table of statuses" +msgstr "Statusliste" -#: app/views/request/new.rhtml:104 -msgid "Write your request in <strong>simple, precise language</strong>." +#: app/views/general/_advanced_search_tips.rhtml:39 +msgid "Table of varieties" msgstr "" -"Formulieren Sie Ihre Anfrage in <strong>schlicht und präzise </strong>." -#: app/views/request/new.rhtml:105 -msgid "" -"Ask for <strong>specific</strong> documents or information, this site is not" -" suitable for general enquiries." -msgstr "" -"Fragen Sie nach <strong>spezifischen</strong> Dokumenten oder Informationen." -" Diese Seite ist nicht für generelle Anfragen vorgesehen. " +#: app/views/general/search.rhtml:75 +msgid "Tags (separated by a space):" +msgstr "Tags (mit Leerzeichen getrennt):" -#: app/views/request/new.rhtml:106 -msgid "" -"Keep it <strong>focused</strong>, you'll be more likely to get what you want" -" (<a href=\"%s\">why?</a>)." -msgstr "" -"Machen Sie es <strong>kurz und bündig</strong>, die Wahrscheinlichkeit die " -"gewünschten Informationen zu erhalten ist somit größer(<a " -"href=\"%s\">Warum?</a>)." +#: app/views/request/preview.rhtml:45 +msgid "Tags:" +msgstr "Links:" -#: app/views/request/new.rhtml:113 -msgid "Your request:" -msgstr "Ihre Anfrage:" +#: app/views/general/exception_caught.rhtml:21 +msgid "Technical details" +msgstr "Technische Details" -#: app/views/request/new.rhtml:120 -msgid "" -"Everything that you enter on this page, including <strong>your name</strong>, \n" -" will be <strong>displayed publicly</strong> on\n" -" this website forever (<a href=\"%s\">why?</a>)." -msgstr "" -"Jegliche auf dieser Seite eingegebene Information, inklusive <strong>Ihrem Namen</strong>, ⏎ wird\n" -" permanent auf dieser Internetseite <strong>veröffentlicht</strong>(<a href=\"%s\"> Warum?</a>)." +#: app/controllers/request_game_controller.rb:52 +msgid "Thank you for helping us keep the site tidy!" +msgstr "vielen Dank für die Ihre Mithilfe die Seite aktuell zu halten. " -#: app/views/request/new.rhtml:123 -msgid "" -"If you are thinking of using a pseudonym,\n" -" please <a href=\"%s\">read this first</a>." -msgstr "" -"Wenn Sie ein Pseudonym als Benutzername verwenden möchten,\n" -" bitte <a href=\"%s\">lesen Sie hier</a>." +#: app/controllers/comment_controller.rb:62 +msgid "Thank you for making an annotation!" +msgstr "Vielen Dank für Ihre Anmerkung" -#: app/views/request/new.rhtml:128 +#: app/controllers/request_controller.rb:747 msgid "" -"Everything that you enter on this page \n" -" will be <strong>displayed publicly</strong> on\n" -" this website forever (<a href=\"%s\">why?</a>)." +"Thank you for responding to this FOI request! Your response has been " +"published below, and a link to your response has been emailed to " msgstr "" -"Jegliche auf dieser Seite eingegebene Information wird\n" -" permanent auf dieser Internetseite <strong>veröffentlicht</strong>(<a href=\"%s\"> Warum?</a>)." +"Vielen Dank für Ihre IFG-Anfrage! Ihre Antwort wird unten angezeigt und ein " +"Link zu Ihrer Antwort wurde gesendet an" -#: app/views/request/new.rhtml:135 +#: app/controllers/request_controller.rb:384 msgid "" -"<strong> Can I request information about myself?</strong>\n" -"\t\t\t<a href=\"%s\">No! (Click here for details)</a>" +"Thank you for updating the status of the request '<a " +"href=\"{{url}}\">{{info_request_title}}</a>'. There are some more requests " +"below for you to classify." msgstr "" -"<strong> Kann ich Informationen zu meiner eigenen Person anfragen?</strong>\n" -"<span class=\"whitespace other\" title=\"Tab\">»</span><span class=\"whitespace other\" title=\"Tab\">»</span><span class=\"whitespace other\" title=\"Tab\">»</span><a href=\"%s\">Nein! (Weitere Informationen)</a>" - -#: app/views/request/new.rhtml:143 -msgid "Preview your public request" -msgstr "Vorschau der Anfrage ansehen" - -#: app/views/request/new_bad_contact.rhtml:1 -msgid "Missing contact details for '" -msgstr "Folgende Kontaktdetails fehlen:" +"Herzlichen Dank für die Aktualisierung der Anfrage '<a " +"href=\"{{url}}\">{{info_request_title}}</a>'. Untenstehend finden Sie einige" +" weitere Anfragen, welche durch Sie zugeordnet werden sollten." -#: app/views/request/new_bad_contact.rhtml:5 -msgid "" -"Unfortunately, we do not have a working {{info_request_law_used_full}}\n" -"address for" -msgstr "" -"Wir haben leider keine funktionierende Email-Adresse für " -"{{info_request_law_used_full}}" +#: app/controllers/request_controller.rb:387 +msgid "Thank you for updating this request!" +msgstr "Vielen Dank für die Aktualisierung dieser Anfrage!" -#: app/views/request/new_bad_contact.rhtml:6 -msgid "" -"You may be able to find\n" -"one on their website, or by phoning them up and asking. If you manage\n" -"to find one, then please <a href=\"{{help_url}}\">send it to us</a>." -msgstr "" -"Sie können eventuell eine auf deren Internetseite finden, oder sie anrufen " -"und nachfragen. Sollten Sie eine herausfinden, freuen wir uns über Ihre <a " -"href=\"{{help_url}}\">Zusendung</a>." +#: app/controllers/user_controller.rb:416 +#: app/controllers/user_controller.rb:432 +msgid "Thank you for updating your profile photo" +msgstr "Vielen Dank für die Aktualisierung Ihres Profilbildes" -#: app/views/request/new_please_describe.rhtml:5 +#: app/views/request_game/play.rhtml:42 msgid "" -"Please select each of these requests in turn, and <strong>let everyone know</strong>\n" -"if they are successful yet or not." +"Thanks for helping - your work will make it easier for everyone to find successful\n" +"responses, and maybe even let us make league tables..." msgstr "" -"Bitte wählen Sie diese Anfragen der Reihe nach aus und <strong>lassen Sie " -"jederman wissen</strong>, ob sie bereits erfolgreich waren oder noch nicht. " +"Vielen Dank für die Hilfe - Ihre Arbeit wird es für jeden leichter machen " +"erfolgreiche Antworten zu finden und es uns eventuell sogar ermöglichen " +"Ranglisten zu erstellen..." -#: app/views/request/new_please_describe.rhtml:16 +#: app/views/user/show.rhtml:20 msgid "" -"When you're done, <strong>come back here</strong>, <a href=\"%s\">reload " -"this page</a> and file your new request." +"Thanks very much - this will help others find useful stuff. We'll\n" +" also, if you need it, give advice on what to do next about your\n" +" requests." msgstr "" -"Wenn Sie fertig sind, <strong>kommen Sie hierher zurück</strong>, <a " -"href=\"%s\">laden Sie die Seite erneut</a> und stellen Sie Ihre neue " -"Anfrage." +"Vielen herzlichen Dank - dass hilft anderen auch Nützliches zu finden. Gerne" +" beraten wir Sie auch bei den nächsten Schritten Ihrer Anfragen, falls Sie " +"dies wünschen. " #: app/views/request/new_please_describe.rhtml:20 msgid "" @@ -3237,351 +3164,382 @@ msgstr "" "Gerne beraten wir Sie auch bei den nächsten Schritten Ihrer Anfragen, falls " "Sie dies wünschen. " -#: app/views/request/preview.rhtml:5 -msgid "3. Now check your request" -msgstr "3. Überprüfen Sie nun Ihre Anfrage" - -#: app/views/request/preview.rhtml:8 -msgid "" -"Your name, request and any responses will appear in <strong>search engines</strong>\n" -" (<a href=\"%s\">details</a>)." -msgstr "" -"Ihr Name, Ihre Anfrage und alle Antworten werden in <strong>Suchmaschinen</strong> angezeigt werden\n" -" (<a href=\"%s\">Details</a>)." - -#: app/views/request/preview.rhtml:31 +#: app/controllers/user_controller.rb:207 msgid "" -"<strong>Privacy note:</strong> If you want to request private information about\n" -" yourself then <a href=\"%s\">click here</a>." +"That doesn't look like a valid email address. Please check you have typed it" +" correctly." msgstr "" -"<strong>Privacy note:</strong> Falls Sie Informationen zu Ihrer eingenen " -"Person erfragen wollen <a href=\"%s\">Klicken Sie hier</a>." - -#: app/views/request/preview.rhtml:40 -msgid "Edit this request" -msgstr "Anfrage bearbeiten" +"Dies sieht nicht nach einer gültigen Emailadresse aus. Bitte überprüfen Sie " +"Ihre Eingabe. " -#: app/views/request/preview.rhtml:41 -msgid "Send request" -msgstr "Anfrage senden" +#: app/views/request/_other_describe_state.rhtml:43 +#: app/views/request/_describe_state.rhtml:47 +msgid "The <strong>review has finished</strong> and overall:" +msgstr "Die <strong>Prüfung wurde abgeschlossen</strong> und insgesamt:" -#: app/views/request/preview.rhtml:45 -msgid "Tags:" -msgstr "Links:" +#: app/views/request/new.rhtml:60 +msgid "The Freedom of Information Act <strong>does not apply</strong> to" +msgstr "Das Informationsfreiheitsgesetz <strong>trifft nicht zu</strong> auf" -#: app/views/request/select_authority.rhtml:27 -msgid "Select the authority to write to" -msgstr "Wählen Sie die zu kontaktierende Behörde" +#: app/views/user_mailer/changeemail_already_used.rhtml:8 +msgid "The accounts have been left as they previously were." +msgstr "Die Nutzerkonten wurden in Ihrem ursprünglichen Zustand belassen." -#: app/views/request/select_authority.rhtml:29 -msgid "1. Select an authority" -msgstr "1. Behörde auswählen" +#: app/views/request/_other_describe_state.rhtml:48 +msgid "" +"The authority do <strong>not have</strong> the information <small>(maybe " +"they say who does)" +msgstr "" +"Die Informationen <strong>liegen der Behörde nicht vor</strong> the " +"information <small>(vielleicht können sie Ihnen mitteilen von wem Sie die " +"Informationen erhalten können)" -#: app/views/request/select_authority.rhtml:35 +#: app/views/request/show_response.rhtml:26 msgid "" -"First, type in the <strong>name of the UK public authority</strong> you'd \n" -" <br>like information from. <strong>By law, they have to respond</strong>\n" -" (<a href=\"%s\">why?</a>)." +"The authority only has a <strong>paper copy</strong> of the information." msgstr "" -"Zuerst, geben Sie <strong>EU Behörde</strong> ein, von welcher Sie \n" -" <br>Informationen anfragen möchten. <strong>Diese muss Ihnen wie gesetzlich vorgschrieben antworten</strong>\n" -" (<a href=\"%s\">warum?</a>)." +"Die zuständige Behörde ist ausschliesslich in Besitz einer gedruckten " +"Version <strong>paper copy</strong> der angefragten Informtion. " -#: app/views/request/show.rhtml:5 +#: app/views/request/show_response.rhtml:18 msgid "" -"This request has prominence 'hidden'. You can only see it because you are logged\n" -" in as a super user." +"The authority say that they <strong>need a postal\n" +" address</strong>, not just an email, for it to be a valid FOI request" msgstr "" -"Diese Anfrage ist verborgen. Sie können sie nur sehen weil Sie als " -"Supernutzer eingeloggt sind. " +"Die Behörde gibt an, dass sie für eine gültige IFG-Anfrage eine " +"<strong>Postanschrift</strong>, nicht nur eine Emailadresse, benötigt." -#: app/views/request/show.rhtml:11 +#: app/views/request/show.rhtml:109 msgid "" -"This request is hidden, so that only you the requester can see it. Please\n" -" <a href=\"%s\">contact us</a> if you are not sure why." +"The authority would like to / has <strong>responded by post</strong> to this" +" request." msgstr "" -"Diese Anfrage ist verborgen, so dass ausschliesslich Sie als Nutzer sie sehen können. \n" -"Bitte⏎ <a href=\"%s\">kontaktieren Sie us</a> falls Sie nicht wissen warum." +"Dhe Behörde würde gerne / hat <strong>postalisch</strong> auf diese Anfrage " +"reagiert." -#: app/views/request/show.rhtml:36 +#: app/views/request_mailer/stopped_responses.rhtml:1 msgid "" -"{{user}} (<a href=\"{{user_admin_url}}\">admin</a>) made this " -"{{law_used_full}} request (<a href=\"{{request_admin_url}}\">admin</a>) to " -"{{public_body_link}} (<a href=\"{{public_body_admin_url}}\">admin</a>)" +"The email that you, on behalf of {{public_body}}, sent to\n" +"{{user}} to reply to an {{law_used_short}}\n" +"request has not been delivered." msgstr "" +"Ihre im Namen von {{public_body}} an\n" +"{{user}} gesendete Anfrage, um auf {{law_used_short}}\n" +"zu reagieren, wurde nicht übermittelt." -#: app/views/request/show.rhtml:44 -msgid "{{user}} made this {{law_used_full}} request" -msgstr "{{user}} hat diese {{law_used_full}} Anfrage gestellt" +#: app/views/general/exception_caught.rhtml:5 +msgid "The page doesn't exist. Things you can try now:" +msgstr "Die Seite existiert nicht. Was Sie nun versuchen können:" -#: app/views/request/show.rhtml:45 -msgid "to {{public_body}}" -msgstr "an {{public_body}}" +#: app/views/general/_advanced_search_tips.rhtml:27 +msgid "The public authority does not have the information requested" +msgstr "Der Behörde liegen die angefragten Informationen nicht vor. " -#: app/views/request/show.rhtml:52 -msgid "" -"Please <strong>answer the question above</strong> so we know whether the " +#: app/views/general/_advanced_search_tips.rhtml:31 +msgid "The public authority would like part of the request explained" msgstr "" -"Bitte <strong>beantworten Sie die oben angezeigte Frage</strong>, damit wir " -"wissen ob" - -#: app/views/request/show.rhtml:53 -msgid "useful information." -msgstr "nützliche Information" +"Die Behörde würde gerne weitere Erläuterungen zu einem Teil der Anfrage " +"erhalten." -#: app/views/request/show.rhtml:55 -msgid "This request has an <strong>unknown status</strong>." -msgstr "Diese Anfrage hat einen <strong>unbekannten Status</strong>." +#: app/views/general/_advanced_search_tips.rhtml:32 +msgid "The public authority would like to / has responded by post" +msgstr "Die Behörde würde gerne / hat Ihnen postalisch geantwortet" -#: app/views/request/show.rhtml:57 -msgid "We're waiting for someone to read" -msgstr "Wir warten, dass es von jemandem gelesen wird" +#: app/views/request/_other_describe_state.rhtml:60 +msgid "The request has been <strong>refused</strong>" +msgstr "Die Anfrage wurde <strong>abgelehnt</strong>" -#: app/views/request/show.rhtml:59 +#: app/controllers/request_controller.rb:358 msgid "" -"and update the status accordingly. Perhaps <strong>you</strong> might like " -"to help out by doing that?" +"The request has been updated since you originally loaded this page. Please " +"check for any new incoming messages below, and try again." msgstr "" -"und aktualisieren Sie den Status entsprechend. Vielleicht würden " -"<strong>Sie</strong> uns somit gerne unterstützen?" +"Die Anfrage wurde seit Ihrem letzten Besuch auf dieser Seite aktualisiert. " +"Bitte checken Sie unten nach neu eingegangenen Nachrichten, nud versuchen " +"Sie es erneut." -#: app/views/request/show.rhtml:61 -msgid "We're waiting for" -msgstr "Wir erwarten" +#: app/views/request/show.rhtml:104 +msgid "The request is <strong>waiting for clarification</strong>." +msgstr "<strong>Klärung</strong> der Anfrage wird erwartet." -#: app/views/request/show.rhtml:62 -msgid "to read" -msgstr "zu lesen" +#: app/views/request/show.rhtml:97 +msgid "The request was <strong>partially successful</strong>." +msgstr "Ihre Anfrage war <strong>teilweise erfolgreich</strong>." -#: app/views/request/show.rhtml:64 -msgid "and update the status." -msgstr "und aktualisieren Sie den Status. " +#: app/views/request/show.rhtml:93 +msgid "The request was <strong>refused</strong> by" +msgstr "Die Anfrage wurde <strong>abgelehnt</strong> durch" -#: app/views/request/show.rhtml:68 -msgid "" -"Currently <strong>waiting for a response</strong> from {{public_body_link}}," -" they must respond promptly and" -msgstr "" -"<strong>Antwort</strong> von {{public_body_link}} wird erwartet. Sie sollten" -" in Kürze eine Antwort erhalten und" +#: app/views/request/show.rhtml:95 +msgid "The request was <strong>successful</strong>." +msgstr "Die Anfrage war <strong>erfolgreich</strong>." -#: app/views/request/show.rhtml:72 -msgid "normally" -msgstr "normalerweise" +#: app/views/general/_advanced_search_tips.rhtml:28 +msgid "The request was refused by the public authority" +msgstr "Die Anfrage wurde von der Behörde abgelehnt" -#: app/views/request/show.rhtml:74 -msgid "no later than" -msgstr "nicht später als" +#: app/views/request/hidden.rhtml:9 +msgid "" +"The request you have tried to view has been removed. There are\n" +"various reasons why we might have done this, sorry we can't be more specific here. Please <a\n" +" href=\"%s\">contact us</a> if you have any questions." +msgstr "" +"Die von Ihnen ausgewählte Anfrage wurde verweigert. Dies kann unterschiedliche Ursachen haben, welche an dieser Stelle leider nicht näher erläutert werden können. Bitte<a\n" +" href=\"%s\">kontaktieren Sie uns</a> für weitere Fragen. " -#: app/views/request/show.rhtml:77 -msgid "Response to this request is <strong>delayed</strong>." -msgstr "Die Antwort auf diese Anfrage ist <strong>im Rückstand</strong>." +#: app/views/general/_advanced_search_tips.rhtml:36 +msgid "The requester has abandoned this request for some reason" +msgstr "" +"Der Anfragensteller hat die Anfrage aus unbekannten Gründen zurückgezogen. " -#: app/views/request/show.rhtml:78 +#: app/views/request/_followup.rhtml:59 msgid "" -"By law, {{public_body_link}} should normally have responded " -"<strong>promptly</strong> and" +"The response to your request has been <strong>delayed</strong>. You can say that, \n" +" by law, the authority should normally have responded\n" +" <strong>promptly</strong> and" msgstr "" -"Nach gesetzlicher Vorschrift sollte {{public_body_link}} " -"<strong>umgehend</strong> geantwortet haben und" +"Die Beantwortung auf Ihre Anfrage ist verspätet. Nach gesetzlicher " +"Vorschrift sollte die Behörde unverzüglich geantwortet haben und" -#: app/views/request/show.rhtml:82 -msgid "by" -msgstr "von" +#: app/views/request/_followup.rhtml:71 +msgid "" +"The response to your request is <strong>long overdue</strong>. You can say that, by \n" +" law, under all circumstances, the authority should have responded\n" +" by now" +msgstr "" +"The response to your request is <strong>long overdue</strong>. Nach " +"gesetzlicher Vorschrift sollte {{public_body_link}} Ihnen inzwischen unter " +"allen Umständen geantwortet haben. " -#: app/views/request/show.rhtml:85 -msgid "Response to this request is <strong>long overdue</strong>." +#: app/views/public_body/show.rhtml:128 +msgid "" +"The search index is currently offline, so we can't show the Freedom of " +"Information requests that have been made to this authority." msgstr "" -"Die Antwort auf diese Anfrage ist <strong>lange im Rückstand</strong>." +"Da die Suchanzeige momentan offline ist, können wir die an diese Behörde " +"gestellten Informationsfreiheitsanfragen gerade leider nicht anzeigen. " -#: app/views/request/show.rhtml:86 +#: app/views/user/show.rhtml:158 msgid "" -"By law, under all circumstances, {{public_body_link}} should have responded " -"by now" +"The search index is currently offline, so we can't show the Freedom of " +"Information requests this person has made." msgstr "" -"Nach gesetzlicher Vorschrift sollte {{public_body_link}} Ihnen inzwischen " -"unter allen Umständen geantwortet haben. " +"Da die Suchanzeige momentan offline ist, können wir durch diese Person " +"gestellten Informationsfreiheitsanfragen gerade leider nicht anzeigen. " -#: app/views/request/show.rhtml:88 -msgid "You can <strong>complain</strong> by" -msgstr "Sie können sich <strong>beschweren</strong>, indem sie" +#: app/controllers/track_controller.rb:144 +msgid "Then you can cancel the alert." +msgstr "Dann können Sie die Statusnachricht abmelden " -#: app/views/request/show.rhtml:89 -msgid "requesting an internal review" -msgstr "Interne Prüfung beantragen " +#: app/controllers/track_controller.rb:174 +msgid "Then you can cancel the alerts." +msgstr "Dann können Sie die Statusnachrichten abmelden" -#: app/views/request/show.rhtml:91 -msgid "<strong>did not have</strong> the information requested." -msgstr "Die angefragten Informationen waren <strong>nicht vorhanden</strong>." +#: app/controllers/user_controller.rb:267 +msgid "Then you can change your email address used on {{site_name}}" +msgstr "können Sie Ihre auf {{site_name}} verwendete Email-Adresse beenden" -#: app/views/request/show.rhtml:93 -msgid "The request was <strong>refused</strong> by" -msgstr "Die Anfrage wurde <strong>abgelehnt</strong> durch" +#: app/controllers/user_controller.rb:221 +msgid "Then you can change your password on {{site_name}}" +msgstr "Dann können Sie Ihr Passwort unter {{site_name}} ändern" -#: app/views/request/show.rhtml:95 -msgid "The request was <strong>successful</strong>." -msgstr "Die Anfrage war <strong>erfolgreich</strong>." +#: app/controllers/request_controller.rb:344 +msgid "Then you can classify the FOI response you have got from " +msgstr "" +"Dann klassifizieren Sie die IFG-Anfrage welche Sie erhalten haben, von" -#: app/views/request/show.rhtml:97 -msgid "The request was <strong>partially successful</strong>." -msgstr "Ihre Anfrage war <strong>teilweise erfolgreich</strong>." +#: app/controllers/request_controller.rb:774 +msgid "Then you can download a zip file of {{info_request_title}}." +msgstr "" +"Dann können Sie eine Zip-Datei von {{info_request_title}} herunterladen. " -#: app/views/request/show.rhtml:100 -msgid "is <strong>waiting for your clarification</strong>." -msgstr "<strong>Ihre Erläuterung wird erwartet</strong>." +#: app/controllers/request_game_controller.rb:41 +msgid "Then you can play the request categorisation game." +msgstr "Dann können Sie die helden einige Anfraggen zuzuordnen. " -#: app/views/request/show.rhtml:101 -msgid "Please" -msgstr "Bitte" +#: app/controllers/user_controller.rb:348 +msgid "Then you can send a message to " +msgstr "Dann können Sie eine Nachricht senden an" -#: app/views/request/show.rhtml:102 -msgid "send a follow up message" -msgstr "Nachfrage versenden" +#: app/controllers/user_controller.rb:541 +msgid "Then you can sign in to {{site_name}}" +msgstr "Dann können Sie sich auf {{site_name}} einloggen. " -#: app/views/request/show.rhtml:104 -msgid "The request is <strong>waiting for clarification</strong>." -msgstr "<strong>Klärung</strong> der Anfrage wird erwartet." +#: app/controllers/request_controller.rb:82 +msgid "Then you can update the status of your request to " +msgstr "Dann können Sie den Status Ihrer Nachricht aktualisieren" -#: app/views/request/show.rhtml:105 -msgid "If you are {{user_link}}, please" -msgstr "Wenn Sie {{user_link}} sind, bitte" +#: app/controllers/request_controller.rb:713 +msgid "Then you can upload an FOI response. " +msgstr "Dann können Sie eine IFG-Antwort hochladen. " -#: app/views/request/show.rhtml:106 -msgid "sign in" -msgstr "Anmelden" +#: app/controllers/request_controller.rb:551 +msgid "Then you can write follow up message to " +msgstr "Dann können Sie eine Nachfrage senden an" -#: app/views/request/show.rhtml:106 -msgid "to send a follow up message." -msgstr "um eine Nachfrage zu senden. " +#: app/controllers/request_controller.rb:552 +msgid "Then you can write your reply to " +msgstr "Dann können Sie Ihre Antwort schreiben an" -#: app/views/request/show.rhtml:109 +#: app/models/track_thing.rb:270 msgid "" -"The authority would like to / has <strong>responded by post</strong> to this" -" request." +"Then you will be emailed whenever '{{user_name}}' requests something or gets" +" a response." msgstr "" -"Dhe Behörde würde gerne / hat <strong>postalisch</strong> auf diese Anfrage " -"reagiert." +"Dann erhalten Sie eine Email sobald '{{user_name}}' eine Anfrage stellt oder" +" eine Antwort erhält. " -#: app/views/request/show.rhtml:111 +#: app/models/track_thing.rb:286 msgid "" -"Waiting for an <strong>internal review</strong> by {{public_body_link}} of " -"their handling of this request." +"Then you will be emailed whenever a new request or response matches your " +"search." msgstr "" -"<strong>Interne Prüfung</strong> durch {{public_body_link}} wird erwartet." +"Dann werden Sie per Email über neue Anfragen oder Antworten informiert, die " +"auf Ihre Suche zutreffen. " -#: app/views/request/show.rhtml:113 -msgid "" -"There was a <strong>delivery error</strong> or similar, which needs fixing " -"by the {{site_name}} team." +#: app/models/track_thing.rb:235 +msgid "Then you will be emailed whenever an FOI request succeeds." msgstr "" -"Es ist ein <strong>Übermittlungsfehler</strong>oder ähnliches aufgetreten, " -"welcher von unserem {{site_name}} Team repariert werden muss. " +"Sie werden bei jeder erfolgreichen IFG-Anfrage per Email benachrichtigt. " -#: app/views/request/show.rhtml:115 +#: app/models/track_thing.rb:219 +msgid "Then you will be emailed whenever anyone makes a new FOI request." +msgstr "" +"Sie werden dann per email informiert, sobald jemand eine neue IFG-Anfrage " +"stellt. " + +#: app/models/track_thing.rb:254 msgid "" -"This request has had an unusual response, and <strong>requires " -"attention</strong> from the {{site_name}} team." +"Then you will be emailed whenever someone requests something or gets a " +"response from '{{public_body_name}}'." msgstr "" -"Diese Anfrage erhielt eine ungewöhnliche Antwort und müsste einmal durch das" -" {{site_name}} team <strong>überprüft</strong> werden." +"Dann erhalten Sie eine Email sobald jemand eine Anfrage an die folgende " +"Behörde stellt oder eine Antwort von dieser erhält: '{{public_body_name}}'" -#: app/views/request/show.rhtml:117 +#: app/models/track_thing.rb:203 msgid "" -"This request has been <strong>withdrawn</strong> by the person who made it. \n" -" \t There may be an explanation in the correspondence below." +"Then you will be emailed whenever the request '{{request_title}}' is " +"updated." msgstr "" -"Diese Anfrage wurde von dem/der Anfrageninhaber/in <strong>zurückgezogen</strong>. \n" -" <span class=\"whitespace other\" title=\"Tab\">»</span> Sie können evt. eine Begründung im unten angefügten Kommunikationsverlauf finden." +"Dann erhalten Sie jedesmal eine Email, wenn die Anfrage '{{request_title}}' " +"aktualisiert wird." -#: app/views/request/show_response.rhtml:13 -msgid "Which of these is happening?" -msgstr "Welcher dieser Aspekte ist zutreffend?" +#: app/controllers/request_controller.rb:32 +msgid "Then you'll be allowed to send FOI requests." +msgstr "Dann ist es Ihnen gestattet eine IFG-Anfrage zu senden. " -#: app/views/request/show_response.rhtml:18 +#: app/controllers/request_controller.rb:304 +msgid "Then your FOI request to {{public_body_name}} will be sent." +msgstr "Dann wird Ihre OFG-Anfrage an {{public_body_name}} gesendet. " + +#: app/controllers/comment_controller.rb:56 +msgid "Then your annotation to {{info_request_title}} will be posted." +msgstr "Dann wird Ihr Kommentar zu {{info_request_title}} gesendet." + +#: app/views/request_mailer/comment_on_alert_plural.rhtml:1 msgid "" -"The authority say that they <strong>need a postal\n" -" address</strong>, not just an email, for it to be a valid FOI request" +"There are {{count}} new annotations on your {{info_request}} request. Follow" +" this link to see what they wrote." msgstr "" -"Die Behörde gibt an, dass sie für eine gültige IFG-Anfrage eine " -"<strong>Postanschrift</strong>, nicht nur eine Emailadresse, benötigt." +"Es gibt {{count}} neue Anmerkungen zu Ihrer {{info_request}} Anfrage. Folgen" +" Sie dem Link, um diese anzusehen. " -#: app/views/request/show_response.rhtml:26 +#: app/views/public_body/show.rhtml:7 +msgid "There is %d person following this authority" +msgid_plural "There are %d people following this authority" +msgstr[0] "Diese Behörde wird von %d Person beobachtet" +msgstr[1] "Diese Behörde wird von %d Personen beobachtet." + +#: app/views/request/_sidebar.rhtml:5 +msgid "There is %d person following this request" +msgid_plural "There are %d people following this request" +msgstr[0] " %d Person verfolgen diese Anfrage" +msgstr[1] " %d Personen verfolgen diese Anfrage" + +#: app/views/user/show.rhtml:4 msgid "" -"The authority only has a <strong>paper copy</strong> of the information." +"There is <strong>more than one person</strong> who uses this site and has this name. \n" +" One of them is shown below, you may mean a different one:" msgstr "" -"Die zuständige Behörde ist ausschliesslich in Besitz einer gedruckten " -"Version <strong>paper copy</strong> der angefragten Informtion. " +"Es gibt <strong>mehrere Nutzer</strong> mit diesem Namen. Einer wird unten " +"angezeigt, Sie könnten jedoch einen andere Person meinen:" -#: app/views/request/show_response.rhtml:29 +#: app/views/request/show.rhtml:113 msgid "" -"At the bottom of this page, write a reply to them trying to persuade them to scan it in\n" -" (<a href=\"%s\">more details</a>)." +"There was a <strong>delivery error</strong> or similar, which needs fixing " +"by the {{site_name}} team." msgstr "" -"Am Ende der Seite können Sie eine Antwort mit der Aufforderung das Dokument einzuscannen senden\n" -" (<a href=\"%s\">weitere Details</a>)." +"Es ist ein <strong>Übermittlungsfehler</strong>oder ähnliches aufgetreten, " +"welcher von unserem {{site_name}} Team repariert werden muss. " -#: app/views/request/show_response.rhtml:34 -msgid "" -"You want to <strong>give your postal address</strong> to the authority in " -"private." +#: app/controllers/user_controller.rb:140 +#: app/controllers/public_body_controller.rb:82 +msgid "There was an error with the words you entered, please try again." msgstr "" -"Sie möchten <strong>Ihre Anschrift</strong> geschützt an die Behörde senden." +"Mit den von Ihren eingegebenen Worten ist etwas schiefgegangen. Versuchen " +"Sie es erneut. " -#: app/views/request/show_response.rhtml:37 -msgid "To do that please send a private email to " -msgstr "Senden Sie uns hierfür bitte eine private Email" +#: app/views/public_body/show.rhtml:117 app/views/general/search.rhtml:10 +msgid "There were no requests matching your query." +msgstr "Es gab keine zu Ihrer Suche passenden Anfragen." -#: app/views/request/show_response.rhtml:39 -msgid "" -"containing your postal address, and asking them to reply to this request.\n" -" Or you could phone them." -msgstr "" -"Ihre Postanschrift beinhaltend und Sie fragend auf diese Afrage zu antworten.\n" -" Oder Sie könnten Sie anrufen." +#: app/views/request/_describe_state.rhtml:38 +msgid "They are going to reply <strong>by post</strong>" +msgstr "Ich erhalte meine Antwort <strong>auf dem Postweg</strong>" -#: app/views/request/show_response.rhtml:42 +#: app/views/request/_describe_state.rhtml:52 msgid "" -"When you receive the paper response, please help\n" -" others find out what it says:" +"They do <strong>not have</strong> the information <small>(maybe they say who" +" does)</small>" msgstr "" -"Wenn Sie die gedruckte Antwort erhalten, machen Sie den Inhalt bitte für " -"andere Nutzer zugänglich" +"Die Informationen <strong>liegen nicht vor</strong> <small>(vielleicht " +"können sie Ihnen mitteilen von wem Sie die Informationen erhalten " +"können)</small>" -#: app/views/request/show_response.rhtml:45 +#: app/views/user/show.rhtml:83 +msgid "They have been given the following explanation:" +msgstr "Die folgende Erklärung wurde abgegeben:" + +#: app/views/request_mailer/overdue_alert.rhtml:3 msgid "" -"Add an annotation to your request with choice quotes, or\n" -" a <strong>summary of the response</strong>." +"They have not replied to your {{law_used_short}} request {{title}} promptly," +" as normally required by law" msgstr "" -"Fügen Sie Ihrer Anfrage einen Kommentar mit Wahlzitat oder, " -"eine<strong>Zusammenfassung Ihrer Antwort</strong>hinzu. " +"Ihre {{law_used_short}} Anfrage {{title}}wurde nicht im gesetzlich " +"vorgeschriebenen Zeitrahmen beantwortet. " -#: app/views/request/show_response.rhtml:47 +#: app/views/request_mailer/very_overdue_alert.rhtml:3 msgid "" -"If you can, scan in or photograph the response, and <strong>send us\n" -" a copy to upload</strong>." +"They have not replied to your {{law_used_short}} request {{title}}, \n" +"as required by law" msgstr "" -"Fall möglich, scannen oder photographieren Sie die Antwort und<strong>senden" -" Sie uns eine Kopie zum Upload</strong>." - -#: app/views/request/show_response.rhtml:60 -msgid "New response to your request" -msgstr "Neue Antwort auf Ihre Anfrage" +"Ihre {{law_used_short}} Anfrage {{title}} wurde nicht nach gesetzlicher " +"Vorschrift beantwortet" -#: app/views/request/show_response.rhtml:62 -msgid "Response to your request" -msgstr "Reagieren Sie auf Ihre Anfrage" +#: app/views/request/_after_actions.rhtml:3 +msgid "Things to do with this request" +msgstr "Weitere Möglichkeiten für diese Anfrage" -#: app/views/request/show_response.rhtml:66 -msgid "New response to {{law_used_short}} request" -msgstr "Neue Antwort auf {{law_used_short}} Anfrage" +#: app/views/public_body/show.rhtml:71 +msgid "This authority no longer exists, so you cannot make a request to it." +msgstr "" +"Diese Behörde existiert nichtmehr. Es ist folglich nicht möglich eine " +"Anfrage zu stellen. " -#: app/views/request/similar.rhtml:7 -msgid "No similar requests found." -msgstr "Keine vergleichbaren Anfragen gefunden. " +#: app/views/request/_hidden_correspondence.rhtml:23 +msgid "" +"This comment has been hidden. See annotations to\n" +" find out why. If you are the requester, then you may <a href=\"%s\">sign in</a> to view the response." +msgstr "" +"Dieser Kommentar wurde verborgen. Sehen Sie die Anmerkungen, um den Grund zu" +" erfahren. Falls Sie diese Anfrage gestellt haben können Sie sich <a " +"href=\"%s\">einloggen</a> um die Antwort zu lesen." -#: app/views/request/similar.rhtml:18 -msgid "Unexpected search result type " -msgstr "Unerwartetes Suchergebnis" +#: app/views/request/new.rhtml:63 +msgid "" +"This covers a very wide spectrum of information about the state of\n" +" the <strong>natural and built environment</strong>, such as:" +msgstr "" #: app/views/request/simple_correspondence.rhtml:1 msgid "" @@ -3592,212 +3550,211 @@ msgstr "" "Dies ist eine Klartext-Version der IFG-Anfrage \"{{request_title}}\". Die " "aktuellste, vollständige Version ist auf {{full_url}} erhältlich" -#: app/views/request/simple_correspondence.rhtml:17 -#: app/views/request/simple_correspondence.rhtml:29 -#: app/views/request/simple_correspondence.rhtml:36 -msgid "Date:" -msgstr "Datum:" - -#: app/views/request/simple_correspondence.rhtml:21 -msgid "Attachment:" -msgstr "Anhang:" - -#: app/views/request/simple_correspondence.rhtml:42 -msgid "{{username}} left an annotation:" -msgstr "{{username}} hat eine Nachricht hinterlassen" - -#: app/views/request/upload_response.rhtml:5 -msgid "Respond to the FOI request" -msgstr "IFG-Anfrage beantworten" - -#: app/views/request/upload_response.rhtml:5 -msgid " made by " -msgstr "erstellt durch" - -#: app/views/request/upload_response.rhtml:8 +#: app/views/request/_view_html_prefix.rhtml:9 msgid "" -"Your response will <strong>appear on the Internet</strong>, <a " -"href=\"%s\">read why</a> and answers to other questions." +"This is an HTML version of an attachment to the Freedom of Information " +"request" msgstr "" -"Ihre Antwort, sowie Antworten auf andere Anfragen wierden <strong>im " -"Internet erscheinen</strong>, <a href=\"%s\">Lesen Sie warum</a>" - -#: app/views/request/upload_response.rhtml:11 -msgid "Respond by email" -msgstr "Email-Antwort senden" +"Dies ist eine HTML Version eines Anhanges der Informationsfreiheitsanfrage" -#: app/views/request/upload_response.rhtml:13 +#: app/views/request_mailer/stopped_responses.rhtml:5 msgid "" -"You should have received a copy of the request by email, and you can respond\n" -"by <strong>simply replying</strong> to that email. For your convenience, here is the address:" +"This is because {{title}} is an old request that has been\n" +"marked to no longer receive responses." msgstr "" -"Sie sollten eine Kopie diesr Anfrage per Email erhalten haben. Sie können darauf reagieren, indem Sie\n" -"by <strong>einfach antworten</strong> to that email. For your convenience, here is the address:" +"Die Ursache ist der veraltete Status dieser Anfrage {{title}}, \n" +"welche keine weiteren Antworten erhalten kann." -#: app/views/request/upload_response.rhtml:16 +#: app/views/track/_tracking_links.rhtml:8 msgid "" -"You may <strong>include attachments</strong>. If you would like to attach a\n" -"file too large for email, use the form below." +"This is your own request, so you will be automatically emailed when new " +"responses arrive." msgstr "" -"Vielleicht möchten Sie <strong>Dateien anhängen</strong>. Falls Sie eine " -"Datei anhängen möchten, welche für die Emailübertragung zu groß sind, " -"verwenden Sie das untenstehende Formular. " - -#: app/views/request/upload_response.rhtml:21 -msgid "Respond using the web" -msgstr "Online antworten" +"Dies ist Ihre eigene Anfrage. Sie erhalten eine automatische " +"Emailbenachrichtigung, sobald Ihre Anfrage beantwortet wird. " -#: app/views/request/upload_response.rhtml:23 +#: app/views/request/_hidden_correspondence.rhtml:17 msgid "" -"Enter your response below. You may attach one file (use email, or \n" -"<a href=\"%s\">contact us</a> if you need more)." +"This outgoing message has been hidden. See annotations to\n" +"\t\t\t\t\t\tfind out why. If you are the requester, then you may <a href=\"%s\">sign in</a> to view the response." msgstr "" -"Geben Sie unten Ihre Antwort ein. Sie könne eine Datei anhängen (nutzen Sie Email, oder \n" -"<a href=\"%s\">kontaktieren Sie uns</a> falls Sie mehrere Anhänge benötigen)." - -#: app/views/request/upload_response.rhtml:28 -msgid "Response:" -msgstr "Antwort:" +"Dieser Kommentar wurde verborgen. Sehen Sie die Anmerkungen, um den Grund zu" +" erfahren. Falls Sie diese Anfrage gestellt haben können Sie sich <a " +"href=\"%s\">einloggen</a> um die Antwort zu lesen." -#: app/views/request/upload_response.rhtml:33 -msgid "Attachment (optional):" -msgstr "Anhang (freiwillig)" +#: app/views/request/_other_describe_state.rhtml:40 +#: app/views/request/_describe_state.rhtml:44 +msgid "This particular request is finished:" +msgstr "Diese Anfrage wurde abgeschlossen:" -#: app/views/request/upload_response.rhtml:40 +#: app/views/user/show.rhtml:138 msgid "" -" (<strong>patience</strong>, especially for large files, it may take a " -"while!)" +"This person has made no Freedom of Information requests using this site." msgstr "" -" (<strong>Geduld</strong>, speziell für größere Dateien kann es einen Moment" -" dauern!)" +"Diese Person hat eine Informationsfreiheits-Anfrage über diese Seite " +"gestellt. " -#: app/views/request_game/play.rhtml:1 app/views/request_game/play.rhtml:30 -msgid "Play the request categorisation game!" -msgstr "Helfen Sie uns ausstehende Anfragen zu kategorisieren!" +#: app/views/user/show.rhtml:143 +msgid "This person's %d Freedom of Information request" +msgid_plural "This person's %d Freedom of Information requests" +msgstr[0] "" +" %d Informationsfreiheitsanfragen dieses Benutzers / dieser Benutzerin" +msgstr[1] "" +" %d Informationsfreiheitsanfragen dieses Benutzers / dieser Benutzerin" -#: app/views/request_game/play.rhtml:31 -msgid "" -"Some people who've made requests haven't let us know whether they were\n" -"successful or not. We need <strong>your</strong> help –\n" -"choose one of these requests, read it, and let everyone know whether or not the\n" -"information has been provided. Everyone'll be exceedingly grateful." -msgstr "" -"Nicht alle Anfragensteller haben uns über den Erfolg Ihrer Anfragen " -"informiert. Wir sind auf <strong>Ihre</strong> Hilfe angewiesen. Wählen Sie " -"eine dieser Anfragen, lesen Sie sie und teilen Sie uns mit, ob die " -"gewünschte Information zur Verfügung gestellt wurde. Alle Nutzer wären Ihnen" -" ausgesprochen dankbar. " +#: app/views/user/show.rhtml:171 +msgid "This person's %d annotation" +msgid_plural "This person's %d annotations" +msgstr[0] "Die %d Anmerkung dieser Person" +msgstr[1] "Die %d Anmerkungen dieser Person" -#: app/views/request_game/play.rhtml:39 -msgid "I don't like these ones — give me some more!" -msgstr "Ich würde gerne andere Anfragen erhalten!" +#: app/views/user/show.rhtml:164 +msgid "This person's annotations" +msgstr "Die Anmerkungen dieser Person" -#: app/views/request_game/play.rhtml:40 -msgid "I don't want to do any more tidying now!" -msgstr "Ich möchte gerade keine weiteren Anfragen bearbeiten!" +#: app/views/request/_describe_state.rhtml:84 +msgid "This request <strong>requires administrator attention</strong>" +msgstr "Diese Anfrage <strong>müsste einmal überprüft werden</strong>" -#: app/views/request_game/play.rhtml:42 +#: app/views/request/show.rhtml:55 +msgid "This request has an <strong>unknown status</strong>." +msgstr "Diese Anfrage hat einen <strong>unbekannten Status</strong>." + +#: app/views/request/show.rhtml:117 msgid "" -"Thanks for helping - your work will make it easier for everyone to find successful\n" -"responses, and maybe even let us make league tables..." +"This request has been <strong>withdrawn</strong> by the person who made it. \n" +" \t There may be an explanation in the correspondence below." msgstr "" -"Vielen Dank für die Hilfe - Ihre Arbeit wird es für jeden leichter machen " -"erfolgreiche Antworten zu finden und es uns eventuell sogar ermöglichen " -"Ranglisten zu erstellen..." +"Diese Anfrage wurde von dem/der Anfrageninhaber/in <strong>zurückgezogen</strong>. \n" +" <span class=\"whitespace other\" title=\"Tab\">»</span> Sie können evt. eine Begründung im unten angefügten Kommunikationsverlauf finden." -#: app/views/request_mailer/comment_on_alert.rhtml:1 +#: app/models/info_request.rb:395 msgid "" -"{{user_name}} has annotated your {{law_used_short}} \n" -"request. Follow this link to see what they wrote." +"This request has been set by an administrator to \"allow new responses from " +"nobody\"" msgstr "" -"{{user_name}} hat Ihres {{law_used_short}} \n" -"Anfrage kommentiert. Folgen Sie diesem Link, um die Anmerkung zu sehen." -#: app/views/request_mailer/comment_on_alert.rhtml:6 -#: app/views/request_mailer/comment_on_alert_plural.rhtml:5 -#: app/views/request_mailer/new_response.rhtml:15 -#: app/views/request_mailer/new_response_reminder_alert.rhtml:8 -#: app/views/request_mailer/not_clarified_alert.rhtml:9 -#: app/views/request_mailer/old_unclassified_updated.rhtml:8 -#: app/views/request_mailer/overdue_alert.rhtml:9 -#: app/views/request_mailer/stopped_responses.rhtml:16 -#: app/views/request_mailer/very_overdue_alert.rhtml:11 -#: app/views/track_mailer/event_digest.rhtml:66 -#: app/views/user_mailer/already_registered.rhtml:11 -#: app/views/user_mailer/changeemail_already_used.rhtml:10 -#: app/views/user_mailer/changeemail_confirm.rhtml:13 -#: app/views/user_mailer/confirm_login.rhtml:11 -msgid "the {{site_name}} team" -msgstr "das {{site_name}} Team" +#: app/views/request/show.rhtml:115 +msgid "" +"This request has had an unusual response, and <strong>requires " +"attention</strong> from the {{site_name}} team." +msgstr "" +"Diese Anfrage erhielt eine ungewöhnliche Antwort und müsste einmal durch das" +" {{site_name}} team <strong>überprüft</strong> werden." -#: app/views/request_mailer/comment_on_alert_plural.rhtml:1 +#: app/views/request/show.rhtml:5 msgid "" -"There are {{count}} new annotations on your {{info_request}} request. Follow" -" this link to see what they wrote." +"This request has prominence 'hidden'. You can only see it because you are logged\n" +" in as a super user." msgstr "" -"Es gibt {{count}} neue Anmerkungen zu Ihrer {{info_request}} Anfrage. Folgen" -" Sie dem Link, um diese anzusehen. " +"Diese Anfrage ist verborgen. Sie können sie nur sehen weil Sie als " +"Supernutzer eingeloggt sind. " -#: app/views/request_mailer/new_response.rhtml:1 -msgid "You have a new response to the {{law_used_full}} request " +#: app/views/request/show.rhtml:11 +msgid "" +"This request is hidden, so that only you the requester can see it. Please\n" +" <a href=\"%s\">contact us</a> if you are not sure why." msgstr "" -"Sie haben eine neue Antwort auf die Anfrage {{law_used_full}} erhalten " +"Diese Anfrage ist verborgen, so dass ausschliesslich Sie als Nutzer sie sehen können. \n" +"Bitte⏎ <a href=\"%s\">kontaktieren Sie us</a> falls Sie nicht wissen warum." -#: app/views/request_mailer/new_response.rhtml:2 -msgid "that you made to" -msgstr "welche Sie stellten an:" +#: app/views/request/_other_describe_state.rhtml:10 +#: app/views/request/_describe_state.rhtml:7 +msgid "This request is still in progress:" +msgstr "Diese Anfrage ist noch in Bearbeitung" -#: app/views/request_mailer/new_response.rhtml:5 -msgid "To view the response, click on the link below." +#: app/views/request/_hidden_correspondence.rhtml:10 +msgid "" +"This response has been hidden. See annotations to find out why.\n" +" If you are the requester, then you may <a href=\"%s\">sign in</a> to view the response." msgstr "" -"Um die Antwort zu lesen, klicken Sie bitte auf den unten angezeigten Link. " +"Dieser Kommentar wurde verborgen. Sehen Sie die Anmerkungen, um den Grund zu" +" erfahren. Falls Sie diese Anfrage gestellt haben können Sie sich <a " +"href=\"%s\">anmelden</a> um die Antwort zu lesen." -#: app/views/request_mailer/new_response.rhtml:9 +#: app/views/request/details.rhtml:6 msgid "" -"When you get there, please update the status to say if the response \n" -"contains any useful information." +"This table shows the technical details of the internal events that happened\n" +"to this request on {{site_name}}. This could be used to generate information about\n" +"the speed with which authorities respond to requests, the number of requests\n" +"which require a postal response and much more." msgstr "" -"Wenn Sie dort hinkommen, aktualisieren Sie bitte den Status indem Sie uns " -"wissen lassen, ob die Antwort nützliche Informationen enthält. " -#: app/views/request_mailer/new_response.rhtml:12 +#: app/views/user/show.rhtml:79 +msgid "This user has been banned from {{site_name}} " +msgstr "Dieser Nutzer wurde von {{site_name}} entfernt" + +#: app/views/user_mailer/changeemail_already_used.rhtml:5 msgid "" -"Although all responses are automatically published, we depend on\n" -"you, the original requester, to evaluate them." +"This was not possible because there is already an account using \n" +"the email address {{email}}." msgstr "" -"Obwould alle Antworten automatisch veröffentlicht werden, sind wir auf Sie " -"als ursprünglichen Antragsteller angewiesen, um diese zu bewerten" +"Dieser Vorgang war nicht möglich, da bereits ein Nutzerkonto mit der Email-" +"Adresse {{email}} besteht." -#: app/views/request_mailer/new_response_reminder_alert.rhtml:1 -msgid "To let us know, follow this link and then select the appropriate box." +#: app/models/track_thing.rb:218 +msgid "To be emailed about any new requests" +msgstr "Um Emails zu allen neuen Anfragen zu erhalten" + +#: app/models/track_thing.rb:234 +msgid "To be emailed about any successful requests" +msgstr "Um per Email über erfolgreiche Anfragen informiert zu werden" + +#: app/models/track_thing.rb:269 +msgid "To be emailed about requests by '{{user_name}}'" +msgstr "Um Emails zu Anfragen von '{{user_name}}' zu erhalten" + +#: app/models/track_thing.rb:253 +msgid "" +"To be emailed about requests made using {{site_name}} to the public " +"authority '{{public_body_name}}'" msgstr "" -"Um uns zu informieren, folgen Sie bitte dem Link und wählen Sie das " -"zutreffende Feld aus. " +"Um Emails bzgl. der durch {{site_name}} an die Behörde " +"'{{public_body_name}}' gestellte Anfragen" -#: app/views/request_mailer/new_response_reminder_alert.rhtml:5 +#: app/controllers/track_controller.rb:173 +msgid "To cancel these alerts" +msgstr "Um diese Benachrichtigungen zu löschen" + +#: app/controllers/track_controller.rb:143 +msgid "To cancel this alert" +msgstr "Um diese Benachrichtigung zu löschen" + +#: app/views/user/no_cookies.rhtml:5 msgid "" -"Your request was called {{info_request}}. Letting everyone know whether you " -"got the information will help us keep tabs on" +"To carry on, you need to sign in or make an account. Unfortunately, there\n" +"was a technical problem trying to do this." msgstr "" -"Ihre Anfrage hat den folgenden Titel: {{info_request}}. Bitte informieren " -"Sie uns, ob Sie die gewünschte Information erhalten. Dies hilft uns die " -"Seite aktuell zu halten." +"Um fortzufahren müssen Sie sich anmelden oder ein Benutzerkonto erstellen. " +"Leider sind bei diesem Versuch technische Störungen aufgetreten. " -#: app/views/request_mailer/not_clarified_alert.rhtml:1 -msgid "request." -msgstr "Anfrage." +#: app/controllers/user_controller.rb:266 +msgid "To change your email address used on {{site_name}}" +msgstr "Um Ihre auf {{site_name}} verwendete Email-Adresse zu ändern" + +#: app/controllers/request_controller.rb:343 +msgid "To classify the response to this FOI request" +msgstr "Um die Antwort auf diese IFG-Anfrage zu klassifizieren" + +#: app/views/request/show_response.rhtml:37 +msgid "To do that please send a private email to " +msgstr "Senden Sie uns hierfür bitte eine private Email" #: app/views/request_mailer/not_clarified_alert.rhtml:2 msgid "To do this, first click on the link below." msgstr "Klicken Sie hierfür bitte auf den unten angezeigten Link." -#: app/views/request_mailer/not_clarified_alert.rhtml:6 -msgid "" -"You will only get an answer to your request if you follow up\n" -"with the clarification." -msgstr "" -"Sie können nur eine Antwort auf Ihre Anfrage erhalten wenn Sie mti der " -"Aufklärung fortfahren. " +#: app/controllers/request_controller.rb:773 +msgid "To download the zip file" +msgstr "Um die Zip-Datei herunterzuladen" + +#: app/models/track_thing.rb:285 +msgid "To follow requests and responses matching your search" +msgstr "Um Ihrer Suchanfrage ähnelnten Anfragen und Antworten zu folgen" + +#: app/models/track_thing.rb:202 +msgid "To follow updates to the request '{{request_title}}'" +msgstr "Um Aktualisierungen der Anfrage '{{request_title}}' zu folgen" #: app/views/request_mailer/old_unclassified_updated.rhtml:1 msgid "" @@ -3810,274 +3767,385 @@ msgstr "" "Sie mit dieser Änderung nicht einverstanden sind, aktualisieren Sie diesen " "bitte erneut, in einen Ihrer Meinung nach besser zutreffenden Status. " -#: app/views/request_mailer/old_unclassified_updated.rhtml:4 -msgid "Follow this link to see the request:" -msgstr "Folgen Sie diesem Link, um die Anfrage anzusehen:" +#: app/views/request_mailer/new_response_reminder_alert.rhtml:1 +msgid "To let us know, follow this link and then select the appropriate box." +msgstr "" +"Um uns zu informieren, folgen Sie bitte dem Link und wählen Sie das " +"zutreffende Feld aus. " -#: app/views/request_mailer/overdue_alert.rhtml:1 -msgid "have delayed." -msgstr "haben verspätet." +#: app/controllers/request_game_controller.rb:40 +msgid "To play the request categorisation game" +msgstr "Um uns mit der Kategorisierung von Anfragen zu unterstützen" -#: app/views/request_mailer/overdue_alert.rhtml:3 +#: app/controllers/comment_controller.rb:55 +msgid "To post your annotation" +msgstr "Um Ihre Anmerkung zu senden" + +#: app/controllers/request_controller.rb:549 +msgid "To reply to " +msgstr "Um eine Antwort zu senden an" + +#: app/controllers/request_controller.rb:548 +msgid "To send a follow up message to " +msgstr "Um eine Nachfrage zu senden" + +#: app/controllers/user_controller.rb:347 +msgid "To send a message to " +msgstr "Um eine Nachricht zu senden an " + +#: app/controllers/request_controller.rb:31 +#: app/controllers/request_controller.rb:303 +msgid "To send your FOI request" +msgstr "Um Ihre IFG-Anfrage zu senden" + +#: app/controllers/request_controller.rb:81 +msgid "To update the status of this FOI request" +msgstr "Um den Status dieser IFG-Anfrage zu aktualisieren" + +#: app/controllers/request_controller.rb:712 msgid "" -"They have not replied to your {{law_used_short}} request {{title}} promptly," -" as normally required by law" +"To upload a response, you must be logged in using an email address from " msgstr "" -"Ihre {{law_used_short}} Anfrage {{title}}wurde nicht im gesetzlich " -"vorgeschriebenen Zeitrahmen beantwortet. " +"Um eine Antwort hochzuladen müssen Sie angemeldet sein und dafür eine " +"folgende Email-Adresse benutzen:" -#: app/views/request_mailer/overdue_alert.rhtml:3 -msgid "during term time" -msgstr "während der Saison" +#: app/views/general/search.rhtml:24 +msgid "" +"To use the advanced search, combine phrases and labels as described in the " +"search tips below." +msgstr "" +"Um die erweiterte Suchoption zu nutzen, kombinieren Sie Formulierungen und " +"Kennzeichen, wie in den unten aufgeführten Suchhinweisen beschrieben. " -#: app/views/request_mailer/overdue_alert.rhtml:5 +#: app/views/public_body/view_email_captcha.rhtml:5 msgid "" -"Click on the link below to send a message to {{public_body}} reminding them " -"to reply to your request." +"To view the email address that we use to send FOI requests to " +"{{public_body_name}}, please enter these words." msgstr "" -"Klicken Sie auf den unten aufgeführten Link an {{public_body}}, um eine " -"Anfrageerinnerung zu versenden." +"Geben Sie bitte diese Worte ein, um die Email-Adresse zu sehen, welche wir " +"verwenden, um IFG-Anfragen an {{public_body_name}} zu senden." -#: app/views/request_mailer/requires_admin.rhtml:2 -msgid "has reported an" -msgstr "hat berichtet" +#: app/views/request_mailer/new_response.rhtml:5 +msgid "To view the response, click on the link below." +msgstr "" +"Um die Antwort zu lesen, klicken Sie bitte auf den unten angezeigten Link. " -#: app/views/request_mailer/requires_admin.rhtml:3 -msgid "" -"response as needing administrator attention. Take a look, and reply to this\n" -"email to let them know what you are going to do about it." +#: app/views/request/_request_listing_short_via_event.rhtml:9 +msgid "To {{public_body_link_absolute}}" +msgstr "An {{public_body_link_absolute}}" + +#: app/views/request/preview.rhtml:17 app/views/request/new.rhtml:40 +#: app/views/request/followup_preview.rhtml:22 +#: app/views/request/simple_correspondence.rhtml:16 +#: app/views/request/simple_correspondence.rhtml:28 +msgid "To:" +msgstr "An:" + +#: app/views/general/_localised_datepicker.rhtml:7 +msgid "Today" +msgstr "Heute" + +#: app/views/request/select_authority.rhtml:47 +#: app/views/public_body/_search_ahead.rhtml:3 +msgid "Top search results:" +msgstr "Beste Suchergebnisse:" + +#: app/models/track_thing.rb:247 +msgid "Track requests to {{public_body_name}} by email" +msgstr "An {{public_body_name}} gestellte Anfragen via Email verfolgen" + +#: app/models/track_thing.rb:279 +msgid "Track things matching this search by email" +msgstr "Folgen Sie ähnlichen Anfragen etc. per Email" + +#: app/views/user/show.rhtml:29 +msgid "Track this person" +msgstr "Dieser Person folgen " + +#: app/models/track_thing.rb:263 +msgid "Track this person by email" +msgstr "Dieser Person via Email folgen" + +#: app/models/track_thing.rb:196 +msgid "Track this request by email" +msgstr "Diese Anfrage via Email verfolgen" + +#: app/views/general/search.rhtml:141 +msgid "Track this search" msgstr "" -"Antwort als Administrator-Check bedürftig. Schau nach und antworte auf diese" -" Email, um sie wissen zu lassen was Du damit tun wirst. " -#: app/views/request_mailer/requires_admin.rhtml:9 -msgid "Administration URL:" -msgstr "Administrator URL" +#: locale/model_attributes.rb:33 +msgid "TrackThing|Track medium" +msgstr "TrackThing|Track medium" -#: app/views/request_mailer/stopped_responses.rhtml:1 +#: locale/model_attributes.rb:32 +msgid "TrackThing|Track query" +msgstr "TrackThing|Track query" + +#: locale/model_attributes.rb:34 +msgid "TrackThing|Track type" +msgstr "TrackThing|Track type" + +#: app/views/request/_sidebar.rhtml:13 +msgid "Tweet this request" +msgstr "Tweet diese Anfrage" + +#: app/views/general/_advanced_search_tips.rhtml:15 msgid "" -"The email that you, on behalf of {{public_body}}, sent to\n" -"{{user}} to reply to an {{law_used_short}}\n" -"request has not been delivered." +"Type <strong><code>01/01/2008..14/01/2008</code></strong> to only show " +"things that happened in the first two weeks of January." msgstr "" -"Ihre im Namen von {{public_body}} an\n" -"{{user}} gesendete Anfrage, um auf {{law_used_short}}\n" -"zu reagieren, wurde nicht übermittelt." +"Geben Sie <strong><code>01/01/2008..14/01/2008</code></strong> ein, um " +"ausschliesslich Vorgänge aus diesem Zeitraum anzuzeigen." -#: app/views/request_mailer/stopped_responses.rhtml:5 +#: app/models/public_body.rb:37 +msgid "URL name can't be blank" +msgstr "URL muss angegeben werden" + +#: app/models/user_mailer.rb:45 +msgid "Unable to change email address on {{site_name}}" +msgstr "Nicht in der Lage die Emailadresse auf {{site_name}} zu ändern" + +#: app/views/request/followup_bad.rhtml:4 +msgid "Unable to send a reply to {{username}}" +msgstr "Antwort an {{username}} kann nicht gesendet werden" + +#: app/views/request/followup_bad.rhtml:2 +msgid "Unable to send follow up message to {{username}}" +msgstr "Nachfrage an {{username}} kann nicht gesendet werden" + +#: app/views/request/list.rhtml:27 +msgid "Unexpected search result type" +msgstr "Unerwartetes Suchergebnis" + +#: app/views/request/similar.rhtml:18 +msgid "Unexpected search result type " +msgstr "Unerwartetes Suchergebnis" + +#: app/views/user/wrong_user_unknown_email.rhtml:3 msgid "" -"This is because {{title}} is an old request that has been\n" -"marked to no longer receive responses." +"Unfortunately we don't know the FOI\n" +"email address for that authority, so we can't validate this.\n" +"Please <a href=\"%s\">contact us</a> to sort it out." msgstr "" -"Die Ursache ist der veraltete Status dieser Anfrage {{title}}, \n" -"welche keine weiteren Antworten erhalten kann." +"Leider ist uns die IFG-Emailadresse dieser Behörde nicht bekannt, somit können wir dies nicht bestätigen.\n" +"Bitte <a href=\"%s\">kontaktieren Sie uns</a> zur Klärung der Angelegenheit." -#: app/views/request_mailer/stopped_responses.rhtml:10 +#: app/views/request/new_bad_contact.rhtml:5 msgid "" -"If this is incorrect, or you would like to send a late response to the request\n" -"or an email on another subject to {{user}}, then please\n" -"email {{contact_email}} for help." +"Unfortunately, we do not have a working {{info_request_law_used_full}}\n" +"address for" msgstr "" -"Falls dies falsch ist oder Sie eine späte Antwort auf diese Anfrage oder zu einem anderen Thema an {{user}} senden möchten, dann mailen Sie bitte\n" -" {{contact_email}} ffür weitere Hilfe." +"Wir haben leider keine funktionierende Email-Adresse für " +"{{info_request_law_used_full}}" -#: app/views/request_mailer/stopped_responses.rhtml:14 -msgid "Your original message is attached." -msgstr "Ihre ursprüngliche Nachricht befindet sich im Anhang. " +#: lib/world_foi_websites.rb:5 +msgid "United Kingdom" +msgstr "Vereinigtes Königreich" -#: app/views/request_mailer/very_overdue_alert.rhtml:1 -msgid "are long overdue." -msgstr "sind lange überfällig. " +#: lib/world_foi_websites.rb:17 +msgid "United States of America" +msgstr "Vereinigte Staaten von Amerika" -#: app/views/request_mailer/very_overdue_alert.rhtml:3 -msgid "" -"They have not replied to your {{law_used_short}} request {{title}}, \n" -"as required by law" -msgstr "" -"Ihre {{law_used_short}} Anfrage {{title}} wurde nicht nach gesetzlicher " -"Vorschrift beantwortet" +#: app/views/general/exception_caught.rhtml:22 +msgid "Unknown" +msgstr "Unbekannt" -#: app/views/request_mailer/very_overdue_alert.rhtml:4 -msgid "even during holidays" -msgstr "sogar während der Ferien" +#: app/models/info_request.rb:809 +msgid "Unusual response." +msgstr "Ungewöhnliche Antwort." -#: app/views/request_mailer/very_overdue_alert.rhtml:6 +#: app/views/request/_after_actions.rhtml:13 +#: app/views/request/_after_actions.rhtml:35 +msgid "Update the status of this request" +msgstr "Status der Anfrage aktualisieren" + +#: app/controllers/request_controller.rb:83 +msgid "Update the status of your request to " +msgstr "Aktualisieren Sie den Status Ihrer Anfrage an" + +#: app/views/general/_advanced_search_tips.rhtml:6 msgid "" -"Click on the link below to send a message to {{public_body_name}} telling them to reply to your request. You might like to ask for an internal\n" -"review, asking them to find out why response to the request has been so slow." +"Use OR (in capital letters) where you don't mind which word, e.g. " +"<strong><code>commons OR lords</code></strong>" msgstr "" -"Klickeb Suin Sie auf den unten aufgeführten Link, um eine Nachricht an " -"{{public_body_name}} zu senden. Sie möchten eventuell eine interne Prüfung " -"anfragen, um zu fragen warum die Beantwortung der Anfrage so lange dauert." +"Nutzen Sie ODER (in Großbuchstaben) wo es Ihnen gleich ist, welches Wort " +"verwendet wird, z.B. <strong><code>Komission ODER Ausschuss</code></strong>" -#: app/views/track/_tracking_links.rhtml:8 +#: app/views/general/_advanced_search_tips.rhtml:7 msgid "" -"This is your own request, so you will be automatically emailed when new " -"responses arrive." +"Use quotes when you want to find an exact phrase, e.g. " +"<strong><code>\"Liverpool City Council\"</code></strong>" msgstr "" -"Dies ist Ihre eigene Anfrage. Sie erhalten eine automatische " -"Emailbenachrichtigung, sobald Ihre Anfrage beantwortet wird. " +"Verwenden Sie Anführungszeichen, e.g. <strong><code>\"Europäischer " +"Bürgerbeauftragter\"</code></strong>" -#: app/views/track/_tracking_links.rhtml:21 -msgid "Follow by email" -msgstr "Per Email folgen" +#: locale/model_attributes.rb:70 +msgid "UserInfoRequestSentAlert|Alert type" +msgstr "UserInfoRequestSentAlert|Alert type" -#: app/views/track/_tracking_links.rhtml:26 -msgid "RSS feed of updates" -msgstr "RSS Feeds für Neuigkeiten" +#: locale/model_attributes.rb:81 +msgid "User|About me" +msgstr "BenutzerIÜber mich" -#: app/views/track/_tracking_links.rhtml:26 -msgid "RSS feed" -msgstr "RSS feed" +#: locale/model_attributes.rb:79 +msgid "User|Admin level" +msgstr "User|Admin level" -#: app/views/track_mailer/event_digest.rhtml:21 -msgid "{{public_body}} sent a response to {{user_name}}" -msgstr "{{public_body}} hat eine Antwort an {{user_name}} gesendet" +#: locale/model_attributes.rb:80 +msgid "User|Ban text" +msgstr "User|Ban text" -#: app/views/track_mailer/event_digest.rhtml:24 -msgid "{{user_name}} sent a follow up message to {{public_body}}" -msgstr "{{user_name}} hat eine Nachfrage an {{public_body}} gesendet" +#: locale/model_attributes.rb:72 +msgid "User|Email" +msgstr "BenutzerIEmail" -#: app/views/track_mailer/event_digest.rhtml:28 -msgid "{{user_name}} sent a request to {{public_body}}" -msgstr "{{user_name}} ´hat eine Anfrage an {{public_body}} gesendet" +#: locale/model_attributes.rb:76 +msgid "User|Email confirmed" +msgstr "UserIEmail bestätigt" -#: app/views/track_mailer/event_digest.rhtml:31 -msgid "{{user_name}} added an annotation" -msgstr "{{user_name}} hat eine Anmerkung beigefügt" +#: locale/model_attributes.rb:74 +msgid "User|Hashed password" +msgstr "Benutzer | Verschlüsseltes Passwort" -#: app/views/track_mailer/event_digest.rhtml:60 -msgid "Alter your subscription" -msgstr "Ändern Sie Ihre Registrierung" +#: locale/model_attributes.rb:78 +msgid "User|Last daily track email" +msgstr "User|Last daily track email" -#: app/views/track_mailer/event_digest.rhtml:63 -msgid "Please click on the link below to cancel or alter these emails." -msgstr "" -"Bitte klicken Sie auf den unten angezeigten Link, um diese Emails zu " -"annullieren oder ändern." +#: locale/model_attributes.rb:73 +msgid "User|Name" +msgstr "BenutzerIName" -#: app/views/user/_signin.rhtml:7 -msgid "If you've used {{site_name}} before" -msgstr "Falls Sie {{site_name}} zuvor genutzt haben" +#: locale/model_attributes.rb:75 +msgid "User|Salt" +msgstr "User|Salt" -#: app/views/user/_signin.rhtml:11 app/views/user/_signup.rhtml:9 -#: app/views/user/signchangepassword_send_confirm.rhtml:13 -msgid "Your e-mail:" -msgstr "Ihre Email:" +#: locale/model_attributes.rb:77 +msgid "User|Url name" +msgstr "Benutzer|URL Name" -#: app/views/user/_signin.rhtml:16 app/views/user/_signup.rhtml:30 -msgid "Password:" -msgstr "Passwort:" +#: app/views/public_body/show.rhtml:34 +msgid "View FOI email address" +msgstr "IFG-Emailadressen ansehen" -#: app/views/user/_signin.rhtml:21 -msgid "Forgotten your password?" -msgstr "Passwort vergessen?" +#: app/views/public_body/view_email_captcha.rhtml:1 +msgid "View FOI email address for '{{public_body_name}}'" +msgstr "IFG-Emailadresse für {{public_body_name}} ansehen" -#: app/views/user/_signin.rhtml:26 -msgid "" -"Remember me</label> (keeps you signed in longer;\n" -" do not use on a public computer) " -msgstr "" -"Login speichern</label> (Sie bleiben eingeloggt. Nutzen Sie diese Funktion " -"nicht an öffentlichen Computern) " +#: app/views/public_body/view_email_captcha.rhtml:3 +msgid "View FOI email address for {{public_body_name}}" +msgstr "IFG-Emailadresse für {{public_body_name}} ansehen" -#: app/views/user/_signin.rhtml:32 -msgid "Sign in" -msgstr "Anmelden" +#: app/views/contact_mailer/user_message.rhtml:10 +msgid "View Freedom of Information requests made by {{user_name}}:" +msgstr "Sehen Sie die durch {{user_name}} gestellten IFG-Anfragen an:" -#: app/views/user/_signup.rhtml:6 -msgid "If you're new to {{site_name}}" -msgstr "Falls Sie neu auf {{site_name}} sind" +#: app/controllers/request_controller.rb:155 +msgid "View and search requests" +msgstr "Ansehen und Suchen von Anfragen" -#: app/views/user/_signup.rhtml:13 +#: app/views/general/_topnav.rhtml:6 +msgid "View authorities" +msgstr "Behörden ansehen" + +#: app/views/public_body/view_email_captcha.rhtml:12 +msgid "View email" +msgstr "Email ansehen" + +#: app/views/general/_topnav.rhtml:5 +msgid "View requests" +msgstr "Anfragen ansehen" + +#: app/models/info_request.rb:801 +msgid "Waiting clarification." +msgstr "Klärung wird erwartet. " + +#: app/views/request/show.rhtml:111 msgid "" -"We will not reveal your email address to anybody unless you or\n" -" the law tell us to (<a href=\"%s\">details</a>). " +"Waiting for an <strong>internal review</strong> by {{public_body_link}} of " +"their handling of this request." msgstr "" -"Ohne Ihre Zustimmung oder gesetzliche Vorschrift werden wir Ihre Email-" -"Adresse zu keinem Zeitpunkt veröffentlichen. (<a href=\"%s\">details</a>) " - -#: app/views/user/_signup.rhtml:18 -msgid "Your name:" -msgstr "Ihr Name:" +"<strong>Interne Prüfung</strong> durch {{public_body_link}} wird erwartet." -#: app/views/user/_signup.rhtml:22 +#: app/views/general/_advanced_search_tips.rhtml:33 msgid "" -"Your <strong>name will appear publicly</strong> \n" -" (<a href=\"%s\">why?</a>)\n" -" on this website and in search engines. If you\n" -" are thinking of using a pseudonym, please \n" -" <a href=\"%s\">read this first</a>." +"Waiting for the public authority to complete an internal review of their " +"handling of the request" msgstr "" -"Ihr <strong>Name wird öffentlich</strong> \n" -" (<a href=\"%s\">warum?</a>)\n" -" auf dieser Internetseite und in Suchmaschinen angezeigt.Falls Sie lieber ein Pseudonym nutzen möchten, \n" -" <a href=\"%s\">lesen Sie erst hier</a>." +"Die Fertigstellung einer internen Prüfung der Bearbeitungsweise Ihrer " +"Anfrage durch die Behörde wird erwartet" -#: app/views/user/_signup.rhtml:35 -msgid "Password: (again)" -msgstr "Passwort: (nochmal eingeben)" +#: app/views/general/_advanced_search_tips.rhtml:26 +msgid "Waiting for the public authority to reply" +msgstr "Antwort der Behörde wird erwartet" -#: app/views/user/_signup.rhtml:46 -msgid "Sign up" -msgstr "Benutzerkonto erstellen" +#: app/models/request_mailer.rb:125 +msgid "Was the response you got to your FOI request any good?" +msgstr "" -#: app/views/user/_user_listing_single.rhtml:19 -#: app/views/user/_user_listing_single.rhtml:20 -msgid "made." -msgstr "erledigt." +#: app/views/public_body/view_email.rhtml:17 +msgid "We do not have a working request email address for this authority." +msgstr "" +"Für diese Behörde ist keine funktionierende Emailadresse zur " +"Anfragenstellung verfügbar. " -#: app/views/user/_user_listing_single.rhtml:21 -msgid "Joined in" -msgstr "Angemeldet" +#: app/views/request/followup_bad.rhtml:24 +msgid "" +"We do not have a working {{law_used_full}} address for {{public_body_name}}." +msgstr "" +"Wir haben keine funktionierende {{law_used_full}} Adresse für " +"{{public_body_name}}." -#: app/views/user/bad_token.rhtml:2 +#: app/views/request/_describe_state.rhtml:107 msgid "" -"Please check the URL (i.e. the long code of letters and numbers) is copied\n" -"correctly from your email." +"We don't know whether the most recent response to this request contains\n" +" information or not\n" +" –\n" +"\tif you are {{user_link}} please <a href=\"{{url}}\">sign in</a> and let everyone know." msgstr "" -"Bitte überprüfen Sie, ob Sie die URL (Webadresse) korrekt aus Ihrer Email " -"kopiert haben. " +"Wir sind nicht sicher, ob die letzte Antwort auf diese Anfrage Informationen enthält\n" +" –\n" +"<span class=\"whitespace other\" title=\"Tab\">»</span>falls Sie {{user_link}} sind, bitte <a href=\"{{url}}\">melden Sich an</a> und lassen es uns wissen. " -#: app/views/user/bad_token.rhtml:7 +#: app/views/user_mailer/confirm_login.rhtml:8 msgid "" -"If you can't click on it in the email, you'll have to <strong>select and copy\n" -"it</strong> from the email. Then <strong>paste it into your browser</strong>, into the place\n" -"you would type the address of any other webpage." +"We will not reveal your email address to anybody unless you\n" +"or the law tell us to." msgstr "" -"Falls Sie den link in Ihrer Email nicht anklicken können, müssen Sie diesen " -"<strong>auswählen und kopieren</strong>. <strong>Fügen Sie diesen dann in " -"Ihr Browserfenster ein</strong>, an der Stelle, an der Sie auch jede andere " -"Webadresse eingeben würden." +"Wir werden Ihre Emailadresse nicht veröffentlichen, sofern nicht von Ihnen " +"freigegeben oder gesetzlich vorgeschrieben. " -#: app/views/user/bad_token.rhtml:13 +#: app/views/user/_signup.rhtml:13 msgid "" -"If you got the email <strong>more than six months ago</strong>, then this login link won't work any\n" -"more. Please try doing what you were doing from the beginning." +"We will not reveal your email address to anybody unless you or\n" +" the law tell us to (<a href=\"%s\">details</a>). " msgstr "" -"Wenn Sie diese Email <strong>vor mehr als sechs Monaten erhalten " -"haben</strong>, ist dieser Anmeldecode nichtmehr aktiv. Bitte nehmen Sie " -"eine neue Registrierung vor. " +"Ohne Ihre Zustimmung oder gesetzliche Vorschrift werden wir Ihre Email-" +"Adresse zu keinem Zeitpunkt veröffentlichen. (<a href=\"%s\">details</a>) " -#: app/views/user/banned.rhtml:9 +#: app/views/user_mailer/changeemail_confirm.rhtml:10 msgid "" -"You will be unable to make new requests, send follow ups, add annotations or\n" -"send messages to other users. You may continue to view other requests, and set\n" -"up\n" -"email alerts." +"We will not reveal your email addresses to anybody unless you\n" +"or the law tell us to." msgstr "" -"Sie werden keine Anfragen stellen-, Nachfragen senden-, Kommentare " -"hinzufügen- oder anderen Nachrichten senden können. Sie können weiterhin " -"andere Anfragen anschauen oder die Funktion zur automatischen " -"Emailbenachrichtigung einrichten." +"Ohne Ihre Zustimmung oder gesetzliche Vorschrift werden wir Ihre Email-" +"Adresse zu keinem Zeitpunkt veröffentlichen." -#: app/views/user/banned.rhtml:15 +#: app/views/request/show.rhtml:61 +msgid "We're waiting for" +msgstr "Wir erwarten" + +#: app/views/request/show.rhtml:57 +msgid "We're waiting for someone to read" +msgstr "Wir warten, dass es von jemandem gelesen wird" + +#: app/views/user/signchangeemail_confirm.rhtml:6 msgid "" -"If you would like us to lift this ban, then you may politely\n" -"<a href=\"/help/contact\">contact us</a> giving reasons.\n" +"We've sent an email to your new email address. You'll need to click the link in\n" +"it before your email address will be changed." msgstr "" -"Falls Sie möchten, dass wir diese Sperre aufheben, mögen Sie uns höflich\n" -"<a href=\"/help/contact\">kontaktieren</a> und einen Grund angeben.\n" +"Wir haben eine Email an Ihre neue Emailadresse gesendet. Sie müssen den Link" +" in dieser Email anklicken, um Ihre neue Adresse zu aktivieren. " #: app/views/user/confirm.rhtml:6 msgid "" @@ -4087,936 +4155,971 @@ msgstr "" "Wir haben Ihnen eine Email gesendet. Um fortzufahren klicken Sie bitte den " "darin angezeigten Link. " -#: app/views/user/confirm.rhtml:11 -msgid "" -"<small>If you use web-based email or have \"junk mail\" filters, also check your\n" -"bulk/spam mail folders. Sometimes, our messages are marked that way.</small>\n" -"</p>" -msgstr "" -"Sollten Sie eine webbasierten Emailanbieter oder ´Junk-mail´ Filter nutzen, " -"prüfen Sie Ihren Spamordner. Es kommt vor, dass unsere Nachrichten dort " -"landen. " - -#: app/views/user/contact.rhtml:32 +#: app/views/user/signchangepassword_confirm.rhtml:6 msgid "" -"<strong>Note:</strong> You're sending a message to yourself, presumably\n" -" to try out how it works." +"We've sent you an email, click the link in it, then you can change your " +"password." msgstr "" -"<strong>Achtung:</strong> Sie senden eine Nachricht an sich selbst, " -"vermutlich um herauszufinden, wie es funktioniert. " +"Wir haben Ihnen eine Email gesendet. Klicken Sie den darin angezeigten Link," +" um Ihr Passwort zu ändern. " -#: app/views/user/contact.rhtml:35 -msgid " <strong>Privacy note:</strong> Your email address will be given to" -msgstr "" -" <strong>Datenschutzerklärung:</strong> Ihre Emailadresse wird " -"weitergeleitet an: " +#: app/views/request/_followup.rhtml:85 +msgid "What are you doing?" +msgstr "Was machen Sie?" -#: app/views/user/contact.rhtml:36 -msgid " when you send this message." -msgstr "wenn Sie diese Nachricht senden. " +#: app/views/request/_describe_state.rhtml:4 +msgid "What best describes the status of this request now?" +msgstr "Was ist die beste Beschreibung für diese Anfrage?" -#: app/views/user/no_cookies.rhtml:3 -msgid "Please enable \"cookies\" to carry on" -msgstr "Bitte erlauben Sie Cookies, um fortzufahren" +#: app/views/general/frontpage.rhtml:54 +msgid "What information has been released?" +msgstr "Welche Informationen wurden veröffentlicht?" -#: app/views/user/no_cookies.rhtml:5 +#: app/views/request_mailer/new_response.rhtml:9 msgid "" -"To carry on, you need to sign in or make an account. Unfortunately, there\n" -"was a technical problem trying to do this." +"When you get there, please update the status to say if the response \n" +"contains any useful information." msgstr "" -"Um fortzufahren müssen Sie sich anmelden oder ein Benutzerkonto erstellen. " -"Leider sind bei diesem Versuch technische Störungen aufgetreten. " +"Wenn Sie dort hinkommen, aktualisieren Sie bitte den Status indem Sie uns " +"wissen lassen, ob die Antwort nützliche Informationen enthält. " -#: app/views/user/no_cookies.rhtml:8 +#: app/views/request/show_response.rhtml:42 msgid "" -"It may be that your browser is not set to accept a thing called \"cookies\",\n" -"or cannot do so. If you can, please enable cookies, or try using a different\n" -"browser. Then press refresh to have another go." +"When you receive the paper response, please help\n" +" others find out what it says:" msgstr "" -"Möglicherweise blockiert Ihr Browser keine sogenannten ´Cookies´. Bitte " -"erlauben Sie diese oder versuchen Sie es mit einem anderen Browser. Klicken " -"Sie anschliessend auf aktualisieren, um es erneut zu versuchen. " +"Wenn Sie die gedruckte Antwort erhalten, machen Sie den Inhalt bitte für " +"andere Nutzer zugänglich" -#: app/views/user/no_cookies.rhtml:12 +#: app/views/request/new_please_describe.rhtml:16 msgid "" -"If your browser is set to accept cookies and you are seeing this message,\n" -"then there is probably a fault with our server." -msgstr "" -"Sollte Ihr Browser Cookies zulassen und Sie trotzdem diese Nachricht " -"erhalten, gibt es wahrscheinlich ein Problem mit unserem Server." - -#: app/views/user/no_cookies.rhtml:15 -msgid "Please <a href=\"%s\">get in touch</a> with us so we can fix it." +"When you're done, <strong>come back here</strong>, <a href=\"%s\">reload " +"this page</a> and file your new request." msgstr "" -"Bitte<a href=\"%s\">nehmen Sie Kontakt mit uns auf</a>, damit wir das " -"Problem beheben können. " +"Wenn Sie fertig sind, <strong>kommen Sie hierher zurück</strong>, <a " +"href=\"%s\">laden Sie die Seite erneut</a> und stellen Sie Ihre neue " +"Anfrage." -#: app/views/user/no_cookies.rhtml:17 -msgid "" -"Let us know what you were doing when this message\n" -"appeared and your browser and operating system type and version." -msgstr "" -"Teilen Sie uns mit bei welchem Vorgang diese Nachricht angezeigt wurde, also" -" auch den Namen Ihres Browsers, und den Namen und die Version Ihres " -"Betriebssystems." +#: app/views/request/show_response.rhtml:13 +msgid "Which of these is happening?" +msgstr "Welcher dieser Aspekte ist zutreffend?" -#: app/views/user/no_cookies.rhtml:20 -msgid "If you are still having trouble, please <a href=\"%s\">contact us</a>." -msgstr "" -"Sollten weiterhin Probleme bestehen, bitte <a href=\"%s\">kontaktieren Sie " -"uns</a>." +#: app/views/general/frontpage.rhtml:37 +msgid "Who can I request information from?" +msgstr "Von wem kann ich Informationen anfragen?" -#: app/views/user/set_crop_profile_photo.rhtml:1 app/views/user/show.rhtml:104 -msgid "Change profile photo" -msgstr "Profilbild ändern" +#: app/models/info_request.rb:811 +msgid "Withdrawn by the requester." +msgstr "Vom Antragsteller zurückgezogen" -#: app/views/user/set_crop_profile_photo.rhtml:6 -msgid "Crop your profile photo" -msgstr "Bearbeiten Sie Ihr Profilbild" +#: app/views/general/_localised_datepicker.rhtml:13 +msgid "Wk" +msgstr "" -#: app/views/user/set_crop_profile_photo.rhtml:35 -msgid "" -"<strong>Privacy note:</strong> Your photo will be shown in public on the Internet, \n" -" wherever you do something on {{site_name}}." +#: app/views/help/alaveteli.rhtml:6 +msgid "Would you like to see a website like this in your country?" msgstr "" -"<strong>Datenschutzhinweis:</strong> Ihr Photo wird öffentlich im Internet angezeigt werden\n" -" wo immer Sie {{site_name}} nutzen." +"Würden Sie eine solche Internetseite gerne für Ihr eigenes Land sehen?" -#: app/views/user/set_draft_profile_photo.rhtml:5 -msgid "Choose your profile photo" -msgstr "Wählen Sie Ihr Profilbild" +#: app/views/request/_after_actions.rhtml:30 +msgid "Write a reply" +msgstr "Schreiben Sie eine Antwort" -#: app/views/user/set_draft_profile_photo.rhtml:13 -msgid "Photo of you:" -msgstr "Ihr Profilbild:" +#: app/controllers/request_controller.rb:555 +msgid "Write a reply to " +msgstr "Antwort senden" -#: app/views/user/set_draft_profile_photo.rhtml:18 -msgid "" -"Your photo will be shown in public <strong>on the Internet</strong>, \n" -" wherever you do something on {{site_name}}." -msgstr "" -"<strong>Datenschutzhinweis:</strong> Ihr Photo wird öffentlich im Internet angezeigt werden\n" -" wo immer Sie {{site_name}} nutzen." +#: app/controllers/request_controller.rb:554 +msgid "Write your FOI follow up message to " +msgstr "Senden Sie Ihre Follow-Up Nachricht an " -#: app/views/user/set_draft_profile_photo.rhtml:22 -msgid "" -"Please don't upload offensive pictures. We will take down images\n" -" that we consider inappropriate." +#: app/views/request/new.rhtml:104 +msgid "Write your request in <strong>simple, precise language</strong>." msgstr "" -"Bitte verwenden Sie keine anstößigen Bilder. Alle unangemessenen Bilder " -"werden von uns entfernt." +"Formulieren Sie Ihre Anfrage in <strong>schlicht und präzise </strong>." -#: app/views/user/set_draft_profile_photo.rhtml:32 -msgid "Next, crop your photo >>" -msgstr "Nächster Schritt: Passen Sie Ihr Photo an >>" +#: app/views/comment/_single_comment.rhtml:10 +msgid "You" +msgstr "Sie" -#: app/views/user/set_draft_profile_photo.rhtml:46 -msgid "OR remove the existing photo" -msgstr "OR entfernen Sie das bestehende Photo" +#: app/controllers/track_controller.rb:98 +msgid "You are already being emailed updates about " +msgstr "Sie erhielten bereits Aktualisierungen zu" -#: app/views/user/set_draft_profile_photo.rhtml:55 -msgid "Cancel, return to your profile page" -msgstr "Abbrechen, zurück zur Profilseite" +#: app/models/track_thing.rb:248 +msgid "You are already tracking requests to {{public_body_name}} by email" +msgstr "Sie verfolgen die Anfragen an {{public_body_name}} bereits via Email" -#: app/views/user/set_profile_about_me.rhtml:1 -msgid "Change the text about you on your profile at {{site_name}}" -msgstr "" -"Ändern Sie den Text zu Ihrer Person in Ihrem Nutzerprofil auf {{site_name}}" +#: app/models/track_thing.rb:280 +msgid "You are already tracking things matching this search by email" +msgstr "Sie folgen einer solchen Suchanfrage bereits per Email" -#: app/views/user/set_profile_about_me.rhtml:3 -#: app/views/user/signchangeemail.rhtml:3 -msgid "internal error" -msgstr "interner Fehler" +#: app/models/track_thing.rb:264 +msgid "You are already tracking this person by email" +msgstr "Sie folgen dieser Person bereits via Email" -#: app/views/user/set_profile_about_me.rhtml:9 -msgid "Edit text about you" -msgstr "Profiltext ändern" +#: app/models/track_thing.rb:197 +msgid "You are already tracking this request by email" +msgstr "Sie folgen dieser Anfrage bereits via Email" -#: app/views/user/set_profile_about_me.rhtml:11 -msgid " What are you investigating using Freedom of Information? " -msgstr " Was recherchieren im Rahmen der Informationsfreiheit?" +#: app/models/track_thing.rb:229 +msgid "You are being emailed about any new successful responses" +msgstr "Sie werden per Email über neue erfolgreiche Antworten informiert " -#: app/views/user/set_profile_about_me.rhtml:14 -msgid "" -" This will appear on your {{site_name}} profile, to make it\n" -" easier for others to get involved with what you're doing." -msgstr "" -" Diese Information wird auf Ihrem {{site_name}} -profil angezeigt werden, um" -" andere Nutzer über Ihre Aktivitäten zu informieren. " +#: app/models/track_thing.rb:213 +msgid "You are being emailed when there are new requests" +msgstr "Im Falle neuer Anfragen werden Sie per Email informiert werden" -#: app/views/user/set_profile_about_me.rhtml:20 -msgid "About you:" -msgstr "Zu Ihrer Person:" +#: app/views/request/show.rhtml:88 +msgid "You can <strong>complain</strong> by" +msgstr "Sie können sich <strong>beschweren</strong>, indem sie" -#: app/views/user/set_profile_about_me.rhtml:26 +#: app/views/request/details.rhtml:58 msgid "" -" Include relevant links, such as to a campaign page, your blog or a\n" -" twitter account. They will be made clickable. \n" -" e.g." +"You can get this page in computer-readable format as part of the main JSON\n" +"page for the request. See the <a href=\"{{api_path}}\">API documentation</a>." msgstr "" -"Fügen Sie relevanten Links ein, z.B. zu einer Kampagnenseite, Ihrem Blog " -"oder Twitterkonto. Die Links werden aktiviert widergegeben. z.B." - -#: app/views/user/set_profile_about_me.rhtml:35 -msgid "Save" -msgstr "Speichern" +"Im Rahmen der HauptJSON Seite können diese Seite in maschinenlesbarer Form erhalten. \n" +" Sehen Sie hier: <a href=\"{{api_path}}\">API Sokumentation</a>." -#: app/views/user/show.rhtml:4 +#: app/views/public_body/show.rhtml:54 msgid "" -"There is <strong>more than one person</strong> who uses this site and has this name. \n" -" One of them is shown below, you may mean a different one:" +"You can only request information about the environment from this authority." msgstr "" -"Es gibt <strong>mehrere Nutzer</strong> mit diesem Namen. Einer wird unten " -"angezeigt, Sie könnten jedoch einen andere Person meinen:" +"Umweltanfragen können ausschliesslich über diese Behörde gestellt werden. " -#: app/views/user/show.rhtml:12 -msgid "" -"Please <strong>go to the following requests</strong>, and let us\n" -" know if there was information in the recent responses to them." +#: app/views/request_mailer/new_response.rhtml:1 +msgid "You have a new response to the {{law_used_full}} request " msgstr "" -"Bitte <strong>gehen Sie zu den folgende Anfragen</strong> und teilen Sie uns" -" mit, ob in den letzten Antworten Informationen enthalten waren." +"Sie haben eine neue Antwort auf die Anfrage {{law_used_full}} erhalten " -#: app/views/user/show.rhtml:20 +#: app/views/general/exception_caught.rhtml:18 msgid "" -"Thanks very much - this will help others find useful stuff. We'll\n" -" also, if you need it, give advice on what to do next about your\n" -" requests." +"You have found a bug. Please <a href=\"{{contact_url}}\">contact us</a> to " +"tell us about the problem" msgstr "" -"Vielen herzlichen Dank - dass hilft anderen auch Nützliches zu finden. Gerne" -" beraten wir Sie auch bei den nächsten Schritten Ihrer Anfragen, falls Sie " -"dies wünschen. " - -#: app/views/user/show.rhtml:29 -msgid "Track this person" -msgstr "Dieser Person folgen " +"Sie haben einen Fehler gefunden. Bitte <a " +"href=\"{{contact_url}}\">kontaktieren Sie uns</a>, um uns das Problem zu " +"schildern" -#: app/views/user/show.rhtml:32 -msgid "On this page" -msgstr "Auf dieser Seite" +#: app/views/user/show.rhtml:138 +msgid "You have made no Freedom of Information requests using this site." +msgstr "" +"Sie haben eine Informationsfreiheits-Anfrage über diese Seite gestellt. " -#: app/views/user/show.rhtml:33 -msgid "FOI requests" -msgstr "IFG-Anfrage" +#: app/controllers/user_controller.rb:510 +msgid "You have now changed the text about you on your profile." +msgstr "Sie haben den Text zu Ihrer Person in Ihrem Profil nun geändert. " -#: app/views/user/show.rhtml:34 -msgid "Annotations" -msgstr "Kommentare" +#: app/controllers/user_controller.rb:328 +msgid "You have now changed your email address used on {{site_name}}" +msgstr "" +"Sie haben die aud der Seite {{site_name}} verwendete Email-Adresse nun " +"geändert" -#: app/views/user/show.rhtml:36 -msgid "Email subscriptions" -msgstr "Email Abo" +#: app/views/user_mailer/already_registered.rhtml:3 +msgid "" +"You just tried to sign up to {{site_name}}, when you\n" +"already have an account. Your name and password have been\n" +"left as they previously were.\n" +"\n" +"Please click on the link below." +msgstr "" +"Sie haben soeben versucht sich als neuer Nutzer von AskTheEU.org zu " +"registrieren, obwohl Sie bereits ein Konto haben. Ihr Benutzername und " +"Passwort sind unverändert. Bitte klicken Sie hier" -#: app/views/user/show.rhtml:53 -msgid "Set your profile photo" -msgstr "Profilbild wählen" +#: app/views/comment/new.rhtml:60 +msgid "" +"You know what caused the error, and can <strong>suggest a solution</strong>," +" such as a working email address." +msgstr "" +"Sie kennen die Ursache des Fehlers und können eine <strong>Lösung " +"anbieten</strong>, wie z.B. eine funktionierende Email-Adresse. " -#: app/views/user/show.rhtml:59 -msgid " (you)" -msgstr " (Sie)" +#: app/views/request/upload_response.rhtml:16 +msgid "" +"You may <strong>include attachments</strong>. If you would like to attach a\n" +"file too large for email, use the form below." +msgstr "" +"Vielleicht möchten Sie <strong>Dateien anhängen</strong>. Falls Sie eine " +"Datei anhängen möchten, welche für die Emailübertragung zu groß sind, " +"verwenden Sie das untenstehende Formular. " -#: app/views/user/show.rhtml:62 -msgid "Joined {{site_name}} in" -msgstr "{{site_name}} beigetreten am" +#: app/views/request/followup_bad.rhtml:24 +msgid "" +"You may be able to find\n" +" one on their website, or by phoning them up and asking. If you manage\n" +" to find one, then please <a href=\"%s\">send it to us</a>." +msgstr "" +"Es ist mögliche eine auf deren Internetseite zu finden oder sie telefonisch " +"zu erfragen. Sollten Sie sie herausfinden, <a href=\"%s\">senden sie sie uns" +" bitte zu</a>." -#: app/views/user/show.rhtml:69 -msgid "Send message to " -msgstr "Nachricht senden an" +#: app/views/request/new_bad_contact.rhtml:6 +msgid "" +"You may be able to find\n" +"one on their website, or by phoning them up and asking. If you manage\n" +"to find one, then please <a href=\"{{help_url}}\">send it to us</a>." +msgstr "" +"Sie können eventuell eine auf deren Internetseite finden, oder sie anrufen " +"und nachfragen. Sollten Sie eine herausfinden, freuen wir uns über Ihre <a " +"href=\"{{help_url}}\">Zusendung</a>." -#: app/views/user/show.rhtml:71 -msgid "just to see how it works" -msgstr "um zu sehen wie es funktioniert" +#: app/controllers/user_controller.rb:488 +msgid "You need to be logged in to change the text about you on your profile." +msgstr "Sie müssen angemeldet sein, um Ihren Profiltext zu ändern. " -#: app/views/user/show.rhtml:79 -msgid "This user has been banned from {{site_name}} " -msgstr "Dieser Nutzer wurde von {{site_name}} entfernt" +#: app/controllers/user_controller.rb:389 +msgid "You need to be logged in to change your profile photo." +msgstr "Sie müssen angemeldet sein, um Ihren Profilbild zu ändern. " -#: app/views/user/show.rhtml:83 -msgid "They have been given the following explanation:" -msgstr "Die folgende Erklärung wurde abgegeben:" +#: app/controllers/user_controller.rb:451 +msgid "You need to be logged in to clear your profile photo." +msgstr "Sie müssen angemeldet sein, um Ihren Profilbild zu löschen." -#: app/views/user/show.rhtml:96 -msgid "edit text about you" -msgstr "Bearbeiten Sie den Infotext zu Ihrer Person" +#: app/controllers/request_controller.rb:565 +msgid "" +"You previously submitted that exact follow up message for this request." +msgstr "" +"Sie haben kürzlich dieselbe Follow-up Nachricht für diese Anfrage gesendet. " -#: app/views/user/show.rhtml:106 -msgid "Change your password" -msgstr "Passwort ändern" +#: app/views/request/upload_response.rhtml:13 +msgid "" +"You should have received a copy of the request by email, and you can respond\n" +"by <strong>simply replying</strong> to that email. For your convenience, here is the address:" +msgstr "" +"Sie sollten eine Kopie diesr Anfrage per Email erhalten haben. Sie können darauf reagieren, indem Sie\n" +"by <strong>einfach antworten</strong> to that email. For your convenience, here is the address:" -#: app/views/user/show.rhtml:107 -msgid "Change your email" -msgstr "Emailadresse ändern" +#: app/views/request/show_response.rhtml:34 +msgid "" +"You want to <strong>give your postal address</strong> to the authority in " +"private." +msgstr "" +"Sie möchten <strong>Ihre Anschrift</strong> geschützt an die Behörde senden." -#: app/views/user/show.rhtml:113 +#: app/views/user/banned.rhtml:9 msgid "" -"<a href=\"%s\">Sign in</a> to change password, subscriptions and more " -"({{user_name}} only)" +"You will be unable to make new requests, send follow ups, add annotations or\n" +"send messages to other users. You may continue to view other requests, and set\n" +"up\n" +"email alerts." msgstr "" -"<a href=\"%s\">Melden Sie sich an,</a> um Ihr Passwort und weitere " -"Einstellungen zu ändern (auschließlich {{user_name}})" +"Sie werden keine Anfragen stellen-, Nachfragen senden-, Kommentare " +"hinzufügen- oder anderen Nachrichten senden können. Sie können weiterhin " +"andere Anfragen anschauen oder die Funktion zur automatischen " +"Emailbenachrichtigung einrichten." -#: app/views/user/show.rhtml:123 -msgid "Search your contributions" -msgstr "Suchen Sie Ihre Beiträge" +#: app/controllers/track_controller.rb:154 +msgid "You will no longer be emailed updates about " +msgstr "Sie erhalten keinen weiteren Aktualisierungen über" -#: app/views/user/show.rhtml:125 -msgid "Search contributions by this person" -msgstr "Suchen Sie Beiträge dieser Person" +#: app/controllers/track_controller.rb:183 +msgid "You will no longer be emailed updates for those alerts" +msgstr "Sie werden keine weiteren Aktualisierungen zu diesen Alerts erhalten" -#: app/views/user/show.rhtml:136 -msgid "You have made no Freedom of Information requests using this site." -msgstr "" -"Sie haben eine Informationsfreiheits-Anfrage über diese Seite gestellt. " +#: app/controllers/track_controller.rb:111 +msgid "You will now be emailed updates about " +msgstr "Sie erhalten nun Email-Aktualisierungen über" -#: app/views/user/show.rhtml:136 +#: app/views/request_mailer/not_clarified_alert.rhtml:6 msgid "" -"This person has made no Freedom of Information requests using this site." +"You will only get an answer to your request if you follow up\n" +"with the clarification." +msgstr "" +"Sie können nur eine Antwort auf Ihre Anfrage erhalten wenn Sie mti der " +"Aufklärung fortfahren. " + +#: app/models/request_mailer.rb:105 +msgid "You're long overdue a response to your FOI request - " msgstr "" -"Diese Person hat eine Informationsfreiheits-Anfrage über diese Seite " -"gestellt. " -#: app/views/user/show.rhtml:141 +#: app/controllers/user_controller.rb:460 +msgid "You've now cleared your profile photo" +msgstr "Sie haben Ihr Profilbild nun gelöscht" + +#: app/views/user/show.rhtml:143 msgid "Your %d Freedom of Information request" msgid_plural "Your %d Freedom of Information requests" msgstr[0] "Ihre %d Informationsfreiheitsanfrage" msgstr[1] "Ihre %d Informationsfreiheitsanfragen" -#: app/views/user/show.rhtml:141 -msgid "This person's %d Freedom of Information request" -msgid_plural "This person's %d Freedom of Information requests" -msgstr[0] "" -" %d Informationsfreiheitsanfragen dieses Benutzers / dieser Benutzerin" -msgstr[1] "" -" %d Informationsfreiheitsanfragen dieses Benutzers / dieser Benutzerin" - -#: app/views/user/show.rhtml:155 -msgid "Freedom of Information requests made by you" -msgstr "Von Ihnen gestellte IFG-Anfragen" - -#: app/views/user/show.rhtml:155 -msgid "Freedom of Information requests made by this person" -msgstr "Informationsfreiheits-Anfrage durch diese Person gestellt" +#: app/views/user/show.rhtml:171 +msgid "Your %d annotation" +msgid_plural "Your %d annotations" +msgstr[0] "Ihre %d Anmerkunge" +msgstr[1] "Ihre %d Anmerkungen" -#: app/views/user/show.rhtml:156 +#: app/views/user/_signup.rhtml:22 msgid "" -"The search index is currently offline, so we can't show the Freedom of " -"Information requests this person has made." +"Your <strong>name will appear publicly</strong> \n" +" (<a href=\"%s\">why?</a>)\n" +" on this website and in search engines. If you\n" +" are thinking of using a pseudonym, please \n" +" <a href=\"%s\">read this first</a>." msgstr "" -"Da die Suchanzeige momentan offline ist, können wir durch diese Person " -"gestellten Informationsfreiheitsanfragen gerade leider nicht anzeigen. " +"Ihr <strong>Name wird öffentlich</strong> \n" +" (<a href=\"%s\">warum?</a>)\n" +" auf dieser Internetseite und in Suchmaschinen angezeigt.Falls Sie lieber ein Pseudonym nutzen möchten, \n" +" <a href=\"%s\">lesen Sie erst hier</a>." -#: app/views/user/show.rhtml:162 +#: app/views/user/show.rhtml:164 msgid "Your annotations" msgstr "Ihre Anmerkungen" -#: app/views/user/show.rhtml:162 -msgid "This person's annotations" -msgstr "Die Anmerkungen dieser Person" - -#: app/views/user/show.rhtml:165 app/views/user/show.rhtml:185 -msgid "None made." -msgstr "Keine gestellt." - -#: app/views/user/show.rhtml:169 -msgid "Your %d annotation" -msgid_plural "Your %d annotations" -msgstr[0] "Ihre %d Anmerkunge" -msgstr[1] "Ihre %d Anmerkungen" +#: app/views/contact_mailer/user_message.rhtml:3 +msgid "" +"Your details have not been given to anyone, unless you choose to reply to this\n" +"message, which will then go directly to the person who wrote the message." +msgstr "" +"Ihre Details wurden nicht weitergegeben, ausser wenn Sie sich entschieden " +"haben auf diese Nachricht zu antworten. Ihre Antwort geht dann direkt an die" +" Person, welche die Nachricht geschrieben hat. " -#: app/views/user/show.rhtml:169 -msgid "This person's %d annotation" -msgid_plural "This person's %d annotations" -msgstr[0] "Die %d Anmerkung dieser Person" -msgstr[1] "Die %d Anmerkungen dieser Person" +#: app/views/user/signchangepassword_send_confirm.rhtml:13 +#: app/views/user/_signup.rhtml:9 app/views/user/_signin.rhtml:11 +msgid "Your e-mail:" +msgstr "Ihre Email:" -#: app/views/user/show.rhtml:184 +#: app/views/user/show.rhtml:186 msgid "Your email subscriptions" msgstr "Ihr Email-Abo" -#: app/views/user/show.rhtml:187 -msgid "email subscription" -msgstr "Anleitung mailen" - -#: app/views/user/show.rhtml:196 app/views/user/show.rhtml:210 -msgid "unsubscribe all" -msgstr "alle abbestellen" - -#: app/views/user/show.rhtml:224 -msgid "unsubscribe" -msgstr "abmelden" - -#: app/views/user/sign.rhtml:8 -msgid "Please sign in as " -msgstr "Anmelden als" - -#: app/views/user/sign.rhtml:11 -msgid "please sign in as " -msgstr "Bitte melden Sie sich an als" - -#: app/views/user/sign.rhtml:20 -msgid "Sign in or make a new account" -msgstr "Anmelden oder neues Benutzerkonto erstellen" - -#: app/views/user/sign.rhtml:26 -msgid " Please sign in or make a new account." -msgstr "Bitte melden Sie sich an oder erstellen Sie ein neues Benutzerkonto." - -#: app/views/user/sign.rhtml:28 -msgid "please sign in or make a new account." -msgstr "Bitte melden Sie sich an oder erstellen Sie ein neues Benutzerkonto." - -#: app/views/user/signchangeemail.rhtml:15 -msgid "Old e-mail:" -msgstr "Alte Emailadresse: " +#: app/controllers/request_controller.rb:562 +msgid "" +"Your follow up has not been sent because this request has been stopped to " +"prevent spam. Please <a href=\"%s\">contact us</a> if you really want to " +"send a follow up message." +msgstr "" +"Ihre Nachfrage wurde nicht gesendet, da Sie durch unseren Spamfilter " +"gestoppt wurde. Bitte <a href=\"%s\">kontaktieren Sie uns</a> wenn Sie " +"wirklich eine Nachfrage senden möchten. " -#: app/views/user/signchangeemail.rhtml:20 -msgid "New e-mail:" -msgstr "Neue Email:" +#: app/controllers/request_controller.rb:590 +msgid "Your follow up message has been sent on its way." +msgstr "Ihre Follow-up Nachricht wurde gesendet." -#: app/views/user/signchangeemail.rhtml:25 -msgid "Your password:" -msgstr "Ihr Passwort:" +#: app/controllers/request_controller.rb:588 +msgid "Your internal review request has been sent on its way." +msgstr "Ihre Anfrage zur internen Überprüfung wurde gesendet. " -#: app/views/user/signchangeemail.rhtml:30 +#: app/controllers/help_controller.rb:63 msgid "" -"<strong>Note:</strong>\n" -" We will send an email to your new email address. Follow the\n" -" instructions in it to confirm changing your email." +"Your message has been sent. Thank you for getting in touch! We'll get back " +"to you soon." msgstr "" -"<strong>Note:</strong>\n" -" Es wird eine Email an Ihre neue Emailadresse versendet. Folgen Sie den darin angegebenen Schritten, um die Änderung Ihrer Emailadresse zu bestätigen." +"Ihre Nachricht wurde gesendet. Vielen Dank für die Kontaktaufnahme! Wir " +"werden uns in Kürze mit Ihnen in Verbindung senden. " -#: app/views/user/signchangeemail.rhtml:37 -msgid "Change email on {{site_name}}" -msgstr "Email ändern auf {{site_name}}" +#: app/controllers/user_controller.rb:367 +msgid "Your message to {{recipient_user_name}} has been sent!" +msgstr "Ihre Nachricht an {{recipient_user_name}} wurde versendet!" -#: app/views/user/signchangeemail_confirm.rhtml:3 -#: app/views/user/signchangepassword_confirm.rhtml:1 -#: app/views/user/signchangepassword_confirm.rhtml:3 -msgid "Now check your email!" -msgstr "Rufen Sie nun Ihre Emails ab. " +#: app/views/request/followup_preview.rhtml:15 +msgid "Your message will appear in <strong>search engines</strong>" +msgstr "" +"Ihre Nachricht wird in <strong>Suchmaschinen</strong> angezeigt werden" -#: app/views/user/signchangeemail_confirm.rhtml:6 +#: app/views/comment/preview.rhtml:10 msgid "" -"We've sent an email to your new email address. You'll need to click the link in\n" -"it before your email address will be changed." +"Your name and annotation will appear in <strong>search engines</strong>." msgstr "" -"Wir haben eine Email an Ihre neue Emailadresse gesendet. Sie müssen den Link" -" in dieser Email anklicken, um Ihre neue Adresse zu aktivieren. " +"Ihr Name und Ihr Kommentar wird in <strong>Suchmaschinen</strong>.angezeigt " +"werden. " -#: app/views/user/signchangeemail_confirm.rhtml:11 -#: app/views/user/signchangepassword_confirm.rhtml:10 +#: app/views/request/preview.rhtml:8 msgid "" -"If you use web-based email or have \"junk mail\" filters, also check your\n" -"bulk/spam mail folders. Sometimes, our messages are marked that way." +"Your name, request and any responses will appear in <strong>search engines</strong>\n" +" (<a href=\"%s\">details</a>)." msgstr "" -"Sollten Sie ein webbasiertes Emailkonto oder Spamfilter benutzen, überrpüfen" -" Sie Ihre Bulk-, Spamordner. Unsere Nachrichten landen teilweise in diese " -"Ordnern. " +"Ihr Name, Ihre Anfrage und alle Antworten werden in <strong>Suchmaschinen</strong> angezeigt werden\n" +" (<a href=\"%s\">Details</a>)." -#: app/views/user/signchangepassword.rhtml:1 -#: app/views/user/signchangepassword.rhtml:11 -#: app/views/user/signchangepassword_send_confirm.rhtml:1 -#: app/views/user/signchangepassword_send_confirm.rhtml:9 -msgid "Change your password on {{site_name}}" -msgstr "Ändern Sie Ihr Passwort: {{site_name}}" +#: app/views/user/_signup.rhtml:18 +msgid "Your name:" +msgstr "Ihr Name:" -#: app/views/user/signchangepassword.rhtml:15 -msgid "New password:" -msgstr "Neues Passwort:" +#: app/views/request_mailer/stopped_responses.rhtml:14 +msgid "Your original message is attached." +msgstr "Ihre ursprüngliche Nachricht befindet sich im Anhang. " -#: app/views/user/signchangepassword.rhtml:20 -msgid "New password: (again)" -msgstr "Neues Passwort: (erneut eingeben)" +#: app/controllers/user_controller.rb:249 +msgid "Your password has been changed." +msgstr "Ihr Passwort wurde geändert." -#: app/views/user/signchangepassword.rhtml:27 -msgid "Change password on {{site_name}}" -msgstr "Passwort ändern: {{site_name}}" +#: app/views/user/signchangeemail.rhtml:25 +msgid "Your password:" +msgstr "Ihr Passwort:" -#: app/views/user/signchangepassword_confirm.rhtml:6 +#: app/views/user/set_draft_profile_photo.rhtml:18 msgid "" -"We've sent you an email, click the link in it, then you can change your " -"password." +"Your photo will be shown in public <strong>on the Internet</strong>, \n" +" wherever you do something on {{site_name}}." msgstr "" -"Wir haben Ihnen eine Email gesendet. Klicken Sie den darin angezeigten Link," -" um Ihr Passwort zu ändern. " +"<strong>Datenschutzhinweis:</strong> Ihr Photo wird öffentlich im Internet angezeigt werden\n" +" wo immer Sie {{site_name}} nutzen." -#: app/views/user/signchangepassword_send_confirm.rhtml:18 +#: app/views/request_mailer/new_response_reminder_alert.rhtml:5 msgid "" -" <strong>Note:</strong>\n" -" We will send you an email. Follow the instructions in it to change\n" -" your password." +"Your request was called {{info_request}}. Letting everyone know whether you " +"got the information will help us keep tabs on" msgstr "" -"<strong>Note:</strong>⏎ Sie werden in Kürze eine Email erhalten. Folgen Sie " -"der Anleitung, um Ihr Passwort⏎ zu ändern." - -#: app/views/user/signchangepassword_send_confirm.rhtml:26 -msgid "Submit" -msgstr "Senden" +"Ihre Anfrage hat den folgenden Titel: {{info_request}}. Bitte informieren " +"Sie uns, ob Sie die gewünschte Information erhalten. Dies hilft uns die " +"Seite aktuell zu halten." -#: app/views/user/wrong_user.rhtml:2 -msgid "Sorry, but only {{user_name}} is allowed to do that." -msgstr "Sorry, aber dieser Vorgang ist {{user_name}} vorbehalten." +#: app/views/request/new.rhtml:113 +msgid "Your request:" +msgstr "Ihre Anfrage:" -#: app/views/user/wrong_user_unknown_email.rhtml:3 +#: app/views/request/upload_response.rhtml:8 msgid "" -"Unfortunately we don't know the FOI\n" -"email address for that authority, so we can't validate this.\n" -"Please <a href=\"%s\">contact us</a> to sort it out." +"Your response will <strong>appear on the Internet</strong>, <a " +"href=\"%s\">read why</a> and answers to other questions." msgstr "" -"Leider ist uns die IFG-Emailadresse dieser Behörde nicht bekannt, somit können wir dies nicht bestätigen.\n" -"Bitte <a href=\"%s\">kontaktieren Sie uns</a> zur Klärung der Angelegenheit." +"Ihre Antwort, sowie Antworten auf andere Anfragen wierden <strong>im " +"Internet erscheinen</strong>, <a href=\"%s\">Lesen Sie warum</a>" -#: app/views/user_mailer/already_registered.rhtml:3 +#: app/views/comment/new.rhtml:63 msgid "" -"You just tried to sign up to {{site_name}}, when you\n" -"already have an account. Your name and password have been\n" -"left as they previously were.\n" -"\n" -"Please click on the link below." +"Your thoughts on what the {{site_name}} <strong>administrators</strong> " +"should do about the request." msgstr "" -"Sie haben soeben versucht sich als neuer Nutzer von AskTheEU.org zu " -"registrieren, obwohl Sie bereits ein Konto haben. Ihr Benutzername und " -"Passwort sind unverändert. Bitte klicken Sie hier" +"Ihre Meinung zu empfehlenswerten Schritte von {{site_name}} durch die " +"<strong>Administratoren</strong> bzgl. der Anfrage." -#: app/views/user_mailer/changeemail_already_used.rhtml:1 -msgid "" -"Someone, perhaps you, just tried to change their email address on\n" -"{{site_name}} from {{old_email}} to {{new_email}}." -msgstr "" -"Jemand, evtl. Sie selber, hat soeben versucht seine/ihre Email-Adresse auf\n" -"{{site_name}} von{{old_email}} in {{new_email}} zu ändern." +#: app/models/track_mailer.rb:25 +msgid "Your {{site_name}} email alert" +msgstr "Ihr {{site_name}} Email Alarm" -#: app/views/user_mailer/changeemail_already_used.rhtml:5 -msgid "" -"This was not possible because there is already an account using \n" -"the email address {{email}}." -msgstr "" -"Dieser Vorgang war nicht möglich, da bereits ein Nutzerkonto mit der Email-" -"Adresse {{email}} besteht." +#: app/models/outgoing_message.rb:70 +msgid "Yours faithfully," +msgstr "Mit freundlichem Gruß, " -#: app/views/user_mailer/changeemail_already_used.rhtml:8 -msgid "The accounts have been left as they previously were." -msgstr "Die Nutzerkonten wurden in Ihrem ursprünglichen Zustand belassen." +#: app/models/outgoing_message.rb:68 +msgid "Yours sincerely," +msgstr "Mit freundlichem Gruß, " -#: app/views/user_mailer/changeemail_confirm.rhtml:3 +#: app/views/request/new.rhtml:88 msgid "" -"Please click on the link below to confirm that you want to \n" -"change the email address that you use for {{site_name}}\n" -"from {{old_email}} to {{new_email}}" +"a one line summary of the information you are requesting, \n" +"\t\t\te.g." msgstr "" -"Bitte klicken Sie auf den unten angezeigten Link, um zu bestätigen, dass Sie \n" -"die für {{site_name}} verwendete Email-Adresse\n" -"von {{old_email}} in {{new_email}} ändern möchten" +"Einzeilige Zusammenfassung der von Ihnen angefragten Information, \n" +"<span class=\"whitespace other\" title=\"Tab\">»</span><span class=\"whitespace other\" title=\"Tab\">»</span><span class=\"whitespace other\" title=\"Tab\">»</span>e.g." -#: app/views/user_mailer/changeemail_confirm.rhtml:10 -msgid "" -"We will not reveal your email addresses to anybody unless you\n" -"or the law tell us to." -msgstr "" -"Ohne Ihre Zustimmung oder gesetzliche Vorschrift werden wir Ihre Email-" -"Adresse zu keinem Zeitpunkt veröffentlichen." +#: app/views/public_body/show.rhtml:45 +msgid "admin" +msgstr "Administration" -#: app/views/user_mailer/confirm_login.rhtml:3 -msgid "Please click on the link below to confirm your email address." -msgstr "" -"Klicken Sie auf den unten aufgeführten Link, um Ihre Emailadresse zu " -"bestätigen." +#: app/views/request/_request_filter_form.rhtml:30 +msgid "all requests" +msgstr "alle Anfragen" -#: app/views/user_mailer/confirm_login.rhtml:8 +#: app/views/public_body/show.rhtml:43 +msgid "also called {{public_body_short_name}}" +msgstr "auch genannt: {{public_body_short_name}}" + +#: app/views/request/_request_filter_form.rhtml:25 +#: app/views/general/search.rhtml:114 +msgid "and" +msgstr "und" + +#: app/views/request/show.rhtml:59 msgid "" -"We will not reveal your email address to anybody unless you\n" -"or the law tell us to." +"and update the status accordingly. Perhaps <strong>you</strong> might like " +"to help out by doing that?" msgstr "" -"Wir werden Ihre Emailadresse nicht veröffentlichen, sofern nicht von Ihnen " -"freigegeben oder gesetzlich vorgeschrieben. " +"und aktualisieren Sie den Status entsprechend. Vielleicht würden " +"<strong>Sie</strong> uns somit gerne unterstützen?" -#: lib/world_foi_websites.rb:5 -msgid "United Kingdom" -msgstr "Vereinigtes Königreich" +#: app/views/request/show.rhtml:64 +msgid "and update the status." +msgstr "und aktualisieren Sie den Status. " -#: lib/world_foi_websites.rb:9 -msgid "Kosovo" -msgstr "Kosovo" +#: app/views/request/_describe_state.rhtml:101 +msgid "and we'll suggest <strong>what to do next</strong>" +msgstr "und wir werden <strong>nächstmögliche Schritte</strong> vorschlagen" -#: lib/world_foi_websites.rb:13 -msgid "European Union" -msgstr "Europäische Union" +#: app/views/general/frontpage.rhtml:60 +msgid "answered a request about" +msgstr "eine Anfrage beantwortet über" -#: lib/world_foi_websites.rb:17 -msgid "United States of America" -msgstr "Vereinigte Staaten von Amerika" +#: app/models/track_thing.rb:211 +msgid "any <a href=\"/list\">new requests</a>" +msgstr "jegliche <a href=\"/list\">neue Anfragen</a>" -#: lib/world_foi_websites.rb:21 -msgid "New Zealand" -msgstr "Neuseeland" +#: app/models/track_thing.rb:227 +msgid "any <a href=\"/list/successful\">successful requests</a>" +msgstr "jegliche <a href=\"/list/successful\">erfolgreiche Anfragen</a>" -#: lib/world_foi_websites.rb:25 -msgid "Germany" -msgstr "Deutschland" +#: app/models/track_thing.rb:116 +msgid "anything" +msgstr "alles" -#: lib/world_foi_websites.rb:29 -msgid "Chile" -msgstr "Chile" +#: app/views/request_mailer/very_overdue_alert.rhtml:1 +msgid "are long overdue." +msgstr "sind lange überfällig. " -#: locale/model_attributes.rb:2 -msgid "public body" -msgstr "Behörde" +#: app/models/track_thing.rb:89 app/views/general/search.rhtml:55 +msgid "authorities" +msgstr "Behörden" -#: locale/model_attributes.rb:3 -msgid "PublicBody|Name" -msgstr "Behörde|Name" +#: app/models/track_thing.rb:104 +msgid "awaiting a response" +msgstr "eine Antwort erwartend" -#: locale/model_attributes.rb:4 -msgid "PublicBody|Short name" -msgstr "PublicBody|Short name" +#: app/controllers/public_body_controller.rb:123 +msgid "beginning with" +msgstr "mit Anfangsbuchstabe " -#: locale/model_attributes.rb:5 -msgid "PublicBody|Request email" -msgstr "Behörde|Email anfragen" +#: app/models/track_thing.rb:95 +msgid "between two dates" +msgstr "zwischen zwei Datum" -#: locale/model_attributes.rb:6 -msgid "PublicBody|Version" -msgstr "Behörde|Version" +#: app/views/request/show.rhtml:82 +msgid "by" +msgstr "von" -#: locale/model_attributes.rb:7 -msgid "PublicBody|Last edit editor" -msgstr "PublicBody|Last edit editor" +#: app/views/request/_followup.rhtml:65 +msgid "by <strong>{{date}}</strong>" +msgstr "bis zum <strong>{{date}}</strong>" -#: locale/model_attributes.rb:8 -msgid "PublicBody|Last edit comment" -msgstr "PublicBody|Last edit comment" +#: app/views/request/_request_listing_via_event.rhtml:26 +msgid "by {{public_body_name}} to {{info_request_user}} on {{date}}." +msgstr "von {{public_body_name}} an {{info_request_user}} am {{date}}." -#: locale/model_attributes.rb:9 -msgid "PublicBody|Url name" -msgstr "Behörde|URL" +#: app/views/request/_request_listing_short_via_event.rhtml:10 +msgid "by {{user_link_absolute}}" +msgstr "durch {{user_link_absolute}}" -#: locale/model_attributes.rb:10 -msgid "PublicBody|Home page" -msgstr "PublicBody|Home page" +#: locale/model_attributes.rb:35 +msgid "censor rule" +msgstr "censor rule" -#: locale/model_attributes.rb:11 -msgid "PublicBody|Notes" -msgstr "Behörde|Anmerkung" +#: locale/model_attributes.rb:20 +msgid "comment" +msgstr "Kommentar" -#: locale/model_attributes.rb:12 -msgid "PublicBody|First letter" -msgstr "PublicBody|First letter" +#: app/models/track_thing.rb:86 +#: app/views/request/_request_filter_form.rhtml:14 +#: app/views/general/search.rhtml:103 +msgid "comments" +msgstr "Anmerkungen" -#: locale/model_attributes.rb:13 -msgid "PublicBody|Publication scheme" -msgstr "PublicBody|Publication scheme" +#: app/views/request/show_response.rhtml:39 +msgid "" +"containing your postal address, and asking them to reply to this request.\n" +" Or you could phone them." +msgstr "" +"Ihre Postanschrift beinhaltend und Sie fragend auf diese Afrage zu antworten.\n" +" Oder Sie könnten Sie anrufen." -#: locale/model_attributes.rb:14 -msgid "profile photo" -msgstr "Profilbild" +#: app/models/info_request_event.rb:323 +msgid "display_status only works for incoming and outgoing messages right now" +msgstr "" +"Anzeigestatus funktioniert momentan nur für ein- und ausgehende Nachrichten" -#: locale/model_attributes.rb:15 -msgid "ProfilePhoto|Data" -msgstr "ProfilePhoto|Data" +#: app/views/request_mailer/overdue_alert.rhtml:3 +msgid "during term time" +msgstr "während der Saison" -#: locale/model_attributes.rb:16 -msgid "ProfilePhoto|Draft" -msgstr "ProfilePhoto|Draft" +#: app/views/user/show.rhtml:96 +msgid "edit text about you" +msgstr "Bearbeiten Sie den Infotext zu Ihrer Person" + +#: app/views/user/show.rhtml:189 +msgid "email subscription" +msgstr "Anleitung mailen" + +#: app/views/request_mailer/very_overdue_alert.rhtml:4 +msgid "even during holidays" +msgstr "sogar während der Ferien" + +#: app/views/general/search.rhtml:56 +msgid "everything" +msgstr "alles" #: locale/model_attributes.rb:17 msgid "exim log" msgstr "exim log" -#: locale/model_attributes.rb:18 -msgid "EximLog|Order" -msgstr "EximLog|Order" +#: locale/model_attributes.rb:57 +msgid "exim log done" +msgstr "exim log done" -#: locale/model_attributes.rb:19 -msgid "EximLog|Line" -msgstr "EximLog|Line" +#: app/views/request_mailer/requires_admin.rhtml:2 +msgid "has reported an" +msgstr "hat berichtet" -#: locale/model_attributes.rb:20 -msgid "comment" -msgstr "Kommentar" +#: app/views/request_mailer/overdue_alert.rhtml:1 +msgid "have delayed." +msgstr "haben verspätet." -#: locale/model_attributes.rb:21 -msgid "Comment|Comment type" -msgstr "Comment|Comment type" +#: locale/model_attributes.rb:54 +msgid "holiday" +msgstr "Urlaub" -#: locale/model_attributes.rb:22 -msgid "Comment|Body" -msgstr "Comment|Body" +#: app/views/request/_followup.rhtml:63 app/views/request/show.rhtml:70 +#: app/views/request/show.rhtml:80 +msgid "in term time" +msgstr "während des Semesters" -#: locale/model_attributes.rb:23 -msgid "Comment|Visible" -msgstr "Comment|Visible" +#: locale/model_attributes.rb:60 +msgid "incoming message" +msgstr "Eingehende Nachricht" -#: locale/model_attributes.rb:24 -msgid "Comment|Locale" -msgstr "Comment|Locale" +#: locale/model_attributes.rb:82 +msgid "info request" +msgstr "Informationsanfrage" -#: locale/model_attributes.rb:25 -msgid "outgoing message" -msgstr "Gesendete Nachricht" +#: locale/model_attributes.rb:40 +msgid "info request event" +msgstr "Verlauf Informationsanfrage" -#: locale/model_attributes.rb:26 -msgid "OutgoingMessage|Body" -msgstr "OutgoingMessage|Body" +#: app/views/user/signchangeemail.rhtml:3 +#: app/views/user/set_profile_about_me.rhtml:3 +msgid "internal error" +msgstr "interner Fehler" -#: locale/model_attributes.rb:27 -msgid "OutgoingMessage|Status" -msgstr "OutgoingMessage|Status" +#: app/views/general/search.rhtml:91 +msgid "internal reviews" +msgstr "interne Prüfung" -#: locale/model_attributes.rb:28 -msgid "OutgoingMessage|Message type" -msgstr "OutgoingMessage|Message type" +#: app/views/request/show.rhtml:100 +msgid "is <strong>waiting for your clarification</strong>." +msgstr "<strong>Ihre Erläuterung wird erwartet</strong>." -#: locale/model_attributes.rb:29 -msgid "OutgoingMessage|Last sent at" -msgstr "OutgoingMessage|Last sent at" +#: app/views/user/show.rhtml:71 +msgid "just to see how it works" +msgstr "um zu sehen wie es funktioniert" -#: locale/model_attributes.rb:30 -msgid "OutgoingMessage|What doing" -msgstr "OutgoingMessage|What doing" +#: app/views/comment/_single_comment.rhtml:10 +msgid "left an annotation" +msgstr "Anmerkung hinterlassen" -#: locale/model_attributes.rb:31 -msgid "track thing" -msgstr "nachverfolgen" +#: app/views/user/_user_listing_single.rhtml:19 +#: app/views/user/_user_listing_single.rhtml:20 +msgid "made." +msgstr "erledigt." -#: locale/model_attributes.rb:32 -msgid "TrackThing|Track query" -msgstr "TrackThing|Track query" +#: app/views/request/_request_filter_form.rhtml:13 +#: app/views/general/search.rhtml:102 +msgid "messages from authorities" +msgstr "Nachrichten von Behörden" -#: locale/model_attributes.rb:33 -msgid "TrackThing|Track medium" -msgstr "TrackThing|Track medium" +#: app/views/request/_request_filter_form.rhtml:12 +#: app/views/general/search.rhtml:101 +msgid "messages from users" +msgstr "Nachrichten von Nutzern" -#: locale/model_attributes.rb:34 -msgid "TrackThing|Track type" -msgstr "TrackThing|Track type" +#: app/views/request/show.rhtml:74 +msgid "no later than" +msgstr "nicht später als" -#: locale/model_attributes.rb:35 -msgid "censor rule" -msgstr "censor rule" +#: app/views/request/followup_bad.rhtml:18 +msgid "" +"no longer exists. If you are trying to make\n" +" From the request page, try replying to a particular message, rather than sending\n" +" a general followup. If you need to make a general followup, and know\n" +" an email which will go to the right place, please <a href=\"%s\">send it to us</a>." +msgstr "" +"besteht nicht mehr. Falls Sie versuchen \n" +" Von der Anfragen-Seite, versuchen Sie auf spezifische Nachrichten zu Antworten anstatt generelle Nachfragen zu versenden. Wenn Sie eine gnerelle Nachfrage stellen müssen und eine Email-Adresse kennen, die an die richtige Stelle geht, <a href=\"%s\">senden Sie uns diese</a> bitte zu." -#: locale/model_attributes.rb:36 -msgid "CensorRule|Text" -msgstr "CensorRule|Text" +#: app/views/request/show.rhtml:72 +msgid "normally" +msgstr "normalerweise" -#: locale/model_attributes.rb:37 -msgid "CensorRule|Replacement" -msgstr "CensorRule|Replacement" +#: locale/model_attributes.rb:25 +msgid "outgoing message" +msgstr "Gesendete Nachricht" -#: locale/model_attributes.rb:38 -msgid "CensorRule|Last edit editor" -msgstr "CensorRule|Last edit editor" +#: app/views/user/sign.rhtml:11 +msgid "please sign in as " +msgstr "Bitte melden Sie sich an als" -#: locale/model_attributes.rb:39 -msgid "CensorRule|Last edit comment" -msgstr "CensorRule|Last edit comment" +#: app/views/user/sign.rhtml:28 +msgid "please sign in or make a new account." +msgstr "Bitte melden Sie sich an oder erstellen Sie ein neues Benutzerkonto." -#: locale/model_attributes.rb:40 -msgid "info request event" -msgstr "Verlauf Informationsanfrage" +#: locale/model_attributes.rb:47 +msgid "post redirect" +msgstr "" -#: locale/model_attributes.rb:41 -msgid "InfoRequestEvent|Event type" -msgstr "InfoRequestEvent|Event type" +#: locale/model_attributes.rb:14 +msgid "profile photo" +msgstr "Profilbild" -#: locale/model_attributes.rb:42 -msgid "InfoRequestEvent|Params yaml" -msgstr "InfoRequestEvent|Params yaml" +#: locale/model_attributes.rb:2 +msgid "public body" +msgstr "Behörde" -#: locale/model_attributes.rb:43 -msgid "InfoRequestEvent|Described state" -msgstr "InfoRequestEvent|Described state" +#: app/views/request_mailer/not_clarified_alert.rhtml:1 +msgid "request." +msgstr "Anfrage." -#: locale/model_attributes.rb:44 -msgid "InfoRequestEvent|Calculated state" -msgstr "InfoRequestEvent|Calculated state" +#: app/views/request/show.rhtml:89 +msgid "requesting an internal review" +msgstr "Interne Prüfung beantragen " -#: locale/model_attributes.rb:45 -msgid "InfoRequestEvent|Last described at" -msgstr "InfoRequestEvent|Last described at" +#: app/models/track_thing.rb:92 app/models/track_thing.rb:111 +#: app/models/track_thing.rb:113 app/views/general/search.rhtml:53 +msgid "requests" +msgstr "Anfragen" -#: locale/model_attributes.rb:46 -msgid "InfoRequestEvent|Prominence" -msgstr "InfoRequestEvent|Prominence" +#: app/models/track_thing.rb:112 +msgid "requests which are {{list_of_statuses}}" +msgstr "Anfragen mit dem Status {{list_of_statuses}} " -#: locale/model_attributes.rb:47 -msgid "post redirect" +#: app/views/request_mailer/requires_admin.rhtml:3 +msgid "" +"response as needing administrator attention. Take a look, and reply to this\n" +"email to let them know what you are going to do about it." msgstr "" +"Antwort als Administrator-Check bedürftig. Schau nach und antworte auf diese" +" Email, um sie wissen zu lassen was Du damit tun wirst. " -#: locale/model_attributes.rb:48 -msgid "PostRedirect|Token" -msgstr "PostRedirect|Token" +#: app/views/request/show.rhtml:102 +msgid "send a follow up message" +msgstr "Nachfrage versenden" -#: locale/model_attributes.rb:49 -msgid "PostRedirect|Uri" -msgstr "PostRedirect|Uri" +#: app/views/request/_request_listing_via_event.rhtml:23 +msgid "sent to {{public_body_name}} by {{info_request_user}} on {{date}}." +msgstr "" +"gesendet an {{public_body_name}} durch {{info_request_user}} am {{date}}." -#: locale/model_attributes.rb:50 -msgid "PostRedirect|Post params yaml" -msgstr "PostRedirect|Post params yaml" +#: app/views/request/show.rhtml:106 +msgid "sign in" +msgstr "Anmelden" -#: locale/model_attributes.rb:51 -msgid "PostRedirect|Email token" -msgstr "PostRedirect|Email token" +#: app/models/track_thing.rb:101 +msgid "successful" +msgstr "erfolgreich" -#: locale/model_attributes.rb:52 -msgid "PostRedirect|Reason params yaml" -msgstr "PostRedirect|Reason params yaml" +#: app/views/request/_request_filter_form.rhtml:31 +#: app/views/general/search.rhtml:88 +msgid "successful requests" +msgstr "erfolgreiche Anfragen" -#: locale/model_attributes.rb:53 -msgid "PostRedirect|Circumstance" -msgstr "PostRedirect|Circumstance" +#: app/views/request_mailer/new_response.rhtml:2 +msgid "that you made to" +msgstr "welche Sie stellten an:" -#: locale/model_attributes.rb:54 -msgid "holiday" -msgstr "Urlaub" +#: app/views/request/_followup.rhtml:23 app/views/request/_followup.rhtml:28 +#: app/views/request/_followup.rhtml:34 +msgid "the main FOI contact address for {{public_body}}" +msgstr "die Haupt-Kontaktadresse für {{public_body}}" -#: locale/model_attributes.rb:55 -msgid "Holiday|Day" -msgstr "Holiday|Day" +#: app/views/request/_followup.rhtml:3 +msgid "the main FOI contact at {{public_body}}" +msgstr "der Hauptkontakt für {{public_body}}" -#: locale/model_attributes.rb:56 -msgid "Holiday|Description" -msgstr "Holiday|Description" +#: app/views/request_mailer/comment_on_alert_plural.rhtml:5 +#: app/views/request_mailer/old_unclassified_updated.rhtml:8 +#: app/views/request_mailer/new_response_reminder_alert.rhtml:8 +#: app/views/request_mailer/very_overdue_alert.rhtml:11 +#: app/views/request_mailer/overdue_alert.rhtml:9 +#: app/views/request_mailer/stopped_responses.rhtml:16 +#: app/views/request_mailer/new_response.rhtml:15 +#: app/views/request_mailer/not_clarified_alert.rhtml:9 +#: app/views/request_mailer/comment_on_alert.rhtml:6 +#: app/views/user_mailer/already_registered.rhtml:11 +#: app/views/user_mailer/confirm_login.rhtml:11 +#: app/views/user_mailer/changeemail_confirm.rhtml:13 +#: app/views/user_mailer/changeemail_already_used.rhtml:10 +#: app/views/track_mailer/event_digest.rhtml:66 +msgid "the {{site_name}} team" +msgstr "das {{site_name}} Team" -#: locale/model_attributes.rb:57 -msgid "exim log done" -msgstr "exim log done" +#: app/views/request/show.rhtml:62 +msgid "to read" +msgstr "zu lesen" -#: locale/model_attributes.rb:58 -msgid "EximLogDone|Filename" -msgstr "EximLogDone|Filename" +#: app/views/request/show.rhtml:106 +msgid "to send a follow up message." +msgstr "um eine Nachfrage zu senden. " -#: locale/model_attributes.rb:59 -msgid "EximLogDone|Last stat" -msgstr "EximLogDone|Last stat" +#: app/views/request/show.rhtml:45 +msgid "to {{public_body}}" +msgstr "an {{public_body}}" -#: locale/model_attributes.rb:60 -msgid "incoming message" -msgstr "Eingehende Nachricht" +#: locale/model_attributes.rb:31 +msgid "track thing" +msgstr "nachverfolgen" -#: locale/model_attributes.rb:61 -msgid "IncomingMessage|Cached attachment text clipped" -msgstr "IncomingMessage|Cached attachment text clipped" +#: app/views/request/_hidden_correspondence.rhtml:32 +msgid "unexpected prominence on request event" +msgstr "" -#: locale/model_attributes.rb:62 -msgid "IncomingMessage|Cached main body text folded" -msgstr "IncomingMessage|Cached main body text folded" +#: app/views/request/_request_listing_via_event.rhtml:30 +msgid "unknown event type indexed " +msgstr "unbekannter Aktionstyp angezeigt" -#: locale/model_attributes.rb:63 -msgid "IncomingMessage|Cached main body text unfolded" -msgstr "IncomingMessage|Cached main body text unfolded" +#: app/views/request/followup_bad.rhtml:29 +msgid "unknown reason " +msgstr "unbekannte Ursache" -#: locale/model_attributes.rb:64 -msgid "IncomingMessage|Sent at" -msgstr "" +#: app/models/info_request_event.rb:318 app/models/info_request.rb:816 +msgid "unknown status " +msgstr "unbekannter Status" -#: locale/model_attributes.rb:65 -msgid "IncomingMessage|Subject" -msgstr "" +#: app/views/request/_request_filter_form.rhtml:33 +#: app/views/general/search.rhtml:90 +msgid "unresolved requests" +msgstr "ungelöste Anfragen" -#: locale/model_attributes.rb:66 -msgid "IncomingMessage|Safe mail from" -msgstr "" +#: app/views/user/show.rhtml:226 +msgid "unsubscribe" +msgstr "abmelden" -#: locale/model_attributes.rb:67 -msgid "IncomingMessage|Mail from domain" -msgstr "" +#: app/views/user/show.rhtml:198 app/views/user/show.rhtml:212 +msgid "unsubscribe all" +msgstr "alle abbestellen" -#: locale/model_attributes.rb:68 -msgid "IncomingMessage|Valid to reply to" -msgstr "" +#: app/models/track_thing.rb:98 +msgid "unsuccessful" +msgstr "nicht erfolgreich" -#: locale/model_attributes.rb:69 -msgid "user info request sent alert" -msgstr "" +#: app/views/request/_request_filter_form.rhtml:32 +#: app/views/general/search.rhtml:89 +msgid "unsuccessful requests" +msgstr "nicht erfolgreiche Anfragen" -#: locale/model_attributes.rb:70 -msgid "UserInfoRequestSentAlert|Alert type" -msgstr "UserInfoRequestSentAlert|Alert type" +#: app/views/request/show.rhtml:53 +msgid "useful information." +msgstr "nützliche Information" #: locale/model_attributes.rb:71 msgid "user" msgstr "Benutzer" -#: locale/model_attributes.rb:72 -msgid "User|Email" -msgstr "BenutzerIEmail" +#: locale/model_attributes.rb:69 +msgid "user info request sent alert" +msgstr "" -#: locale/model_attributes.rb:73 -msgid "User|Name" -msgstr "BenutzerIName" +#: app/models/track_thing.rb:83 app/views/general/search.rhtml:54 +msgid "users" +msgstr "Nutzer" -#: locale/model_attributes.rb:74 -msgid "User|Hashed password" -msgstr "Benutzer | Verschlüsseltes Passwort" +#: app/views/request/list.rhtml:21 +msgid "{{count}} FOI requests found" +msgstr "{{count}} IFG-Anfragen gefunden" -#: locale/model_attributes.rb:75 -msgid "User|Salt" -msgstr "User|Salt" +#: app/views/request/new.rhtml:27 +msgid "" +"{{existing_request_user}} already\n" +" created the same request on {{date}}. You can either view the <a href=\"{{existing_request}}\">existing request</a>,\n" +" or edit the details below to make a new but similar request." +msgstr "" +"{{existing_request_user}} already\n" +" created the same request on {{date}}. You can either view the <a href=\"{{existing_request}}\">existing request</a>,\n" +" or edit the details below to make a new but similar request." -#: locale/model_attributes.rb:76 -msgid "User|Email confirmed" -msgstr "UserIEmail bestätigt" +#: app/views/request/_after_actions.rhtml:23 +msgid "{{info_request_user_name}} only:" +msgstr "Nur {{info_request_user_name}}:" -#: locale/model_attributes.rb:77 -msgid "User|Url name" -msgstr "Benutzer|URL Name" +#: app/models/info_request.rb:245 +msgid "{{law_used_full}} request - {{title}}" +msgstr "" -#: locale/model_attributes.rb:78 -msgid "User|Last daily track email" -msgstr "User|Last daily track email" +#: app/models/info_request.rb:243 +msgid "{{law_used_full}} request GQ - {{title}}" +msgstr "" -#: locale/model_attributes.rb:79 -msgid "User|Admin level" -msgstr "User|Admin level" +#: app/views/general/frontpage.rhtml:62 +msgid "{{length_of_time}} ago" +msgstr "vor {{length_of_time}} " -#: locale/model_attributes.rb:80 -msgid "User|Ban text" -msgstr "User|Ban text" +#: app/models/track_thing.rb:122 +msgid "{{list_of_things}} matching text '{{search_query}}'" +msgstr "{{list_of_things}} passen zum Text '{{search_query}}'" -#: locale/model_attributes.rb:81 -msgid "User|About me" -msgstr "BenutzerIÜber mich" +#: app/views/general/blog.rhtml:56 +msgid "{{number_of_comments}} comments" +msgstr "{{number_of_comments}} Kommentare" -#: locale/model_attributes.rb:82 -msgid "info request" -msgstr "Informationsanfrage" +#: app/views/request/_after_actions.rhtml:45 +msgid "{{public_body_name}} only:" +msgstr "Nur {{public_body_name}}:" -#: locale/model_attributes.rb:83 -msgid "InfoRequest|Title" -msgstr "InfoRequest|Title" +#: app/views/track_mailer/event_digest.rhtml:21 +msgid "{{public_body}} sent a response to {{user_name}}" +msgstr "{{public_body}} hat eine Antwort an {{user_name}} gesendet" -#: locale/model_attributes.rb:84 -msgid "InfoRequest|Described state" -msgstr "InfoRequest|Described state" +#: app/controllers/user_controller.rb:43 +msgid "{{search_results}} matching '{{query}}'" +msgstr "{{search_results}} passen zu '{{query}}'" -#: locale/model_attributes.rb:85 -msgid "InfoRequest|Awaiting description" -msgstr "InfoAnfrage | Beschreibung wird erwartet" +#: app/views/general/blog.rhtml:1 +msgid "{{site_name}} blog and tweets" +msgstr "{{site_name}} Blog und Tweets" -#: locale/model_attributes.rb:86 -msgid "InfoRequest|Prominence" -msgstr "InfoRequest|Prominence" +#: app/views/general/frontpage.rhtml:38 +msgid "" +"{{site_name}} covers requests to {{number_of_authorities}} authorities, " +"including:" +msgstr "" +"{{site_name}} beinhaltet Anfragen an {{number_of_authorities}} Behörden, " +"einschliesslich:" -#: locale/model_attributes.rb:87 -msgid "InfoRequest|Url title" -msgstr "InfoRequest|Url title" +#: app/views/public_body/view_email.rhtml:7 +msgid "" +"{{site_name}} sends new requests to <strong>{{request_email}}</strong> for " +"this authority." +msgstr "" -#: locale/model_attributes.rb:88 -msgid "InfoRequest|Law used" -msgstr "InfoRequest|Law used" +#: app/views/general/frontpage.rhtml:55 +msgid "" +"{{site_name}} users have made {{number_of_requests}} requests, including:" +msgstr "" +"{{site_name}} Benutzer haben {{number_of_requests}} Anfragen gestellt, u.a.:" -#: locale/model_attributes.rb:89 -msgid "InfoRequest|Allow new responses from" -msgstr "InfoAnfrage | Neue Antworten zulassen von" +#: app/models/user.rb:133 +msgid "{{user_name}} (Account suspended)" +msgstr "{{user_name}} (Account suspended)" -#: locale/model_attributes.rb:90 -msgid "InfoRequest|Handle rejected responses" -msgstr "InfoRequest|Handle rejected responses" +#: app/views/track_mailer/event_digest.rhtml:31 +msgid "{{user_name}} added an annotation" +msgstr "{{user_name}} hat eine Anmerkung beigefügt" -#: locale/model_attributes.rb:91 -msgid "InfoRequest|Idhash" -msgstr "InfoRequest|Idhash" +#: app/views/request_mailer/comment_on_alert.rhtml:1 +msgid "" +"{{user_name}} has annotated your {{law_used_short}} \n" +"request. Follow this link to see what they wrote." +msgstr "" +"{{user_name}} hat Ihres {{law_used_short}} \n" +"Anfrage kommentiert. Folgen Sie diesem Link, um die Anmerkung zu sehen." + +#: app/views/contact_mailer/user_message.rhtml:2 +msgid "{{user_name}} has used {{site_name}} to send you the message below." +msgstr "" +"{{user_name}} hat {{site_name}} verwendet, um Ihnen die unten angezeigte " +"Nachricht zu senden." + +#: app/views/track_mailer/event_digest.rhtml:24 +msgid "{{user_name}} sent a follow up message to {{public_body}}" +msgstr "{{user_name}} hat eine Nachfrage an {{public_body}} gesendet" + +#: app/views/track_mailer/event_digest.rhtml:28 +msgid "{{user_name}} sent a request to {{public_body}}" +msgstr "{{user_name}} ´hat eine Anfrage an {{public_body}} gesendet" + +#: app/views/request/simple_correspondence.rhtml:42 +msgid "{{username}} left an annotation:" +msgstr "{{username}} hat eine Nachricht hinterlassen" + +#: app/views/request/show.rhtml:36 +msgid "" +"{{user}} (<a href=\"{{user_admin_url}}\">admin</a>) made this " +"{{law_used_full}} request (<a href=\"{{request_admin_url}}\">admin</a>) to " +"{{public_body_link}} (<a href=\"{{public_body_admin_url}}\">admin</a>)" +msgstr "" + +#: app/views/request/show.rhtml:44 +msgid "{{user}} made this {{law_used_full}} request" +msgstr "{{user}} hat diese {{law_used_full}} Anfrage gestellt" diff --git a/locale/en/app.po b/locale/en/app.po index c8693fbd0..436f63b10 100644 --- a/locale/en/app.po +++ b/locale/en/app.po @@ -3968,7 +3968,7 @@ msgid "" msgstr "" #: app/models/user.rb:122 -msgid "{{user_name}} (Banned)" +msgid "{{user_name}} (Account suspended)" msgstr "" #: app/views/request_mailer/comment_on_alert.rhtml:1 diff --git a/locale/es/app.po b/locale/es/app.po index f51a7327e..a7e7a97e2 100644 --- a/locale/es/app.po +++ b/locale/es/app.po @@ -1219,7 +1219,7 @@ msgstr "" "para el nombre" #: app/models/user.rb:133 -msgid "{{user_name}} (Banned)" +msgid "{{user_name}} (Account suspended)" msgstr "{{user_name}} (Expulsado)" #: app/models/user.rb:146 diff --git a/locale/fr/app.po b/locale/fr/app.po index 74dbbdb33..21def02ca 100644 --- a/locale/fr/app.po +++ b/locale/fr/app.po @@ -1078,7 +1078,7 @@ msgstr "" "nom." #: app/models/user.rb:133 -msgid "{{user_name}} (Banned)" +msgid "{{user_name}} (Account suspended)" msgstr "" #: app/models/user.rb:146 diff --git a/locale/model_attributes.rb b/locale/model_attributes.rb index e68b40168..7265ceb5b 100644 --- a/locale/model_attributes.rb +++ b/locale/model_attributes.rb @@ -32,11 +32,6 @@ _('track thing') _('TrackThing|Track query') _('TrackThing|Track medium') _('TrackThing|Track type') -_('censor rule') -_('CensorRule|Text') -_('CensorRule|Replacement') -_('CensorRule|Last edit editor') -_('CensorRule|Last edit comment') _('info request event') _('InfoRequestEvent|Event type') _('InfoRequestEvent|Params yaml') @@ -44,6 +39,11 @@ _('InfoRequestEvent|Described state') _('InfoRequestEvent|Calculated state') _('InfoRequestEvent|Last described at') _('InfoRequestEvent|Prominence') +_('censor rule') +_('CensorRule|Text') +_('CensorRule|Replacement') +_('CensorRule|Last edit editor') +_('CensorRule|Last edit comment') _('post redirect') _('PostRedirect|Token') _('PostRedirect|Uri') @@ -51,23 +51,22 @@ _('PostRedirect|Post params yaml') _('PostRedirect|Email token') _('PostRedirect|Reason params yaml') _('PostRedirect|Circumstance') -_('holiday') -_('Holiday|Day') -_('Holiday|Description') -_('exim log done') -_('EximLogDone|Filename') -_('EximLogDone|Last stat') _('incoming message') _('IncomingMessage|Cached attachment text clipped') _('IncomingMessage|Cached main body text folded') _('IncomingMessage|Cached main body text unfolded') -_('IncomingMessage|Sent at') _('IncomingMessage|Subject') -_('IncomingMessage|Safe mail from') _('IncomingMessage|Mail from domain') _('IncomingMessage|Valid to reply to') -_('user info request sent alert') -_('UserInfoRequestSentAlert|Alert type') +_('IncomingMessage|Last parsed') +_('IncomingMessage|Mail from') +_('IncomingMessage|Sent at') +_('holiday') +_('Holiday|Day') +_('Holiday|Description') +_('exim log done') +_('EximLogDone|Filename') +_('EximLogDone|Last stat') _('user') _('User|Email') _('User|Name') @@ -79,6 +78,20 @@ _('User|Last daily track email') _('User|Admin level') _('User|Ban text') _('User|About me') +_('User|Locale') +_('User|Email bounced at') +_('User|Email bounce message') +_('User|No limit') +_('foi attachment') +_('FoiAttachment|Content type') +_('FoiAttachment|Filename') +_('FoiAttachment|Charset') +_('FoiAttachment|Display size') +_('FoiAttachment|Url part number') +_('FoiAttachment|Within rfc822 subject') +_('FoiAttachment|Hexdigest') +_('user info request sent alert') +_('UserInfoRequestSentAlert|Alert type') _('info request') _('InfoRequest|Title') _('InfoRequest|Described state') diff --git a/locale/sq/app.po b/locale/sq/app.po index cf09cf3b5..7f09488ad 100644 --- a/locale/sq/app.po +++ b/locale/sq/app.po @@ -5021,7 +5021,7 @@ msgstr "" "përfshirë:" #: app/models/user.rb:133 -msgid "{{user_name}} (Banned)" +msgid "{{user_name}} (Account suspended)" msgstr "{{user_name}} (Përjashtuar)" #: app/views/track_mailer/event_digest.rhtml:31 diff --git a/locale/sq/app.po_ b/locale/sq/app.po_ index 2bf510317..b4988db14 100644 --- a/locale/sq/app.po_ +++ b/locale/sq/app.po_ @@ -4283,7 +4283,7 @@ msgid "" msgstr "" #: app/models/user.rb:122 -msgid "{{user_name}} (Banned)" +msgid "{{user_name}} (Account suspended)" msgstr "" #: app/views/request_mailer/comment_on_alert.rhtml:1 diff --git a/locale/sq/app_old3.po b/locale/sq/app_old3.po index 548775fc1..07463d4e7 100644 --- a/locale/sq/app_old3.po +++ b/locale/sq/app_old3.po @@ -4529,7 +4529,7 @@ msgstr "" "strong> për këtë autoritet." #: app/models/user.rb:122 -msgid "{{user_name}} (Banned)" +msgid "{{user_name}} (Account suspended)" msgstr "" #: app/views/request_mailer/comment_on_alert.rhtml:1 diff --git a/locale/sq/app_old4.po b/locale/sq/app_old4.po index a0a7b952e..d80e13397 100644 --- a/locale/sq/app_old4.po +++ b/locale/sq/app_old4.po @@ -4283,7 +4283,7 @@ msgid "" msgstr "" #: app/models/user.rb:122 -msgid "{{user_name}} (Banned)" +msgid "{{user_name}} (Account suspended)" msgstr "" #: app/views/request_mailer/comment_on_alert.rhtml:1 diff --git a/locale/sq/app_old5.po b/locale/sq/app_old5.po index 780ae4b41..40b79ed7b 100644 --- a/locale/sq/app_old5.po +++ b/locale/sq/app_old5.po @@ -4423,7 +4423,7 @@ msgstr "" "për këtë autoritet." #: app/models/user.rb:122 -msgid "{{user_name}} (Banned)" +msgid "{{user_name}} (Account suspended)" msgstr "{{user_name}} (Përjashtuar)" #: app/views/request_mailer/comment_on_alert.rhtml:1 diff --git a/locale/sr/app.po b/locale/sr/app.po index 9d13a3a0d..bfbab585f 100644 --- a/locale/sr/app.po +++ b/locale/sr/app.po @@ -3899,7 +3899,7 @@ msgid "" msgstr "" #: app/models/user.rb:122 -msgid "{{user_name}} (Banned)" +msgid "{{user_name}} (Account suspended)" msgstr "" #: app/views/request_mailer/comment_on_alert.rhtml:1 diff --git a/locale/sr@latin/app.po b/locale/sr@latin/app.po index d362dc935..92c1da85c 100644 --- a/locale/sr@latin/app.po +++ b/locale/sr@latin/app.po @@ -3900,7 +3900,7 @@ msgid "" msgstr "" #: app/models/user.rb:122 -msgid "{{user_name}} (Banned)" +msgid "{{user_name}} (Account suspended)" msgstr "" #: app/views/request_mailer/comment_on_alert.rhtml:1 diff --git a/public/images/navimg/logo-trans.png b/public/images/navimg/logo-trans.png Binary files differindex 917bec8b0..320a52efd 100644 --- a/public/images/navimg/logo-trans.png +++ b/public/images/navimg/logo-trans.png diff --git a/public/robots.txt b/public/robots.txt index 029ae0dbf..6a8628c93 100644 --- a/public/robots.txt +++ b/public/robots.txt @@ -24,3 +24,9 @@ Disallow: /feed/ Disallow: /profile/ Disallow: /signin Disallow: /body/*/view_email$ + +# The following adding Jan 2012 to stop robots crawling pages +# generated in error (see +# https://github.com/sebbacon/alaveteli/issues/311). Can be removed +# later in 2012 when the error pages have been dropped from the index +Disallow: *.json.j* diff --git a/public/stylesheets/ie6-custom.css b/public/stylesheets/ie6-custom.css index 6ebde600c..64d632e72 100644 --- a/public/stylesheets/ie6-custom.css +++ b/public/stylesheets/ie6-custom.css @@ -1,6 +1 @@ /* drop your local IE-specific CSS overrides in here */ - -#banner -{ - background-image: url(../images/navimg/bnnr-temp-100pxd.jpg); -} diff --git a/public/stylesheets/main.css b/public/stylesheets/main.css index 1166975d7..b9559ba17 100644 --- a/public/stylesheets/main.css +++ b/public/stylesheets/main.css @@ -1,8 +1,8 @@ body { text-align:center; color:#444; -font-size:12px; -font-family:Arial, sans-serif; +font-size:15px; +font-family: sans-serif; margin:0; padding:0; } @@ -10,7 +10,7 @@ padding:0; #banner { position:absolute; top:0; -background-color:#EEE; +background-color:#F3F3F3; left:0; width:100%; border:none; @@ -24,9 +24,9 @@ position:absolute; left:0; z-index:150; text-align:right; --moz-opacity:0.7px; +-moz-opacity:0.7; filter:alpha(opacity= 70) !important; -opacity:0.7px; +opacity:0.7; width:auto; right:0; top:10px; @@ -60,7 +60,7 @@ top:120px; margin-left:115px; width:auto; font-family:Arial, sans-serif; -font-size:18px; +font-size:1.2em; padding:0; } @@ -78,8 +78,8 @@ margin:0; padding:0; } -#topnav li a:hover { -color:#000; +#topnav li a:hover, a:hover { +color:purple; } #logged_in_bar { @@ -87,8 +87,8 @@ clear:none; font-size:0.9em; z-index:200; color:#444; -top:18px; -right:210px; +top:14px; +right:22em; float:none; position:absolute; padding:0.2em 10px 0.25em 1em; @@ -135,7 +135,7 @@ clear:left; } h1 { -font-size:42px; +font-size:2.2em; margin-bottom:15px; margin-top:10px; } @@ -171,7 +171,7 @@ border:1px solid #222; border-radius:5px; -moz-border-radius:5px; color:#222; -font-size:18px; +font-size:1.1em; text-align:left; width:412px; margin:0 14em 40px 0; @@ -223,7 +223,7 @@ margin-bottom:2em; } .request_listing,.body_listing,.user_listing { -font-size:0.8em; +font-size:0.9em; margin-top:1.5em; border-bottom:#9C9C9C; overflow:hidden; @@ -401,7 +401,6 @@ color:#FFF; #error,.errorExplanation,#hidden_request { color:#FF0606; -font-size:1.4em; font-weight:700; background-color:#fee; border-color:#FF0C11; @@ -424,7 +423,7 @@ border-width:1px; padding:0.2em; } -#notice,.describe_state_form,.undescribed_requests,.gone_postal_help { +#notice, .notice { color:#16C132; font-size:1.4em; font-weight:700; @@ -473,17 +472,6 @@ font-size:1em; text-align:right; } -div.comment_in_request { -float:left; -overflow:auto; -width:550px; -border-color:#5F5F5F; -border-style:dotted; -border-width:1px; -margin:0 0 1em 50px; -padding:0 0.5em; -} - div#after_actions { float:left; margin-bottom:1em; @@ -498,7 +486,7 @@ div[id|="outgoing"] p { } div[id|="incoming"] { -background-color:#DEDEDE; +background-color:#F3F3F3; } div[id|="incoming"] p { @@ -510,9 +498,7 @@ margin-left:50px; } div[id|="comment"] h2 { -margin-left:1em; font-size:1em; -text-align:right; } .comment_quote { @@ -678,15 +664,14 @@ margin-left:25%; } #signup .form_item_note,#signin .form_note { -font-size:0.8em; +font-size:0.9em; margin-left:11.5em; width:24em; } div.controller_help dt a,div.controller_help h1 a,div#help_unhappy h1 a.hover_a { text-decoration:none; -font-size:0.8em; -color:#fff; +font-size:0.9em; background-color:#fff; } @@ -726,13 +711,13 @@ padding:0.5em 0; background-color:#fc9; border:solid 2px #f60; border-top:none; -opacity:0.97px; --moz-border-radius-bottomleft:10px; --moz-border-radius-bottomright:10px; +opacity:0.97; +border-bottom-left-radius:10px; +border-bottom-right-radius:10px; position:fixed; width:70%; left:15%; -z-index:200; +z-index:2000; max-height:95%; overflow:auto; padding:4px; @@ -746,7 +731,7 @@ margin:0.5em 0; float:right; clear:none; width:20em; -font-size:0.8em; +font-size:0.9em; margin:0 0 2em 2em; } @@ -806,13 +791,13 @@ padding:0.5em 1em; #user_public_banned .details { margin-left:4em; margin-right:4em; -font-size:0.8em; +font-size:0.9em; font-style:italic; } div.lang { text-align:right; -font-size:0.8em; +font-size:0.9em; right:0; z-index:200; top:40px; @@ -865,7 +850,7 @@ margin-top:1em; } .form_explanation,div[id|="comment"] p { -font-size:0.8em; +font-size:0.9em; } .undescribed_requests,#preview_form p,.attachment { @@ -877,11 +862,11 @@ clear:left; } .correspondence_text,.comment_in_request_text { -margin:0 1.2em 0 0.8em; +margin:0 1.2em 0 0.9em; } #request_header_text,#request_search_ahead_results { -font-size:0.8em; +font-size:0.9em; margin-left:11em; } @@ -892,12 +877,12 @@ text-decoration:none; } h2,dt { -font-size:21px; +font-size:1.8em; } h3 { text-decoration:none; -font-size:20px; +font-size:1.6em; margin-top:3px; margin-bottom:10px; } @@ -916,7 +901,7 @@ margin:auto; position:absolute; left:0; top:70px; -z-index:100; +z-index:1000; } a img { @@ -925,16 +910,15 @@ border:none; #navigation_search input[type=image] { border:0; -margin-bottom:-9px; +margin-bottom:-8px; margin-left:-4px; } #navigation_search input[type=text] { -font-size:12px; border-radius:5px 0 0 5px; -moz-border-radius:5px 0 0 5px; border-color:#222; -padding:5px 5px 4px; +height: 14px; } #topnav ul li { @@ -954,6 +938,23 @@ float:left; #request_header_text { margin-left:110px; +width: 30em; +border-radius:3px; +-moz-border-radius:3px; +margin-top: 10px; +background-color:#D5FFD8; +border-color:#1EFF38; +border-style:solid; +border-width:1px; +padding:0.5em; + +font-style: italic; + + +} + +#request_header_text h3 { + font-size: 1em; } #stepwise_make_request a img { @@ -965,7 +966,7 @@ margin-left:6px; p.subtitle { margin-top:10px; margin-bottom:20px; -font-size:18px; +font-size:1.2em; font-style:normal; color:#222; } @@ -987,27 +988,25 @@ padding:12px 0 6px; .request_listing span.head,.user_listing span.head,.body_listing span.head { background:none; -font-size:21px; +font-size: 1.5em; margin-bottom:6px; padding:0; } .request_listing span.head a,.user_listing span.head a,.body_listing span.head a { text-decoration:none; -font-size:20px; +font-size:1.3em; margin-top:3px; display:block; margin-bottom:-6px; } .request_listing .requester { -font-size:12px; padding-bottom:0; } .body_listing span.desc,.body_listing span.bottomline,.user_listing span.bottomline { font-style:normal; -font-size:12px; font-weight:400; margin:0; padding:0; @@ -1018,7 +1017,7 @@ font-style:normal; margin-bottom:0; margin-top:12px; background-position:top left; -font-size:14px; +font-size:1.1em; font-weight:400; min-height:36px; padding:3px 0 0 27px; @@ -1036,7 +1035,6 @@ color:#C1272D; #request_sidebar { width:212px; -font-size:12px; } .feed_link { @@ -1046,7 +1044,6 @@ padding:4px 0; .request_listing span.desc { background:url(/images/quote-marks.png) no-repeat; min-height:60px; -font-size:12px; width:auto; color:#444; line-height:18px; @@ -1086,7 +1083,6 @@ padding-right:2px; } form.feed_form input[type="submit"] { -font-size:12px; line-height:12px; padding:2px 4px; } @@ -1127,7 +1123,7 @@ padding-bottom:5px; } #request_form label,label.form_label,span#to_public_body { -font-size:18px; +font-size: 1.1em; } #date_range label,#filter_requests_form label { @@ -1160,6 +1156,7 @@ margin-left:117px; } span#to_public_body { +font-weight: bold; } #left_column { @@ -1201,7 +1198,7 @@ width:10%; height:100px; text-align:center; margin-top:45px; -font-size:16px; +font-size:1.2em; font-family:Georgia; font-style:italic; color:#444; @@ -1217,7 +1214,7 @@ margin-left:10.5em; } form input[type=text],form input[type=password] { -font-size:14px; +font-size:1.1em; width:200px; color:#555; border-radius:3px; @@ -1233,7 +1230,7 @@ width:130px !important; background:url(/images/calendar.png) no-repeat 115px 3px; border-radius:3px !important; -moz-border-radius:3px !important; -font-size:14px !important; +font-size:1.1em !important; margin:0 !important; } @@ -1248,19 +1245,19 @@ border-radius:2px; -moz-border-radius:2px; text-shadow:1px 1px 0 #5B841D; font-size:18px; -cursor:hand; -padding:5px 11px; +cursor:pointer; +padding:5px 6px; } a.link_button_green_large { background:url(/images/button-gradient-large.png); -font-size:22px; +font-size:2em; line-height:22px; padding-bottom:7px; } form input[type=submit].small { -font-size:15px; +font-size:1.1em; line-height:10px; padding:4px 9px; } @@ -1295,7 +1292,6 @@ border:1px solid #DEBEDD; border-radius:5px; -moz-border-radius:5px; color:#DDD; -font-size:18px; text-align:center; width:255px; height:210px; @@ -1328,7 +1324,6 @@ padding:5px 0; #frontpage_examples .excerpt { cursor:pointer; background:url(/images/quote-marks.png) no-repeat; -font-size:12px; color:#444; line-height:18px; min-height:30px; @@ -1342,19 +1337,28 @@ background:url(/images/defaultprofilepic.png); div.correspondence,div.comment_in_request { width:600px; -font-size:13px; border-radius:6px; -moz-border-radius:6px; -border-width:0; +border-width:1px; padding:4px 20px 0 9px; } div.outgoing.correspondence { - background: #EFEFEF; + background: #FFFFD2; } div[id|="comment"] p { -font-size:13px; +} + +div.comment_in_request { +float:left; +overflow:auto; +width:550px; +border-color:#5F5F5F; +border-style:dotted; +border-width:1px; +margin:0 0 1em 50px; +padding:0 0.5em; } .comment_in_request_text { @@ -1477,7 +1481,7 @@ top:2px; border:none; background:#FFF; cursor:pointer; -opacity:1px; +opacity:1; } #ui-datepicker-div .ui-datepicker-next-hover { @@ -1486,25 +1490,26 @@ top:2px; border:none; background:#FFF; cursor:pointer; -opacity:1px; +opacity:1; } #other-country-notice { background:#222; color:#FFF; -font-size:16px; +font-size:1.1em; width:100%; z-index:999; display:block; position:absolute; top:0; -opacity:0.9px; +opacity:0.9; } p.public-body-name-prefix { color:#888; margin-top:15px; margin-bottom:-15px; +font-size: 1.2em; } #other-country-notice a { @@ -1517,7 +1522,7 @@ text-decoration:none; display:inline-block; border-radius:2px; -moz-border-radius:2px; -cursor:hand; +cursor:pointer; background:url(/images/small-white-cross.png) no-repeat; width:15px; height:15px; @@ -1533,7 +1538,7 @@ position:absolute; text-align:left; background-color:#FFF; z-index:999; -opacity:0.9px; +opacity:0.9; border-radius:6px; -moz-border-radius:6px; border:1px solid #444; @@ -1567,14 +1572,12 @@ border:solid 1px Red !important; .errorExplanation { border-radius:6px; -moz-border-radius:6px; -font-size:12px; font-weight:400; width:554px; margin:20px 0 30px; } #notice,.describe_state_form,#other_recipients { -font-size:12px; font-weight:400; background:#E9FDD3 !important; color:#517704; @@ -1605,7 +1608,7 @@ margin-bottom:0; } div.correspondence p.preview_subject { -font-size:18px !important; +font-size:1.2em !important; margin-left:10px; line-height:25px; } @@ -1629,6 +1632,10 @@ div.controller_help h1 a,#logged_in_bar a,#logged_in_bar a:visited,#stepwise_mak width:625px; float:left; } +#authority_preview .request_left, +#authority_preview #header_left { + width: 100%; +} #request_sidebar h2,.list-filter-item { margin-bottom:10px; @@ -1640,7 +1647,7 @@ display:none; #ui-datepicker-div .ui-datepicker-prev,#ui-datepicker-div .ui-datepicker-next { margin-top:2px; -opacity:0.5px; +opacity:0.5; } div.controller_help dt:hover > a:hover,div.controller_help h1:hover > a:hover,div#help_unhappy h1:hover > a.hover_a:hover,h2 a:hover,.request_listing span.head a:hover,.user_listing span.head a:hover,.body_listing span.head a:hover,.request_listing .requester a,.feed_link a:hover,.act_link a:hover,#header_right > a:hover { @@ -1649,4 +1656,4 @@ text-decoration:underline; .request_listing a,.body_listing a,.user_listing a,.request_short_listing a,h2 a,.feed_link a { text-decoration:none; -}
\ No newline at end of file +} diff --git a/script/clear-caches b/script/clear-caches index 2d91774ef..be1d3d017 100755 --- a/script/clear-caches +++ b/script/clear-caches @@ -4,7 +4,7 @@ LOC=`dirname $0` -"$LOC/runner" "ActiveRecord::Base.connection.execute(\"update incoming_messages set cached_attachment_text_clipped = null, cached_main_body_text_unfolded = null, cached_main_body_text_folded = null, sent_at = null, subject = null, safe_mail_from = null, mail_from_domain = null, valid_to_reply_to = null\")" +"$LOC/runner" "ActiveRecord::Base.connection.execute(\"update incoming_messages set cached_attachment_text_clipped = null, cached_main_body_text_unfolded = null, cached_main_body_text_folded = null, sent_at = null, subject = null, mail_from = null, mail_from_domain = null, valid_to_reply_to = null, last_parsed = null\")" # Remove page cache (do it in two stages so live site gets cache cleared faster) rm -fr $LOC/../old-cache diff --git a/script/generate_pot.sh b/script/generate_pot.sh index 287d33e7f..0c5dfda36 100755 --- a/script/generate_pot.sh +++ b/script/generate_pot.sh @@ -3,6 +3,6 @@ cd `dirname $0` rake gettext:store_model_attributes -rake gettext:find -git checkout ../locale/*/app.po +rake gettext:findpot +echo "Now commit the new app.pot and push. See TRANSLATE.md for next steps"
\ No newline at end of file diff --git a/script/handle-mail-replies b/script/handle-mail-replies index 9451bc9f2..68cab9035 100755 --- a/script/handle-mail-replies +++ b/script/handle-mail-replies @@ -120,12 +120,21 @@ def is_oof?(message) end end + if message.header_string("Auto-Submitted") == "auto-generated" + if subject =~ /out of( the)? office/ + return true + end + end + if subject.start_with? "out of office autoreply:" return true end if subject == "out of office" return true end + if subject == "out of office reply" + return true + end if subject.end_with? "is out of the office" return true end diff --git a/script/load-sample-data b/script/load-sample-data index 0521ef849..e5f1be4cd 100755 --- a/script/load-sample-data +++ b/script/load-sample-data @@ -4,9 +4,16 @@ # the fact that the fixtures aren't aware of the fact that RawEmails # have a filesystem representation of their contents -LOC=`dirname $0` +LOC=`dirname "$0"` + rake --silent spec:db:fixtures:load -"$LOC/runner" 'puts File.expand_path(File.dirname(__FILE__) + "/spec/spec_helper"); require File.expand_path(File.dirname(__FILE__) + "/spec/spec_helper"); RawEmail.all().each {|email| email.data = load_file_fixture("useless_raw_email.email")}' +"$LOC/runner" /dev/stdin <<END +env = ENV["RAILS_ENV"] +require "spec/spec_helper.rb" # this sets RAILS_ENV to 'test' +ENV["RAILS_ENV"] = env # so restore to what it was before + +load_raw_emails_data +END -echo "Loaded fixtures."
\ No newline at end of file +echo "Loaded fixtures. You may now wish to run $LOC/update-xapian-index" diff --git a/script/rails-post-deploy b/script/rails-post-deploy index df9f67528..263d5d926 100755 --- a/script/rails-post-deploy +++ b/script/rails-post-deploy @@ -55,33 +55,6 @@ cd log touch development.log fastcgi.crash.log production.log test.log cd .. -# Force appropriate environment (via a hack in config/boot.rb which needs -# applying to your rails app, see foi/config/boot.rb) -if [ ! -e "config/rails_env.rb" ] -then - cat <<END - -***************************************************************** -WARNING: About to make config/rails_env.rb which, via special -code in config/boot.rb, forces the Rails environment to be a -particular one - this is used for the mySociety deployment -system. You don't want it for local development, because it will -not work in a confusing way you try and use two environments -(e.g. development and test) in the same working directory. -***************************************************************** - -END -fi -if [ "$OPTION_STAGING_SITE" = "0" ] -then - echo "ENV['RAILS_ENV'] = 'production'" > config/rails_env.rb -elif [[ "$OPTION_DOMAIN" == *"test"* ]] -then - echo "ENV['RAILS_ENV'] = 'test'" > config/rails_env.rb -else - echo "ENV['RAILS_ENV'] = 'development'" > config/rails_env.rb -fi - if [ -n "$OPTION_THEME_URL" ] then script/plugin install --force $OPTION_THEME_URL diff --git a/script/rebuild-xapian-index b/script/rebuild-xapian-index index 11e4a46be..5986f5259 100755 --- a/script/rebuild-xapian-index +++ b/script/rebuild-xapian-index @@ -1,6 +1,4 @@ #!/bin/bash cd `dirname $0` -rake --silent xapian:rebuild_index models="PublicBody User InfoRequestEvent" - - +rake --silent "$@" xapian:rebuild_index models="PublicBody User InfoRequestEvent" diff --git a/script/spec-all-pairs b/script/spec-all-pairs new file mode 100755 index 000000000..5b6439a4e --- /dev/null +++ b/script/spec-all-pairs @@ -0,0 +1,81 @@ +#!/bin/bash + +# Try all ordered pairs of spec files, +# to winkle out order-dependent failures. + +log_file=/dev/null + +test_pair () { + rake db:test:prepare > /dev/null 2>&1 + output=$(script/spec "$1" "$2" 2>&1) + if [ $? -eq 0 ] + then + echo "OK: $1 $2" + return 0 + else + echo >> "$log_file" "FAILED: $1 $2" + echo >> "$log_file" "=======================================" + echo >> "$log_file" "$output" + echo >> "$log_file" + + echo "FAILED: $1 $2" + return 1 + fi +} + +all_pairs() { + specs=spec/*/*.rb + + for spec1 in $specs + do + all_okay=true + for spec2 in $specs + do + if ! test_pair "$spec1" "$spec2" + then + all_okay=false + fi + done + done + + $all_okay + return $? +} + +pairs_from_stdin() { + all_okay=true + while read line + do + case "$line" in + \*\ FAILED:\ *|\ + spec/*.rb\ spec/*.rb) + line=${line#\* FAILED: } + if ! test_pair $line + then + all_okay=false + fi + ;; + *) + echo "No match: $line" + ;; + esac + done + + $all_okay + return $? +} + +if [ "$1" = --log ] +then + shift + log_file=$1 + shift + cp /dev/null "$log_file" +fi +if [ "$1" = "-" ] +then + pairs_from_stdin +else + all_pairs +fi +exit $? diff --git a/script/update-xapian-index b/script/update-xapian-index index 8d1fa7d0c..6ece02de0 100755 --- a/script/update-xapian-index +++ b/script/update-xapian-index @@ -1,5 +1,5 @@ #!/bin/bash cd `dirname $0` -rake --silent xapian:update_index +rake --silent xapian:update_index "$@" diff --git a/spec/controllers/admin_public_body_controller_spec.rb b/spec/controllers/admin_public_body_controller_spec.rb index 22af3df80..1e82a0ba4 100644 --- a/spec/controllers/admin_public_body_controller_spec.rb +++ b/spec/controllers/admin_public_body_controller_spec.rb @@ -2,14 +2,19 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') describe AdminPublicBodyController, "when administering public bodies" do integrate_views - fixtures :public_bodies, :public_body_translations, :public_body_versions, :users, :info_requests, :raw_emails, :incoming_messages, :outgoing_messages, :comments, :info_request_events, :track_things before 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 @@ -25,9 +30,9 @@ describe AdminPublicBodyController, "when administering public bodies" do end it "creates a new public body" do - PublicBody.count.should == 2 + 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' } } - PublicBody.count.should == 3 + PublicBody.count.should == n + 1 end it "edits a public body" do @@ -42,29 +47,45 @@ describe AdminPublicBodyController, "when administering public bodies" do pb.name.should == "Renamed" end + it "does not destroy a public body that has associated requests" do + id = public_bodies(:humpadink_public_body).id + n = PublicBody.count + post :destroy, { :id => id } + response.should redirect_to(:controller=>'admin_public_body', :action=>'show', :id => id) + PublicBody.count.should == n + end + it "destroys a public body" do - PublicBody.count.should == 2 - post :destroy, { :id => 3 } - PublicBody.count.should == 1 + n = PublicBody.count + post :destroy, { :id => public_bodies(:forlorn_public_body).id } + response.should redirect_to(:controller=>'admin_public_body', :action=>'list') + PublicBody.count.should == n - 1 end it "sets a using_admin flag" do get :show, :id => 2 session[:using_admin].should == 1 end + + it "mass assigns tags" do + n = PublicBody.count + post :mass_tag_add, { :new_tag => "department", :table_name => "substring" } + response.flash[:notice].should == "Added tag to table of bodies." + response.should redirect_to(:action=>'list') + PublicBody.find_by_tag("department").count.should == n + end end describe AdminPublicBodyController, "when administering public bodies and paying attention to authentication" do integrate_views - fixtures :public_bodies, :public_body_translations, :public_body_versions, :users, :info_requests, :raw_emails, :incoming_messages, :outgoing_messages, :comments, :info_request_events, :track_things it "disallows non-authenticated users to do anything" do @request.env["HTTP_AUTHORIZATION"] = "" - PublicBody.count.should == 2 + n = PublicBody.count post :destroy, { :id => 3 } response.code.should == "401" - PublicBody.count.should == 2 + PublicBody.count.should == n session[:using_admin].should == nil end @@ -73,19 +94,22 @@ describe AdminPublicBodyController, "when administering public bodies and paying config['ADMIN_USERNAME'] = '' config['ADMIN_PASSWORD'] = '' @request.env["HTTP_AUTHORIZATION"] = "" - PublicBody.count.should == 2 - post :destroy, { :id => 3 } - PublicBody.count.should == 1 + + n = PublicBody.count + post :destroy, { :id => public_bodies(:forlorn_public_body).id } + PublicBody.count.should == n - 1 session[:using_admin].should == 1 end + it "skips admin authorisation when no username set" do config = MySociety::Config.load_default() config['ADMIN_USERNAME'] = '' config['ADMIN_PASSWORD'] = 'fuz' @request.env["HTTP_AUTHORIZATION"] = "" - PublicBody.count.should == 2 - post :destroy, { :id => 3 } - PublicBody.count.should == 1 + + n = PublicBody.count + post :destroy, { :id => public_bodies(:forlorn_public_body).id } + PublicBody.count.should == n - 1 session[:using_admin].should == 1 end it "forces authorisation when password and username set" do @@ -93,11 +117,11 @@ describe AdminPublicBodyController, "when administering public bodies and paying config['ADMIN_USERNAME'] = 'biz' config['ADMIN_PASSWORD'] = 'fuz' @request.env["HTTP_AUTHORIZATION"] = "" - PublicBody.count.should == 2 + n = PublicBody.count basic_auth_login(@request, "baduser", "badpassword") - post :destroy, { :id => 3 } + post :destroy, { :id => public_bodies(:forlorn_public_body).id } response.code.should == "401" - PublicBody.count.should == 2 + PublicBody.count.should == n session[:using_admin].should == nil end @@ -107,7 +131,6 @@ end describe AdminPublicBodyController, "when administering public bodies with i18n" do integrate_views - fixtures :public_bodies, :public_body_translations, :public_body_versions, :users, :info_requests, :raw_emails, :incoming_messages, :outgoing_messages, :comments, :info_request_events, :track_things before do username = MySociety::Config.get('ADMIN_USERNAME', '') @@ -167,43 +190,47 @@ describe AdminPublicBodyController, "when administering public bodies with i18n" end it "destroy a public body" do - PublicBody.count.should == 2 - post :destroy, { :id => 3 } - PublicBody.count.should == 1 + n = PublicBody.count + post :destroy, { :id => public_bodies(:forlorn_public_body).id } + PublicBody.count.should == n - 1 end end describe AdminPublicBodyController, "when creating public bodies with i18n" do integrate_views - fixtures :public_bodies, :public_body_translations, :public_body_versions, :users, :info_requests, :raw_emails, :incoming_messages, :outgoing_messages, :comments, :info_request_events, :track_things before do username = MySociety::Config.get('ADMIN_USERNAME', '') password = MySociety::Config.get('ADMIN_PASSWORD', '') basic_auth_login @request - ActionController::Routing::Routes.filters.clear # don't auto-insert locale, complicates assertions + @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 - PublicBody.count.should == 2 + 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' } } - PublicBody.count.should == 3 + PublicBody.count.should == n + 1 body = PublicBody.find_by_name("New Quango") response.should redirect_to(:controller=>'admin_public_body', :action=>'show', :id=>body.id) end it "creates a new public body with multiple locales" do - PublicBody.count.should == 2 + 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', :translated_versions => [{ :locale => "es", :name => "Mi Nuevo Quango", :short_name => "", :request_email => 'newquango@localhost' }] } } - PublicBody.count.should == 3 + PublicBody.count.should == n + 1 body = PublicBody.find_by_name("New Quango") body.translations.map {|t| t.locale.to_s}.sort.should == ["en", "es"] diff --git a/spec/controllers/admin_request_controller_spec.rb b/spec/controllers/admin_request_controller_spec.rb index 635d73b9e..ece1fe389 100644 --- a/spec/controllers/admin_request_controller_spec.rb +++ b/spec/controllers/admin_request_controller_spec.rb @@ -2,9 +2,17 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') describe AdminRequestController, "when administering requests" do integrate_views - fixtures :users, :public_bodies, :public_body_translations, :public_body_versions, :info_requests, :raw_emails, :incoming_messages, :outgoing_messages, :comments, :info_request_events, :track_things before { basic_auth_login @request } + before(:each) do + load_raw_emails_data + @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/list page" do get :index end @@ -41,10 +49,14 @@ end describe AdminRequestController, "when administering the holding pen" do integrate_views - fixtures :users, :public_bodies, :public_body_translations, :public_body_versions, :info_requests, :raw_emails, :incoming_messages, :outgoing_messages, :comments, :info_request_events, :track_things before(:each) do basic_auth_login @request - load_raw_emails_data(raw_emails) + load_raw_emails_data + @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 a rejection reason for an incoming message from an invalid address" do diff --git a/spec/controllers/admin_track_controller_spec.rb b/spec/controllers/admin_track_controller_spec.rb index b87ee9f0e..728c79f1f 100644 --- a/spec/controllers/admin_track_controller_spec.rb +++ b/spec/controllers/admin_track_controller_spec.rb @@ -2,7 +2,6 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') describe AdminTrackController, "when administering tracks" do integrate_views - fixtures :users, :info_requests, :incoming_messages, :outgoing_messages, :comments, :info_request_events, :track_things it "shows the list page" do get :list diff --git a/spec/controllers/admin_user_controller_spec.rb b/spec/controllers/admin_user_controller_spec.rb index b2b2d0626..65ecbc37d 100644 --- a/spec/controllers/admin_user_controller_spec.rb +++ b/spec/controllers/admin_user_controller_spec.rb @@ -2,7 +2,6 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') describe AdminUserController, "when administering users" do integrate_views - fixtures :users, :info_requests, :incoming_messages, :outgoing_messages, :comments, :info_request_events, :track_things before { basic_auth_login @request } it "shows the index/list page" do diff --git a/spec/controllers/application_controller_spec.rb b/spec/controllers/application_controller_spec.rb index 875d7d224..f16cee312 100644 --- a/spec/controllers/application_controller_spec.rb +++ b/spec/controllers/application_controller_spec.rb @@ -1,10 +1,47 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') +require 'fakeweb' + +describe ApplicationController, "when accessing third party services" do + before (:each) do + FakeWeb.clean_registry + end + after (:each) do + FakeWeb.clean_registry + end + it "should succeed if the service responds OK" do + config = MySociety::Config.load_default() + config['GAZE_URL'] = 'http://denmark.com' + FakeWeb.register_uri(:get, %r|denmark.com|, :body => "DK") + country = self.controller.send :country_from_ip + country.should == "DK" + end + it "should fail silently if the country_from_ip domain doesn't exist" do + config = MySociety::Config.load_default() + config['GAZE_URL'] = 'http://12123sdf14qsd.com' + country = self.controller.send :country_from_ip + country.should == config['ISO_COUNTRY_CODE'] + end + it "should fail silently if the country_from_ip service doesn't exist" do + config = MySociety::Config.load_default() + config['GAZE_URL'] = 'http://www.google.com' + country = self.controller.send :country_from_ip + country.should == config['ISO_COUNTRY_CODE'] + end + it "should fail silently if the country_from_ip service returns an error" do + FakeWeb.register_uri(:get, %r|500.com|, :body => "Error", :status => ["500", "Error"]) + config = MySociety::Config.load_default() + config['GAZE_URL'] = 'http://500.com' + country = self.controller.send :country_from_ip + country.should == config['ISO_COUNTRY_CODE'] + end +end + +describe ApplicationController, "when caching fragments" do + it "should not fail with long filenames" do + long_name = "blahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblah.txt" + path = self.controller.send(:foi_fragment_cache_path, long_name) + self.controller.send(:foi_fragment_cache_write, path, "whassap") + end -describe ApplicationController, "when authenticating user" do - integrate_views - fixtures :users - -# it "blah" do -# end end diff --git a/spec/controllers/comment_controller_spec.rb b/spec/controllers/comment_controller_spec.rb index 4c14b8d24..93752537c 100644 --- a/spec/controllers/comment_controller_spec.rb +++ b/spec/controllers/comment_controller_spec.rb @@ -2,7 +2,6 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') describe CommentController, "when commenting on a request" do integrate_views - fixtures :users, :public_bodies, :public_body_translations, :public_body_versions, :info_requests, :incoming_messages, :outgoing_messages, :comments, :info_request_events, :track_things it "should give an error and render 'new' template when body text is just some whitespace" do post :new, :url_title => info_requests(:naughty_chicken_request).url_title, diff --git a/spec/controllers/general_controller_spec.rb b/spec/controllers/general_controller_spec.rb index 40a676d61..7fc019c64 100644 --- a/spec/controllers/general_controller_spec.rb +++ b/spec/controllers/general_controller_spec.rb @@ -1,23 +1,28 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') +require 'fakeweb' + +describe GeneralController, "when trying to show the blog" do + before (:each) do + FakeWeb.clean_registry + end + after (:each) do + FakeWeb.clean_registry + end + + it "should fail silently if the blog is returning an error" do + FakeWeb.register_uri(:get, %r|.*|, :body => "Error", :status => ["500", "Error"]) + get :blog + response.status.should == "200 OK" + assigns[:blog_items].count.should == 0 + end +end describe GeneralController, "when searching" do integrate_views - fixtures [ - :public_bodies, - :public_body_translations, - :public_body_versions, - :users, - :info_requests, - :raw_emails, - :incoming_messages, - :outgoing_messages, - :comments, - :info_request_events, - :track_things, - ] before(:each) do - load_raw_emails_data(raw_emails) + load_raw_emails_data + rebuild_xapian_index end it "should render the front page successfully" do @@ -68,36 +73,58 @@ describe GeneralController, "when searching" do it "should redirect from search query URL to pretty URL" do post :search_redirect, :query => "mouse" # query hidden in POST parameters - response.should redirect_to(:action => 'search', :combined => "mouse", :view => "requests") # URL /search/:query/all + response.should redirect_to(:action => 'search', :combined => "mouse", :view => "all") # URL /search/:query/all end describe "when using different locale settings" do home_link_regex = /href=".*\/en"/ it "should generate URLs with a locale prepended when there's more than one locale set" do - ActionController::Routing::Routes.add_filters('conditionallyprependlocale') get :frontpage response.should have_text(home_link_regex) end it "should generate URLs without a locale prepended when there's only one locale set" do - ActionController::Routing::Routes.add_filters('conditionallyprependlocale') - old_available_locales = FastGettext.default_available_locales - available_locales = ['en'] - FastGettext.default_available_locales = available_locales - I18n.available_locales = available_locales + old_fgt_available_locales = FastGettext.default_available_locales + old_i18n_available_locales = I18n.available_locales + FastGettext.default_available_locales = I18n.available_locales = ['en'] get :frontpage response.should_not have_text(home_link_regex) - FastGettext.default_available_locales = old_available_locales - I18n.available_locales = old_available_locales + FastGettext.default_available_locales = old_fgt_available_locales + I18n.available_locales = old_i18n_available_locales + end + end + + describe 'when constructing the list of recent requests' do + before(:each) do + load_raw_emails_data + rebuild_xapian_index + end + + it 'should list the newest successful request first' do + # Make sure the newest is listed first even if an older one + # has a newer comment or was reclassified more recently: + # https://github.com/sebbacon/alaveteli/issues/370 + # + # This is a deliberate behaviour change, in that the + # previous behaviour (showing more-recently-reclassified + # requests first) was intentional. + get :frontpage + assigns[:request_events].first.info_request.should == info_requests(:another_boring_request) + end + + it 'should coalesce duplicate requests' do + get :frontpage + assigns[:request_events].map(&:info_request).select{|x|x.url_title =~ /^spam/}.length.should == 1 end end describe 'when using xapian search' do # rebuild xapian index after fixtures loaded - before(:all) do + before(:each) do + load_raw_emails_data rebuild_xapian_index end @@ -128,21 +155,31 @@ describe GeneralController, "when searching" do it "should filter results based on end of URL being 'all'" do get :search, :combined => ['"bob"', "all"] - assigns[:xapian_requests].results.size.should == 2 - assigns[:xapian_users].results.size.should == 1 - assigns[:xapian_bodies].results.size.should == 0 + assigns[:xapian_requests].results.map{|x| x[:model]}.should =~ [ + info_request_events(:useless_outgoing_message_event), + info_request_events(:silly_outgoing_message_event), + info_request_events(:useful_incoming_message_event), + info_request_events(:another_useful_incoming_message_event), + ] + assigns[:xapian_users].results.map{|x| x[:model]}.should == [users(:bob_smith_user)] + assigns[:xapian_bodies].results.should == [] end it "should filter results based on end of URL being 'users'" do get :search, :combined => ['"bob"', "users"] assigns[:xapian_requests].should == nil - assigns[:xapian_users].results.size.should == 1 + assigns[:xapian_users].results.map{|x| x[:model]}.should == [users(:bob_smith_user)] assigns[:xapian_bodies].should == nil end it "should filter results based on end of URL being 'requests'" do get :search, :combined => ['"bob"', "requests"] - assigns[:xapian_requests].results.size.should == 2 + assigns[:xapian_requests].results.map{|x|x[:model]}.should =~ [ + info_request_events(:useless_outgoing_message_event), + info_request_events(:silly_outgoing_message_event), + info_request_events(:useful_incoming_message_event), + info_request_events(:another_useful_incoming_message_event), + ] assigns[:xapian_users].should == nil assigns[:xapian_bodies].should == nil end @@ -151,7 +188,7 @@ describe GeneralController, "when searching" do get :search, :combined => ['"quango"', "bodies"] assigns[:xapian_requests].should == nil assigns[:xapian_users].should == nil - assigns[:xapian_bodies].results.size.should == 1 + assigns[:xapian_bodies].results.map{|x|x[:model]}.should == [public_bodies(:geraldine_public_body)] end it "should show help when searching for nothing" do diff --git a/spec/controllers/public_body_controller_spec.rb b/spec/controllers/public_body_controller_spec.rb index 8182e1331..e6eca0781 100644 --- a/spec/controllers/public_body_controller_spec.rb +++ b/spec/controllers/public_body_controller_spec.rb @@ -4,7 +4,11 @@ require 'json' describe PublicBodyController, "when showing a body" do integrate_views - fixtures :public_bodies, :public_body_translations, :public_body_versions, :users, :info_requests, :raw_emails, :incoming_messages, :outgoing_messages, :comments, :info_request_events, :track_things + + before(:each) do + load_raw_emails_data + rebuild_xapian_index + end it "should be successful" do get :show, :url_name => "dfh", :view => 'all' @@ -21,11 +25,23 @@ describe PublicBodyController, "when showing a body" do assigns[:public_body].should == public_bodies(:humpadink_public_body) end - it "should assign the requests" do + it "should assign the requests (1)" do get :show, :url_name => "tgq", :view => 'all' - assigns[:xapian_requests].results.count.should == 2 + assigns[:xapian_requests].results.map{|x|x[:model].info_request}.should =~ InfoRequest.all( + :conditions => ["public_body_id = ?", public_bodies(:geraldine_public_body).id]) + end + + it "should assign the requests (2)" do get :show, :url_name => "tgq", :view => 'successful' - assigns[:xapian_requests].results.count.should == 0 + assigns[:xapian_requests].results.map{|x|x[:model].info_request}.should =~ InfoRequest.all( + :conditions => ["described_state = ? and public_body_id = ?", + "successful", public_bodies(:geraldine_public_body).id]) + end + + it "should assign the requests (3)" do + get :show, :url_name => "dfh", :view => 'all' + assigns[:xapian_requests].results.map{|x|x[:model].info_request}.should =~ InfoRequest.all( + :conditions => ["public_body_id = ?", public_bodies(:humpadink_public_body).id]) end it "should assign the body using different locale from that used for url_name" do @@ -43,9 +59,13 @@ describe PublicBodyController, "when showing a body" do end it "should redirect use to the relevant locale even when url_name is for a different locale" do - ActionController::Routing::Routes.filters.clear + old_filters = ActionController::Routing::Routes.filters + ActionController::Routing::Routes.filters = RoutingFilter::Chain.new + get :show, {:url_name => "edfh", :view => 'all'} response.should redirect_to "http://test.host/body/dfh" + + ActionController::Routing::Routes.filters = old_filters end it "should redirect to newest name if you use historic name of public body in URL" do @@ -61,7 +81,6 @@ end describe PublicBodyController, "when listing bodies" do integrate_views - fixtures :public_bodies, :public_body_translations, :public_body_versions, :users, :info_requests, :raw_emails, :incoming_messages, :outgoing_messages, :comments, :info_request_events, :track_things it "should be successful" do get :list @@ -70,25 +89,28 @@ describe PublicBodyController, "when listing bodies" do it "should list all bodies from default locale, even when there are no translations for selected locale" do PublicBody.with_locale(:en) do - english_only = PublicBody.new(:name => 'English only', + @english_only = PublicBody.new(:name => 'English only', :short_name => 'EO', :request_email => 'english@flourish.org', :last_edit_editor => 'test', :last_edit_comment => '') - english_only.save + @english_only.save end PublicBody.with_locale(:es) do get :list - assigns[:public_bodies].length.should == 3 + assigns[:public_bodies].include?(@english_only).should == true end end it "should list bodies in alphabetical order" do + # Note that they are alphabetised by localised name get :list response.should render_template('list') - assigns[:public_bodies].should == [ public_bodies(:humpadink_public_body), public_bodies(:geraldine_public_body) ] + assigns[:public_bodies].should == PublicBody.all( + :conditions => "id <> #{PublicBody.internal_admin_body.id}", + :order => "(select name from public_body_translations where public_body_id=public_bodies.id and locale='en')") assigns[:tag].should == "all" assigns[:description].should == "" end @@ -114,22 +136,23 @@ 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') - assigns[:public_bodies].should == [ public_bodies(:geraldine_public_body) ] + assigns[:public_bodies].should =~ PublicBody.all(:conditions => "id not in (#{public_bodies(:humpadink_public_body).id}, #{PublicBody.internal_admin_body.id})") get :list response.should render_template('list') - assigns[:public_bodies].count.should == 2 - + assigns[:public_bodies].should =~ PublicBody.all(:conditions => "id <> #{PublicBody.internal_admin_body.id}") end it "should list a machine tagged thing, should get it in both ways" do @@ -157,8 +180,6 @@ end describe PublicBodyController, "when showing JSON version for API" do - fixtures :public_bodies, :public_body_translations, :public_body_versions, :users, :info_requests, :raw_emails, :incoming_messages, :outgoing_messages, :comments, :info_request_events, :track_things - it "should be successful" do get :show, :url_name => "dfh", :format => "json", :view => 'all' @@ -172,38 +193,45 @@ describe PublicBodyController, "when showing JSON version for API" do end describe PublicBodyController, "when doing type ahead searches" do - fixtures :public_bodies, :public_body_translations, :public_body_versions, :users, :info_requests, :raw_emails, :incoming_messages, :outgoing_messages, :comments, :info_request_events, :track_things + + integrate_views + + before(:each) do + load_raw_emails_data + rebuild_xapian_index + end it "should return nothing for the empty query string" do - get :search_typeahead, :q => "" + get :search_typeahead, :query => "" response.should render_template('public_body/_search_ahead') assigns[:xapian_requests].should be_nil end it "should return a body matching the given keyword, but not users with a matching description" do - get :search_typeahead, :q => "Geraldine" + get :search_typeahead, :query => "Geraldine" response.should render_template('public_body/_search_ahead') + response.body.should include('search_ahead') assigns[:xapian_requests].results.size.should == 1 assigns[:xapian_requests].results[0][:model].name.should == public_bodies(:geraldine_public_body).name end it "should return all requests matching any of the given keywords" do - get :search_typeahead, :q => "Geraldine Humpadinking" + get :search_typeahead, :query => "Geraldine Humpadinking" response.should render_template('public_body/_search_ahead') - assigns[:xapian_requests].results.size.should == 2 - assigns[:xapian_requests].results[0][:model].name.should == public_bodies(:humpadink_public_body).name - assigns[:xapian_requests].results[1][:model].name.should == public_bodies(:geraldine_public_body).name + assigns[:xapian_requests].results.map{|x|x[:model]}.should =~ [ + public_bodies(:humpadink_public_body), + public_bodies(:geraldine_public_body), + ] end it "should return requests matching the given keywords in any of their locales" do - get :search_typeahead, :q => "baguette" # part of the spanish notes + get :search_typeahead, :query => "baguette" # part of the spanish notes response.should render_template('public_body/_search_ahead') - assigns[:xapian_requests].results.size.should == 1 - assigns[:xapian_requests].results[0][:model].name.should == public_bodies(:humpadink_public_body).name + assigns[:xapian_requests].results.map{|x|x[:model]}.should =~ [public_bodies(:humpadink_public_body)] end it "should not return matches for short words" do - get :search_typeahead, :q => "b" + get :search_typeahead, :query => "b" response.should render_template('public_body/_search_ahead') assigns[:xapian_requests].should be_nil end diff --git a/spec/controllers/request_controller_spec.rb b/spec/controllers/request_controller_spec.rb index 4994c2a8f..25dce3f22 100644 --- a/spec/controllers/request_controller_spec.rb +++ b/spec/controllers/request_controller_spec.rb @@ -4,58 +4,125 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') require 'json' describe RequestController, "when listing recent requests" do - fixtures :users, :public_bodies, :public_body_translations, :public_body_versions, :info_requests, :raw_emails, :incoming_messages, :outgoing_messages, :comments, :info_request_events, :track_things before(:each) do - load_raw_emails_data(raw_emails) + load_raw_emails_data rebuild_xapian_index end it "should be successful" do - get :list, :view => 'recent' + get :list, :view => 'all' response.should be_success end it "should render with 'list' template" do - get :list, :view => 'recent' + get :list, :view => 'all' response.should render_template('list') end it "should filter requests" do get :list, :view => 'all' - assigns[:list_results].size.should == 2 + assigns[:list_results].map(&:info_request).should =~ InfoRequest.all + + # default sort order is the request with the most recently created event first + assigns[:list_results].map(&:info_request).should == InfoRequest.all( + :order => "(select max(info_request_events.created_at) from info_request_events where info_request_events.info_request_id = info_requests.id) DESC") + get :list, :view => 'successful' - assigns[:list_results].size.should == 0 + assigns[:list_results].map(&:info_request).should =~ InfoRequest.all( + :conditions => "id in ( + select info_request_id + from info_request_events + where not exists ( + select * + from info_request_events later_events + where later_events.created_at > info_request_events.created_at + and later_events.info_request_id = info_request_events.info_request_id + and later_events.described_state is not null + ) + and info_request_events.described_state in ('successful', 'partially_successful') + )") end it "should filter requests by date" do + # The semantics of the search are that it finds any InfoRequest + # that has any InfoRequestEvent created in the specified range + get :list, :view => 'all', :request_date_before => '13/10/2007' - assigns[:list_results].size.should == 1 + assigns[:list_results].map(&:info_request).should =~ InfoRequest.all( + :conditions => "id in (select info_request_id from info_request_events where created_at < '2007-10-13'::date)") + get :list, :view => 'all', :request_date_after => '13/10/2007' - assigns[:list_results].size.should == 1 - get :list, :view => 'all', :request_date_after => '10/10/2007', :request_date_before => '01/01/2010' - assigns[:list_results].size.should == 2 + assigns[:list_results].map(&:info_request).should =~ InfoRequest.all( + :conditions => "id in (select info_request_id from info_request_events where created_at > '2007-10-13'::date)") + + get :list, :view => 'all', :request_date_after => '13/10/2007', :request_date_before => '01/11/2007' + assigns[:list_results].map(&:info_request).should =~ InfoRequest.all( + :conditions => "id in (select info_request_id from info_request_events where created_at between '2007-10-13'::date and '2007-11-01'::date)") + end + + it "should make a sane-sized cache tag" do + get :list, :view => 'all', :request_date_after => '13/10/2007', :request_date_before => '01/11/2007' + assigns[:cache_tag].size.should <= 32 + end + + it "should list internal_review requests as unresolved ones" do + get :list, :view => 'awaiting' + + # This doesn’t precisely duplicate the logic of the actual + # query, but it is close enough to give the same result with + # the current set of test data. + assigns[:list_results].should =~ InfoRequestEvent.all( + :conditions => "described_state in ( + 'waiting_response', 'waiting_clarification', + 'internal_review', 'gone_postal', 'error_message', 'requires_admin' + ) and not exists ( + select * + from info_request_events later_events + where later_events.created_at > info_request_events.created_at + and later_events.info_request_id = info_request_events.info_request_id + )") + + + get :list, :view => 'awaiting' + assigns[:list_results].map(&:info_request).include?(info_requests(:fancy_dog_request)).should == false + + event = info_request_events(:useless_incoming_message_event) + event.described_state = event.calculated_state = "internal_review" + event.save! + rebuild_xapian_index + + get :list, :view => 'awaiting' + assigns[:list_results].map(&:info_request).include?(info_requests(:fancy_dog_request)).should == true end it "should assign the first page of results" do xap_results = mock_model(ActsAsXapian::Search, :results => (1..25).to_a.map { |m| { :model => m } }, - :matches_estimated => 103) + :matches_estimated => 1000000) InfoRequest.should_receive(:full_search). - with([InfoRequestEvent]," variety:sent", "created_at", anything, anything, anything, anything). + with([InfoRequestEvent]," (variety:sent OR variety:followup_sent OR variety:response OR variety:comment)", "created_at", anything, anything, anything, anything). and_return(xap_results) - get :list, :view => 'recent' + get :list, :view => 'all' assigns[:list_results].size.should == 25 + assigns[:show_no_more_than].should == RequestController::MAX_RESULTS end + it "should return 404 for pages we don't want to serve up" do + xap_results = mock_model(ActsAsXapian::Search, + :results => (1..25).to_a.map { |m| { :model => m } }, + :matches_estimated => 1000000) + lambda { + get :list, :view => 'all', :page => 100 + }.should raise_error(ActiveRecord::RecordNotFound) + end + end describe RequestController, "when showing one request" do - fixtures :public_bodies, :public_body_translations, :public_body_versions, :users, :info_requests, :raw_emails, :incoming_messages, :outgoing_messages, :comments, :info_request_events, :track_things # all needed as integrating views - before(:each) do - load_raw_emails_data(raw_emails) + load_raw_emails_data end it "should be successful" do @@ -80,24 +147,40 @@ describe RequestController, "when showing one request" do describe 'when handling an update_status parameter' do - - before do - mock_request = mock_model(InfoRequest, :url_title => 'test_title', - :title => 'test title', - :null_object => true) - InfoRequest.stub!(:find_by_url_title).and_return(mock_request) - end - it 'should assign the "update status" flag to the view as true if the parameter is present' do - get :show, :url_title => 'test_title', :update_status => 1 + get :show, :url_title => 'why_do_you_have_such_a_fancy_dog', :update_status => 1 assigns[:update_status].should be_true end - it 'should assign the "update status" flag to the view as true if the parameter is present' do - get :show, :url_title => 'test_title' + it 'should assign the "update status" flag to the view as false if the parameter is not present' do + get :show, :url_title => 'why_do_you_have_such_a_fancy_dog' assigns[:update_status].should be_false end + it 'should require login' do + session[:user_id] = nil + get :show, :url_title => 'why_do_you_have_such_a_fancy_dog', :update_status => 1 + post_redirect = PostRedirect.get_last_post_redirect + response.should redirect_to(:controller => 'user', :action => 'signin', :token => post_redirect.token) + end + + it 'should work if logged in as the requester' do + session[:user_id] = users(:bob_smith_user).id + get :show, :url_title => 'why_do_you_have_such_a_fancy_dog', :update_status => 1 + response.should render_template "request/show" + end + + it 'should not work if logged in as not the requester' do + session[:user_id] = users(:silly_name_user).id + get :show, :url_title => 'why_do_you_have_such_a_fancy_dog', :update_status => 1 + response.should render_template "user/wrong_user" + end + + it 'should work if logged in as an admin user' do + session[:user_id] = users(:admin_user).id + get :show, :url_title => 'why_do_you_have_such_a_fancy_dog', :update_status => 1 + response.should render_template "request/show" + end end describe 'when handling incoming mail' do @@ -123,7 +206,8 @@ describe RequestController, "when showing one request" do it "should download attachments" do ir = info_requests(:fancy_dog_request) - ir.incoming_messages.each { |x| x.parse_raw_email! } + ir.incoming_messages.each { |x| x.parse_raw_email!(true) } + get :show, :url_title => 'why_do_you_have_such_a_fancy_dog' response.content_type.should == "text/html" size_before = assigns[:info_request_events].size @@ -134,10 +218,12 @@ describe RequestController, "when showing one request" do get :show, :url_title => 'why_do_you_have_such_a_fancy_dog' (assigns[:info_request_events].size - size_before).should == 1 ir.reload - get :get_attachment, :incoming_message_id => ir.incoming_messages[1].id, :id => ir.id, :part => 2, :file_name => ['hello.txt'] + + get :get_attachment, :incoming_message_id => ir.incoming_messages[1].id, :id => ir.id, :part => 2, :file_name => ['hello.txt'], :skip_cache => 1 response.content_type.should == "text/plain" response.should have_text(/Second hello/) - get :get_attachment, :incoming_message_id => ir.incoming_messages[1].id, :id => ir.id, :part => 3, :file_name => ['hello.txt'] + + get :get_attachment, :incoming_message_id => ir.incoming_messages[1].id, :id => ir.id, :part => 3, :file_name => ['hello.txt'], :skip_cache => 1 response.content_type.should == "text/plain" response.should have_text(/First hello/) end @@ -149,7 +235,7 @@ describe RequestController, "when showing one request" do response.should have_text(/tënde/u) end - it "should generate valid HTML verson of plain text attachments " do + it "should generate valid HTML verson of plain text attachments" do ir = info_requests(:fancy_dog_request) receive_incoming_mail('incoming-request-two-same-name.email', ir.incoming_email) ir.reload @@ -158,6 +244,71 @@ describe RequestController, "when showing one request" do response.should have_text(/Second hello/) end + # This is a regression test for a bug where URLs of this form were causing 500 errors + # instead of 404s. + # + # (Note that in fact only the integer-prefix of the URL part is used, so there are + # *some* “ugly URLs containing a request id that isn't an integer” that actually return + # a 200 response. The point is that IDs of this sort were triggering an error in the + # error-handling path, causing the wrong sort of error response to be returned in the + # case where the integer prefix referred to the wrong request.) + # + # https://github.com/sebbacon/alaveteli/issues/351 + it "should return 404 for ugly URLs containing a request id that isn't an integer" do + ir = info_requests(:fancy_dog_request) + receive_incoming_mail('incoming-request-two-same-name.email', ir.incoming_email) + ir.reload + ugly_id = "55195" + lambda { + get :get_attachment, :incoming_message_id => ir.incoming_messages[1].id, :id => ugly_id, :part => 2, :file_name => ['hello.txt.html'], :skip_cache => 1 + }.should raise_error(ActiveRecord::RecordNotFound) + + lambda { + get :get_attachment_as_html, :incoming_message_id => ir.incoming_messages[1].id, :id => ugly_id, :part => 2, :file_name => ['hello.txt'], :skip_cache => 1 + }.should raise_error(ActiveRecord::RecordNotFound) + end + it "should return 404 when incoming message and request ids don't match" do + ir = info_requests(:fancy_dog_request) + wrong_id = info_requests(:naughty_chicken_request).id + receive_incoming_mail('incoming-request-two-same-name.email', ir.incoming_email) + ir.reload + lambda { + get :get_attachment_as_html, :incoming_message_id => ir.incoming_messages[1].id, :id => wrong_id, :part => 2, :file_name => ['hello.txt.html'], :skip_cache => 1 + }.should raise_error(ActiveRecord::RecordNotFound) + end + it "should return 404 for ugly URLs contain a request id that isn't an integer, even if the integer prefix refers to an actual request" do + ir = info_requests(:fancy_dog_request) + receive_incoming_mail('incoming-request-two-same-name.email', ir.incoming_email) + ir.reload + ugly_id = "%d95" % [info_requests(:naughty_chicken_request).id] + + lambda { + get :get_attachment, :incoming_message_id => ir.incoming_messages[1].id, :id => ugly_id, :part => 2, :file_name => ['hello.txt.html'], :skip_cache => 1 + }.should raise_error(ActiveRecord::RecordNotFound) + + lambda { + get :get_attachment_as_html, :incoming_message_id => ir.incoming_messages[1].id, :id => ugly_id, :part => 2, :file_name => ['hello.txt'], :skip_cache => 1 + }.should raise_error(ActiveRecord::RecordNotFound) + end + it "should return 404 when incoming message and request ids don't match" do + ir = info_requests(:fancy_dog_request) + wrong_id = info_requests(:naughty_chicken_request).id + receive_incoming_mail('incoming-request-two-same-name.email', ir.incoming_email) + ir.reload + lambda { + get :get_attachment_as_html, :incoming_message_id => ir.incoming_messages[1].id, :id => wrong_id, :part => 2, :file_name => ['hello.txt.html'], :skip_cache => 1 + }.should raise_error(ActiveRecord::RecordNotFound) + end + + it "should generate valid HTML verson of PDF attachments " do + ir = info_requests(:fancy_dog_request) + receive_incoming_mail('incoming-request-pdf-attachment.email', ir.incoming_email) + ir.reload + get :get_attachment_as_html, :incoming_message_id => ir.incoming_messages[1].id, :id => ir.id, :part => 2, :file_name => ['fs_50379341.pdf.html'], :skip_cache => 1 + response.content_type.should == "text/html" + response.should have_text(/Walberswick Parish Council/) + end + it "should not cause a reparsing of the raw email, even when the result would be a 404 " do ir = info_requests(:fancy_dog_request) receive_incoming_mail('incoming-request-two-same-name.email', ir.incoming_email) @@ -205,7 +356,7 @@ describe RequestController, "when showing one request" do receive_incoming_mail('incoming-request-two-same-name.email', ir.incoming_email) lambda { - get :get_attachment, :incoming_message_id => ir.incoming_messages[1].id, :id => ir.id, :part => 2, + get :get_attachment, :incoming_message_id => ir.incoming_messages[1].id, :id => ir.id, :part => 2, :file_name => ['http://trying.to.hack'] }.should raise_error(ActiveRecord::RecordNotFound) end @@ -219,12 +370,16 @@ describe RequestController, "when showing one request" do censor_rule.last_edit_editor = "unknown" censor_rule.last_edit_comment = "none" ir.censor_rules << censor_rule - - receive_incoming_mail('incoming-request-two-same-name.email', ir.incoming_email) - - get :get_attachment, :incoming_message_id => ir.incoming_messages[1].id, :id => ir.id, :part => 2, :file_name => ['hello.txt'] - response.content_type.should == "text/plain" - response.should have_text(/xxxxxx hello/) + + begin + receive_incoming_mail('incoming-request-two-same-name.email', ir.incoming_email) + + get :get_attachment, :incoming_message_id => ir.incoming_messages[1].id, :id => ir.id, :part => 2, :file_name => ['hello.txt'], :skip_cache => 1 + response.content_type.should == "text/plain" + response.should have_text(/xxxxxx hello/) + ensure + ir.censor_rules.clear + end end it "should censor with rules on the user (rather than the request)" do @@ -237,12 +392,16 @@ describe RequestController, "when showing one request" do censor_rule.last_edit_comment = "none" ir.user.censor_rules << censor_rule - receive_incoming_mail('incoming-request-two-same-name.email', ir.incoming_email) - ir.reload + begin + receive_incoming_mail('incoming-request-two-same-name.email', ir.incoming_email) + ir.reload - get :get_attachment, :incoming_message_id => ir.incoming_messages[1].id, :id => ir.id, :part => 2, :file_name => ['hello.txt'], :skip_cache => 1 - response.content_type.should == "text/plain" - response.should have_text(/xxxxxx hello/) + get :get_attachment, :incoming_message_id => ir.incoming_messages[1].id, :id => ir.id, :part => 2, :file_name => ['hello.txt'], :skip_cache => 1 + response.content_type.should == "text/plain" + response.should have_text(/xxxxxx hello/) + ensure + ir.user.censor_rules.clear + end end it "should censor attachment names" do @@ -273,9 +432,12 @@ describe RequestController, "when showing one request" do censor_rule.last_edit_editor = "unknown" censor_rule.last_edit_comment = "none" ir.censor_rules << censor_rule - - get :show, :url_title => 'why_do_you_have_such_a_fancy_dog' - response.body.should have_tag("p.attachment strong", /goodbye.txt/m) + begin + get :show, :url_title => 'why_do_you_have_such_a_fancy_dog' + response.body.should have_tag("p.attachment strong", /goodbye.txt/m) + ensure + ir.censor_rules.clear + end end it "should make a zipfile available, which has a different URL when it changes" do @@ -287,7 +449,7 @@ describe RequestController, "when showing one request" do old_path = assigns[:url_path] response.location.should have_text(/#{assigns[:url_path]}$/) zipfile = Zip::ZipFile.open(File.join(File.dirname(__FILE__), "../../cache/zips", old_path)) { |zipfile| - zipfile.count.should == 2 + zipfile.count.should == 1 # just the message } receive_incoming_mail('incoming-request-two-same-name.email', ir.incoming_email) get :download_entire_request, :url_title => title @@ -295,25 +457,29 @@ describe RequestController, "when showing one request" do old_path = assigns[:url_path] response.location.should have_text(/#{assigns[:url_path]}$/) zipfile = Zip::ZipFile.open(File.join(File.dirname(__FILE__), "../../cache/zips", old_path)) { |zipfile| - zipfile.count.should == 2 + zipfile.count.should == 3 # the message plus two "hello.txt" files } + + # The path of the zip file is based on the hash of the timestamp of the last request + # in the thread, so we wait for a second to make sure this one will have a different + # timestamp than the previous. + sleep 1 receive_incoming_mail('incoming-request-attachment-unknown-extension.email', ir.incoming_email) get :download_entire_request, :url_title => title assigns[:url_path].should have_text(/#{title}.zip$/) + assigns[:url_path].should_not == old_path response.location.should have_text(/#{assigns[:url_path]}/) zipfile = Zip::ZipFile.open(File.join(File.dirname(__FILE__), "../../cache/zips", assigns[:url_path])) { |zipfile| - zipfile.count.should == 4 + zipfile.count.should == 5 # the message, two hello.txt, the unknown attachment, and its empty message } - assigns[:url_path].should_not == old_path end end end describe RequestController, "when changing prominence of a request" do - fixtures :public_bodies, :public_body_translations, :public_body_versions, :users, :info_requests, :raw_emails, :incoming_messages, :outgoing_messages, :info_request_events, :track_things # all needed as integrating views before(:each) do - load_raw_emails_data(raw_emails) + load_raw_emails_data end it "should not show hidden requests" do @@ -379,11 +545,11 @@ describe RequestController, "when changing prominence of a request" do ir.save! receive_incoming_mail('incoming-request-two-same-name.email', ir.incoming_email) - get :get_attachment, :incoming_message_id => ir.incoming_messages[1].id, :id => ir.id, :part => 2 + get :get_attachment, :incoming_message_id => ir.incoming_messages[1].id, :id => ir.id, :part => 2, :skip_cache => 1 response.content_type.should == "text/html" response.should_not have_text(/Second hello/) response.should render_template('request/hidden') - get :get_attachment, :incoming_message_id => ir.incoming_messages[1].id, :id => ir.id, :part => 3 + get :get_attachment, :incoming_message_id => ir.incoming_messages[1].id, :id => ir.id, :part => 3, :skip_cache => 1 response.content_type.should == "text/html" response.should_not have_text(/First hello/) response.should render_template('request/hidden') @@ -398,7 +564,6 @@ end # end describe RequestController, "when searching for an authority" do - fixtures :public_bodies, :users # Whether or not sign-in is required for this step is configurable, # so we make sure we're logged in, just in case @@ -411,7 +576,7 @@ describe RequestController, "when searching for an authority" do get :select_authority, :query => "" response.should render_template('select_authority') - assigns[:xapian_requests].results.size == 0 + assigns[:xapian_requests].should == nil end it "should return matching bodies" do @@ -422,11 +587,24 @@ describe RequestController, "when searching for an authority" do assigns[:xapian_requests].results.size == 1 assigns[:xapian_requests].results[0][:model].name.should == public_bodies(:geraldine_public_body).name end + + it "should not give an error when user users unintended search operators" do + for phrase in ["Marketing/PR activities - Aldborough E-Act Free Schoo", + "Request for communications between DCMS/Ed Vaizey and ICO from Jan 1st 2011 - May ", + "Bellevue Road Ryde Isle of Wight PO33 2AR - what is the", + "NHS Ayrshire & Arran", + " cardiff", + "Foo * bax", + "qux ~ quux"] + lambda { + get :select_authority, :query => phrase + }.should_not raise_error(StandardError) + end + end end describe RequestController, "when creating a new request" do integrate_views - fixtures :public_bodies, :public_body_translations, :public_body_versions, :users, :info_requests, :incoming_messages, :outgoing_messages, :comments, :info_request_events, :track_things before do @user = users(:bob_smith_user) @@ -555,6 +733,58 @@ describe RequestController, "when creating a new request" do response.should redirect_to(:action => 'show', :url_title => ir2.url_title) end + + it 'should respect the rate limit' do + # Try to create three requests in succession. + # (The limit set in config/test.yml is two.) + session[:user_id] = users(:robin_user) + + post :new, :info_request => { :public_body_id => @body.id, + :title => "What is the answer to the ultimate question?", :tag_string => "" }, + :outgoing_message => { :body => "Please supply the answer from your files." }, + :submitted_new_request => 1, :preview => 0 + response.should redirect_to(:action => 'show', :url_title => 'what_is_the_answer_to_the_ultima') + + + post :new, :info_request => { :public_body_id => @body.id, + :title => "Why did the chicken cross the road?", :tag_string => "" }, + :outgoing_message => { :body => "Please send me all the relevant documents you hold." }, + :submitted_new_request => 1, :preview => 0 + response.should redirect_to(:action => 'show', :url_title => 'why_did_the_chicken_cross_the_ro') + + post :new, :info_request => { :public_body_id => @body.id, + :title => "What's black and white and red all over?", :tag_string => "" }, + :outgoing_message => { :body => "Please send all minutes of meetings and email records that address this question." }, + :submitted_new_request => 1, :preview => 0 + response.should render_template('user/rate_limited') + end + + it 'should ignore the rate limit for specified users' do + # Try to create three requests in succession. + # (The limit set in config/test.yml is two.) + session[:user_id] = users(:robin_user) + users(:robin_user).no_limit = true + users(:robin_user).save! + + post :new, :info_request => { :public_body_id => @body.id, + :title => "What is the answer to the ultimate question?", :tag_string => "" }, + :outgoing_message => { :body => "Please supply the answer from your files." }, + :submitted_new_request => 1, :preview => 0 + response.should redirect_to(:action => 'show', :url_title => 'what_is_the_answer_to_the_ultima') + + + post :new, :info_request => { :public_body_id => @body.id, + :title => "Why did the chicken cross the road?", :tag_string => "" }, + :outgoing_message => { :body => "Please send me all the relevant documents you hold." }, + :submitted_new_request => 1, :preview => 0 + response.should redirect_to(:action => 'show', :url_title => 'why_did_the_chicken_cross_the_ro') + + post :new, :info_request => { :public_body_id => @body.id, + :title => "What's black and white and red all over?", :tag_string => "" }, + :outgoing_message => { :body => "Please send all minutes of meetings and email records that address this question." }, + :submitted_new_request => 1, :preview => 0 + response.should redirect_to(:action => 'show', :url_title => 'whats_black_and_white_and_red_al') + end end @@ -600,6 +830,7 @@ describe RequestController, "when making a new request" do it "should fail if user is banned" do @user.stub!(:can_file_requests?).and_return(false) + @user.stub!(:exceeded_limit?).and_return(false) @user.should_receive(:can_fail_html).and_return('FAIL!') session[:user_id] = @user.id get :new, :public_body_id => @body.id @@ -610,10 +841,9 @@ end describe RequestController, "when viewing an individual response for reply/followup" do integrate_views - fixtures :public_bodies, :public_body_translations, :public_body_versions, :users, :info_requests, :raw_emails, :incoming_messages, :outgoing_messages, :comments, :info_request_events, :track_things # all needed as integrating views before(:each) do - load_raw_emails_data(raw_emails) + load_raw_emails_data end it "should ask for login if you are logged in as wrong person" do @@ -657,13 +887,11 @@ end describe RequestController, "when classifying an information request" do - fixtures :public_bodies, :public_body_translations, :public_body_versions, :users, :info_requests, :raw_emails, :incoming_messages, :outgoing_messages, :comments, :info_request_events, :track_things # all needed as integrating views - before(:each) do @dog_request = info_requests(:fancy_dog_request) @dog_request.stub!(:is_old_unclassified?).and_return(false) InfoRequest.stub!(:find).and_return(@dog_request) - load_raw_emails_data(raw_emails) + load_raw_emails_data end def post_status(status) @@ -901,7 +1129,11 @@ describe RequestController, "when classifying an information request" do session[:user_id] = @request_owner.id @dog_request = info_requests(:fancy_dog_request) InfoRequest.stub!(:find).and_return(@dog_request) - ActionController::Routing::Routes.filters.clear + @old_filters = ActionController::Routing::Routes.filters + ActionController::Routing::Routes.filters = RoutingFilter::Chain.new + end + after do + ActionController::Routing::Routes.filters = @old_filters end def request_url @@ -993,10 +1225,9 @@ end describe RequestController, "when sending a followup message" do integrate_views - fixtures :public_bodies, :public_body_translations, :public_body_versions, :users, :info_requests, :raw_emails, :incoming_messages, :outgoing_messages, :comments, :info_request_events, :track_things # all needed as integrating views before(:each) do - load_raw_emails_data(raw_emails) + load_raw_emails_data end it "should require login" do @@ -1076,10 +1307,9 @@ end describe RequestController, "sending overdue request alerts" do integrate_views - fixtures :public_bodies, :public_body_translations, :public_body_versions, :users, :info_requests, :raw_emails, :incoming_messages, :outgoing_messages, :comments, :info_request_events, :track_things # all needed as integrating views before(:each) do - load_raw_emails_data(raw_emails) + load_raw_emails_data end it "should send an overdue alert mail to creators of overdue requests" do @@ -1090,8 +1320,8 @@ describe RequestController, "sending overdue request alerts" do RequestMailer.alert_overdue_requests deliveries = ActionMailer::Base.deliveries - deliveries.size.should == 1 - mail = deliveries[0] + deliveries.size.should == 2 + mail = deliveries[1] mail.body.should =~ /promptly, as normally/ mail.to_addrs.first.to_s.should == info_requests(:naughty_chicken_request).user.name_and_email @@ -1118,8 +1348,8 @@ describe RequestController, "sending overdue request alerts" do RequestMailer.alert_overdue_requests deliveries = ActionMailer::Base.deliveries - deliveries.size.should == 1 - mail = deliveries[0] + deliveries.size.should == 2 + mail = deliveries[1] mail.body.should =~ /promptly, as normally/ mail.to_addrs.first.to_s.should == info_requests(:naughty_chicken_request).user.name_and_email end @@ -1143,8 +1373,8 @@ describe RequestController, "sending overdue request alerts" do RequestMailer.alert_overdue_requests deliveries = ActionMailer::Base.deliveries - deliveries.size.should == 1 - mail = deliveries[0] + deliveries.size.should == 2 + mail = deliveries[1] mail.body.should =~ /required by law/ mail.to_addrs.first.to_s.should == info_requests(:naughty_chicken_request).user.name_and_email @@ -1164,10 +1394,9 @@ end describe RequestController, "sending unclassified new response reminder alerts" do integrate_views - fixtures :public_bodies, :public_body_translations, :public_body_versions, :users, :info_requests, :raw_emails, :incoming_messages, :outgoing_messages, :comments, :info_request_events, :track_things # all needed as integrating views before(:each) do - load_raw_emails_data(raw_emails) + load_raw_emails_data end it "should send an alert" do @@ -1195,9 +1424,8 @@ end describe RequestController, "clarification required alerts" do integrate_views - fixtures :public_bodies, :public_body_translations, :public_body_versions, :users, :info_requests, :raw_emails, :incoming_messages, :outgoing_messages, :comments, :info_request_events, :track_things # all needed as integrating views before(:each) do - load_raw_emails_data(raw_emails) + load_raw_emails_data end it "should send an alert" do @@ -1249,9 +1477,8 @@ end describe RequestController, "comment alerts" do integrate_views - fixtures :public_bodies, :public_body_translations, :public_body_versions, :users, :info_requests, :raw_emails, :incoming_messages, :outgoing_messages, :comments, :info_request_events, :track_things # all needed as integrating views before(:each) do - load_raw_emails_data(raw_emails) + load_raw_emails_data end it "should send an alert (once and once only)" do @@ -1324,9 +1551,8 @@ end describe RequestController, "when viewing comments" do integrate_views - fixtures :users, :info_requests, :raw_emails, :incoming_messages, :outgoing_messages, :comments, :info_request_events, :track_things before(:each) do - load_raw_emails_data(raw_emails) + load_raw_emails_data end it "should link to the user who submitted it" do @@ -1348,7 +1574,6 @@ end describe RequestController, "authority uploads a response from the web interface" do integrate_views - fixtures :public_bodies, :public_body_translations, :public_body_versions, :users, :info_requests, :incoming_messages, :outgoing_messages, :comments, :info_request_events, :track_things before(:each) do # domain after the @ is used for authentication of FOI officers, so to test it @@ -1434,11 +1659,9 @@ describe RequestController, "authority uploads a response from the web interface end describe RequestController, "when showing JSON version for API" do - - fixtures :public_bodies, :public_body_translations, :public_body_versions, :users, :info_requests, :raw_emails, :incoming_messages, :outgoing_messages, :comments, :info_request_events, :track_things before(:each) do - load_raw_emails_data(raw_emails) + load_raw_emails_data end it "should return data in JSON form" do @@ -1455,7 +1678,8 @@ describe RequestController, "when showing JSON version for API" do end describe RequestController, "when doing type ahead searches" do - fixtures :public_bodies, :public_body_translations, :public_body_versions, :users, :info_requests, :raw_emails, :incoming_messages, :outgoing_messages, :comments, :info_request_events, :track_things + + integrate_views it "should return nothing for the empty query string" do get :search_typeahead, :q => "" @@ -1473,16 +1697,44 @@ describe RequestController, "when doing type ahead searches" do it "should return all requests matching any of the given keywords" do get :search_typeahead, :q => "money dog" response.should render_template('request/_search_ahead.rhtml') - assigns[:xapian_requests].results.size.should == 2 - assigns[:xapian_requests].results[0][:model].title.should == info_requests(:fancy_dog_request).title - assigns[:xapian_requests].results[1][:model].title.should == info_requests(:naughty_chicken_request).title + assigns[:xapian_requests].results.map{|x|x[:model].info_request}.should =~ [ + info_requests(:fancy_dog_request), + info_requests(:naughty_chicken_request), + info_requests(:another_boring_request), + ] end - it "should not return matches for short words" do + it "should not return matches for short words" do get :search_typeahead, :q => "a" response.should render_template('request/_search_ahead.rhtml') assigns[:xapian_requests].should be_nil end + + it "should do partial matches for longer words" do + get :search_typeahead, :q => "chick" + response.should render_template('request/_search_ahead.rhtml') + assigns[:xapian_requests].results.size.should ==1 + end + + it "should not give an error when user users unintended search operators" do + for phrase in ["Marketing/PR activities - Aldborough E-Act Free Schoo", + "Request for communications between DCMS/Ed Vaizey and ICO from Jan 1st 2011 - May ", + "Bellevue Road Ryde Isle of Wight PO33 2AR - what is the", + "NHS Ayrshire & Arran", + "uda ( units of dent", + "frob * baz", + "bar ~ qux"] + lambda { + get :search_typeahead, :q => phrase + }.should_not raise_error(StandardError) + end + end + + it "should return all requests matching any of the given keywords" do + get :search_typeahead, :q => "dog -chicken" + assigns[:xapian_requests].results.size.should == 1 + end + end diff --git a/spec/controllers/request_game_controller_spec.rb b/spec/controllers/request_game_controller_spec.rb index cc0808ef3..7247cd388 100644 --- a/spec/controllers/request_game_controller_spec.rb +++ b/spec/controllers/request_game_controller_spec.rb @@ -1,10 +1,8 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') describe RequestGameController, "when playing the game" do - - fixtures :public_bodies, :public_body_translations, :public_body_versions, :users, :info_requests, :raw_emails, :incoming_messages, :outgoing_messages, :comments, :info_request_events, :track_things # all needed as integrating views before(:each) do - load_raw_emails_data(raw_emails) + load_raw_emails_data end it "should show the game homepage" do diff --git a/spec/controllers/track_controller_spec.rb b/spec/controllers/track_controller_spec.rb index 90d13495f..38a447640 100644 --- a/spec/controllers/track_controller_spec.rb +++ b/spec/controllers/track_controller_spec.rb @@ -36,17 +36,18 @@ end describe TrackController, "when sending alerts for a track" do integrate_views - fixtures :public_bodies, :public_body_translations, :public_body_versions, :users, :info_requests, :raw_emails, :incoming_messages, :outgoing_messages, :comments, :info_request_events, :track_things, :track_things_sent_emails include LinkToHelper # for main_url before(:each) do - load_raw_emails_data(raw_emails) + load_raw_emails_data rebuild_xapian_index end it "should send alerts" do # Don't do clever locale-insertion-unto-URL stuff - ActionController::Routing::Routes.filters.clear + old_filters = ActionController::Routing::Routes.filters + ActionController::Routing::Routes.filters = RoutingFilter::Chain.new + # set the time the comment event happened at to within the last week ire = info_request_events(:silly_comment_event) ire.created_at = Time.now - 3.days @@ -91,6 +92,9 @@ describe TrackController, "when sending alerts for a track" do TrackMailer.alert_tracks deliveries = ActionMailer::Base.deliveries deliveries.size.should == 0 + + # Restore the routing filters + ActionController::Routing::Routes.filters = old_filters end it "should send localised alerts" do @@ -110,10 +114,9 @@ end describe TrackController, "when viewing RSS feed for a track" do integrate_views - fixtures :public_bodies, :public_body_translations, :public_body_versions, :users, :info_requests, :raw_emails, :incoming_messages, :outgoing_messages, :comments, :info_request_events, :track_things before(:each) do - load_raw_emails_data(raw_emails) + load_raw_emails_data rebuild_xapian_index end @@ -136,10 +139,9 @@ end describe TrackController, "when viewing JSON version of a track feed" do integrate_views - fixtures :public_bodies, :public_body_translations, :public_body_versions, :users, :info_requests, :raw_emails, :incoming_messages, :outgoing_messages, :comments, :info_request_events, :track_things before(:each) do - load_raw_emails_data(raw_emails) + load_raw_emails_data rebuild_xapian_index end diff --git a/spec/controllers/user_controller_spec.rb b/spec/controllers/user_controller_spec.rb index 399b275a7..1a701ad43 100644 --- a/spec/controllers/user_controller_spec.rb +++ b/spec/controllers/user_controller_spec.rb @@ -8,9 +8,9 @@ require 'json' describe UserController, "when showing a user" do integrate_views - fixtures :users, :public_bodies, :public_body_translations, :public_body_versions, :info_requests, :raw_emails, :incoming_messages, :outgoing_messages, :comments, :info_request_events, :track_things before(:each) do - load_raw_emails_data(raw_emails) + load_raw_emails_data + rebuild_xapian_index end it "should be successful" do @@ -28,6 +28,16 @@ describe UserController, "when showing a user" do response.should render_template('show') end + it "should distinguish between 'my profile' and 'my requests' for logged in users" do + session[:user_id] = users(:bob_smith_user).id + get :show, :url_name => "bob_smith", :view => 'requests' + response.body.should_not include("Change your password") + response.body.should match(/Your [0-9]+ Freedom of Information requests/) + get :show, :url_name => "bob_smith", :view => 'profile' + response.body.should include("Change your password") + response.body.should_not match(/Your [0-9]+ Freedom of Information requests/) + end + it "should assign the user" do get :show, :url_name => "bob_smith" assigns[:display_user].should == users(:bob_smith_user) @@ -35,22 +45,28 @@ describe UserController, "when showing a user" do it "should search the user's contributions" do get :show, :url_name => "bob_smith" - assigns[:xapian_requests].results.count.should == 2 + assigns[:xapian_requests].results.map{|x|x[:model].info_request}.should =~ InfoRequest.all( + :conditions => "user_id = #{users(:bob_smith_user).id}") + get :show, :url_name => "bob_smith", :user_query => "money" - assigns[:xapian_requests].results.count.should == 1 + assigns[:xapian_requests].results.map{|x|x[:model].info_request}.should =~ [ + info_requests(:naughty_chicken_request), + info_requests(:another_boring_request), + ] end -# Error handling not quite good enough for this yet -# it "should not show unconfirmed users" do -# get :show, :url_name => "silly_emnameem" -# assigns[:display_users].should == [ users(:silly_name_user) ] -# end + it "should not show unconfirmed users" do + begin + get :show, :url_name => "unconfirmed_user" + rescue => e + end + e.should be_an_instance_of(ActiveRecord::RecordNotFound) + end end describe UserController, "when signing in" do integrate_views - fixtures :users def get_last_postredirect post_redirects = PostRedirect.find_by_sql("select * from post_redirects order by id desc limit 1") @@ -86,7 +102,9 @@ describe UserController, "when signing in" do end it "should log in when you give right email/password, and redirect to where you were" do - ActionController::Routing::Routes.filters.clear + old_filters = ActionController::Routing::Routes.filters + ActionController::Routing::Routes.filters = RoutingFilter::Chain.new + get :signin, :r => "/list" response.should render_template('sign') post_redirect = get_last_postredirect @@ -97,6 +115,26 @@ describe UserController, "when signing in" do # response doesn't contain /en/ but redirect_to does... response.should redirect_to(:controller => 'request', :action => 'list', :post_redirect => 1) response.should_not send_email + + ActionController::Routing::Routes.filters = old_filters + end + + it "should not log you in if you use an invalid PostRedirect token, and shouldn't give 500 error either" do + old_filters = ActionController::Routing::Routes.filters + ActionController::Routing::Routes.filters = RoutingFilter::Chain.new + + post_redirect = "something invalid" + lambda { + post :signin, { :user_signin => { :email => 'bob@localhost', :password => 'jonespassword' }, + :token => post_redirect + } + }.should_not raise_error(NoMethodError) + post :signin, { :user_signin => { :email => 'bob@localhost', :password => 'jonespassword' }, + :token => post_redirect } + response.should render_template('sign') + assigns[:post_redirect].should == nil + + ActionController::Routing::Routes.filters = old_filters end # No idea how to test this in the test framework :( @@ -120,7 +158,9 @@ describe UserController, "when signing in" do end it "should confirm your email, log you in and redirect you to where you were after you click an email link" do - ActionController::Routing::Routes.filters.clear + old_filters = ActionController::Routing::Routes.filters + ActionController::Routing::Routes.filters = RoutingFilter::Chain.new + get :signin, :r => "/list" post_redirect = get_last_postredirect @@ -146,13 +186,14 @@ describe UserController, "when signing in" do get :confirm, :email_token => post_redirect.email_token session[:user_id].should == users(:unconfirmed_user).id response.should redirect_to(:controller => 'request', :action => 'list', :post_redirect => 1) + + ActionController::Routing::Routes.filters = old_filters end end describe UserController, "when signing up" do integrate_views - fixtures :users it "should be an error if you type the password differently each time" do post :signup, { :user_signup => { :email => 'new@localhost', :name => 'New Person', @@ -210,7 +251,6 @@ end describe UserController, "when signing out" do integrate_views - fixtures :users it "should log you out and redirect to the home page" do session[:user_id] = users(:bob_smith_user).id @@ -220,18 +260,21 @@ describe UserController, "when signing out" do end it "should log you out and redirect you to where you were" do - ActionController::Routing::Routes.filters.clear + old_filters = ActionController::Routing::Routes.filters + ActionController::Routing::Routes.filters = RoutingFilter::Chain.new + session[:user_id] = users(:bob_smith_user).id get :signout, :r => '/list' session[:user_id].should be_nil response.should redirect_to(:controller => 'request', :action => 'list') + + ActionController::Routing::Routes.filters = old_filters end end describe UserController, "when sending another user a message" do integrate_views - fixtures :users it "should redirect to signin page if you go to the contact form and aren't signed in" do get :contact, :id => users(:silly_name_user) @@ -269,7 +312,6 @@ end describe UserController, "when changing password" do integrate_views - fixtures :users it "should show the email form when not logged in" do get :signchangepassword @@ -340,7 +382,6 @@ end describe UserController, "when changing email address" do integrate_views - fixtures :users it "should require login" do get :signchangeemail @@ -486,7 +527,6 @@ end describe UserController, "when using profile photos" do integrate_views - fixtures :users before do @user = users(:bob_smith_user) @@ -502,6 +542,13 @@ describe UserController, "when using profile photos" do post :set_profile_photo, { :id => @user.id, :file => @uploadedfile, :submitted_draft_profile_photo => 1, :automatically_crop => 1 } end + it "should return a 404 not a 500 when a profile photo has not been set" do + @user.profile_photo.should be_nil + lambda { + get :get_profile_photo, {:url_name => @user.url_name } + }.should raise_error(ActiveRecord::RecordNotFound) + end + it "should let you change profile photo if you're logged in as the user" do @user.profile_photo.should be_nil session[:user_id] = @user.id @@ -535,8 +582,6 @@ describe UserController, "when using profile photos" do end describe UserController, "when showing JSON version for API" do - - fixtures :users it "should be successful" do get :show, :url_name => "bob_smith", :format => "json" diff --git a/spec/fixtures/comments.yml b/spec/fixtures/comments.yml index ed1925bfa..b73385a55 100644 --- a/spec/fixtures/comments.yml +++ b/spec/fixtures/comments.yml @@ -8,4 +8,13 @@ silly_comment: user_id: "2" created_at: 2008-08-13 01:25:17.486939 +sensible_comment: + id: 2 + body: This a wise and helpful annotation. + info_request_id: 106 + visible: t + comment_type: request + user_id: 1 + created_at: 2008-08-13 01:25:17.486939 + updated_at: 2008-08-13 01:25:17.486939 diff --git a/spec/fixtures/files/incoming-request-pdf-attachment.email b/spec/fixtures/files/incoming-request-pdf-attachment.email new file mode 100644 index 000000000..1163725ec --- /dev/null +++ b/spec/fixtures/files/incoming-request-pdf-attachment.email @@ -0,0 +1,543 @@ +MIME-Version: 1.0
+Received: by 10.100.197.1 with HTTP; Sun, 8 Jan 2012 01:16:15 -0800 (PST)
+Reply-To: bar@frob.com
+Date: Sun, 8 Jan 2012 09:16:15 +0000
+Delivered-To: seb.bacon@gmail.com
+Message-ID: <CACwNqZkZDZiLtxD=CmE55kBGCBgnDVS1YGtrdC=tOhz+8dpokA@mail.gmail.com>
+Subject: Hello
+From: EMAIL_FROM
+To: FOI Person <EMAIL_TO>
+Content-Type: multipart/mixed; boundary=0016e644b8d0e3913b04b600bbe4
+
+--0016e644b8d0e3913b04b600bbe4
+Content-Type: text/plain; charset=ISO-8859-1
+
+PDF attachment enclosed.
+
+--0016e644b8d0e3913b04b600bbe4
+Content-Type: application/pdf; name="fs_50379341.pdf"
+Content-Disposition: attachment; filename="fs_50379341.pdf"
+Content-Transfer-Encoding: base64
+X-Attachment-Id: f_gx5ul6jw0
+
+JVBERi0xLjUNJeLjz9MNCjIwNCAwIG9iag08PC9MaW5lYXJpemVkIDEvTCAyOTYwNy9PIDIwNi9F
+IDExNTE2L04gNS9UIDI5MjMzL0ggWyA0NjUgMjQwXT4+DWVuZG9iag0gICAgICAgICAgICAgICAg
+DQoyMTEgMCBvYmoNPDwvRGVjb2RlUGFybXM8PC9Db2x1bW5zIDQvUHJlZGljdG9yIDEyPj4vRmls
+dGVyL0ZsYXRlRGVjb2RlL0lEWzxBRjMzQjg1MTFGOUJDMjI5RDlFMDM1QzI3RTBFODIyRT48MzM0
+QjkwQThFRDQ0OTg0MUJDMUM3QTE5NkM3NzNDRDg+XS9JbmRleFsyMDQgMjFdL0luZm8gMjAzIDAg
+Ui9MZW5ndGggNTcvUHJldiAyOTIzNC9Sb290IDIwNSAwIFIvU2l6ZSAyMjUvVHlwZS9YUmVmL1db
+MSAyIDFdPj5zdHJlYW0NCmjeYmJkEGBgYmDaCCJ8gQRjCJBgeQ4k2BOAhNA5IHHvLwMTI0M0kMXA
+wEgG8Z+R6StAgAEA0IkH/g0KZW5kc3RyZWFtDWVuZG9iag1zdGFydHhyZWYNCjANCiUlRU9GDQog
+ICAgICAgIA0KMjI0IDAgb2JqDTw8L0MgMTQxL0ZpbHRlci9GbGF0ZURlY29kZS9JIDE2NC9MIDEy
+NS9MZW5ndGggMTQwL08gMTA5L1MgNzQ+PnN0cmVhbQ0KaN5iYGBgYmBglgORrM4MfAwIwMfADIQs
+DBwHHPrW+F8MPsDA9aTIgkHq4Tpx3gL2BvYG9YYKhgq4FFAHFwND1W8gzQrEbCAjGEMYeBkYlpyR
+ZF8yo/UCSISbgaH2MEgGiI6DLWHoug3hM3QBMQ8DQz2IBjqHOxAszrwASAkyMMy5CdXmDhBgAPuw
+HeMNCmVuZHN0cmVhbQ1lbmRvYmoNMjA1IDAgb2JqDTw8L0xhc3RNb2RpZmllZChEOjIwMTExMTIy
+MTUwMTQzKS9NYXJrSW5mbzw8L0xldHRlcnNwYWNlRmxhZ3MgMC9NYXJrZWQgdHJ1ZT4+L01ldGFk
+YXRhIDE1IDAgUi9PQ1Byb3BlcnRpZXM8PC9EPDwvT3JkZXJbXS9SQkdyb3Vwc1tdPj4vT0NHc1sy
+MTIgMCBSXT4+L091dGxpbmVzIDI4IDAgUi9QYWdlTGFiZWxzIDIwMCAwIFIvUGFnZUxheW91dC9P
+bmVDb2x1bW4vUGFnZXMgMjAyIDAgUi9QaWVjZUluZm88PC9NYXJrZWRQREY8PC9MYXN0TW9kaWZp
+ZWQoRDoyMDExMTEyMjE1MDE0Myk+Pj4+L1N0cnVjdFRyZWVSb290IDM3IDAgUi9UeXBlL0NhdGFs
+b2c+Pg1lbmRvYmoNMjA2IDAgb2JqDTw8L0NvbnRlbnRzIDIwOCAwIFIvQ3JvcEJveFswIDAgNTk1
+IDg0Ml0vTWVkaWFCb3hbMCAwIDU5NSA4NDJdL1BhcmVudCAyMDIgMCBSL1Jlc291cmNlczw8L0Nv
+bG9yU3BhY2U8PC9DUzAgMjEzIDAgUj4+L0V4dEdTdGF0ZTw8L0dTMCAyMTQgMCBSPj4vRm9udDw8
+L1RUMCAyMTYgMCBSL1RUMSAyMTggMCBSL1RUMiAyMjAgMCBSL1RUMyAyMjIgMCBSPj4vUHJvY1Nl
+dFsvUERGL1RleHQvSW1hZ2VDXS9Qcm9wZXJ0aWVzPDwvTUMwIDIyMyAwIFI+Pi9YT2JqZWN0PDwv
+SW0wIDIwOSAwIFI+Pj4+L1JvdGF0ZSAwL1N0cnVjdFBhcmVudHMgMC9UYWJzL1MvVHlwZS9QYWdl
+Pj4NZW5kb2JqDTIwNyAwIG9iag08PC9GaWx0ZXIvRmxhdGVEZWNvZGUvRmlyc3QgMTAwL0xlbmd0
+aCA5MDEvTiAxMi9UeXBlL09ialN0bT4+c3RyZWFtDQpo3qRW227bOBDVp/AxeXAp3kmgMOA4cRJg
+3QbrtCkQ5IG1GUeoLAWyim1/fncPKduRi6ZtHAv0kHPhcEZnhuKMk5xwJggzDFQS5uJaEa4i1UQq
+B2qIkxbUEsYUhMwRxi04PCdM5QITBlNjMOFRjM04uAo7vn1L3/lVOLoIfhGaSV23oTmm198fA30/
+Pqcf1n4ZoDNugm/r5rK6r59WR//+l42yedZkdfY581mbkewqO80m2RSrL1mAhGQue5Mx0HtoxfVN
+ootjOvv6uY1+Rk37T918GQ7pFZydlWEVqhZetvKLyTD9bunleHzi12GBGHJk5u87aL2/Ive+XOO4
+V1PC6Gy0Wc6mJH+T8y6Us2/t+az1baD1YycfDmE7Ws/hirA8V3TsHy9CsXxIy5yehk424Lmjk9Iv
+10RwOqmr9uSk/nY7wAuAyBAmpUkWd0k48aui/H70MTQLX/njxIv5pRtOYszaJrTzB/qubla+TKyb
+zrWE58vWl8V8VC3LQHI6a8PqI3GbOKJqPFlTPCL/9FPvxCmgmJ2os3N3Vs3rRVEt6U1Rjap1sVtP
+imbdjh98sw3raduEMGSX/uU3Kkzq3du4br6GdJbdgbD3on1Y3woV4bp9DDf4l0qmETlCd/Mt1UL/
+0djad0+MlWgLcwuxs8SgNrTgRBmFOYZiRALwUsUolIrHMKgPYw3RKAZYO9XtgAqKWzrreg62j86x
+L8pE8Q11msQQ41wLlI9BKFKCz9PcmY6vgYqkgyGRhGgvnEyyqGtRp5HGkb/w4drd9ZHrfgVcxn4G
+XK0VGQiONhETCRO9h9xRU/iyh9u0nl4fiFtrX4jbrbsDcWv2cQuV38OWG3v32m6AVw8R+q/JX9IN
+Bid1ufhNas0zqWVGH9YTOqcHJtgd1Bjkj0hXUqTR5xnGdqO/fprJfH8fY3RqNJJYkSoWTdlCzwpU
+nUyy1Bu6+9GiUVtoGBH9GsuxZ7Sy6ZZluDF/1gS0RbtwRNmO6ti7cInGuYFhF5qGmzhjubKJrWOv
+ieoY0uE0Dr1A6U6GMzjj0nnZM3XOcumebQJC8P0mwPQvmsAOr7KH1/gdMYjlwjh6oWN8D6/noW6W
+RR+vG86r8KpfeoftOT0Mr5z9gFf2J3jlexfOax4rXreTEjEAZba4F72TabzDeD1uNPGVKJzpgIEv
+tzWKlafgN99y09Ph8H8BBgBWKcQSDQplbmRzdHJlYW0NZW5kb2JqDTIwOCAwIG9iag08PC9GaWx0
+ZXIvRmxhdGVEZWNvZGUvTGVuZ3RoIDE4MTY+PnN0cmVhbQ0KSIm8V11v47YSfdevmEe5iCWSkih5
+URTIR/c2BbbJbnyxD9480BId68aWvBIdb/79HVIfph0pLYqiSBBLijlzZuacmdF3h0ASMohmkUcY
+TJOQegmHSjpff4LC+e4QjwSgn86Sky/hrf6S+Y7/nwcCT7VDw9AL6YwQHgDBH0oSCEPiBcFsNsNn
+cRBCunX82y2Bm9L57PiXlcpXIlXw88/+pVIiXcsMFv683MGjf3VV/oAFZx4ei2foMkAbjHKPJ2EM
+CeFeyBDco/+wX6rXnQT/NykyWYE/N3f34ikvhMrLAn755ermGtDjZ+dq7vh31+B/uiZgHnbo/fkc
+IcN85UwxaELwMgVzSSOYH4CyJigGHaSwATDfOu4XuZKVLFL5AeDjQ0SCeBaEFCbz/zm/fkInv86b
+T+3dCrrFha5p45pop2TQHU+wMq27o2H/Xufu0/XtDX75aI615nQg3NjUccTGcKCLZ2ybKxpE3oxD
+jIUinf2PlZRZuYVyBbfFqqy2TRovETRDi/DN/Xh3e/ltMoiDWjiCN2FRL+LIIepRhmnNRmJhnQ0T
+QXwsRaiNTBE4p8YIclcbuZFpXmuIRanyVA7aDCxcZDzdbBZ7HPgs8DDUd9Idvk33lM48TiINjNF3
+oou6o9NjgZrwmMZCegM3zsK9EUqzajJlASGu/uT8+EkJ/FG+yMmUu9slcp8RirR7nP/+xinvU9oH
+Pf9pBGB8CjDoAWqs5tzCvd8vN3kKl5Np6O4nzFXrUl9WeJmrV335YTINXNDQacRC96vYIML6kKfP
+cC+qvF7Ddbkv0nwDw4iTUxRMo2Aej5KwA3+ZZZWs6w8miHPF8CD0kqQpYeSxhnVtXRYYN2M8QngP
+UtS7SrwOY5gNlMpUKtAYuBcHyYnZT/lms8pNPTYZfClFNhIcJWM5btqNDs/O2LDU6ImRY8vCztvV
+6aHcq/VBAzL12UyoO4qpl11zcr9alZvnyVSnafhAcEKqBkTn2r29x2v+35th6KF1FCVN2Z/KhkYn
+XYE1PJ4yL2ZaKscmYLddTjzkS5hQj+NHHHgRNj8vNONrZfqx5YC/bRHTYwc6J1gYYTPrJgD1BiHH
+MNzjqVZgF6jVkPrArFyy5rsLd76WkJbb3UbgYCsUiPoZ5+WJribT2BVY4hN5fUNx6pPmDru2Kpty
+Huec3XLcXVW+5JmE3Gr9+PuCmi33NeATJTXs8zlJmjmZeHHcRlfVaCTd7LO8eAIbA2Osxht0giNG
+2zozFbKGFMaWra+0LLJ9qi7wcFVJTeh6h4/06IV6v9zmGlsf23kmaYzLSNSCy3QeLFAXbxGaKNtD
+FjtrJQoTUlnhvlFfAN6CyF66yWNnI7Q8tok9d+yNiPus/8V93+4hsR4SG6bf7G/Qz1p8Yot+hn32
+NnBdbrd5rQUnqyZdWSfAvMb4hLKDhCzP9HS2EsTOxrppOobfr3DI1RpqmWpPNdAL3S9FodmdaVGV
+K1PkkU0t8XBV7URjQOh1BQ76+BoHpysLlL8hjiFmU41x2kxbi6dEbHU44W6hbaomB5X8vpf4rEYR
+Kg/ma8wF/i5lKvY1akr1iehkpn2bU7VCajQo3g5c11LjBRIPBApyg6YqudrXYoMm+8xScwg35ain
+nt6KLkxW8wKXBDiU1bOOPROv9YgGm+pPWzMW/SuZyvylk3QL3YNhFjMyyuLAJnAwSGBG/yUCtz3y
+hNMTXSZpUblPUtR7QIBtfTqer0WN5w7Qi11AIQ8t38bJj6tj0gWFPOk7RN/tLXrpbL9TMGPJ5upv
+ErISAzH6KfWuZuzklTxRqPYpniXq7BWQi7vaGxn7jA28ahgYQTeOM/1OZKCa5thEX8uB0Ywo9fvH
+n4xmNrC9nxPqfD7TJEIH7XwOh/kV/nP8Wrh3KC0Od6lqti3mths5ubCKOdRmmnXNFuzCtVsLHCpk
+4tnYMIk9WguPnBzVbddk7MkudN+u0ypfmn/ATlTiqRK7NVBvWNHRX1N0NJxx/s9tRO1C1GSjbegY
+BAbFzFvRdmlUctZMsZkHrOuLbYE8uFXIeaGTY+Seq/cU1lg420tqVHtlzr/VLVayle5owdBo2OVA
+6VIvJbzIH7pIuHQ1ItpJjXBkX2DxaF0Y1bat2vDh2iR/ozbWi8vsbW2Oy+qRfQIXhOLdFTLGvbqr
+UFUIXdyXHJsoVpZ2pe0r906dGjuWBEYJg9jf6c34Isl6YZ65vzVqb8nzwWqY2OH8y0rlK5EqneJL
+pUS6RncL/6pUqtzCo391Vf6ARfs6gWgpDyAgkcc51gsfU/168eg/7JfqdSfB/1hiH6jAn5u7e/GE
+uTUq7up2dw1YSwLmTrfQY7FG+2TU1XHbVhgnCJvp11xqkkYNV+bOdycgSCSDlHP8P1rA1IS6X3+F
+4tTd0Ul7KCJNNL0XtNjkSf/57PxfgAEA+xIfxA0KZW5kc3RyZWFtDWVuZG9iag0yMDkgMCBvYmoN
+PDwvQml0c1BlckNvbXBvbmVudCA4L0NvbG9yU3BhY2UgMjEzIDAgUi9GaWx0ZXIvRENURGVjb2Rl
+L0hlaWdodCAyMjUvTGVuZ3RoIDQ0MDIvU3VidHlwZS9JbWFnZS9UeXBlL1hPYmplY3QvV2lkdGgg
+MzAxPj5zdHJlYW0NCv/Y/+4ADkFkb2JlAGSAAAAAAf/bAIQADAgICAkIDAkJDBELCgsRFQ8MDA8V
+GBMTFRMTGBcSFBQUFBIXFxscHhwbFyQkJyckJDUzMzM1Ozs7Ozs7Ozs7OwENCwsNDg0QDg4QFA4P
+DhQUEBEREBQdFBQVFBQdJRoXFxcXGiUgIx4eHiMgKCglJSgoMjIwMjI7Ozs7Ozs7Ozs7/8AAEQgA
+4QEtAwEiAAIRAQMRAf/EAT8AAAEFAQEBAQEBAAAAAAAAAAMAAQIEBQYHCAkKCwEAAQUBAQEBAQEA
+AAAAAAAAAQACAwQFBgcICQoLEAABBAEDAgQCBQcGCAUDDDMBAAIRAwQhEjEFQVFhEyJxgTIGFJGh
+sUIjJBVSwWIzNHKC0UMHJZJT8OHxY3M1FqKygyZEk1RkRcKjdDYX0lXiZfKzhMPTdePzRieUpIW0
+lcTU5PSltcXV5fVWZnaGlqa2xtbm9jdHV2d3h5ent8fX5/cRAAICAQIEBAMEBQYHBwYFNQEAAhED
+ITESBEFRYXEiEwUygZEUobFCI8FS0fAzJGLhcoKSQ1MVY3M08SUGFqKygwcmNcLSRJNUoxdkRVU2
+dGXi8rOEw9N14/NGlKSFtJXE1OT0pbXF1eX1VmZ2hpamtsbW5vYnN0dXZ3eHl6e3x//aAAwDAQAC
+EQMRAD8A9VSSSSUpJJJJSkkkklKSSSSUpJJJJSkkkklKSSSSUpJJJJSkkkklKSSSSUpJJJJSkkkk
+lKSSSSUpJJJJSkkkklKSSSSUpJJJJSkkkklKSSSSUpJJJJSkkkklKSSSSUpJJJJSkkkklKSSSSUp
+JJJJSkkkklKSSSSUpJJJJSkkkklKSSSSUpJJJJSkkkklKSSSSUpJJJJSkkkklKSSSSUpJJJJSkkk
+klKSSSSUpJJJJSkkkklKSSSSUpJJJJSkkkklKSSSSUpJJJJSkkkklKSSSSUpJJJJSkkkklKSSSSU
+pJJJJSkkkklKSSSSUpJJJJSkkkklKSSSSUpJJJJSkkkklKSSSSUpJJJJSkkkklKSSSSUpJJJJSkk
+kklKSSSSUpJJJJSkkkklKSSSSUpJJJJSkkkklKSSSSUpJJJJSkkkklKSSSSUpJJJJSkkkklKSSSS
+UpJJJJSkkkklKSSSSUpJQstqqbute1jfFxAH4qQIcAWmQeCElLpJJJKUkkkkpSSSSSlJJJJKUkkk
+kpSSSSSlJJJJKUkkkkpSSSSSlJJJJKUkkkkpSSSSSlJJJJKUkkkkpSSSSSlJJJJKUkkkkpSSSodW
+630vo1TLupXiiu12xjiHOl0THtBRAJNDVRIGp0fIPrz1LNzvrHm15L3eni2upoqJ9rWt0BA/lcyu
+k/xT9TzX5OX0173WYjKhawEyGO3BsN8N0o31gu/xbddyPtd+e6jKIAfbS143Acbg6sg/Fb/1KZ9U
+6ce7H+r13rvaWuybHbvUdM7S7c1unPGitTmPZ4eAjQbjQNaED7vFxA/V6VJJQttqprdbc9tdbBLn
+vIa0DzJVRss0lzeX/jC+qmK4sOZ6zhz6LHPH+cBH4odH+Mj6p2uDTkvqnvZU8D7wCn+3P90/Yt9y
+H7w+16hJVsHqOB1Cn1sHIrya/wB6twdHxjhWUyqXKSVDqfXuj9JaD1DLrxydWscZefgxsu/BYh/x
+mfVMP2+vaR+8Knx+ROEJnURJ+i0ziNyA9Ukszpf1l6F1Y7cDMrts59Kdr/8AMfBWmgQRoRSQQdQb
+UkkkglSSSSSlJJJJKUkkkkpSSSSSlJJJJKUkkkkpSSSSSlJJJJKUkkkkpSSSSSlJJJJKUub+u/1Z
+y/rHhY+Pi210uotNjjbuggtLdNoPiukSRjIxII3CJREgQdi/PfU+n39Mz78DJj1sd5Y8tMtPeR8Q
+uy/xSE/tbOHb7O3/AKsLA+vH/is6l/xo/wCoat//ABSf8r53/hcf9WFeyG8JJ6gFpYxWYAdCX0nq
+OfjdNwrs7KdsooaXvPfTsPM8BeKfWT609S+sGUX5DzXitP6DFafY0dif3nea7b/G1nvr6fhdPYYG
+TY6yweIqAgfe5eb4OK7NzcfDZo7ItZUD4b3BspnLYwI8Z36eTJzEyZcAb3Rvqv1zrYL+n4xfU0wb
+nEMrnw3O5+Ss9S+o/wBZum0m+/EL6WiXvpcLNo8SG+78F7RhYePgYlWHjMFdFDQxjR4D+9HTDzUr
+0ApcOWjWpNvl3+KM/wCU+of8Qz/q10f19+uDuhY7cLBI/aOS2Q46+lXxvjxPZdVVjY9JLqqmVk8l
+rQ0n7l4Z9a+oP6j9Ys/JcZHrOrr8mVnY0fglADNlMiNANlTJxYxEHU9XPJy8/Klxfk5WQ6JMve9x
+/Ero2f4tfrW+j1vQra4iRS6xof8A+R/Fan+KfpdV+dl9SsaHOxWtrpns6ydzh57RHzXqCfmzmEuG
+IGm63FgEo8UidX55yMbM6fluoyGPxsqh2rTLXNPYgj8oXpn+L7663dTP7I6o/fmMaXY955sa3lrv
+5QGvmFX/AMbPS6ji4nVWNAtZZ9ntcO7XAubPwLT96896bm2YHUMbNqMPx7G2D5HUfMJ1DNjutfyK
+yziyVen7H6ESUWPD2Ne36LgCPgVJUW6pJJJJSkkkklKSSSSUpJJJJSkkkklKSSSSUpJJJJSkkkkl
+KSSSSUpJJJJSkkkklKSSVfMz8LAqF2bfXj1k7Q+xwaCTrEn4JKfFvrx/4rOpf8aP+oat/wDxSf8A
+K+d/4XH/AFYXNfWzMx836x5+VivFtFlvssHDgAGyPuW3/iy6p0/p3Vso517MZt1AbW6w7WkhwMSd
+OFfmD7NVrwhpQI96/Eun/jeqd6nTLvzYtZ8/YVxf1dvZj9e6dfZoyvJqLieI3BesfXTo7frF9XC7
+BLbrqoycRzDIfAMtaf5TTovGCC0kGWuBgg6EEIcuRLHw9rBTnBjk4u9F+jEl579Xf8aGG3Drxutt
+sbfU0N+01t3teBpLgNQ7xVzqP+NToVNLvsFduXdHsBb6bJ/lOdr9wVU4Ml1wn9jYGbHV8Qe2Xz71
+ep9HVs2l4hzMi1pHweV6V9Q/rh1jr/UsqjP9L0qqfUYK27SCXhvMnsVgf4zfq7bh9TPWaGE4mZHr
+EcMuAjX+uBPxU2Ae3kMJbkMWb14xKOwLqf4obmfZ+pUT7w+t8eRDh/Behrwn6sfWLI+r3U25tTfV
+qcPTyKZjew66HxHIXpTP8Z31VdT6jrLmPiTUaiXT4ae38U3PimZmQBIPZOHLHgAJoju1/wDGtcxn
+1dpqJ99uSzaP6rXkrydrS9wY3VziAB5nRb/1x+tdv1kzmPaw04eOC3HqcZdr9J7o0kwj/UD6u29X
+61Xk2M/UsFwtteRo541ZWPnqfJT4x7WK5ebFkPuZKj5PsOMw141VbuWMa0/ECEVcb/jC+tub0Ouj
+C6cQzKyWue64gO2MB2+0HSSVyv1a/wAYXXKOp01dSvOZiXvbXYHhu5u4xua5oHHgqscE5R4xXk2J
+ZoRlwm31xJJJRMqkkkklKSSSSUpJJJJSkkkklKSSSSUpJJJJSkkkklKSSSSUpJJJJSkkkklKXO/X
+j6v5vX+lVYeE6ttjL22k2kgQGub2B8V0Sq53UsXAFTspxYy1xYH9m7WPtJd5bWFOgSJAjcIkAQQd
+i+X/APjVfWP/AEuL/nv/APIJv/Gp+sf+lxf89/8A5Bei/wDOfo/rikXEjYXmwNO0EO9PZxu3E9oR
+H/WPobAS7MZDeSJI1b6nIH7uvwU3v5u34MPs4u/4s+hYN3T+jYeDeWm3GpZW8t1bLRBiYWH9Zf8A
+F70vrVrsvHccLNfq+xgljz4vZpr5hbNn1i6PXT6xyAWkPIhrpJrBLmjT6WnCVX1h6TaQPXDC521o
+eIJkNIJ/dHvA90aqIHIDxCwWQiBHCaIfNMn/ABW/WapxFJx8hvZzXlp+57Qli/4rfrJa4C91GM3u
+4vLz9zB/Femft/pjsV2TRZ9oa17KwyoS5z7Y9NrQ7b9KeeE56506r25Vn2W5rC+ym2NzAAT7iwub
+w0ka8KX7xl7fgx+xi7/i5n1U+peH9W/UuZc/Iy7mhllhG1u2d0NYJ7+JW9k42Pl0Pxsmtt1Fo22V
+vEgg+Koj6ydEIcRlt9uhEOmZLYjbMyEw+svRTtLclrmOB94mJ9kCOSXeoIgKKXHI2QbZRwAUKp47
+rP8Aina+x1vRckVtOv2fIkgeTbGyfvCwj/iy+tYftFVJH73qiPySvUX/AFg6S1+03ggFzXP/ADWl
+g3OBJ79tO6X/ADg6Nua37WwFw3CZEAbvpSPb9B2h8FIM+YDv5hiOHET28i8L0n/FNebG2dYy2trG
+ppx5Lj5GxwEfcvQun9Owum4jMPBqbRRX9FjfHuSe5Piqx+sXSdpNd3qkN3vawGWsDtjnvmNobBmV
+K7rWKxlDqWWZTskPdUypvuLa/pu/SFkASmTnkn81+Wy+EccPlpxvrx9Tn/WKmm7FsbVm4wIZvnY9
+jtdpImNeCub+rn+LLqVfUasrq7q68fHeLPSrdvc8tMgTEATyuwH1x6Q60V1i14dEPDIaRsbYTLiO
+A8K7+3ukS0fame5/ptOsEyBoYiJMTwnDJljHhrTyQYY5S4uvm6CSSShZVJJJJKUkkkkpSSSSSlJJ
+JJKUkkkkpSSSSSlJJJJKUkkkkpSSSSSlJJJJKUqfUul4vUqm1ZO7awuI2mNXMdUf+i8q4kkDWyiL
+3cyz6vYL7n5AdbXe9/qCxjoLXzulsgjuoM+rPS66Ps7A9tf6QxvM/pahjv1/qj71rJJ3FLujhj2c
+e/6rdLvyTkWG0uLnPLd/tlwIJ40+l2SH1X6duLi+5xeW+tL/AOcDNpaHwOAWA6QthJLjl3KOGPZz
+R0HAFDqG+o0EU7Xh3uaccBtTmnsRCFb9WcC8uN9l9vqa2bn/AEnhprFhgD3BroEaeS10kOKXdPCO
+zmnoHTze28797XvsHu03WONjvxKBZ9VelvYWTYAa21TuB9rW1sH0mkcVhbKSPFLurhj2cX/ml0o2
+OsJtLyQWnf8ARIENcIHI5kyfFTd9V+lvqtqtFlgvcH3FztXu/SS4xGp9V3C10kuOXco4I9g5uJ0H
+CxG2tqL5vr9Gxx2/RBceGtDZ957KLfq9hsxqMeqy6o42/wBO5j4sAtM2N42wfCNOy1EkOI908I7O
+Ufq10vYK2te2sSAwOMAFtVcfdU1R/wCbHTyaSXWuGMSKGuLXBjCWu9Mbmn2y0efmtdJHjl3Vwx7K
+SSSTUqSSSSUpJJJJSkkkklKSSSSUpJJJJSkkkklKSSSSUpJJJJSkkkklKSSSSUpJJJJSkkkklKSS
+SSUpJJJJSkkkklKSSSSUpJJJJSkkkklKSSSSUpJJJJSkkkklKSSSSUpJJJJSkkkklKSSSSUpJJJJ
+SkkkklKSSSSUpJJJJSkkkklKSSSSUpJJJJSkkkklKSSSSUpJJJJSkkkklKSSSSUpJJJJSkkkklKS
+SSSUpJJJJSkkkklKSSSSUpJJJJSkkkklKSSSSUpJJJJSkkkklKSSSSUpJJJJSkkkklKSSSSUpJJJ
+JSkkkklKSSSSUpJJJJSkkkklKSSSSUpJJJJSkkkklKSSSSUpJJJJSkkkklKSSSSUpJJJJSkkkklK
+SSSSUpJJJJSkkkklKSSSSUpJJJJSkkkklKSSSSUpJJJJSkkkklKSSSSUpJJJJSkkkklKSSSSUpJJ
+JJSkkkklKSXyqkkp+qkl8qpJKfqpJfKqSSn6qSXyqkkp+qkl8qpJKfqpJfKqSSn6qSXyqkkp+qkl
+8qpJKfqpJfKqSSn6qSXyqkkp+qkl8qpJKfqpJfKqSSn6qSXyqkkp+qkl8qpJKfqpJfKqSSn6qSXy
+qkkp+qkl8qpJKfqpJfKqSSn6qSXyqkkp/9kNCmVuZHN0cmVhbQ1lbmRvYmoNMjEwIDAgb2JqDTw8
+L0FsdGVybmF0ZS9EZXZpY2VSR0IvRmlsdGVyL0ZsYXRlRGVjb2RlL0xlbmd0aCAyNTk3L04gMz4+
+c3RyZWFtDQpo3pyWd1RU1xaHz713eqHNMNIZepMuMID0LiAdBFEYZgYYygDDDE1siKhARBERAUWQ
+oIABo6FIrIhiISioYA9IEFBiMIqoqGRG1kp8eXnv5eX3x73f2mfvc/fZe5+1LgAkTx8uLwWWAiCZ
+J+AHejjTV4VH0LH9AAZ4gAGmADBZ6am+Qe7BQCQvNxd6usgJ/IveDAFI/L5l6OlPp4P/T9KsVL4A
+AMhfxOZsTjpLxPkiTsoUpIrtMyKmxiSKGUaJmS9KUMRyYo5b5KWffRbZUczsZB5bxOKcU9nJbDH3
+iHh7hpAjYsRHxAUZXE6miG+LWDNJmMwV8VtxbDKHmQ4AiiS2CziseBGbiJjEDw50EfFyAHCkuC84
+5gsWcLIE4kO5pKRm87lx8QK6LkuPbmptzaB7cjKTOAKBoT+Tlcjks+kuKcmpTF42AItn/iwZcW3p
+oiJbmlpbWhqaGZl+Uaj/uvg3Je7tIr0K+NwziNb3h+2v/FLqAGDMimqz6w9bzH4AOrYCIHf/D5vm
+IQAkRX1rv/HFeWjieYkXCFJtjI0zMzONuByWkbigv+t/OvwNffE9I/F2v5eH7sqJZQqTBHRx3Vgp
+SSlCPj09lcni0A3/PMT/OPCv81gayInl8Dk8UUSoaMq4vDhRu3lsroCbwqNzef+pif8w7E9anGuR
+KPWfADXKCEjdoALk5z6AohABEnlQ3PXf++aDDwXimxemOrE4958F/fuucIn4kc6N+xznEhhMZwn5
+GYtr4msJ0IAAJAEVyAMVoAF0gSEwA1bAFjgCN7AC+IFgEA7WAhaIB8mADzJBLtgMCkAR2AX2gkpQ
+A+pBI2gBJ0AHOA0ugMvgOrgJ7oAHYASMg+dgBrwB8xAEYSEyRIHkIVVICzKAzCAGZA+5QT5QIBQO
+RUNxEA8SQrnQFqgIKoUqoVqoEfoWOgVdgK5CA9A9aBSagn6F3sMITIKpsDKsDRvDDNgJ9oaD4TVw
+HJwG58D58E64Aq6Dj8Ht8AX4OnwHHoGfw7MIQIgIDVFDDBEG4oL4IRFILMJHNiCFSDlSh7QgXUgv
+cgsZQaaRdygMioKiowxRtihPVAiKhUpDbUAVoypRR1HtqB7ULdQoagb1CU1GK6EN0DZoL/QqdBw6
+E12ALkc3oNvQl9B30OPoNxgMhobRwVhhPDHhmATMOkwx5gCmFXMeM4AZw8xisVh5rAHWDuuHZWIF
+2ALsfuwx7DnsIHYc+xZHxKnizHDuuAgcD5eHK8c14c7iBnETuHm8FF4Lb4P3w7Px2fgSfD2+C38D
+P46fJ0gTdAh2hGBCAmEzoYLQQrhEeEh4RSQS1YnWxAAil7iJWEE8TrxCHCW+I8mQ9EkupEiSkLST
+dIR0nnSP9IpMJmuTHckRZAF5J7mRfJH8mPxWgiJhJOElwZbYKFEl0S4xKPFCEi+pJekkuVYyR7Jc
+8qTkDclpKbyUtpSLFFNqg1SV1CmpYalZaYq0qbSfdLJ0sXST9FXpSRmsjLaMmwxbJl/msMxFmTEK
+QtGguFBYlC2UesolyjgVQ9WhelETqEXUb6j91BlZGdllsqGyWbJVsmdkR2gITZvmRUuildBO0IZo
+75coL3FawlmyY0nLksElc3KKco5yHLlCuVa5O3Lv5enybvKJ8rvlO+QfKaAU9BUCFDIVDipcUphW
+pCraKrIUCxVPKN5XgpX0lQKV1ikdVupTmlVWUfZQTlXer3xReVqFpuKokqBSpnJWZUqVomqvylUt
+Uz2n+owuS3eiJ9Er6D30GTUlNU81oVqtWr/avLqOeoh6nnqr+iMNggZDI1ajTKNbY0ZTVdNXM1ez
+WfO+Fl6LoRWvtU+rV2tOW0c7THubdof2pI6cjpdOjk6zzkNdsq6Dbppune5tPYweQy9R74DeTX1Y
+30I/Xr9K/4YBbGBpwDU4YDCwFL3Ueilvad3SYUOSoZNhhmGz4agRzcjHKM+ow+iFsaZxhPFu417j
+TyYWJkkm9SYPTGVMV5jmmXaZ/mqmb8YyqzK7bU42dzffaN5p/nKZwTLOsoPL7lpQLHwttll0W3y0
+tLLkW7ZYTllpWkVbVVsNM6gMf0Yx44o12trZeqP1aet3NpY2ApsTNr/YGtom2jbZTi7XWc5ZXr98
+zE7djmlXazdiT7ePtj9kP+Kg5sB0qHN44qjhyHZscJxw0nNKcDrm9MLZxJnv3OY852Ljst7lvCvi
+6uFa6NrvJuMW4lbp9thd3T3Ovdl9xsPCY53HeU+0p7fnbs9hL2Uvllej18wKqxXrV/R4k7yDvCu9
+n/jo+/B9unxh3xW+e3wfrtRayVvZ4Qf8vPz2+D3y1/FP8/8+ABPgH1AV8DTQNDA3sDeIEhQV1BT0
+Jtg5uCT4QYhuiDCkO1QyNDK0MXQuzDWsNGxklfGq9auuhyuEc8M7I7ARoRENEbOr3VbvXT0eaRFZ
+EDm0RmdN1pqraxXWJq09EyUZxYw6GY2ODotuiv7A9GPWMWdjvGKqY2ZYLqx9rOdsR3YZe4pjxynl
+TMTaxZbGTsbZxe2Jm4p3iC+Pn+a6cCu5LxM8E2oS5hL9Eo8kLiSFJbUm45Kjk0/xZHiJvJ4UlZSs
+lIFUg9SC1JE0m7S9aTN8b35DOpS+Jr1TQBX9TPUJdYVbhaMZ9hlVGW8zQzNPZkln8bL6svWzd2RP
+5LjnfL0OtY61rjtXLXdz7uh6p/W1G6ANMRu6N2pszN84vslj09HNhM2Jm3/IM8krzXu9JWxLV75y
+/qb8sa0eW5sLJAr4BcPbbLfVbEdt527v32G+Y/+OT4XswmtFJkXlRR+KWcXXvjL9quKrhZ2xO/tL
+LEsO7sLs4u0a2u2w+2ipdGlO6dge3z3tZfSywrLXe6P2Xi1fVl6zj7BPuG+kwqeic7/m/l37P1TG
+V96pcq5qrVaq3lE9d4B9YPCg48GWGuWaopr3h7iH7tZ61LbXadeVH8Yczjj8tD60vvdrxteNDQoN
+RQ0fj/COjBwNPNrTaNXY2KTUVNIMNwubp45FHrv5jes3nS2GLbWttNai4+C48Pizb6O/HTrhfaL7
+JONky3da31W3UdoK26H27PaZjviOkc7wzoFTK051d9l2tX1v9P2R02qnq87Inik5Szibf3bhXM65
+2fOp56cvxF0Y647qfnBx1cXbPQE9/Ze8L1257H75Yq9T77krdldOX7W5euoa41rHdcvr7X0WfW0/
+WPzQ1m/Z337D6kbnTeubXQPLB84OOgxeuOV66/Jtr9vX76y8MzAUMnR3OHJ45C777uS9pHsv72fc
+n3+w6SH6YeEjqUflj5Ue1/2o92PriOXImVHX0b4nQU8ejLHGnv+U/tOH8fyn5KflE6oTjZNmk6en
+3KduPlv9bPx56vP56YKfpX+ufqH74rtfHH/pm1k1M/6S/3Lh1+JX8q+OvF72unvWf/bxm+Q383OF
+b+XfHn3HeNf7Puz9xHzmB+yHio96H7s+eX96uJC8sPCbAAMA94Tz+w0KZW5kc3RyZWFtDWVuZG9i
+ag0xIDAgb2JqDTw8L0NvbnRlbnRzIDIgMCBSL0Nyb3BCb3hbMCAwIDU5NSA4NDJdL01lZGlhQm94
+WzAgMCA1OTUgODQyXS9QYXJlbnQgMjAyIDAgUi9SZXNvdXJjZXM8PC9Db2xvclNwYWNlPDwvQ1Mw
+IDIxMyAwIFI+Pi9FeHRHU3RhdGU8PC9HUzAgMjE0IDAgUj4+L0ZvbnQ8PC9UVDAgMjE2IDAgUi9U
+VDEgMjE4IDAgUi9UVDIgMjAgMCBSL1RUMyAyMjAgMCBSPj4vUHJvY1NldFsvUERGL1RleHQvSW1h
+Z2VDXS9Qcm9wZXJ0aWVzPDwvTUMwIDIyMyAwIFI+Pi9YT2JqZWN0PDwvSW0wIDIwOSAwIFI+Pj4+
+L1JvdGF0ZSAwL1N0cnVjdFBhcmVudHMgMS9UYWJzL1MvVHlwZS9QYWdlPj4NZW5kb2JqDTIgMCBv
+YmoNPDwvRmlsdGVyL0ZsYXRlRGVjb2RlL0xlbmd0aCAyMjE5Pj5zdHJlYW0NCkiJpFfbjts4En33
+V9SjPWjLulteDAboy2TTC2STTBvIg6cfaIm2OSOLjki123+/VaRudsu5zCJAxxLEupw6dar4deRC
+EvoQLSLH9WGahJ6TxFDy0ZdfoBh9HbmOGwC9XSRnH+EjfWS+mf37yYWtGnlh6ITewnXjAFz857kJ
+hKHrBMFiscB38yCEdD+aPe5deJCjz6PZbanFhqUafv11dqs1S3c8g9VsKQ/wPLu7k6+win0Hj80X
+6DJAG74XO3ESziFxYyf0Mbjn2VO11qcDh9l7zjJewmxpnj6xrSiYFrKA3367e7gH9Ph5dLcczT7e
+w+zDvQvmZRP9bLnEkGG5GU0xadfFnymYn14EyyN4vk3Khyak0Aaw3I/Gf/ANL3mR8n8BvHuK3GC+
+CEIPJsu/Rr9/QCe/L+3/5L2XdB0Xuvasa5ecuoPu4gQrU7vrDM8+EXYf7h8f8OPOnD+ciRuT6QCm
+vuMHmFU2Gv/p+8EXDkqzIoP1CWRVQsZToQg3LUEoVZE3czxsLfkmxthJ3IjiRUMc9I4Df03zypwt
+pBYpvwGyexR5Ti9M3G4HrAlnWpuZeo7v2aBSWZacvu1QWCQGhdB33NCi4DtR4vdOrcbqII0zvYOT
+rGBTlRhSCZQIhqaq9V8cYa+KnCtlvshlNpnOx9uJj+Ez2MhyT88sh8nz8j+jBrK6JNNLj2N2OHCW
+O4hhOFgSr1eSM3LNDQa2ELWtuTNkwYdhjng16sbt96jr1x8vEYVU7g85w8YoNHbw14orjT3HDFhk
+a3pR6LbS80Vd6dWYQC35i+BHwtYL4IGnHJFLxuvJFKEswXc91yEoe0B2NsOoqTsZ7VfwncxzeRTF
+FliWCepdlk+iMRhCmPJSk3U2/S7TxMSZOL7fMNJUPZVVkYocmuOZCRluq22laj6eBxf4NjhrqVds
+zMmD6rCTeUYBCq1AloI0Jm87xhmkQdArYtArlG9dGRrMfePkKZWoXXJjY2eKn2lI7DpJCDFKH2Ye
+zgPkI7hOaLR4Y8Slcxp+k3uDGhPNIwfl22pMMsjH6Of4aBxGnWp4PTqu3vAxlQXOAOKjxqLvDJfg
+Xu73wlR8elny0CSxQBmuvSuqAdIPdauxC2wtK23gvCZjU2uiz8MjO8FOqKZDSBlAFKQPdqDsGIol
+5/SjyHI+iceZA+85ZJIrK3TXA3aNJ3z7gI4wZSVoaOkd032XCo44UfAJFUZPpvGYmFvCC3+lCCpl
+3LFcyb6rwJa2yeTBaCJScyNSlucnYOpvAy6a66PbwDbUq17dVkiyumoILjZnSRrKoKj2a15OsNGR
+s4dSpjyrylY/OxWZN02Fdno9tS45DX3VMP7dx8fbGgqiRluxDkM3qvWoHTwWQHXW7SmlpYlJxx1W
+6drYOZ86tURQc2OOvVo4AIN9HTfNcNlY58q+GOyk+T9Qdht5w/bHosm5VK1m9AuKc8lXAxharRwj
+o18wO7G1nO7jRzMUS3zsesbMlOUvWH8SvpLngqESQ3uu7mLshIKYpY1v/K7jVCcDrtXquRPP25mC
+QONZhZNYY2dRDVqqmxXCNgIWdIikdRtbg/35jAdxszGKQqQSGo6yyjNi6guyBt8OwOM34UVet9z0
+dcpsGMh9xMdyRnGnQyrocF40cZGlXlyPuomAAkOiIYzo9YkfNMd+OgfdmprXtA/iBjEzZT0HbtVw
+6bBOiChcDktroy92V4tZ2CqSFdsJQ9jb1sbOjtqORIJ8u4TtnnG5qUxrOz2sDD47ZmXVaG6jmbS3
+KDiwUl8lv3GFrB2fUd0Zbufk7Zi+DHLxZmD/wZnCeMyEaPfmtzM7CObOPP7ezF78/MwOXGR9SPXA
+mU1L19Aa6l7TGicOom9M7p7smsw9pE7Uqc+WI84o9q1yE0sEtgQ2x6Fa5yLtKv1GwRMnbpsfWKV3
+uEzpEylvrcNmfaRh007h63vf1Jrr0eZyYlNb4Dbgu6gA5d9EzoydVBdfUu8Skd9FhawqcbMVB5wA
+X+g8biVG3ayaaLHnvenbRGJt1DMeIznwUsjMgGRB6WW7b5bQK3fO2IniRoKEucxkQqW5VPa21U8Q
+870q9VNrqAcPf7XbEeJLhmqE0cZxdyKZFLbfJMa7JZGSuNqAklc6x/N+bBKiXA0ev3rL+Q4/L++j
+HT1X4/fshaps5ZAdC8yqmUk/OruameS1M+limpl5OCxyN1gcdImMUWeD4kyrG1lTstru9OXSZKe9
+8YH4UyJ495iE48xQkBWni/r3FkFz0oscf9Ggh1mfKGM6xl/5/kCH1LV6BlfrSfeixVlN/eGahv+3
+5tRXun5RHwtz7xIF3g1Zc6kjoVD85gzZTHSluhzIOI+bu+w4M/jjRNmIcg9GwxEgXBpNswkNA7PY
+b8f62e11vON51u8m7JtegW7OOnTeWQvI2mrcrCSXdcUYMpHBTk6ScY63jOsiSHPuYhkwbQy5LLaY
+DVGASIyIXdtVSEbbBZQiSbEz9t3yxM5lYUBwglaOvbMlo7mSnez29K3G6/G4dw/x69K5XrsAWZhv
+3oz+ekMgXtDFYLCtptbUWYhtltT11L/2ekJzgFgn12Qxr5cIBVVBFzfFU1MnzywhvasVTUTqL/L+
+pjuiHxTMYLi54p9vrisTpt9dy445jQTWooWp+fBfSl/ihv6CS+oQDa0KI+a0mbr2drphIrcDZM+5
+NqUaXArChsH1DrHnhTbXQgYvLBckrJtKYc8j/0TKh/qy3pEXjhc2GCBf6/4h2ooizStssYxrjKq9
+dPa3tdltqcWGpZqwvtWabqcZrGZ3Umu5h+fZ3Z18hZXdvUJa7OMAd7DIiePQo5XM87EFnmdP1Vqf
+Dhxm76TUCMhsaZ4+sS3y3fClKeDHe8CiumCeaB3s5PDq0hc1zbuvy4xJk9QToylt36S0HH0dBa7n
+hCbSGBcJjA6F2Qlp9/wCxbm7zkl9KHJtNq0XtGhxoj+fR/8TYAA9ZWkRDQplbmRzdHJlYW0NZW5k
+b2JqDTMgMCBvYmoNPDwvQ29udGVudHMgNCAwIFIvQ3JvcEJveFswIDAgNTk1IDg0Ml0vTWVkaWFC
+b3hbMCAwIDU5NSA4NDJdL1BhcmVudCAyMDIgMCBSL1Jlc291cmNlczw8L0NvbG9yU3BhY2U8PC9D
+UzAgMjEzIDAgUj4+L0V4dEdTdGF0ZTw8L0dTMCAyMTQgMCBSPj4vRm9udDw8L1RUMCAyMTYgMCBS
+L1RUMSAyMTggMCBSL1RUMiAyMjAgMCBSL1RUMyAyMCAwIFI+Pi9Qcm9jU2V0Wy9QREYvVGV4dC9J
+bWFnZUNdL1Byb3BlcnRpZXM8PC9NQzAgMjIzIDAgUj4+L1hPYmplY3Q8PC9JbTAgMjA5IDAgUj4+
+Pj4vUm90YXRlIDAvU3RydWN0UGFyZW50cyAyL1RhYnMvUy9UeXBlL1BhZ2U+Pg1lbmRvYmoNNCAw
+IG9iag08PC9GaWx0ZXIvRmxhdGVEZWNvZGUvTGVuZ3RoIDIzMDE+PnN0cmVhbQ0KSIm0V11v27gS
+ffevmEd5sZZJ6sPyYrFAPtrbXqA37Y2BfUj7oEh0rFtbciUqbv79nSEpiXKUbLfAokBrq9Zw5syZ
+M4ffZgySUEC0jnwmYJGE3E9iqOXsz1+gnH2bMZ8FQE/XyehH+JV+pH+z/Nctg4dmxsPQD/masTgA
+hn84SyAMmR8E6/Uan62CELLDbPn+wOC6mn2aLS9qVWzTTMHvvy8vlEqznczhbrmpjvBleXlZfYe7
+WPj42mqNRwYYQ/DYj5NwBQmL/VBgcl+Wt+29ejpKWL6TaS5rWG70t4/pQ1GmqqhK+OOPy+srwBM/
+zS43s+XNFSw/XDHQD7vsl5sNpgyb7WyBRTOGHzPQH3kEmxNwYYoS0KUUmgQ2h5n3X7mVtSwz+RvA
+29uIBat1EHKYb/43e/MBD3mzMf/S6U7RNi88mpujGR3KJo+LE+yMPW4IvPxI2H24en+NPx7C2Up0
+IXFfSCAocgAL4YsAi8pnXl087BRUW8iqw3GfFqUCVYHaSbiqDoeCznkBjtjXKVKQpkGQZe3DZlc0
+UB0K/QBOaQNlpWAIIoYgIQVZmCgL7gtu8smqupb0wlD/OtH1h8Jnoalf+FHivnXnZQqJU5Q68axq
+y6zYfxZCNPhMybpM9/NF4CFjHwt5glxmBSVI+WLXtlUt9YvzL5t/v1Dt4vxIT8NjC8cjy6ZA6jUY
+J1U2C6rivOpEQ5dY3HSekO6bCu5radjfyExTlq+oK32MYIixNsglbjZ04tub9xf+JDN4xwxT3Kon
+2cJwwQbhoT/1toBpmnI/RhKZSvSxZ7yL+pQF12X7QWx/f+ddNG6vIC/mkZdrthzr6hGxhBQe032R
+u11xQAgMkP56CFnL5oh9kPNF5MGpUDvkg2BwquqvRfkAefrUmGCTTVnYYGegvt7mgdlhH47pIeMr
+f8361JBlehrSEtKmqbIiVTrNfL4Qnu29brdOb8gsNpmZWC7fe5bMF6HH5tyjtzUJKOzNXHiaCxTu
+vJ2B007hCt6gE1wM5FgJc+INRq/hMF+svJSGSSnCYTgBFS5mfhLiluB+GEK4CnBkgPmh3hRbLX1D
+FuGEWE3JXhQjbTqV5dEkQaO/T1AHXoeW3ua840hI+WyoezKe4M5ztKYjIPVCUGPgP9WjPNxjnFek
+henGIsrXiLJgnEGjUjVfxJ7Mf5tuYewUHDgTN3BaxDa0ne7rmYc5BlTDx7Qumh2WadUHqYnltjQi
+T1WLg9OXaAYDx4B4K79n+1bLOmJSZBLaknat1s0XlwTrSYsJvK2lzKsDofO+RNE9mN18gZtQ4Ltw
+i5zu9W6YJ6Mda1c8NPPDzx7/PMfUcv1Z4GcMik04ypTARwg5QuhA3ymnieUMOsV4lN8pn5ba+K2V
+jWo+Cxb5hhF9Wk6BK7sFg3ik5qdivydU7F4pK9hX5QNRYLwOzJujHaZXH2ZOLMq1glFHfGxcOM2D
+1dQQOS3faMqavZ7iZpffj8jRBkFBJctwLzYwrow0sB8Zh/WmtE7+8H39f6O9bhU0GAFLp0ChYJfm
+COu2paPTDmCUQo36Kx4jIZ9ps9G9wVjGVXSoUqxCZ1S96jN0pL9Cm4q1yWFoJFlanilyN/VPsCUR
+rFFoe1IXltQ0usRQ/Ega6TtL55w+o/nYOFDvaFlkmTyqDmysHGWpGOlPZxXRIHUwkd3BJtNru+qk
+K9ILlSa30QMywWUzYwsTxwWpHwqtZt1gQHo87gs84bSTpTtf3UgkouOQkcScxMXaSoePRjVfbv/C
+hnIIZVPwASaNTvKDRiee3CPrnzQ6z/yds1HeI4nynKZOY/AcgJdJi9su6traDBP7zJUQV14DUYdx
+u5rmyAfNq4Fw6X3VKhxHavQghPSt63mpR1jWdtjI6Q/EHryD0Fqw+QXPObb3+6KZrzzytQ9tkadY
+wjz2sHuTcsbZD7ZvNdk+zn/SBzzXnTNL4Gqodutp81VfUhxhMJ0PyLPYLZU/bxXiZkSUbJTdnqo4
+aI2ctKamgzqqdQkkhVX1VY+y20ATOm8zkgq694zzs14n8Xnc5WcuRuZSRI0+kRn1AZ05UmFflKTV
+92hgfv0L18zjf8g0j29y27bWFhRnibI9Urad28LN/sPWufdk2mtRdqpQLdm8tLsgVts5yp1Fl1pV
+0mHOnbJQBSLX3SP17jkzeDgAntl406rXC9nFuTFw74m+iHo49DRlkLZqV+FM0eop1BM0u6rd55hL
+ujdLzMlkag1SxJEYlE/GF+hdqMtBQHNsH6pAs03xnkELDR+jMzwrktmmrZI+SzKLgxFGYMy613zH
+lb+tcVem581ifbMo0nO5x2aljWMciPtFafn7sjdb+XHo3A4fC7obYXtJygxsTkGJLqif5HU/KHi1
+KvdPqLKPSLVy2u0yI7UC99WIbV5H2up4rGrVltQxBMXyjAY1l0PAaKiAG59hCXZvzKS2FjsyHq5P
+0V7hFZOhqVg87JTRCEPEbh0Pozq1iFjY+QthwZC1j+4dX0X5z1LL7tG8T9DZwmPiOOg8kwbXa2Ke
+2sacOR7HhmG8bj8SkhZUGgKsTzA4VfVX2rp5+tS8PGULHWY0EhQLEzhIvOLkUMwjIwDngGEbajPN
+ernhZjM6If0X9pv4wf2WTO+34Gf3m+i5Lc7X27vqJB9l/evzPuI1T74CG02XGK4KExI30hAk8dRC
+WtgwowViqYBbCGNqfaevg/5POdhu4nmXkuaC4+dz8vMI4bXMjPz3UVaDdwm6nPgoJb0pzL1DUZ0H
+HOQsVZ0ROkBbqjM7oPMRzOfd4CCnOVy0D21D113OfXgnjZk4A3pgub2vmiguQZ1psZh33FN9muY2
+IvOp3S2My1n70brnDaJMM/2iUPSMfLOZLS9qVVBbiZsXSqUZOby75WWlFOr7l+XlZfUd7mJBviVc
++RGPAwhY5MdxyAEfc4Flflnetvfq6Shh+baqSMmWG/3tY/qAJWnOdIS/uQIcAgb62+VmdOHtFxFB
+zegfc3DUwXmwY4EFizXNAdclB7qkzezbLGDcD3WmMYo+oc1DP0TqzP6EcnzccIh9KWKmmv4UjGhw
+or8+zf4vwAAUVrhNDQplbmRzdHJlYW0NZW5kb2JqDTUgMCBvYmoNPDwvQ29udGVudHMgNiAwIFIv
+Q3JvcEJveFswIDAgNTk1IDg0Ml0vTWVkaWFCb3hbMCAwIDU5NSA4NDJdL1BhcmVudCAyMDIgMCBS
+L1Jlc291cmNlczw8L0NvbG9yU3BhY2U8PC9DUzAgMjEzIDAgUj4+L0V4dEdTdGF0ZTw8L0dTMCAy
+MTQgMCBSPj4vRm9udDw8L1RUMCAyMTYgMCBSL1RUMSAyMTggMCBSPj4vUHJvY1NldFsvUERGL1Rl
+eHQvSW1hZ2VDXS9Qcm9wZXJ0aWVzPDwvTUMwIDIyMyAwIFI+Pi9YT2JqZWN0PDwvSW0wIDIwOSAw
+IFI+Pj4+L1JvdGF0ZSAwL1N0cnVjdFBhcmVudHMgMy9UYWJzL1MvVHlwZS9QYWdlPj4NZW5kb2Jq
+DTYgMCBvYmoNPDwvRmlsdGVyL0ZsYXRlRGVjb2RlL0xlbmd0aCA5NjY+PnN0cmVhbQ0KSIl8Vdtu
+2zgQfddXzKO0gCiSom5FUSB2mt0sELTZCNiHNA+KRNvctUVXouPm7zukJMsx0iJAYjPknMsccr57
+FHLBISkSQjmEuWAkT6GT3r9/QOt99yihMdjVIn+zCb/aTW5P9OcDhXXvMSGIYAWlaQwUfxjNQQhK
+4rgoClzLYgH1zotudxSutXfvRVedUauqNvDxY3RlTFVvZAOPUan38BQtFvoHPKac4LGsQMgYa3CW
+kjQXGeQ0JYIjuafo4fBsXvcSor9k1cgOotJ9+1qtVVsZpVv49GlxvQREvPcWpRd9WUJ0t6TgFif2
+UVkiZShXXoiiKcWPNbiPLIHyCIwPojhMlMRAoNx5/j9yJTvZ1vIDwM1DQuOsiAWDoPzP+3yHIJ/L
+4a9FPxM98kJoNkBTC0rfhUtz7MwINxeOvlrv7pa317h5LvdbJTGEnPAYPzfeo7/Uu53qe7RJdgRu
+W6iCUPhN00lcbNdgNsFT+bfnKvG5Uu5IpoSKxBJuPF9CrXf7bYWmt+Yb57yH2vKclRS5UyI4nhqU
+cEGyXAwFHn0dcB897NoeUSU43EGCQwvH3SEjnF2wDxLfCoBN1cOxU8bIFox2ZWp9aOu51si8IGkx
+Eldb2Hf6RTVW7vqgmgpJAMZGtQbJVFtndzgcmcH9Tr4oeeyhahuQP5zywbDK4Jo77Q46BcJ11uLH
+Ft93dYcK0G/0YdvMe/OTzYNwnpJisvnRh2cJFdKT0BvsVeKvgzD2R7vo3KF08Gw4e+4Ziq2xuQNR
+hx1gw4OQ+7CWaGK13b5aEGxnEGb+3v5nKw1ezaMyuHVjF1QLnMJRd/9bzU312hMYKFzmkk25HBRl
+p4iHQxBHN9He91LN4f1LwkgaT8lz/ZlTP8M4RO4MZyROTxaWmzdhxdQEqd9DV6keVVbQHnYXbnLn
+JstInJ2qPGPe9ApNsY/O3lplA4xtx0g864O5DHE898ZRCsdyZ5FyWVXb8fZYhsqFEY3fuHI3X26v
+rNrLPmMpkZ+YEbAKz2+2uxiqXeluJ939du2eb7aYlU7UbL3z2JjJNLxrVcD8wTrjvDNByHxLsJew
+q/D2dT00ai5/9gRl4/Wjs5ENtNrACnMHxyBMfRSL8bJ4fa3xKUeTN6o/C/gQn7HImX2qfZG9UWv3
+6pM3z++vZs1CG6N3F+NGZCRhOG1impA0xYccl9nFsLnR2vxu2LydMvbhPwX08m1PpnhMTzsq44V9
+LZiTJZyQEkdtTBkRjl+a4v+xAsMpNI3iX4CMhxI6aJgHyDiU3K9776cAAwDczA1EDQplbmRzdHJl
+YW0NZW5kb2JqDTcgMCBvYmoNPDwvQW5ub3RzIDE5IDAgUi9Db250ZW50cyA4IDAgUi9Dcm9wQm94
+WzAgMCA1OTUgODQyXS9NZWRpYUJveFswIDAgNTk1IDg0Ml0vUGFyZW50IDIwMiAwIFIvUmVzb3Vy
+Y2VzPDwvQ29sb3JTcGFjZTw8L0NTMCAyMTMgMCBSPj4vRXh0R1N0YXRlPDwvR1MwIDIxNCAwIFI+
+Pi9Gb250PDwvVFQwIDIxNiAwIFIvVFQxIDIxOCAwIFIvVFQyIDIyMCAwIFI+Pi9Qcm9jU2V0Wy9Q
+REYvVGV4dC9JbWFnZUNdL1hPYmplY3Q8PC9JbTAgMjA5IDAgUj4+Pj4vUm90YXRlIDAvU3RydWN0
+UGFyZW50cyA0L1RhYnMvUy9UeXBlL1BhZ2U+Pg1lbmRvYmoNOCAwIG9iag08PC9GaWx0ZXIvRmxh
+dGVEZWNvZGUvTGVuZ3RoIDE1NDI+PnN0cmVhbQ0KSIm0V1uPm0YUfvevOE8VjsJ4btxWUdS9eNNN
+kybdRcpDtw8sxjapDQ7gdfbf98wAZoyxU0WqvNZimPOdy3duXIWjyWVRpfMoruDNm7dvr26uYTR5
+90BhUY4mYUiBQTgf2ZRQSvEyBn3JHAh3wDhQ/OA/lxMhwQskkZwKCNcj6z6ZJ0WSxckFwO2DQ4UX
+CMlgHH5VuKzGpQqRKiwKNicMRW9GVnuItodsJyABdbqHLCA8ALQED8xGlqPuTT+i6dNBh76NBGVE
+SpAecV2UQ5MZ2gpFMvoC2egqNNR1XjVCjjrfeKW1oxKt7E8EpuBLDk7gEMrB9iUjvqthXyEuPiYo
+qO4G/sEh/Nno/jZiEk1hAaWuqDVTH6SkRIggCPCeh6GN16PJ3ZrCTY5a1UeZ/Bk9nHy8vrtBoZa6
+MORN1BRj3p4xxBxiTDhoSstYulhWkM8h2mySaAVgRtWlxMfzzCMORlEQx8cwSu3FvGcMM4w5yB9v
+z3bfDtf3iGjt4JTsNRuw3IA104cRVzgKdnacOb2s9bRuItz2/DStlkkBm6ioXmAZlYA/odBxqPI2
+DgpTI8kOSQP5hNU4f1nRIhq7VpqVKLhMS7hJ4rRM8wz+yKs0ThSagh7/Hb6vsXiHpZmxNZrNCFe1
+pSBv06Ks7CpF+8IifdpmaMqjNZbW3ZhZ2Twv1lGlNCja8E5VogGPYwJ3xrPoKd9WWnPtS1lb0C9n
+6jQl2KjHMtsUeZyUJayjF3hKIH+qojRLZjAv8vWFkRoGQaIlaNBBhomDJf5T7jW+QW19X69s9Yav
+EPfd/TX8Au/ux7a0Pu+hy9cnhJ1WeB+IGLqQIKL1+RNc5d8hEJS+HnbcPcQQneeiBfkwvbuePoTT
++xMQ3gEE61OjPfswZeDfvB/brnXCGX/PgNlXkVTetc6+THBovEGbPEqKMFldAMVAYOUK6WBBDEIy
+ajBi3UbfUYgxF7gMQHJHnJBiB/kj9i4okOk6SlF3J/ewibJOtOsN1zi64rLuLgBlnI06XiXx3LZg
+0y7FqiZHxo71K+bech1XJVlgJpZjbqVkkT+T7T915cKi6Tk4fw6bzpE3Q9XABQkCx6hy60vyVKZV
+cqGH2r4pMmyw0gUHZ1Qg666IlAgMoSF6MhjyR8Fw6yRXeE00drsd+Yr+b8c2t8oqxcsYnU8a5yeL
+rbo1i3CcYyVO4nxbVKUdZTO762g6xLaOsWFlG9xyMuwiRTvc2kVE8eRBC+yElfqOMVu3aIR0LP1A
+WT1LvpNlhb/Wg6XBnK42Fk2VuQ2V0nVbKoe5dA/qyuY+8U8wYQgdlnQ9/FQqczY43pj/k/PNaDdB
+f77dzeEl38IuLZfGQMNhpSdV1B9Tr/XpGJOp7vfd6Ot3c+WIUUKAf8t8Z+pY5dlCy5vrh2+UzQ5n
+bz1vDzNDUg+zHqTvEK9ZCXBuuEEAtiCubFIjwUpdJc9RVoGyotSDqTdj+5Nf1R+j5pS1zGG5H0O7
+uijJiWwIBojVjcoWxoSzOB9eY+j/wPNl9tJuGri/XdYUlMt8u5rh9O5YONrgHeL6bROAMimek9nY
+9izFp4plFxIkC/OB+4MrDA3qFUajGdF9tOJolWSzqMDhPYteSmWdwp1FVaJ07JZpvM+xzjheG4d5
+wFoPl8N7Fd4qk6w6QRVnA3txRxcumkqBwdkwCjfH2fAR8eMj8mAg7BcN7vXH9EO6UJvWI6eO+T2s
+Re2Bb6RA//h//R69bKlUVC8qZ8cb7/YmLCoR/LAdcveYiqONwz3aOG6jlwQeNuo9shjG9Q63vyLf
+bvSG9DHKokVS6HTtudfEzqXnXfRPWex2FnOdSDWWOblUX1EbaNtbrlVV5diz1uu0VAmcFI+c8xI+
+zeeYx9rik6biiAr8s6YGZ01VV6J5y9BQ5gLyEq/S+TyB3/JtmQwlQxMtT5yzQAy8gQ7Ta2so0wLs
+BQV8iLLT2l3ieWe5EgOFbqqvAUyl6WpdrnBiDah0iM/OKuMDXaXTpcUNVdfLpFymxaB3DjlfZkKc
+8ivoN18NZah9+D0A5/L2VEglcb0jzdNw9K8AAwBBYUiqDQplbmRzdHJlYW0NZW5kb2JqDTkgMCBv
+YmoNPDwvRmlsdGVyL0ZsYXRlRGVjb2RlL0ZpcnN0IDUvTGVuZ3RoIDI5L04gMS9UeXBlL09ialN0
+bT4+c3RyZWFtDQpo3jK0VDBQiDYyB5JBCkZmEMoURMUCBBgASDEFUQ0KZW5kc3RyZWFtDWVuZG9i
+ag0xMCAwIG9iag08PC9GaWx0ZXIvRmxhdGVEZWNvZGUvRmlyc3QgNTYvTGVuZ3RoIDYxNy9OIDgv
+VHlwZS9PYmpTdG0+PnN0cmVhbQ0KaN7EU0tP3DAQ/is+0sPGbydGCHWXdgUSQhVL2UorDibrJi6J
+s3KcAv++thMWikA9cKisscf2PD7PfCYIIEAwYLwAhABRYEAoyGVYGJAoLBxIEUwEwEjmgOQAE8rA
+0RFcqF4vO+vhtXZbZdXszKvGlPCrLbutsRVcGzu3vdnvl8b1/qRWDlACo+cX3ZfO7HznIgQELuG5
+miwwK+BquPWPOw2v3KCvkhKnlHJttr7uN5QTgP4ajLMkUaeC7WdBxV7QNL89REHjLIu04zkf4yaA
+L6wQnawZEHiMJuWb8UIRRagpJ9MqBYi4RSw3paGiDFAWMUZN5jSdCpQn6ygsFD16U8nSHQ/dKXAR
+VpL0t98RLdC7g3EZ5eb4OHRy3pfa+tBgxOGJ2p1qU9Vpi2BsUbybESThslFVH+iQerBYdA+bGaY4
+3gVWMIGTy026XarWNI8HEzU+pbML1erXZInnK++0L2t40blWNeloPUJgAcFoOLdVo8EMc7jyur0O
+1Mwow8+MeKYS/PECf3reCn6/PItyUHu/O4Tw/v4++zX03pQ6q7rf2XAHq8EEWKWGZTc438+U3c68
+M7eDVU0PnzVjf0aU3nR25mKaeLTVD1nt20//NVurTOO7wxcuT3E+123p+6zqzZR/dJ3HDx8/3WKV
+Aq3Gai46t9UOrkEo3rTZJM6ExgIGT+EZvNSl32AsQgsAK2hGAqUZKjJEOWAyz/LiJrTJDaX/plxk
+T77/y+fG3o155tZ2/gkI/QiQnGZMpMRFLuJvyWjgIsckrK+AiH8BYR8HEhMzPlaEIxa+rsgkewWE
+vw/kjwADAFqkkmYNCmVuZHN0cmVhbQ1lbmRvYmoNMTEgMCBvYmoNPDwvRmlsdGVyL0ZsYXRlRGVj
+b2RlL0ZpcnN0IDYwL0xlbmd0aCAzNjAvTiA5L1R5cGUvT2JqU3RtPj5zdHJlYW0NCmjedJJrT8Iw
+FIbPTzkf4dO6djcMISEQjImBRUnwgh8Qa1wcm9kF5c+rbzsgoJBm69m5Pn1XGbFg2WHfZSXYDSNW
+sKR5WPkdVoq9ULDy2BeI+ex34Aw4UBF3u84gr7OKPWeUFGVl+gi+ca4XsNHN2NPNh3YmdZUmmS57
+PZT0TbkJjfVXZRobO14UGo1k1BQlVapb3z80ooI01gvltCLG+xXvK8qw54itaEEVJbAz+Pu0xBeT
+JGEX07yFFhMU9Gnebu/GuydGxoVemzMfjY+ppmdKMWBp29do/2YHJ7A2dAGvWTNgpMjUiJT0afPf
+4Y/hN7klqpgGqKwBuoQnJW5who9SNHLc3T9wIDnwAs7qNH1ybp3LfJrvoNWBZuLsAbzjAwytPnoP
+yuRaXcZAWcO/2kI3mrnknoMKT0P5B1DyHNT2VhxAaatBuf9xGfbKqqZPAUhPcogr+Y/gOM0FTuh7
+f9J+BRgAu1mrqw0KZW5kc3RyZWFtDWVuZG9iag0xMiAwIG9iag08PC9GaWx0ZXIvRmxhdGVEZWNv
+ZGUvRmlyc3QgODI5L0xlbmd0aCAxODA0L04gMTAwL1R5cGUvT2JqU3RtPj5zdHJlYW0NCmjexFhd
+b9s2FP0rBPa8iZffBIoCbbqiWdImaDrsIciD06iZ19QOFGdY//3OFS8d25Eda+02IM6VyKNzP3lJ
+yUallU2KtFE2K2OMclr5YJUjFZxXzqhMpJxVRM4p/JFJuPeKbAYqKHIEWFQUPOZBFQkyQ+asvFaU
+QlSeFOUMZqMMaae8hS6Lewfpg/IeMiVoVsYSZISMVvmkjON72OZgVdDKeJ1UIEiQBPD5jHvwBRgZ
+wBdSVgF8MXoVwJdgP0wwCeQBfBm+BvBl61UEX45GRVJWa9wjDBo+Q7XV4I1OWfYbVJZgfwzKGhtU
+jJAJuKQsLlTMkAAnRNMZrRAi66AcEOvJqAQ+D2cS+AL8T+ALCFICX4TyBL6UgQdfNpDgyzAOKp0G
+PiPkGsHNnB8o5dAb+JERasM4pMDyfYBEPnOEhLNwwTnoRyqcA440CL01uOAkxpJ5FwzyqjmdPQak
+UfMIJxZRIg3aiJiRBm/Co4QcuGR5BMwJYSMCc+anuFwyyoeg1+XIlYNE6n4KmddcEygZr2EsEXJv
+DI+gSAzSTpxta6CUUD4WMSNMewsPyRAKBvVJKFPvWKkBsweQ4ID3kS/AHBBBws8H1m7AHFmF4bpC
+JZABc+8FV2CywFgwc50SQuMTokUY9dnyCJhzZDDKSWsGo440HHz2rDm4mdzdvZ3c8hrS6n1zxKuI
+L04nXTtbfOjalhfU+si79q/FUftVpeb9/Kblp0HGkA9fb9vmbNHdf+xx7+fzxfPn0PKq/TS5v1mc
+o2oAw0rqlXExsPA9P5cSxEXzpp1cTWfXPxg2NRdrjg955fHVu3n3ZXLTJ6DX2E0v72eTG6AnV1dd
+e3cndL3eo3MKRRWFXGTUIkmkEWlFOpFiagwio0jhi8KXhC8JXxK+JHy5SsF54XWCE+fJCb8RvCnj
+EqlQrPBlMhRsKiaIB+KA2C/mi/VivNgupovlYrjYLWYnV3JxitXdx/msOWs/lmS+u/9yd65VdYBb
+K18Y7q18Ybm58oXj7tqbrcS7wP21N0EuLlbLozltXnXz24PJbfN6en3ftc3Ps6vZfNEi6fj3GtW0
+ctdNvrTNq+mfq/XSvLHN4exmOmvPfp+gFIWm1AzoT+4XPNmc3U5mzRoERTv93M7vFzJ3f3n3sZve
+Lm9v22514MPJC/wOWB7yBf97LSOv6whWycv5X72Nj8sU1vw6u2q7pT3Pn///xZqEr67TJHxJ+JLw
+SeUtizoIXgqTgvAG4fOCD73ei3OyMuBq9dP6qpCaIikpcnXVhPXVYuXeimFWnrOCt8JvhdcIjqIY
+QkJEdSKvLT/eC4oURSQKSAzT9TnBa1GshVcXfOkCF+fSDXJ5OvsyWld3GZVgehksRL7okUCGoq2E
+U0m0gzSHwiIRcuUBWXZyJ2mSapNik1qTUvsXm0rpywbi5PIPnHIedo6Tl7+gb3PXKU40p9eqtp/j
+6exz7emuPhs2n60TfojU5a2kL2TXYHZbo0Wen/K0+dTjxdxzoFkdYkXPFkr/pJuT5njyVfrJx/bF
+p0Xb9eP97cv207xry/1i0i3kOe8wwG3jxc30elam+vsV3t+66QLd7u38qm2Ouw+X1Xwj5ksR+e9T
+RLluA2Xn4ZAd7uksmSe8tWG3tz/2gEF/j5ZZqccVGCYzNJiz48sbmS/L6wGEuZfzq6/rZXCw3JNw
+IBoklPmN6lFuDNiPAYcx4DgGnMaA8xgw6f3RB0ObJJYjSSsbtRaPlGG43605y6JR+qGQtoLLnshO
+hSfRAHEGst5ehsRRz/QEC0e7bLrDLIYtL7vzDsvDo5o2tI/HQTw2ZhTajkK7MbE3fhQ6jELHUeg0
+Cp3HoO2oerQ0Cm1GoYdzWQ7U32nX0/9w0/t2zd+0A8W6A8n63NhH6n4sx6q07GEpr++kR+dyii48
+F4/3tBU2ObKVvjHIJse5h+6zatceu3baiFkZ+A7p4pMVxNuDw1fcb6/Vyhnt7YEc0fjTjdSaHe6I
+7Niy3/nHDZHnw+b8OkeuJ4Acd2WuHtJDjXVOjzInbwu6nv7lbUGXw1SOT2f04Q3DDL1hDOldfbq+
+f+i8F7q+nYS90GKJ3moJ8mH6rJnNrD1kpLzyrKBWwy1HBAncMIG8S63ANhionwq7Cyf1IL1DDeml
+Gj2gJvczebcW3sxy3qUk1NrLA7VXv2qV017eqWwVHZ9E/wfndb3jtM6xI7MzducU1tqDHWoPZukk
+bW0P/HF1awL6cjW0O7DLc+H67relI1FtuFXxln6y/MZglt1bvvatthT+EFxQslaNfHkw9QOh2aOp
+LL+LxK2q1uD1s4nbD16/qtBe8PrRxeTtfuNlux+Pm/ldXTvLPmDiUB+w/VTYwWDNkiEMMfDyFa92
+1FgpMr9Lj1/q8UN6+iq0breevuEYN6jmbwEGAKRNY24NCmVuZHN0cmVhbQ1lbmRvYmoNMTMgMCBv
+YmoNPDwvRXh0ZW5kcyAxMiAwIFIvRmlsdGVyL0ZsYXRlRGVjb2RlL0ZpcnN0IDUzOC9MZW5ndGgg
+ODgyL04gNjMvVHlwZS9PYmpTdG0+PnN0cmVhbQ0KaN6sVttqGzEQ/ZWBvtca3QUh4KSFBrsXmkAf
+Qh6cehMCqV3MBpq/7xmtNrbj9Wa39CGRVnPmnJmRNDKbQIrYRDIaQ6KAL4s/7TAysYsYYUoWoyEN
+CFtLOmDNOjJKvj0ZwdhAJsh3JKsFn8g6Dw5FThmMTE78nSYXZd2QZ/A7Sx4Ydo58Chg9BSu4QCH5
+HEO04p8oJuC9omTA75mSh91DWymZAKQkEg+rCgJBGswygVkCYQ8BjoIBk9YygZSO+JLcjSQfWGoB
+U84S6XIQeYVlIXVOTE4CwXIQYSeYIBSCES4Ey1KMqKL8wx/S4QhzklAlgoSEOaKoSngiqqqQEoCY
+SB1QI81GJgETCQFRaixhkjCRGiWFSZQJY3MEjLi1kZwSmC37vHfaomgQJO1YlMHsJELIaJckKDB7
+DeYE5oAdPDmZzPLBUPR98g0Vsnl2OZmfrZfPp6eNXYkpnyGA7okL5kN1t3h6rDNqKoXP6+eTL+vN
+r8UjHLOfi6/9GntLnjH2NWZ+2wJ0BpgekimhGrI6IwMwDl9PoDOymZCPK7oM0P0sXkA2HWcJGRD7
+i/YSeBwQuFzBsk9FeHefplRCnl3LncWslb/J+ajW46Khuy41aMluthEAdEhpGnCz0k2Zm0aJ0HHX
+SbL8Yrf9GagiZ7Zy7jADX1ChjLGMdkBGvhTJ+6MSe3Bd4GYQ3KUCL4mYdDwR3MX9m4IWcXCepBG2
+tYsdtdVyhIrcPsf+KdLN8Q79Wtt9DF1a+fR786aWyRS+Xyu8aPkurXxfve/Xmuae1vSfT9Vi+bC6
+f6eVKU1oe7O23juoVwxNUxrro//Bxwz2iW1zLUmXPtblvF+W4th0tVFaTY8b6RLGu8RBecjb9boC
+aZRnechGOfBYBz3WwYzbRR626+Vd2S0WuwGech3luiXbe2Vzu0rhTa7ckpLr5UoZ499sJfnHRNJ9
+XDr/mEg8sDpw0MNqElPboorrsWcrlgeoiSF3+2QOnq2mum1lWtK+5+oc3pm/9QxH+ffCKe9j8sfD
+yT882+xc16NdDt/2WOzaP66WF6tltapJvVeTr5P54nn9VE8ufy9+VtO7utrk9fx5Vt2tN1XzXS82
+dfFjFbFyVf2pp48P96vGlr8LwHjYf2weajSQz+tlNZlvrm7/k7jakz7HUrXZ1Vad0n8FGABNHxW9
+DQplbmRzdHJlYW0NZW5kb2JqDTE0IDAgb2JqDTw8L0ZpbHRlci9GbGF0ZURlY29kZS9GaXJzdCAx
+My9MZW5ndGggNDQvTiAyL1R5cGUvT2JqU3RtPj5zdHJlYW0NCmjeMjIwUDBQMDIwBGIFGxt9v9Lc
+4miIgIFCUKydHVAsWN/Fzg4gwAC4WAlEDQplbmRzdHJlYW0NZW5kb2JqDTE1IDAgb2JqDTw8L0xl
+bmd0aCA0MjMzL1N1YnR5cGUvWE1ML1R5cGUvTWV0YWRhdGE+PnN0cmVhbQ0KPD94cGFja2V0IGJl
+Z2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4KPHg6eG1wbWV0YSB4bWxu
+czp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNC4yLjEtYzA0MyA1
+Mi4zNzI3MjgsIDIwMDkvMDEvMTgtMTU6MDg6MDQgICAgICAgICI+CiAgIDxyZGY6UkRGIHhtbG5z
+OnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+CiAgICAg
+IDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiCiAgICAgICAgICAgIHhtbG5zOnhtcD0iaHR0
+cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyI+CiAgICAgICAgIDx4bXA6Q3JlYXRvclRvb2w+QWNy
+b2JhdCBQREZNYWtlciA5LjEgZm9yIFdvcmQ8L3htcDpDcmVhdG9yVG9vbD4KICAgICAgICAgPHht
+cDpNb2RpZnlEYXRlPjIwMTEtMTEtMjJUMTU6MDE6NDNaPC94bXA6TW9kaWZ5RGF0ZT4KICAgICAg
+ICAgPHhtcDpDcmVhdGVEYXRlPjIwMTEtMTEtMjJUMTU6MDE6MzVaPC94bXA6Q3JlYXRlRGF0ZT4K
+ICAgICAgICAgPHhtcDpNZXRhZGF0YURhdGU+MjAxMS0xMS0yMlQxNTowMTo0M1o8L3htcDpNZXRh
+ZGF0YURhdGU+CiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICAgICA8cmRmOkRlc2NyaXB0aW9u
+IHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczpwZGY9Imh0dHA6Ly9ucy5hZG9iZS5jb20v
+cGRmLzEuMy8iPgogICAgICAgICA8cGRmOlByb2R1Y2VyPkFjcm9iYXQgRGlzdGlsbGVyIDkuMC4w
+IChXaW5kb3dzKTwvcGRmOlByb2R1Y2VyPgogICAgICAgICA8cGRmOktleXdvcmRzLz4KICAgICAg
+PC9yZGY6RGVzY3JpcHRpb24+CiAgICAgIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiCiAg
+ICAgICAgICAgIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyI+CiAg
+ICAgICAgIDxkYzpmb3JtYXQ+YXBwbGljYXRpb24vcGRmPC9kYzpmb3JtYXQ+CiAgICAgICAgIDxk
+YzpjcmVhdG9yPgogICAgICAgICAgICA8cmRmOlNlcT4KICAgICAgICAgICAgICAgPHJkZjpsaT5t
+aWxib3VybmVqPC9yZGY6bGk+CiAgICAgICAgICAgIDwvcmRmOlNlcT4KICAgICAgICAgPC9kYzpj
+cmVhdG9yPgogICAgICAgICA8ZGM6dGl0bGU+CiAgICAgICAgICAgIDxyZGY6QWx0PgogICAgICAg
+ICAgICAgICA8cmRmOmxpIHhtbDpsYW5nPSJ4LWRlZmF1bHQiPkZyZWVkb20gb2YgSW5mb3JtYXRp
+b24gQWN0IDIwMDAgKFNlY3Rpb24gNTApPC9yZGY6bGk+CiAgICAgICAgICAgIDwvcmRmOkFsdD4K
+ICAgICAgICAgPC9kYzp0aXRsZT4KICAgICAgICAgPGRjOmRlc2NyaXB0aW9uPgogICAgICAgICAg
+ICA8cmRmOkFsdD4KICAgICAgICAgICAgICAgPHJkZjpsaSB4bWw6bGFuZz0ieC1kZWZhdWx0Ii8+
+CiAgICAgICAgICAgIDwvcmRmOkFsdD4KICAgICAgICAgPC9kYzpkZXNjcmlwdGlvbj4KICAgICAg
+PC9yZGY6RGVzY3JpcHRpb24+CiAgICAgIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiCiAg
+ICAgICAgICAgIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIj4K
+ICAgICAgICAgPHhtcE1NOkRvY3VtZW50SUQ+dXVpZDpkMTA5Zjg5Mi1iMTUyLTRlMjMtOWRjMy1l
+ZjNkZDAxMjdkOGQ8L3htcE1NOkRvY3VtZW50SUQ+CiAgICAgICAgIDx4bXBNTTpJbnN0YW5jZUlE
+PnV1aWQ6ODY4YWY5ZjUtOWQwMi00ZDg0LTg5NjUtYTg4MDhlY2NjZTljPC94bXBNTTpJbnN0YW5j
+ZUlEPgogICAgICAgICA8eG1wTU06c3ViamVjdD4KICAgICAgICAgICAgPHJkZjpTZXE+CiAgICAg
+ICAgICAgICAgIDxyZGY6bGk+MzwvcmRmOmxpPgogICAgICAgICAgICA8L3JkZjpTZXE+CiAgICAg
+ICAgIDwveG1wTU06c3ViamVjdD4KICAgICAgPC9yZGY6RGVzY3JpcHRpb24+CiAgICAgIDxyZGY6
+RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiCiAgICAgICAgICAgIHhtbG5zOnBkZng9Imh0dHA6Ly9u
+cy5hZG9iZS5jb20vcGRmeC8xLjMvIj4KICAgICAgICAgPHBkZng6Q29tcGFueT5JbmZvcm1hdGlv
+biBDb21taXNzaW9uZXJzIE9mZmljZTwvcGRmeDpDb21wYW55PgogICAgICAgICA8cGRmeDpTb3Vy
+Y2VNb2RpZmllZD5EOjIwMTExMTIyMTQ1MTE5PC9wZGZ4OlNvdXJjZU1vZGlmaWVkPgogICAgICA8
+L3JkZjpEZXNjcmlwdGlvbj4KICAgPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIAo8P3hwYWNrZXQgZW5kPSJ3
+Ij8+DQplbmRzdHJlYW0NZW5kb2JqDTE2IDAgb2JqDTw8L0ZpbHRlci9GbGF0ZURlY29kZS9GaXJz
+dCA2L0xlbmd0aCA2NC9OIDEvVHlwZS9PYmpTdG0+PnN0cmVhbQ0KaN4yMjBSMFCwsdF3zi/NK1Ew
+1ffOTCmONjIwA4oGKRiCSWMwaQomzUFkrH5IZUGqfkBiemqxnR1AgAEAHocQmg0KZW5kc3RyZWFt
+DWVuZG9iag0xNyAwIG9iag08PC9GaWx0ZXIvRmxhdGVEZWNvZGUvRmlyc3QgNi9MZW5ndGggMjMz
+L04gMS9UeXBlL09ialN0bT4+c3RyZWFtDQpo3mzPTWvDMAwG4L+io32pP9IcOkohLBTGKCt0UBi9
+JLbC3CXWsB1K//3UMlgP00lIL4+Q1RVoWK9VM5dPSmIKY09ziniW6pmm7y5exUscKE1dCRSBZ1PI
+mVtMGd6GITjkZML7uu0KivbJasNlram1qeqP3z3rjUvUdwX27XbXfWGC1cIA43Ck5KV6xeuFmyyk
+2pH/B1tWjO0T+dnhn9aGXMI43jm90HASxxA9XfJJSnXgbxwyF4aA/tFb1sasODD3Z3SFb76HMqLY
+JkRPE9AAj483roDV+qYfOH4b1ZoPbDY/AgwAP1hmow0KZW5kc3RyZWFtDWVuZG9iag0xOCAwIG9i
+ag08PC9EZWNvZGVQYXJtczw8L0NvbHVtbnMgNC9QcmVkaWN0b3IgMTI+Pi9GaWx0ZXIvRmxhdGVE
+ZWNvZGUvSURbPEFGMzNCODUxMUY5QkMyMjlEOUUwMzVDMjdFMEU4MjJFPjwzMzRCOTBBOEVENDQ5
+ODQxQkMxQzdBMTk2Qzc3M0NEOD5dL0luZm8gMjAzIDAgUi9MZW5ndGggMTE0L1Jvb3QgMjA1IDAg
+Ui9TaXplIDIwNC9UeXBlL1hSZWYvV1sxIDIgMV0+PnN0cmVhbQ0KaN5iYgACJkadPwxMDEz+QILz
+I5BgBLOcQWIWQIKFGyRmDiTYfECsSpDECRBxHEhw5AMJ5kcgiS4gIXgdSDDMBcm6A03uA3MZQQQD
+I0GC8Sdx6iCKf5CgeJQYFgTj3NEwIDfoDsFYTP/BWRIgwABfDBGsDQplbmRzdHJlYW0NZW5kb2Jq
+DXN0YXJ0eHJlZg0KMTE2DQolJUVPRg0K
+--0016e644b8d0e3913b04b600bbe4--
\ No newline at end of file diff --git a/spec/fixtures/files/quoted-subject-iso8859-1.email b/spec/fixtures/files/quoted-subject-iso8859-1.email new file mode 100644 index 000000000..6ada69905 --- /dev/null +++ b/spec/fixtures/files/quoted-subject-iso8859-1.email @@ -0,0 +1,462 @@ +From: =?iso-8859-1?Q?Coordena=E7=E3o_de_Relacionamento=2C_Pesquisa_e_Informa=E7?= + =?iso-8859-1?Q?=E3o/CEDI?= <geraldinequango@localhost> +To: FOI Person <EMAIL_TO> +MIME-Version: 1.0 +Content-Type: multipart/related; + type="multipart/alternative"; + boundary="----_=_NextPart_001_01CCB66F.F38B15FC" +Subject: =?iso-8859-1?Q?C=E2mara_Responde=3A__Banco_de_ideias?= +Date: Fri, 9 Dec 2011 10:42:02 -0200 + +This is a multi-part message in MIME format. + +------_=_NextPart_001_01CCB66F.F38B15FC +Content-Type: multipart/alternative; + boundary="----_=_NextPart_002_01CCB66F.F38B15FC" + + +------_=_NextPart_002_01CCB66F.F38B15FC +Content-Type: text/plain; + charset="iso-8859-1" +Content-Transfer-Encoding: quoted-printable + +=20 + +Senhor Benedito, + +=20 + +O Centro de Documenta=E7=E3o e Informa=E7=E3o (Cedi) da C=E2mara dos = +Deputados agradece o seu contato. + +=20 + +Em aten=E7=E3o ao solicitado, informamos que a C=E2mara dos Deputados, = +por iniciativa da Comiss=E3o de Legisla=E7=E3o Participativa - CLP, = +criou um "Banco de Id=E9ias" com o objetivo de registrar e reunir = +id=E9ias de interesse da popula=E7=E3o. As sugest=F5es s=E3o organizadas = +por temas e ficam =E0s disposi=E7=E3o para consulta de entidades da = +sociedade civil e parlamentares, que poder=E3o adot=E1-las, = +aprimorando-as ou n=E3o, para serem transformadas em sugest=E3o de = +iniciativa legislativa, no caso das entidades da sociedade civil, ou em = +proposi=E7=E3o legislativa, no caso dos parlamentares. Cabe ressaltar = +que a Comiss=E3o reserva-se o direito de editar ou resumir os textos = +recebidos. + +A seguir, o endere=E7o eletr=F4nico do Banco de Id=E9ias:=20 + +=20 + +http://www2.camara.gov.br/atividade-legislativa/comissoes/comissoes-perma= +nentes/clp/banideias.htm/banco-de-ideias + +=20 + +Atenciosamente, +***************************************************** +Coordena=E7=E3o de Relacionamento, Pesquisa e Informa=E7=E3o - Corpi +Centro de Documenta=E7=E3o e Informa=E7=E3o - Cedi +C=E2mara dos Deputados - Anexo II +Pra=E7a dos Tr=EAs Poderes - Bras=EDlia - DF=20 +70160-900=20 +Tel.: 0-XX-61- 3216-5777; fax: 0-XX-61- 3216-5757=20 +informa.cedi@camara.gov.br <mailto:informa.cedi@camara.gov.br>=20 +***************************************************** + +mbb + +=20 + +Solicita=E7=E3o:=20 + +=20 + + Prezado(a) C=E2mara dos Deputados, + + =20 + + Gostaria de sugerir que o sal=E1rio de quem trabalha com pol=EDtica + + seja vinculado ao sal=E1rio m=EDnimo. + + =20 + + Atenciosamente, + + Benedito P.B.Neto + + =20 + + ------------------------------------------------------------------- + + =20 + + Por favor use esse endere=E7o de email em todas as repostas para = +este + + pedido: + + leideacesso+request-120-9702221c@queremossaber.org.br + + =20 + + Caso este email - informa.cedi@camara.gov.br - seja o endere=E7o + + errado para fazer acesso a informa=E7=E3o por favor nos contate e + + aponte o endere=E7o correto atrav=E9s desse formul=E1rio: + + http://queremossaber.org.br/pt/help/contact + + =20 + + Aviso: Esta mensagem e todas as respostas ser=E3o publicadas na + + internet. Leia sobre nossa pol=EDtica de privacidade: + + http://queremossaber.org.br/pt/help/officers + + =20 + + Caso voc=EA ache esse servi=E7o =FAtil, por favor entre em contato. + + =20 + + =20 + + ------------------------------------------------------------------- + + +------_=_NextPart_002_01CCB66F.F38B15FC +Content-Type: text/html; + charset="iso-8859-1" +Content-Transfer-Encoding: quoted-printable + +<html xmlns:v=3D"urn:schemas-microsoft-com:vml" = +xmlns:o=3D"urn:schemas-microsoft-com:office:office" = +xmlns:w=3D"urn:schemas-microsoft-com:office:word" = +xmlns:m=3D"http://schemas.microsoft.com/office/2004/12/omml" = +xmlns=3D"http://www.w3.org/TR/REC-html40"><head><meta = +http-equiv=3DContent-Type content=3D"text/html; = +charset=3Diso-8859-1"><meta name=3DGenerator content=3D"Microsoft Word = +14 (filtered medium)"><!--[if !mso]><style>v\:* = +{behavior:url(#default#VML);} +o\:* {behavior:url(#default#VML);} +w\:* {behavior:url(#default#VML);} +.shape {behavior:url(#default#VML);} +</style><![endif]--><style><!-- +/* Font Definitions */ +@font-face + {font-family:Calibri; + panose-1:2 15 5 2 2 2 4 3 2 4;} +@font-face + {font-family:Tahoma; + panose-1:2 11 6 4 3 5 4 4 2 4;} +/* Style Definitions */ +p.MsoNormal, li.MsoNormal, div.MsoNormal + {margin:0cm; + margin-bottom:.0001pt; + font-size:11.0pt; + font-family:"Calibri","sans-serif"; + mso-fareast-language:EN-US;} +a:link, span.MsoHyperlink + {mso-style-priority:99; + color:blue; + text-decoration:underline;} +a:visited, span.MsoHyperlinkFollowed + {mso-style-priority:99; + color:purple; + text-decoration:underline;} +p.MsoPlainText, li.MsoPlainText, div.MsoPlainText + {mso-style-priority:99; + mso-style-link:"Texto sem Formata=E7=E3o Char"; + margin:0cm; + margin-bottom:.0001pt; + font-size:11.0pt; + font-family:"Calibri","sans-serif"; + mso-fareast-language:EN-US;} +p.MsoAcetate, li.MsoAcetate, div.MsoAcetate + {mso-style-priority:99; + mso-style-link:"Texto de bal=E3o Char"; + margin:0cm; + margin-bottom:.0001pt; + font-size:8.0pt; + font-family:"Tahoma","sans-serif"; + mso-fareast-language:EN-US;} +span.TextosemFormataoChar + {mso-style-name:"Texto sem Formata=E7=E3o Char"; + mso-style-priority:99; + mso-style-link:"Texto sem Formata=E7=E3o"; + font-family:"Calibri","sans-serif";} +span.TextodebaloChar + {mso-style-name:"Texto de bal=E3o Char"; + mso-style-priority:99; + mso-style-link:"Texto de bal=E3o"; + font-family:"Tahoma","sans-serif";} +.MsoChpDefault + {mso-style-type:export-only; + font-family:"Calibri","sans-serif"; + mso-fareast-language:EN-US;} +@page WordSection1 + {size:612.0pt 792.0pt; + margin:70.85pt 3.0cm 70.85pt 3.0cm;} +div.WordSection1 + {page:WordSection1;} +--></style><!--[if gte mso 9]><xml> +<o:shapedefaults v:ext=3D"edit" spidmax=3D"1026" /> +</xml><![endif]--><!--[if gte mso 9]><xml> +<o:shapelayout v:ext=3D"edit"> +<o:idmap v:ext=3D"edit" data=3D"1" /> +</o:shapelayout></xml><![endif]--></head><body lang=3DPT-BR link=3Dblue = +vlink=3Dpurple><div class=3DWordSection1><p class=3DMsoNormal><span = +style=3D'mso-fareast-language:PT-BR'><img width=3D566 height=3D58 = +id=3D"Imagem_x0020_1" src=3D"cid:image001.png@01CCB65F.2FD5C970" = +alt=3D"Descri=E7=E3o: Logo Corpi_html_1cd70d8a"><o:p></o:p></span></p><p = +class=3DMsoPlainText> <o:p></o:p></p><p class=3DMsoPlainText>Senhor = +Benedito,<o:p></o:p></p><p class=3DMsoPlainText><o:p> </o:p></p><p = +class=3DMsoPlainText>O Centro de Documenta=E7=E3o e Informa=E7=E3o = +(Cedi) da C=E2mara dos Deputados agradece o seu = +contato.<o:p></o:p></p><p class=3DMsoPlainText><o:p> </o:p></p><p = +class=3DMsoPlainText>Em aten=E7=E3o ao solicitado, informamos que a = +C=E2mara dos Deputados, por iniciativa da Comiss=E3o de Legisla=E7=E3o = +Participativa – CLP, criou um “Banco de Id=E9ias” com = +o objetivo de registrar e reunir id=E9ias de interesse da popula=E7=E3o. = +As sugest=F5es s=E3o organizadas por temas e ficam =E0s disposi=E7=E3o = +para consulta de entidades da sociedade civil e parlamentares, que = +poder=E3o adot=E1-las, aprimorando-as ou n=E3o, para serem transformadas = +em sugest=E3o de iniciativa legislativa, no caso das entidades da = +sociedade civil, ou em proposi=E7=E3o legislativa, no caso dos = +parlamentares. Cabe ressaltar que a Comiss=E3o reserva-se o direito de = +editar ou resumir os textos recebidos.<o:p></o:p></p><p = +class=3DMsoPlainText>A seguir, o endere=E7o eletr=F4nico do Banco de = +Id=E9ias: <o:p></o:p></p><p class=3DMsoPlainText><o:p> </o:p></p><p = +class=3DMsoPlainText>http://www2.camara.gov.br/atividade-legislativa/comi= +ssoes/comissoes-permanentes/clp/banideias.htm/banco-de-ideias<o:p></o:p><= +/p><p class=3DMsoPlainText><o:p> </o:p></p><p = +class=3DMsoNormal><span = +style=3D'font-size:10.0pt;font-family:"Arial","sans-serif";mso-fareast-la= +nguage:PT-BR'>Atenciosamente,<br>****************************************= +*************<br>Coordena=E7=E3o de Relacionamento, Pesquisa e = +Informa=E7=E3o – Corpi<br>Centro de Documenta=E7=E3o e = +Informa=E7=E3o – Cedi<br>C=E2mara dos Deputados – Anexo = +II<br>Pra=E7a dos Tr=EAs Poderes – Bras=EDlia – DF = +<br>70160-900 <br>Tel.: 0-XX-61- 3216-5777; fax: 0-XX-61- 3216-5757 = +<br><a href=3D"mailto:informa.cedi@camara.gov.br"><span = +style=3D'color:windowtext'>informa.cedi@camara.gov.br</span></a><br>*****= +************************************************<o:p></o:p></span></p><p = +class=3DMsoNormal><span = +style=3D'font-size:8.0pt;font-family:"Arial","sans-serif";mso-fareast-lan= +guage:PT-BR'>mbb<o:p></o:p></span></p><p = +class=3DMsoPlainText><o:p> </o:p></p><p = +class=3DMsoPlainText>Solicita=E7=E3o: <o:p></o:p></p><p = +class=3DMsoPlainText><o:p> </o:p></p><p = +class=3DMsoPlainText>=A0=A0=A0=A0 Prezado(a) C=E2mara dos = +Deputados,<o:p></o:p></p><p class=3DMsoPlainText>=A0=A0=A0=A0 = +<o:p></o:p></p><p class=3DMsoPlainText>=A0=A0=A0=A0=A0Gostaria de = +sugerir que o sal=E1rio de quem trabalha com pol=EDtica<o:p></o:p></p><p = +class=3DMsoPlainText>=A0=A0=A0=A0 seja vinculado ao sal=E1rio = +m=EDnimo.<o:p></o:p></p><p class=3DMsoPlainText>=A0=A0=A0=A0 = +<o:p></o:p></p><p = +class=3DMsoPlainText>=A0=A0=A0=A0=A0Atenciosamente,<o:p></o:p></p><p = +class=3DMsoPlainText>=A0=A0=A0=A0 Benedito P.B.Neto<o:p></o:p></p><p = +class=3DMsoPlainText>=A0=A0=A0=A0 <o:p></o:p></p><p = +class=3DMsoPlainText>=A0=A0=A0=A0=A0-------------------------------------= +------------------------------<o:p></o:p></p><p = +class=3DMsoPlainText>=A0=A0=A0=A0 <o:p></o:p></p><p = +class=3DMsoPlainText>=A0=A0=A0=A0=A0Por favor use esse endere=E7o de = +email em todas as repostas para este<o:p></o:p></p><p = +class=3DMsoPlainText>=A0=A0=A0=A0 pedido:<o:p></o:p></p><p = +class=3DMsoPlainText>=A0=A0=A0=A0 = +leideacesso+request-120-9702221c@queremossaber.org.br<o:p></o:p></p><p = +class=3DMsoPlainText>=A0=A0=A0=A0 <o:p></o:p></p><p = +class=3DMsoPlainText>=A0=A0=A0=A0=A0Caso este email - = +informa.cedi@camara.gov.br - seja o endere=E7o<o:p></o:p></p><p = +class=3DMsoPlainText>=A0=A0=A0=A0 errado para fazer acesso a = +informa=E7=E3o por favor nos contate e<o:p></o:p></p><p = +class=3DMsoPlainText>=A0=A0=A0=A0 aponte o endere=E7o correto atrav=E9s = +desse formul=E1rio:<o:p></o:p></p><p class=3DMsoPlainText>=A0=A0=A0=A0 = +http://queremossaber.org.br/pt/help/contact<o:p></o:p></p><p = +class=3DMsoPlainText>=A0=A0=A0=A0 <o:p></o:p></p><p = +class=3DMsoPlainText>=A0=A0=A0=A0=A0Aviso: Esta mensagem e todas as = +respostas ser=E3o publicadas na<o:p></o:p></p><p = +class=3DMsoPlainText>=A0=A0=A0=A0 internet. Leia sobre nossa pol=EDtica = +de privacidade:<o:p></o:p></p><p class=3DMsoPlainText>=A0=A0=A0=A0 = +http://queremossaber.org.br/pt/help/officers<o:p></o:p></p><p = +class=3DMsoPlainText>=A0=A0=A0=A0 <o:p></o:p></p><p = +class=3DMsoPlainText>=A0=A0=A0=A0=A0Caso voc=EA ache esse servi=E7o = +=FAtil, por favor entre em contato.<o:p></o:p></p><p = +class=3DMsoPlainText>=A0=A0=A0=A0 <o:p></o:p></p><p = +class=3DMsoPlainText>=A0=A0=A0=A0=A0<o:p></o:p></p><p = +class=3DMsoPlainText>=A0=A0=A0=A0=A0-------------------------------------= +------------------------------<o:p></o:p></p></div></body></html> +------_=_NextPart_002_01CCB66F.F38B15FC-- + +------_=_NextPart_001_01CCB66F.F38B15FC +Content-Type: image/png; + name="image001.png" +Content-Transfer-Encoding: base64 +Content-ID: <image001.png@01CCB65F.2FD5C970> +Content-Description: image001.png +Content-Location: image001.png + +iVBORw0KGgoAAAANSUhEUgAAAjYAAAA6CAIAAAAsiYQwAAAjEUlEQVR4nO2dB3gc1bn336nbm7pV +rWZZkiU3ucmWcQMMGBsbguFiMARM5wMSQhIuaf4INyEkfOAvBG4IJU8uJU5CQlxkXHDFvajYlixZ +stUsraTVStt3p9wzK1vI2tVom4rx/J71ejRzznvec2b2/OedOXOG5Hkerjd48LjdLp7v6eg4eKil +utr21NMzdDpVxMt58slDb789O+JmJSQkJK4TyNF2YETgwNhqbbf0dHa7a+vOXjjTve1Ia6PLxtT2 +YOCeV5wql5dEvEye544f/xOAJFESEhISIUKyLEsQxGi7EXm6Ozvr66znu7u6WhpPNeDlZ6qbWxos +1tgeM9B0N01NpDEdF63p5OpWr1spkw1HC2A0rRgGsxISEhLXC6TFYtFqtTiOj7Yn4dLGgOXc+bNV +5hMnjp902C4Z7W2tqYzNbOjp6WJcGKVUEuPieZVbaSYZttN2AjxUjjJ+6dLxJZPVo+27hISEhIQf +BImSyWQKxTV4vs+7zpg7vjrN7tlf4d5daoSoSme6zeHOtVpO82Q6rm/BPZMxeRUpswIFzl3gxFPj +49MTYm4riC0snlyQNylaFaXRYAqVWN3dYG2zNtW26fft33fvzEnZubkjVj8JCQmJ6xxSLpezLDva +bgRHp7E1fd1HCS5bS22djSKAYPPxJVWYy8Db1Tx2GtcU8vvLSRIIrhUfn8elFk5z3nrbf86YgSWM +SyEppbhxj4exOaytra2fNTTtKd/ZRDXWwDmADoqO/WnKwZGpoISEhIQEglQqlWVlZcXFxaPtSRD8 +9jfvWE63OFXj4nQ3UsDlcthBRwtOGLioTlqrydfZp1E5zxWXTJmSmplDavXJIqbcLt7E28w95nZo +O2w5e7Su63jTkfNdh4B0A0GBigYghEElLH17zApQC5dDOY7DvIxUdSUkJCSuU0iapnmedzgc18q1 +PjvAH76oK9Le2I67bOBKZvFOueu5NSkTycycfENGujo1c5zISEXGbW+zQQN/qb6pvsl5sbazu5xr +rK6rMrOnAZcDgQvKpNYAXH1zjnGsnbIEvPrUO8BEkigJCQmJ4YakKCo2NtZoNKalpY22MwHxt7+d +MssID8ZcBK4QCYnjQuGD+W88e69YHgcc7Gw/6yi/dPHSWeeZGkdXC9/e1NIAhAlwEjACaPQdN3h+ +Bhzxy9Nm9v6B9OlbMLpEQkJCYuwjRBtRUVEXzp9PTkwkKGq0/RkS+46NNTnAVAMkA3QDxXa1vLLq +Md90RmisaTRt9Bw1VXeUmU42e6wWtsftcALuAcwjXL5TorrrAyrTbfn13B/0BmaSOElISEiMGEK/ +G20wnNRoqru782JiRtufQeB58F5Y++wvxz6r3eYm587CPBgQZbaq79wbn5OYIKTh3MAzQCj/q3br +J9terCjHoAgD5srcGUJ2HGjs8r2lIIp2azxZD0xYFfE6SUhISEiII3TWGEFMUCguVVUxs2eTZG8n +PsZgu4HUG43wyy3lbld+gZwGYM5xHiC45x54SLh7hMDRSvpM85lf7vq/NhTqzCSBQSu9d4ywy/+C +hwc393zRwoQ4kcuAEhISEhLDwuV4Ii09/UhtbUxDc1ZG/FiUKFIP4Ppwx66KKnsRHVMHzRQkm2x1 +K1dkp+Xl9E/46xObbW470DSwWIiq1B/OlSYvWDPhobANSUhISEgEzTeXvObOnb/3zOaMlJU8Phan +RGqub930wYEcJpakeQIYl8eeksz8dNWUKPk3QrSxav+nbZuA5EONmQbAggu/f8pt2fHxkbAWLhj2 +C57/2Wh7ISEhITFyfCNRiUrZzKTJn1V/eu8k0dFxo8TqX/3rQENDpsbAARfFpTaD46lbCqfMLkKb +XC6XTCazdJne3vemm2kHYoiHcwOC54DBc9NueGLugghYCwwkQt+Uf7Ua9erTWFCpXifDd6N/ZSNi +cLBSArccqapJSEhEiqsGDmSMyzxTdnZfx76SBSVjanrZ+95648BXddGaNAPYCd5Q7Xbrki8++sLT +vVuRPqHv9Sff3O2sBFlE9IkH3iOjYt6Z+qNEMiECBgOgf/+Ilgf0rb3L377ec7D6RoQBKighIXHN +MXBs27Kly35/9Peq88ppmdN7XyU16s+objhy8ONfnsKSFxMYR8I5K9sJxJmvX/mdQejg+F733jZ+ ++PqJP4E2PkKX+FAIRXy46jfzE0dBn8BfCNW33LepL0vf1r7l/tl98wayZkgPxX0L0Gb/BANUKpAq ++673TQNXB1LiZoejahISEuHgZ/j1g9kPfv7lVgr0BRkZMFr6xLm9I/TgzW3nvv/8/0QlLUrBPD2A +WZhxp7kz7z+zJq/IICRjWSDJ4+cOPPX5i2BIjVTZ4DA9n/niPYlFETIYFgN62AHRRt8FwP7LfWlE +8vZfL2K/bz1c3e8PWD8gr3hEGEiVRbL7VtMvfpXMt6YjXDUJCYmg8CNRKr3qhhuX7NyzW+F2Z43W +xN44Dx54/69HXt/w70nUJAVut0GjjSPqSetzD9320LrFvakwkvzk4rmndzwO+qQIFcyBTf7g5KW/ +W/RUhAyGi2+g47vVdzmQvIGn6Z848Ktnvd13xHvwkA0O2ZKjXjUJCYkB+H+INcWgWTVv9ptbdy5S +9sxNmzXCPnmRPf3OV++9/1EGl0tTJAasBTijqf37jyx//albgbcBJrzH/V9njz+/d70JIwCL0KQP +tu510xb/6ob/jIy1CDHYmX6k8oZj3y/9AzsIVVSG405S+DWNSNUkJCQCZLB5FnBtTMKLa+776L0P +Ghacvzf7P4bdkStzQ/T+VfjdtypONEZDTBPFZQMcY6mUjoRn7pr7+svLOJbFvckOna1Yt+sn7Xgj +EHQEbkHxLDg61xYseO2GH+kDnBhpRAi/lxfPO0xdbf+QJbSrYcM0eiJ8s+FXTUJCIkD8SxTvfbJI +xtseXffQF5tLf3j4Lz9fdadCqeibiCjyeOeGQP//+eOKn7z4ywZdbLRsei7OHgVwOZ286sRr/7Vm +9ZqFQkJCeO7pwZb3/rzpZWF8BBYJfUIC6SF/nvfqz5asCb8qIeB7DwnG5Bl6gMFHn/8Bxisi9fU7 +AER8TEdoDFPVJCQkwsG/RHEcB8KU3sLFtOW3LU07V7Oh9PObsibEjM/RsIxcqewd5x1BWLfn5Imz +7/7lq/d3nU6JvSkO74nGuGqOZ60mfYb5r7/+3Xcm65BbgOP17S33nfjtwcqNoE0KY2YjL0JWDlwO +nSr6g+wnVi6+L1LVCYE+ler70+/6cGyGn2ZAvxygzyJa6zeNeHbfcRBDutc3ZN+3psNXNQkJifDx +L1EDnoiaPCE7Pln11cGvzBdborTRs2JjWjpa8/PzddERmHa2k4Hj24/8ed+R0s3nHR4iUT7VgbNa +3sg5OlyE8pGbdY+/9Pzkcd5Z+FjXf1/8x893fHbJVQOa2HCDJ5S72wM2Ys6sWb+d9Mic5Hnh1yVM +Buvv/K4fbKCEb4c+pLVA+tnBBsQH5XPgCYLdGqB74i0ZqapJSEhEisDm/OaZBGXCykV31ZVVbXac +LD25a65m8c5N+/F2a1F+8c23JAFcHVSxNvBGYKJ4jtSe++Dfx45Ud9Udwwhrp1KZnk4ZyoCVuVxG +d/fC4qRXVhWvXDqPoAQnN5858Zfa/7/xUjnLuYBWhn1xjwfGDjLdT6Y99b0Ft+vxMXTzSUJCQkKi +lwBfS4GjLl2OyfKmTE52pX2kb9l5fmMSHZc/667N/7P7Fz99JTk19abFN5aUJCWPV6k0MYPok8fj +sNpt3YePwFtf7SQrT5/yWKzGJAOrT6HVemVUPd9sdFd6zA554dT3X/zxPbPiFTIheLL0tK78/Hf7 +3AfcbhOQCiDCucbI984cAQ7L/fqFT9z/f+aQU8OwJjGiSOGLhMT1RmAS1W9It1amfyZX/0juCx8e +eW/D18/e80hh0Zo3z+0/8oMvvjS/3ZjqcdPMDHYuFsfwE3CMw4Q3NO0GXEZgRDNVc7HGTRgBIzEs +fyqG6bA5eozHif0nPdOB2B2FkwvTsz/53qLiG2YLJTGe3TV1rx78cHvPP4S3tBMkUENGZiLwwrR7 +LAsYn8rk/X3V94pGZzC9hISEhESgBPNyv34oQPXEzGefyOc2dO56ccOyWXPnvnjDfKWyZM8B07Gd +5bgZ6hm+3ORwuO1gxYDrAtABkQV4XAI/TsWzaqLerZzcLnM5qZZxcRnfU9hm3Prs0rum6QFvc3Sd +NFVv2Ltje837TbJ2QZYohXcYYchX9pAyMUjwoihDXtSk+8c/9OjsOaGakpAYSP9nra7nOE9qB4nh +IESJuowKf0a15JnfLPnnmU2fHP2qprnVMDlh/t3x2nSV0pzgvOjs5rXq8yqcq7hEYZiTUmpoGcZa +CXURvciSwidGcRnKhUVTFEatsvlizRcnPtnXVrGlvrLFXQm0DHRKgHBeJMgD5wHWA4wmNjZ5Ser8 +J5WF86YuBmyszI3rS6Qmf4tgHxHs8Hff8XIRcWO4CbPFhmkAeoCNP3aGF0oD8SUiTngSdYU78pbd +kXdrVVNLhfH81srNm3bv7Sb1bKwzPio3LVWlwOkiKtvjpJVqWomzdkJJcJVOtulrjtjuNq3ffrHW +w3a0XmAIs/AQLkGBMjr0mAkXBneA2wUMlqDOnZmZfot6Vn5mQUncxIjUdPiI1ORvY6GPuLamsAuz +xfpGtEfIneAYO4/QjW47SHxbCVKimB4gtT4ru4HUIXGYmJyMPndOLW5sa67ounCk48BfT5/4ynIA +SHILEQ0kDjgOHIEJ86dzPFgFHcJwb1iDgRJ9DzmsjvV+E0KE1Evv/yQPDO+dn8IN1XZKn1k8f+66 +6GlzUufHajQaKhKv5xhmfB/08d06YNOAuXwGTEA34Cng/nkDidUG6/iCivMGPJYknn0wP0WW+0cP +fp/wHcygeIuJ+CmyIwJZ6Uvg7Rmm80O2hq9xEfeCqnKkrg1IXJ8EKVGExt/Kq0QLx6i0hPHoswwW +rC8Bh9VR2rzr0wtHzTXnd1TXc4ntvBYHHikTdTlU6r3PhDRLUCDv29wHRlBIfsC7NQ3ADXDJu46/ +/I30aQ8Hc4g56iXzJ86fd9fCJXFR8uBqNaYRj66wq6f99ttZg08/Ih7l+HZegecNrSIhWO7/sO2A +RhiyLPEWG5BY3KbfxAFWJ5xaizgvYtPvvh6sGcNvh9DqKCHRH38SxbOD3rDxO/uR6JRICrViZc5t +6AM3I5FxdPRc+rD1rN1hP1txphEaGrAOYB12BuMxmwMIHHM67QxwWD+VQvqkkmswnAcZ30nRNF4W +R0+i59Lz3Jw7KTVxXuzCuY8qErlkiNBEstcWw/qDH5VbCwHWSLznDce+b6wpYiSQxBEk4rtbpBnH +cjtIXD/4kyjOGcCDt6FAgCJem/FDbYbwx2QAJ+fAcZujra4bc2DnGoCiiJa6OrPT2f81iizDTCgo +JOUMpPBclCJWsUIRx8bh+qufjvq269PY+fGPHU+GJGRXB4sjw088WPaxyUi2g4SEX/xJ1PDokx/k +uAKFWXR8jA6+GbyXOEKFX1uMncsjY8eTIQlnvEmAeYNK7Jcx254j3A4SEn4Z8l5U74CEMGcb6oX1 +jnQINpMTeJd3OMZVcF5IMjIjEkcdkVsp/RnhjkDkdDgQT0LzVnzgQwgMR6NF3OY12sVfo25LXEN8 +08WfONa69fM9u5w2wHGWxwmCxc4AY+JxGYbNAmAEhcm1ee76/rrFmYJimUzG997bb75k3k9SFNos +QGDCwAakajgLWAqw6UB8DdgUljHGqTY8WrxtW90fD1UzNIUDzgA/HrBk4AjgDwDkAN4BWCaSHp7H +eCJ7gnNSwe0zi8cBgaxpPE77S6++ddiaQhHQYzv04WPfzZ88Fcfxnp6esrKyadOmWq226urq8ePH +YxiWlJRkNps7OjqMRmN0dBRBkCjZxIkT1Wr1qVOn9Ho9SoZ8Rem7urqmTZvW2dlZU1NjMBgKCgpG +ZR/00qdSfX+Krx/Sjt+UgVgbcM88qLy9+E0jkt3vpsHcCISgGm1Aiw3IG6CTIZQe7J4NhAjaDL8d +IuuPxPWJIFE95q4XX/h/724pB908wDQ4WNOwS/UwEQjPRJyosjrgC++booDYA+XvfHHPc9+55Y03 +HnS73Qf37flnVTZQJwGKvcp0GmCcMJEEtCIJGwf5rVDOQ9sOZnZCUoXpzhsry5nt/3KCEulZBUDK +HrAAjPe6ge0Hkww6ScjqBoqFfbCJA9v2yVOK/rHh8Yx0hZMj39hvY5v+DeQ0MNn2P8LkA7S3t5eW +lmZkZGzduqO+vmbGjBmxsXFr1tz3wgvfP3mybOHCBbt3750/f/6hQ18vW7bs5Zd/snr13RZLz549 +e5YvX56env7aa6899NBD27dv37lz18qVdzAMM6o7QkCkLxNfOdj4Pb95A+kmBtwGDzzvkGIQ1Ca/ +bgSy7Ndg4InFRUXclLiFoJKFUOvA/QnNeN/6ANtBZL2ERCAIEvXpriN/31Y7L3HBMdCSvMfqsOtY +Qxw0tbP6KnBMhVN2KMRJppWOcuFF8RTzQdmRHzXdRispmYwcr+AS6JIuzqZw2Xk2vgZkTmjJhppW +mB4HHVbQWSGbZ20xtD06pgePpaZocTlFV0NRjMfhYZouQA2APh1YK1Dt4AI4mwAxVjong0zUaxrL +aw8/9rxh28ZHSQKTy2ilojCVGnfcWV3sdd1s7omNjUfK5HA4/vjH2paWlubmlscee+zQoUNmsy03 +N7ekpC0vb+KZM6f37duXnp7V2WmeN69YLpejGAtlz8zMnDdv3v79XyNxamlBKQdeS5SQ8EUaDtCL +1A4SI4PwBtv9NV1WVTIPejd/MccRPftuxURtHMcxOCShWIWFFAfOnKl1nTxqNLNkN045HVBR0TV3 +rrYV4tuBNHAOULcvv60wJo5gXCqSNLqZDBLXsEBgnJEis1wuT3x8ulqt5Si2Dqez+XqKyOSnKOZk +FS1wqyiy0+6Ji6JMbteEC+Bxy03E7todXY4sUpevnvTVoTM2t4uicRVoDKDuBg8Ik+4Jz0mlpCS1 +traUln5JUQSKilQqNU2TCoXigQfWvv766ygBTcs8Hndubt4NN5S8+eYb06dOPH78ZHv7pVtumYK2 +qtXqzZu3pKamzJkzOzU1qaOja3T3hMTYR7r10ovUDhIjBolxQBtxnECdPsY5L6TdWvzOz28A8L5C +ULh2d3mgREer/bbHf1V1+GA6JecJS0NjU45iCkckZYPVwzmVGvvj3711XPoQj8wyTbzWdZZXRBmx +inWLV76ytoRzA064WZYmCNbKEG6UiPa0fadt5tI/WeO0POhY2T6LoyeaNniAd4Dw9JMV2At8+mQA +FA+VoECpzRgbG2O1Wu12O1Kd6OholUq1fv16ZAkFWDiOozVoee0DD+oNBqU6iqZnIRlDa9asWeNw +OJOSEidOnOjN7oArrxtGuYTK83zfoAxM9NkviesEqVPuRWoHiRFDuNBH4leWHfiSe3VX9An6DeRj +YhKwTR+96Oi2AM8ROBkbH2PpbjaxjPAiKUx+2j7+51v+lZ5OMAyKcmYDHPLmzcDAxEEHwVK3JqdO +mTEH59lmSEsEFfAKGhfu/eA0+qK97/gl1JeH+1FReclTM+FkV3UqOfE8htttjhhDlBbA4b3H1Qp4 +PN4GgOI8buvWrfX1DU8//YRWq/3007/PnTs7Pz/38OHDlZWV999/f2dnZ1xcnMVirag4uGDBgp4e +i8lkqqmpOX369KpVq5DCxcfHVVRUVFdXo/Xz589vbcWjopCG0R9//LHBYLjlllu2bNmi0+nQpt27 +d1+8eHHt2rUjt2euffo/KCN1ahIS4XDd/ppIJCnlgjqRLFQCdMVhk/wmQ59YJF46dd+qZkqWRmJb +AKajOKjb8t9vHwKW9D5D+6VwKU7QORQU5QsPPDm/rF98zx9nAJZL8Lsrj3iKCkDp5jkRt+QLZjCf +baVJHkU0bW1t6akpnV4nEgDqAGes7ShNQ0MDim/uumvlW2+9qVDoVt99x8lTZb/4xd+XLFm0YsWK +Tz75BIVTc+fOPXXq1BtvvJGennHgwL59+75+9NF1zz13Y2dnx8MPP/Lss8/GxsYWFBSUlZWhWOqF +F15AsoSkCGU/fvy42Wyura3NyMjYsuVLvV5z5513vvrqqy+99FKE90A/BgyfG74iRuwQD/OORbDe ++h1RFtkiws84woTTo4XQnhFhZNo28FLGyIjEYbr/N0zdTqR2IomUJN07FK/x8ox5/MAkPILhMQrH +XP1fAB/rZlvYU6mQRmPkbF7rgFgMyCqIdQIrh+o8yGsApgOYSXxLpSxXXSjcQ4KzDFiKchRYFZhX +sGJuZXOwHUxOMAKPabUa5AGSPjOSUGEjx6svP99LEER8fLzL5dZoOZ1ej+EIPjMzIyYmZtq0ourq +s0J9eP6ee+4tLf1Sq1WjGOvYsWPl5WU33njjypXfQTo0c+bMcePGoZipsbEJWWtrM6JviqJmz57d +3Nzs8XhQrFZbe3b16nvQglqtFnM6PL59s5n1DUcelXJhmJvxmtg7EenRRqY9/ZY4Fhgj5yLD9Gsa +vm4nUnZQ8AQmYYHLgphmnPS0IyEYODU4z3lwkjpdYTzdZuIpHGf4otR4IkGmw6gLgLs4JkZpXH5T +XlyCClgWE25hpbHA4t6QiuF5gsdmTssRDAlzmvNtgEVDD+BicxZVIzfw3EsoauJrZRTNeyeNRfLo +vdnF2zjBQyQYPT09W7ZsQaGSTqdDIkTT1KpVq1BIdOzocYNeidTrwIEDWVlZKpXGYulWq3UorlKr +NdHRBrvdlpc30eVKM5lMeXl5wgD6g4eeeuqpqqoaggCUq6WlBWW86aabjEbjtGnTKyrKkUoWFxdH +pNF9GfAzGLB3RU5z/G7yXSn+LLDf7H4HFgdYXAiJfb3yuzXMM74hswdelwFORrAl+58s++YNvKC+ +lNjVc7yKt0DghHAw+PVQfDnYgob0UCSlSGtjVz9WP6QzIe/KYOsbzg4NodsZsqa+x2RQLvlCEt75 +w0uB64YYoAurdh+Em+4cUA+cFCThnxu3/XRLBy/Xk46uV1elrv3RigYMGBSHce5unePpJx9ITKX8 +F/INqLSabJhwAeNkctlgiTjOdmjfkWR6Mo/M87xaq+V7NeoKrHeWChQqzZ8/3263p6amoj+R/CQk +JHjvMMWbu7qzsjPdHk9TY2NGhjAlIBIhmqY5DlpamiwWS2xsXGZmFoZhvYZRFJWRka5UqlJSUtxu +149//NIPf/hDZAdtYhiGJMnOzg6TyZydnRVKG4eHyGmO+BmQSMcXSHbM3/ThvifUgxkJKrFfr3wj +gDDP+IbM7tfnADOG35K+6X3zBlWQeK8R5imzX1MiBwOEep1qsIKGjO1CqKzvnhLX1MF+cb4GfY0H +dbCFfGSGTMg1jaAPvZCoi/Z4UJnYKWCyZKk7d+6w/iHqjsxsT79HWSmCOGG8tPl4Zb4rq4Kt9Niy +LLYeHcuqWL4eThZg02h797Yth9MzMnH8jNuT6Z01ibvyeifSyWPNCuaxhfEUhaQlHsfwNI969+fb +zzV02TyeWQDHhEd/uQZgGgmgz9AO814D2Gw40ECQbkYnl/VKlAbpkLc1DFgXQBJSndOnTzc1XZo5 +05Wdna1UKuvr6xMTE3Ec1xt0n37695iYqFmzirZv3ymX0yUlJX/b+HFMtLzkhpV1dftyc3Pb29vN +ZrNCoUDSFRcXd/bs2fLy8ptvvtlmsy1YsADpk9HYvmPHzsWLF6Ll6OgY9Ilgu48KQfURvseZ71mk +SJYhEwfiQGjZQz6vDMTnEH5+wbakeF8QWd+Ggz6B9N0Uzj7tbzP8o8svEW9AkV0Z1ME2TPWNIMN3 +7JEYAYUoXPk3k6EgG/Hjarf7zbf/8jlAg6Az6NM7qI+LxZLdxLTx9BHg8yn10cL8h1sIsJEzUADG +4PKD3UV7/rADuPeuTDnOeaeFzfZmPwqMKzFBuTR1nXdKPe1hjJ+MJ++saoEzGzN54h8Ak4D7J+j1 +kC/DmCYeK8Rz2mREEc+VOc9OL0yW0QoPzyFLvGAN2ccUYEdltLW1NTc3FxYWIAlhWfbkyZN79+5F +EVVmZqZFwLRixa1bt27Nyso2Gts2bdrUabIkp2SUl5965plnysrK3n//z/n5OT09PSaT6fHHH//i +iy8efviRxsbm7m4T2rp8+fJ3333nySefLC0tnTdvXlpa2jDtgFEnqOM+qNPhcM6dhzQrgvjvWTz7 +MPkc2YJGuKsSkfwBnvSPGHwTh8ZgNgNswLHcrY+FX9PYRxh0vuyW4rdLd1nLq1Px8RyOA8Zd4rFc +1BqgBnB69YZngOMZo5UdDww7ZVrykqXj8S6LzN4KrvyjXIcgZrzG+4INbAJw5wQhQbnM8cKbdHOs +HO7gPW4cGMYOzp5MvNwCOdnCAPLpLArdAG3ldBiYeVMqYJkYdLNcqhu3EF3T9d2/f+1ZUkY6bC5X +l9vtMhlZClwec7cFvE8vNTU1O51Og8Gg0Wg8Hs/MmbN6err37v160aKSo0ePlZVVymQKuVy+aNGi +9evXu1yu1tbW1atX33vvvRs2bFAqaRQwIdWsrj53/PiJnJychAQkdUxFRdm5c+fq6uqQzejoaBRj +oYyjvZuGkcD7kaD6nQh2UgMI0OZglx1Esg+fz5EtaISjJZHixAPESF3z8bUZeAOOkcjSlxH7NfVJ +2phtCnEEicpMSNn2yvqNG3fsudQY1W0Gq47ArDywnZDkgjpUNRno9JxDrVbRCdH/QU747sNrddGa +7s62oiJDXEyNjAAGk7MYxWM8zVp6yJibGCQ/mIUgSY5xEPFxrktUvN4lN0yYcGlJSbeHnmgn9TJO +xoGdwWQKtstGxiaxXTypUoCNF6RxXJzONkVXsGLVggkTxgle8thNaZrGqXYt69b2JEcZhKdxFQpF +fv4klUqJQigMwxISErq7LUuXLn3ttV/r9Ya1ax9AqlNRUXHhQv3Ro0eefvrpysrKCRMmIJVCUdHR +o0fvvPPO/fv3z549a+rU6Z2dHUiu3n33XaVSOXPmzAceeOCjjz4qKirasmVLbGxs77Szw4rvvQoY +hkNK5PwrIiVG1u0Aw51wjIeQfcRkbCQ9iVRj9i0MdrIfQmg7pM2gPAwt+2gREbfFzzAi1e1E/BZU +H5dnOh+fHf+Dl+77ntveYTLZLXoMs+DAd4DTKcybRyGJikYSpVGpxkUrruTUGmJef2GN3G0ieNaD +I4mieYyQsRYradB5jCjI6SEJOcc6iRiVx9hDy5Plqgl3x9+6bCbKayNjUEqU3oPJlazJSsYomG6O +UquRNArPSxlkV7+ySqGmPvrj3RZcr2NcBGNVaAxoZVRU1IIFJVarrXcs+NSpU0EYho6//PLLfaMr +CgoKMjIyULyF9KykpIQgiLi4OLQVqRTaevfdd6M1SN6yszMnTy4sLS1duXJlb8Y1a9agTWazWavV +4qKDDwcFibzLGUTy4Gc6F9nk1/KAH3mA2QdLH5TbgZc4mLfhONz/1rdIdr8+h5AxtJYMhOFugTA9 +GfJgGOwIFJGfQAoKPGOYDF8DihcR8pEZrBuBdDsidkLzQZyr3rdE0Mr4BKXwfKxwiQ9SRXNi4IlX +8qCMunq1QSt8C+8n7Kcycd6VQBMKmhY0TgNXvgRivEu9s7gONpcrFq2Jib7s8DeGVSo1+lx2nrg8 +OwWGQf/5ilQqVf8E/V8x1X8Zadjtt9/e92dvYr1eP4g/Q8NjkHTr8uCyDK4xQWUZ7PKL76YhsweY +3u/RGaBvImlEKiKecbA1ISQIJ2MILRnUcggFie9BEbMBbg32GPa7ryN+IA25NfwGDMG4+Dll4In9 +rg+coCwH3hdFSqvCeCUgJus3h9+3gci+IBHHsI9/tiyCBscyImfBEmOf4btKIxEa0g+qj3Ak6luk +TsMDdT21kNTHXbuM5L6TjpMAuVYaarj9/Ja8WF1CQkJC4tuHJFESEhISEmMUSaIkJCQkJMYokkRJ +SEhISIxR/heHXcIrMvkS1gAAAABJRU5ErkJggg== + +------_=_NextPart_001_01CCB66F.F38B15FC--
\ No newline at end of file diff --git a/spec/fixtures/files/useless_raw_email.email b/spec/fixtures/files/raw_emails/1.email index 2e4585af7..2e4585af7 100644 --- a/spec/fixtures/files/useless_raw_email.email +++ b/spec/fixtures/files/raw_emails/1.email diff --git a/spec/fixtures/files/raw_emails/2.email b/spec/fixtures/files/raw_emails/2.email new file mode 100644 index 000000000..eab0b0f8d --- /dev/null +++ b/spec/fixtures/files/raw_emails/2.email @@ -0,0 +1,20 @@ +From: "FOI Person" <foiperson@localhost> +To: "Bob Smith" <bob@localhost> +Date: Tue, 13 Nov 2007 11:39:55 +0000 +Bcc: +Subject: Re: Your email +Reply-To: +In-Reply-To: <471f1eae5d1cb_7347..fdbe67386164@cat.tmail> +Content-Type: text/plain; charset=utf-8 + +Dear “Bob”, + +In the financial year 2010–2011, this Department spent a +total of nine hundred of your earth pounds on the purchase +and repair of boring equipment. + +Yours most sincerely, + +Quentin Nobble-Boston, +Permanent Under-Secretary, +Department for Humpadinking diff --git a/spec/fixtures/files/raw_emails/3.email b/spec/fixtures/files/raw_emails/3.email new file mode 100644 index 000000000..a6e780fe5 --- /dev/null +++ b/spec/fixtures/files/raw_emails/3.email @@ -0,0 +1,19 @@ +From: "The Minister" <msw@localhost> +To: "Bob Smith" <bob@localhost> +Date: Tue, 13 Nov 2009 11:39:55 +0000 +Bcc: +Subject: Re: Your message +Reply-To: +In-Reply-To: <471f1eae5d1cb_7347..fdbe67386165@cat.tmail> +Content-Type: text/plain; charset=utf-8 + +Dear “Bob”, + +In the financial year 2010–2011, this Ministry spent precisely +no money at all on the purchase or repair of boring equipment. + +Yours most sincerely, + +Martin Kibble-von Scratsching, +Chief Assistant to the Assistant Chief, +Ministry of Silly Walks diff --git a/spec/fixtures/files/raw_emails/4.email b/spec/fixtures/files/raw_emails/4.email new file mode 100644 index 000000000..c778e5ba9 --- /dev/null +++ b/spec/fixtures/files/raw_emails/4.email @@ -0,0 +1,17 @@ +From: "The Minister" <msw@localhost> +To: robin@localhost +Date: Tue, 13 Nov 2008 11:39:55 +0000 +Bcc: +Subject: Re: v1agra +Reply-To: +In-Reply-To: <fdshjksdahhjkfsdahjkfsd@gfh.example.com> +Content-Type: text/plain; charset=utf-8 + +Thank you for your spam, which we have processed with pleasure. Please +accept herewith our order for six packs of the finest cheap v1agra. + +Yours most sincerely, + +Martin Kibble-von Scratsching, +Chief Assistant to the Assistant Chief, +Ministry of Silly Walks diff --git a/spec/fixtures/files/raw_emails/5.email b/spec/fixtures/files/raw_emails/5.email new file mode 100644 index 000000000..16b65610a --- /dev/null +++ b/spec/fixtures/files/raw_emails/5.email @@ -0,0 +1,17 @@ +From: "The Minister" <sensewalk@localhost> +To: robin@localhost +Date: Tue, 13 Nov 2008 12:39:55 +0000 +Bcc: +Subject: Re: v1agra +Reply-To: +In-Reply-To: <fdshjks+hihhjkfsdahjkfsd@gfh.example.com> +Content-Type: text/plain; charset=utf-8 + +Thank you for your spam, which we have processed with pleasure. Please +accept herewith our order for six packs of the finest cheap v1agra. + +Yours most sincerely, + +Martin Scratsching-von Kibble, +Assistant (Second class) to the Chief Assistant to the Assistant Chief, +Ministry of Sensible Walks diff --git a/spec/fixtures/files/track-response-abcmail-oof.email b/spec/fixtures/files/track-response-abcmail-oof.email new file mode 100644 index 000000000..5d1733143 --- /dev/null +++ b/spec/fixtures/files/track-response-abcmail-oof.email @@ -0,0 +1,80 @@ +Delivered-To: mysociety.robin@gmail.com +Received: by 10.216.154.212 with SMTP id h62cs265517wek; + Fri, 30 Dec 2011 02:03:17 -0800 (PST) +Received: by 10.227.208.129 with SMTP id gc1mr47630338wbb.4.1325239396543; + Fri, 30 Dec 2011 02:03:16 -0800 (PST) +Return-Path: <Name.Removed@example.gov.uk> +Received: from wildfire.ukcod.org.uk (wildfire.ukcod.org.uk. [89.238.145.74]) + by mx.google.com with ESMTPS id ei10si9596065wbb.20.2011.12.30.02.03.16 + (version=TLSv1/SSLv3 cipher=OTHER); + Fri, 30 Dec 2011 02:03:16 -0800 (PST) +Received-SPF: neutral (google.com: 89.238.145.74 is neither permitted nor denied by best guess record for domain of Name.Removed@example.gov.uk) client-ip=89.238.145.74; +Authentication-Results: mx.google.com; spf=neutral (google.com: 89.238.145.74 is neither permitted nor denied by best guess record for domain of Name.Removed@example.gov.uk) smtp.mail=Name.Removed@example.gov.uk +Received: from foi by wildfire.ukcod.org.uk with local (Exim 4.72) + (envelope-from <Name.Removed@example.gov.uk>) + id 1RgZIs-0000ME-1T + for team_delivery@whatdotheyknow.com; Fri, 30 Dec 2011 10:03:10 +0000 +Received: from truro.icritical.com ([93.95.13.13]:51540) + by wildfire.ukcod.org.uk with smtp (Exim 4.72) + (envelope-from <Name.Removed@example.gov.uk>) + id 1RgZIq-0000M6-St + for track@whatdotheyknow.com; Fri, 30 Dec 2011 10:03:09 +0000 +Received: (qmail 19136 invoked from network); 30 Dec 2011 10:03:08 -0000 +Received: from localhost (127.0.0.1) + by truro.icritical.com with SMTP; 30 Dec 2011 10:03:08 -0000 +Received: from truro.icritical.com ([127.0.0.1]) + by localhost (truro.icritical.com [127.0.0.1]) (amavisd-new, port 10024) + with SMTP id 19122-01 for <track@whatdotheyknow.com>; + Fri, 30 Dec 2011 10:03:07 +0000 (GMT) +Received: (qmail 19112 invoked by uid 599); 30 Dec 2011 10:03:06 -0000 +Received: from unknown (HELO abcmail.example.gov.uk) (213.185.212.82) + by truro.icritical.com (qpsmtpd/0.28) with ESMTP; Fri, 30 Dec 2011 10:03:06 +0000 +Subject: AUTO: Name Removed is out of the office (returning 03/01/2012) +Auto-Submitted: auto-generated +From: Name.Removed@example.gov.uk +To: track@whatdotheyknow.com +Message-ID: <OFF4E36F18.ED02EFA3-ON80257976.00373794-80257976.00373794@example.gov.uk> +Date: Fri, 30 Dec 2011 10:03:07 +0000 +X-MIMETrack: Serialize by Router on ABCMail/SVR/ABC(Release 8.5.2FP1|November 29, 2010) at + 30/12/2011 10:03:07 +MIME-Version: 1.0 +Content-type: text/plain; charset=US-ASCII +X-Virus-Scanned: by iCritical at truro.icritical.com + + +I am out of the office until 03/01/2012. + +I will be out of the office until 3rd January December 2012. I will deal +with all emails upon my return. If your query is urgent please contact +Colleague Name on colleague.name@example.gov.uk or 01234 567890. + +If you are requesting information under the Freedom of Information Act, the +Environmental Information Regulations or the Data Protection Act, please +forward your enquiry to colleague.name@example.gov.uk The Council +will begin processing your request once it is received by that address. + + +Thanks + +Name + + + + + +Note: This is an automated response to your message "Your WhatDoTheyKnow +email alert" sent on 30/12/2011 06:54:19. + +This is the only notification you will receive while this person is away. + + +This e-mail and any files transmitted with it are confidential and +intended solely for the use of the individual or entity to whom +they are addressed. +If you have received this e-mail in error please notify the +originator of the message. This footer also confirms that this +e-mail message has been scanned for the presence of computer viruses. + +Any views expressed in this message are those of the individual +sender, except where the sender specifies and with authority, +states them to be the views of Organisation Name. diff --git a/spec/fixtures/files/track-response-outlook-oof.email b/spec/fixtures/files/track-response-outlook-oof.email new file mode 100644 index 000000000..ee5a28b15 --- /dev/null +++ b/spec/fixtures/files/track-response-outlook-oof.email @@ -0,0 +1,587 @@ +Delivered-To: mysociety.robin@gmail.com +Received: by 10.152.24.138 with SMTP id u10cs341636laf; + Thu, 8 Dec 2011 02:39:53 -0800 (PST) +Received: by 10.180.103.131 with SMTP id fw3mr4246912wib.57.1323340792168; + Thu, 08 Dec 2011 02:39:52 -0800 (PST) +Return-Path: <peter@kentadvice.co.uk> +Received: from wildfire.ukcod.org.uk (wildfire.ukcod.org.uk. [89.238.145.74]) + by mx.google.com with ESMTPS id ft12si3357577wbb.14.2011.12.08.02.39.51 + (version=TLSv1/SSLv3 cipher=OTHER); + Thu, 08 Dec 2011 02:39:52 -0800 (PST) +Received-SPF: neutral (google.com: 89.238.145.74 is neither permitted nor denied by best guess record for domain of peter@kentadvice.co.uk) client-ip=89.238.145.74; +Authentication-Results: mx.google.com; spf=neutral (google.com: 89.238.145.74 is neither permitted nor denied by best guess record for domain of peter@kentadvice.co.uk) smtp.mail=peter@kentadvice.co.uk +Received: from foi by wildfire.ukcod.org.uk with local (Exim 4.72) + (envelope-from <peter@kentadvice.co.uk>) + id 1RYbOC-00034X-Vm + for team_delivery@whatdotheyknow.com; Thu, 08 Dec 2011 10:39:45 +0000 +Received: from mail-ey0-f173.google.com ([209.85.215.173]:38997) + by wildfire.ukcod.org.uk with esmtp (Exim 4.72) + (envelope-from <peter@kentadvice.co.uk>) + id 1RYbOC-00034L-GF + for track@whatdotheyknow.com; Thu, 08 Dec 2011 10:39:44 +0000 +Received: by eaai10 with SMTP id i10so1168752eaa.32 + for <track@whatdotheyknow.com>; Thu, 08 Dec 2011 02:39:33 -0800 (PST) +Received: by 10.213.21.148 with SMTP id j20mr131258ebb.87.1323340773446; + Thu, 08 Dec 2011 02:39:33 -0800 (PST) +Received: from PRWin7 (cpc2-tilb7-2-0-cust982.basl.cable.virginmedia.com. [94.168.103.215]) + by mx.google.com with ESMTPS id 49sm16411187eec.1.2011.12.08.02.39.31 + (version=TLSv1/SSLv3 cipher=OTHER); + Thu, 08 Dec 2011 02:39:32 -0800 (PST) +From: "Name Removed" <name-removed@example.co.uk> +To: <track@whatdotheyknow.com> +Subject: Out of Office reply +Date: Thu, 8 Dec 2011 10:39:24 -0000 +Message-ID: <00ab01ccb595$aada0070$008e0150$@co.uk> +MIME-Version: 1.0 +Content-Type: multipart/alternative; + boundary="----=_NextPart_000_00AC_01CCB595.AADA0070" +X-Mailer: Microsoft Office Outlook 12.0 +Thread-Index: Acy1laTpNPAp9QuHRu2X59T70yzpQw== +Content-Language: en-gb + +This is a multi-part message in MIME format. + +------=_NextPart_000_00AC_01CCB595.AADA0070 +Content-Type: text/plain; + charset="US-ASCII" +Content-Transfer-Encoding: 7bit + +Thank you for your message. I am currently out of the office, with [limited] +[no] access to e-mail. + +I will be returning on [day, date]. + +If you need assistance before then, you may reach me at [phone number]. +For urgent issues, please contact [name] at [e-mail address] or [telephone +number]. + +[Signature] + +[Optional: Type your favorite quotation or saying here along with the author +or source] + +------=_NextPart_000_00AC_01CCB595.AADA0070 +Content-Type: text/html; + charset="US-ASCII" +Content-Transfer-Encoding: quoted-printable + +<html xmlns:v=3D"urn:schemas-microsoft-com:vml" = +xmlns:o=3D"urn:schemas-microsoft-com:office:office" = +xmlns:w=3D"urn:schemas-microsoft-com:office:word" = +xmlns:x=3D"urn:schemas-microsoft-com:office:excel" = +xmlns:p=3D"urn:schemas-microsoft-com:office:powerpoint" = +xmlns:a=3D"urn:schemas-microsoft-com:office:access" = +xmlns:dt=3D"uuid:C2F41010-65B3-11d1-A29F-00AA00C14882" = +xmlns:s=3D"uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882" = +xmlns:rs=3D"urn:schemas-microsoft-com:rowset" xmlns:z=3D"#RowsetSchema" = +xmlns:b=3D"urn:schemas-microsoft-com:office:publisher" = +xmlns:ss=3D"urn:schemas-microsoft-com:office:spreadsheet" = +xmlns:c=3D"urn:schemas-microsoft-com:office:component:spreadsheet" = +xmlns:oa=3D"urn:schemas-microsoft-com:office:activation" = +xmlns:html=3D"http://www.w3.org/TR/REC-html40" = +xmlns:q=3D"http://schemas.xmlsoap.org/soap/envelope/" xmlns:D=3D"DAV:" = +xmlns:x2=3D"http://schemas.microsoft.com/office/excel/2003/xml" = +xmlns:ois=3D"http://schemas.microsoft.com/sharepoint/soap/ois/" = +xmlns:dir=3D"http://schemas.microsoft.com/sharepoint/soap/directory/" = +xmlns:ds=3D"http://www.w3.org/2000/09/xmldsig#" = +xmlns:dsp=3D"http://schemas.microsoft.com/sharepoint/dsp" = +xmlns:udc=3D"http://schemas.microsoft.com/data/udc" = +xmlns:xsd=3D"http://www.w3.org/2001/XMLSchema" = +xmlns:sub=3D"http://schemas.microsoft.com/sharepoint/soap/2002/1/alerts/"= + xmlns:ec=3D"http://www.w3.org/2001/04/xmlenc#" = +xmlns:sp=3D"http://schemas.microsoft.com/sharepoint/" = +xmlns:sps=3D"http://schemas.microsoft.com/sharepoint/soap/" = +xmlns:xsi=3D"http://www.w3.org/2001/XMLSchema-instance" = +xmlns:udcxf=3D"http://schemas.microsoft.com/data/udc/xmlfile" = +xmlns:wf=3D"http://schemas.microsoft.com/sharepoint/soap/workflow/" = +xmlns:mver=3D"http://schemas.openxmlformats.org/markup-compatibility/2006= +" xmlns:m=3D"http://schemas.microsoft.com/office/2004/12/omml" = +xmlns:mrels=3D"http://schemas.openxmlformats.org/package/2006/relationshi= +ps" = +xmlns:ex12t=3D"http://schemas.microsoft.com/exchange/services/2006/types"= + = +xmlns:ex12m=3D"http://schemas.microsoft.com/exchange/services/2006/messag= +es" xmlns=3D"http://www.w3.org/TR/REC-html40"> + +<head> +<META HTTP-EQUIV=3D"Content-Type" CONTENT=3D"text/html; = +charset=3Dus-ascii"> + + +<meta name=3DProgId content=3DWord.Document> +<meta name=3DGenerator content=3D"Microsoft Word 12"> +<meta name=3DOriginator content=3D"Microsoft Word 12"> +<link rel=3DFile-List href=3D"cid:filelist.xml@01C895B2.35BC4F70"> +<!--[if gte mso 9]><xml> + <o:OfficeDocumentSettings> + <o:AllowPNG/> + <o:TargetScreenSize>1024x768</o:TargetScreenSize> + </o:OfficeDocumentSettings> +</xml><![endif]--> +<link rel=3DthemeData href=3D"~~themedata~~"> +<link rel=3DcolorSchemeMapping href=3D"~~colorschememapping~~"> +<!--[if gte mso 9]><xml> + <w:WordDocument> + <w:SpellingState>Clean</w:SpellingState> + <w:TrackMoves/> + <w:TrackFormatting/> + <w:EnvelopeVis/> + <w:ValidateAgainstSchemas/> + <w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid> + <w:IgnoreMixedContent>false</w:IgnoreMixedContent> + <w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText> + <w:DoNotPromoteQF/> + <w:LidThemeOther>EN-US</w:LidThemeOther> + <w:LidThemeAsian>X-NONE</w:LidThemeAsian> + <w:LidThemeComplexScript>X-NONE</w:LidThemeComplexScript> + <w:Compatibility> + <w:DoNotExpandShiftReturn/> + <w:BreakWrappedTables/> + <w:SnapToGridInCell/> + <w:WrapTextWithPunct/> + <w:UseAsianBreakRules/> + <w:DontGrowAutofit/> + <w:SplitPgBreakAndParaMark/> + <w:DontVertAlignCellWithSp/> + <w:DontBreakConstrainedForcedTables/> + <w:DontVertAlignInTxbx/> + <w:Word11KerningPairs/> + <w:CachedColBalance/> + </w:Compatibility> + <w:BrowserLevel>MicrosoftInternetExplorer4</w:BrowserLevel> + <m:mathPr> + <m:mathFont m:val=3D"Cambria Math"/> + <m:brkBin m:val=3D"before"/> + <m:brkBinSub m:val=3D"--"/> + <m:smallFrac m:val=3D"off"/> + <m:dispDef/> + <m:lMargin m:val=3D"0"/> + <m:rMargin m:val=3D"0"/> + <m:defJc m:val=3D"centerGroup"/> + <m:wrapIndent m:val=3D"1440"/> + <m:intLim m:val=3D"subSup"/> + <m:naryLim m:val=3D"undOvr"/> + </m:mathPr></w:WordDocument> +</xml><![endif]--><!--[if gte mso 9]><xml> + <w:LatentStyles DefLockedState=3D"false" DefUnhideWhenUsed=3D"true"=20 + DefSemiHidden=3D"true" DefQFormat=3D"false" DefPriority=3D"99"=20 + LatentStyleCount=3D"267"> + <w:LsdException Locked=3D"false" Priority=3D"0" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" QFormat=3D"true" Name=3D"Normal"/> + <w:LsdException Locked=3D"false" Priority=3D"9" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" QFormat=3D"true" Name=3D"heading 1"/> + <w:LsdException Locked=3D"false" Priority=3D"9" QFormat=3D"true" = +Name=3D"heading 2"/> + <w:LsdException Locked=3D"false" Priority=3D"9" QFormat=3D"true" = +Name=3D"heading 3"/> + <w:LsdException Locked=3D"false" Priority=3D"9" QFormat=3D"true" = +Name=3D"heading 4"/> + <w:LsdException Locked=3D"false" Priority=3D"9" QFormat=3D"true" = +Name=3D"heading 5"/> + <w:LsdException Locked=3D"false" Priority=3D"9" QFormat=3D"true" = +Name=3D"heading 6"/> + <w:LsdException Locked=3D"false" Priority=3D"9" QFormat=3D"true" = +Name=3D"heading 7"/> + <w:LsdException Locked=3D"false" Priority=3D"9" QFormat=3D"true" = +Name=3D"heading 8"/> + <w:LsdException Locked=3D"false" Priority=3D"9" QFormat=3D"true" = +Name=3D"heading 9"/> + <w:LsdException Locked=3D"false" Priority=3D"39" Name=3D"toc 1"/> + <w:LsdException Locked=3D"false" Priority=3D"39" Name=3D"toc 2"/> + <w:LsdException Locked=3D"false" Priority=3D"39" Name=3D"toc 3"/> + <w:LsdException Locked=3D"false" Priority=3D"39" Name=3D"toc 4"/> + <w:LsdException Locked=3D"false" Priority=3D"39" Name=3D"toc 5"/> + <w:LsdException Locked=3D"false" Priority=3D"39" Name=3D"toc 6"/> + <w:LsdException Locked=3D"false" Priority=3D"39" Name=3D"toc 7"/> + <w:LsdException Locked=3D"false" Priority=3D"39" Name=3D"toc 8"/> + <w:LsdException Locked=3D"false" Priority=3D"39" Name=3D"toc 9"/> + <w:LsdException Locked=3D"false" Priority=3D"35" QFormat=3D"true" = +Name=3D"caption"/> + <w:LsdException Locked=3D"false" Priority=3D"10" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" QFormat=3D"true" Name=3D"Title"/> + <w:LsdException Locked=3D"false" Priority=3D"1" Name=3D"Default = +Paragraph Font"/> + <w:LsdException Locked=3D"false" Priority=3D"11" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" QFormat=3D"true" Name=3D"Subtitle"/> + <w:LsdException Locked=3D"false" Priority=3D"22" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" QFormat=3D"true" Name=3D"Strong"/> + <w:LsdException Locked=3D"false" Priority=3D"20" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" QFormat=3D"true" Name=3D"Emphasis"/> + <w:LsdException Locked=3D"false" Priority=3D"59" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Table Grid"/> + <w:LsdException Locked=3D"false" UnhideWhenUsed=3D"false" = +Name=3D"Placeholder Text"/> + <w:LsdException Locked=3D"false" Priority=3D"1" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" QFormat=3D"true" Name=3D"No Spacing"/> + <w:LsdException Locked=3D"false" Priority=3D"60" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Light Shading"/> + <w:LsdException Locked=3D"false" Priority=3D"61" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Light List"/> + <w:LsdException Locked=3D"false" Priority=3D"62" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Light Grid"/> + <w:LsdException Locked=3D"false" Priority=3D"63" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Medium Shading 1"/> + <w:LsdException Locked=3D"false" Priority=3D"64" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Medium Shading 2"/> + <w:LsdException Locked=3D"false" Priority=3D"65" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Medium List 1"/> + <w:LsdException Locked=3D"false" Priority=3D"66" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Medium List 2"/> + <w:LsdException Locked=3D"false" Priority=3D"67" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Medium Grid 1"/> + <w:LsdException Locked=3D"false" Priority=3D"68" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Medium Grid 2"/> + <w:LsdException Locked=3D"false" Priority=3D"69" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Medium Grid 3"/> + <w:LsdException Locked=3D"false" Priority=3D"70" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Dark List"/> + <w:LsdException Locked=3D"false" Priority=3D"71" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Colorful Shading"/> + <w:LsdException Locked=3D"false" Priority=3D"72" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Colorful List"/> + <w:LsdException Locked=3D"false" Priority=3D"73" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Colorful Grid"/> + <w:LsdException Locked=3D"false" Priority=3D"60" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Light Shading Accent 1"/> + <w:LsdException Locked=3D"false" Priority=3D"61" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Light List Accent 1"/> + <w:LsdException Locked=3D"false" Priority=3D"62" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Light Grid Accent 1"/> + <w:LsdException Locked=3D"false" Priority=3D"63" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Medium Shading 1 Accent 1"/> + <w:LsdException Locked=3D"false" Priority=3D"64" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Medium Shading 2 Accent 1"/> + <w:LsdException Locked=3D"false" Priority=3D"65" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Medium List 1 Accent 1"/> + <w:LsdException Locked=3D"false" UnhideWhenUsed=3D"false" = +Name=3D"Revision"/> + <w:LsdException Locked=3D"false" Priority=3D"34" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" QFormat=3D"true" Name=3D"List Paragraph"/> + <w:LsdException Locked=3D"false" Priority=3D"29" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" QFormat=3D"true" Name=3D"Quote"/> + <w:LsdException Locked=3D"false" Priority=3D"30" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" QFormat=3D"true" Name=3D"Intense Quote"/> + <w:LsdException Locked=3D"false" Priority=3D"66" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Medium List 2 Accent 1"/> + <w:LsdException Locked=3D"false" Priority=3D"67" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Medium Grid 1 Accent 1"/> + <w:LsdException Locked=3D"false" Priority=3D"68" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Medium Grid 2 Accent 1"/> + <w:LsdException Locked=3D"false" Priority=3D"69" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Medium Grid 3 Accent 1"/> + <w:LsdException Locked=3D"false" Priority=3D"70" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Dark List Accent 1"/> + <w:LsdException Locked=3D"false" Priority=3D"71" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Colorful Shading Accent 1"/> + <w:LsdException Locked=3D"false" Priority=3D"72" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Colorful List Accent 1"/> + <w:LsdException Locked=3D"false" Priority=3D"73" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Colorful Grid Accent 1"/> + <w:LsdException Locked=3D"false" Priority=3D"60" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Light Shading Accent 2"/> + <w:LsdException Locked=3D"false" Priority=3D"61" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Light List Accent 2"/> + <w:LsdException Locked=3D"false" Priority=3D"62" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Light Grid Accent 2"/> + <w:LsdException Locked=3D"false" Priority=3D"63" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Medium Shading 1 Accent 2"/> + <w:LsdException Locked=3D"false" Priority=3D"64" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Medium Shading 2 Accent 2"/> + <w:LsdException Locked=3D"false" Priority=3D"65" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Medium List 1 Accent 2"/> + <w:LsdException Locked=3D"false" Priority=3D"66" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Medium List 2 Accent 2"/> + <w:LsdException Locked=3D"false" Priority=3D"67" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Medium Grid 1 Accent 2"/> + <w:LsdException Locked=3D"false" Priority=3D"68" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Medium Grid 2 Accent 2"/> + <w:LsdException Locked=3D"false" Priority=3D"69" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Medium Grid 3 Accent 2"/> + <w:LsdException Locked=3D"false" Priority=3D"70" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Dark List Accent 2"/> + <w:LsdException Locked=3D"false" Priority=3D"71" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Colorful Shading Accent 2"/> + <w:LsdException Locked=3D"false" Priority=3D"72" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Colorful List Accent 2"/> + <w:LsdException Locked=3D"false" Priority=3D"73" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Colorful Grid Accent 2"/> + <w:LsdException Locked=3D"false" Priority=3D"60" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Light Shading Accent 3"/> + <w:LsdException Locked=3D"false" Priority=3D"61" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Light List Accent 3"/> + <w:LsdException Locked=3D"false" Priority=3D"62" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Light Grid Accent 3"/> + <w:LsdException Locked=3D"false" Priority=3D"63" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Medium Shading 1 Accent 3"/> + <w:LsdException Locked=3D"false" Priority=3D"64" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Medium Shading 2 Accent 3"/> + <w:LsdException Locked=3D"false" Priority=3D"65" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Medium List 1 Accent 3"/> + <w:LsdException Locked=3D"false" Priority=3D"66" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Medium List 2 Accent 3"/> + <w:LsdException Locked=3D"false" Priority=3D"67" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Medium Grid 1 Accent 3"/> + <w:LsdException Locked=3D"false" Priority=3D"68" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Medium Grid 2 Accent 3"/> + <w:LsdException Locked=3D"false" Priority=3D"69" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Medium Grid 3 Accent 3"/> + <w:LsdException Locked=3D"false" Priority=3D"70" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Dark List Accent 3"/> + <w:LsdException Locked=3D"false" Priority=3D"71" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Colorful Shading Accent 3"/> + <w:LsdException Locked=3D"false" Priority=3D"72" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Colorful List Accent 3"/> + <w:LsdException Locked=3D"false" Priority=3D"73" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Colorful Grid Accent 3"/> + <w:LsdException Locked=3D"false" Priority=3D"60" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Light Shading Accent 4"/> + <w:LsdException Locked=3D"false" Priority=3D"61" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Light List Accent 4"/> + <w:LsdException Locked=3D"false" Priority=3D"62" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Light Grid Accent 4"/> + <w:LsdException Locked=3D"false" Priority=3D"63" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Medium Shading 1 Accent 4"/> + <w:LsdException Locked=3D"false" Priority=3D"64" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Medium Shading 2 Accent 4"/> + <w:LsdException Locked=3D"false" Priority=3D"65" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Medium List 1 Accent 4"/> + <w:LsdException Locked=3D"false" Priority=3D"66" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Medium List 2 Accent 4"/> + <w:LsdException Locked=3D"false" Priority=3D"67" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Medium Grid 1 Accent 4"/> + <w:LsdException Locked=3D"false" Priority=3D"68" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Medium Grid 2 Accent 4"/> + <w:LsdException Locked=3D"false" Priority=3D"69" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Medium Grid 3 Accent 4"/> + <w:LsdException Locked=3D"false" Priority=3D"70" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Dark List Accent 4"/> + <w:LsdException Locked=3D"false" Priority=3D"71" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Colorful Shading Accent 4"/> + <w:LsdException Locked=3D"false" Priority=3D"72" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Colorful List Accent 4"/> + <w:LsdException Locked=3D"false" Priority=3D"73" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Colorful Grid Accent 4"/> + <w:LsdException Locked=3D"false" Priority=3D"60" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Light Shading Accent 5"/> + <w:LsdException Locked=3D"false" Priority=3D"61" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Light List Accent 5"/> + <w:LsdException Locked=3D"false" Priority=3D"62" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Light Grid Accent 5"/> + <w:LsdException Locked=3D"false" Priority=3D"63" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Medium Shading 1 Accent 5"/> + <w:LsdException Locked=3D"false" Priority=3D"64" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Medium Shading 2 Accent 5"/> + <w:LsdException Locked=3D"false" Priority=3D"65" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Medium List 1 Accent 5"/> + <w:LsdException Locked=3D"false" Priority=3D"66" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Medium List 2 Accent 5"/> + <w:LsdException Locked=3D"false" Priority=3D"67" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Medium Grid 1 Accent 5"/> + <w:LsdException Locked=3D"false" Priority=3D"68" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Medium Grid 2 Accent 5"/> + <w:LsdException Locked=3D"false" Priority=3D"69" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Medium Grid 3 Accent 5"/> + <w:LsdException Locked=3D"false" Priority=3D"70" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Dark List Accent 5"/> + <w:LsdException Locked=3D"false" Priority=3D"71" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Colorful Shading Accent 5"/> + <w:LsdException Locked=3D"false" Priority=3D"72" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Colorful List Accent 5"/> + <w:LsdException Locked=3D"false" Priority=3D"73" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Colorful Grid Accent 5"/> + <w:LsdException Locked=3D"false" Priority=3D"60" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Light Shading Accent 6"/> + <w:LsdException Locked=3D"false" Priority=3D"61" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Light List Accent 6"/> + <w:LsdException Locked=3D"false" Priority=3D"62" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Light Grid Accent 6"/> + <w:LsdException Locked=3D"false" Priority=3D"63" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Medium Shading 1 Accent 6"/> + <w:LsdException Locked=3D"false" Priority=3D"64" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Medium Shading 2 Accent 6"/> + <w:LsdException Locked=3D"false" Priority=3D"65" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Medium List 1 Accent 6"/> + <w:LsdException Locked=3D"false" Priority=3D"66" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Medium List 2 Accent 6"/> + <w:LsdException Locked=3D"false" Priority=3D"67" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Medium Grid 1 Accent 6"/> + <w:LsdException Locked=3D"false" Priority=3D"68" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Medium Grid 2 Accent 6"/> + <w:LsdException Locked=3D"false" Priority=3D"69" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Medium Grid 3 Accent 6"/> + <w:LsdException Locked=3D"false" Priority=3D"70" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Dark List Accent 6"/> + <w:LsdException Locked=3D"false" Priority=3D"71" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Colorful Shading Accent 6"/> + <w:LsdException Locked=3D"false" Priority=3D"72" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Colorful List Accent 6"/> + <w:LsdException Locked=3D"false" Priority=3D"73" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" Name=3D"Colorful Grid Accent 6"/> + <w:LsdException Locked=3D"false" Priority=3D"19" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" QFormat=3D"true" Name=3D"Subtle Emphasis"/> + <w:LsdException Locked=3D"false" Priority=3D"21" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" QFormat=3D"true" Name=3D"Intense Emphasis"/> + <w:LsdException Locked=3D"false" Priority=3D"31" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" QFormat=3D"true" Name=3D"Subtle Reference"/> + <w:LsdException Locked=3D"false" Priority=3D"32" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" QFormat=3D"true" Name=3D"Intense = +Reference"/> + <w:LsdException Locked=3D"false" Priority=3D"33" SemiHidden=3D"false"=20 + UnhideWhenUsed=3D"false" QFormat=3D"true" Name=3D"Book Title"/> + <w:LsdException Locked=3D"false" Priority=3D"37" = +Name=3D"Bibliography"/> + <w:LsdException Locked=3D"false" Priority=3D"39" QFormat=3D"true" = +Name=3D"TOC Heading"/> + </w:LatentStyles> +</xml><![endif]--> +<style> +<!-- + /* Font Definitions */ + @font-face + {font-family:"Cambria Math"; + panose-1:2 4 5 3 5 4 6 3 2 4; + mso-font-charset:1; + mso-generic-font-family:roman; + mso-font-format:other; + mso-font-pitch:variable; + mso-font-signature:0 0 0 0 0 0;} +@font-face + {font-family:Calibri; + panose-1:2 15 5 2 2 2 4 3 2 4; + mso-font-charset:0; + mso-generic-font-family:swiss; + mso-font-pitch:variable; + mso-font-signature:-1610611985 1073750139 0 0 159 0;} + /* Style Definitions */ + p.MsoNormal, li.MsoNormal, div.MsoNormal + {mso-style-unhide:no; + mso-style-qformat:yes; + mso-style-parent:""; + margin:0in; + margin-bottom:.0001pt; + mso-pagination:widow-orphan; + font-size:11.0pt; + font-family:"Calibri","sans-serif"; + mso-fareast-font-family:Calibri; + mso-fareast-theme-font:minor-latin; + mso-bidi-font-family:"Times New Roman";} +a:link, span.MsoHyperlink + {mso-style-noshow:yes; + mso-style-priority:99; + color:blue; + text-decoration:underline; + text-underline:single;} +a:visited, span.MsoHyperlinkFollowed + {mso-style-noshow:yes; + mso-style-priority:99; + color:purple; + text-decoration:underline; + text-underline:single;} +span.EmailStyle17 + {mso-style-type:personal; + mso-style-noshow:yes; + mso-style-unhide:no; + font-family:"Calibri","sans-serif"; + mso-ascii-font-family:Calibri; + mso-hansi-font-family:Calibri; + color:windowtext;} +span.EmailStyle18 + {mso-style-type:personal-reply; + mso-style-noshow:yes; + mso-style-unhide:no; + mso-ansi-font-size:11.0pt; + mso-bidi-font-size:11.0pt; + font-family:"Calibri","sans-serif"; + mso-ascii-font-family:Calibri; + mso-ascii-theme-font:minor-latin; + mso-hansi-font-family:Calibri; + mso-hansi-theme-font:minor-latin; + mso-bidi-font-family:"Times New Roman"; + mso-bidi-theme-font:minor-bidi; + color:#5F497A; + mso-themecolor:accent4; + mso-themeshade:191;} +.MsoChpDefault + {mso-style-type:export-only; + mso-default-props:yes; + font-size:10.0pt; + mso-ansi-font-size:10.0pt; + mso-bidi-font-size:10.0pt;} +@page Section1 + {size:8.5in 11.0in; + margin:1.0in 1.0in 1.0in 1.0in; + mso-header-margin:.5in; + mso-footer-margin:.5in; + mso-paper-source:0;} +div.Section1 + {page:Section1;} +--> +</style> +<!--[if gte mso 10]> +<style> + /* Style Definitions */=20 + table.MsoNormalTable + {mso-style-name:"Table Normal"; + mso-tstyle-rowband-size:0; + mso-tstyle-colband-size:0; + mso-style-noshow:yes; + mso-style-priority:99; + mso-style-qformat:yes; + mso-style-parent:""; + mso-padding-alt:0in 5.4pt 0in 5.4pt; + mso-para-margin:0in; + mso-para-margin-bottom:.0001pt; + mso-pagination:widow-orphan; + font-size:10.0pt; + font-family:"Times New Roman","serif";} +</style> +<![endif]--><!--[if gte mso 9]><xml> + <o:shapedefaults v:ext=3D"edit" spidmax=3D"1026" /> +</xml><![endif]--><!--[if gte mso 9]><xml> + <o:shapelayout v:ext=3D"edit"> + <o:idmap v:ext=3D"edit" data=3D"1" /> + </o:shapelayout></xml><![endif]--> +</head> + +<body lang=3DEN-US link=3Dblue vlink=3Dpurple = +style=3D'tab-interval:.5in'> + +<div class=3DSection1> + +<p class=3DMsoNormal>Thank you for your message. I am currently out of = +the +office, with [limited] [no] access to e-mail.<o:p></o:p></p> + +<p class=3DMsoNormal><o:p> </o:p></p> + +<p class=3DMsoNormal>I will be returning on [day, date].<o:p></o:p></p> + +<p class=3DMsoNormal><o:p> </o:p></p> + +<p class=3DMsoNormal>If you need assistance before then, you may reach = +me at +[phone number].<o:p></o:p></p> + +<p class=3DMsoNormal>For urgent issues, please contact [name] at [e-mail = +address] +or [telephone number].<o:p></o:p></p> + +<p class=3DMsoNormal><o:p> </o:p></p> + +<p class=3DMsoNormal>[Signature]<o:p></o:p></p> + +<p class=3DMsoNormal><o:p> </o:p></p> + +<p class=3DMsoNormal><i style=3D'mso-bidi-font-style:normal'>[Optional: = +Type your +favorite quotation or saying here along with the author or = +source]<o:p></o:p></i></p> + +</div> + +</body> + +</html> + +------=_NextPart_000_00AC_01CCB595.AADA0070-- + 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/fixtures/incoming_messages.yml b/spec/fixtures/incoming_messages.yml index e15a466ca..fca5c716c 100644 --- a/spec/fixtures/incoming_messages.yml +++ b/spec/fixtures/incoming_messages.yml @@ -1,7 +1,33 @@ useless_incoming_message: - id: 1 - info_request_id: 101 - updated_at: 2007-11-13 18:09:20.042061 - raw_email_id: 1 - created_at: 2007-11-13 18:09:20.042061 + id: 1 + info_request_id: 101 + updated_at: 2007-11-13 18:09:20.042061 + raw_email_id: 1 + created_at: 2007-11-13 18:09:20.042061 +useful_incoming_message: + id: 2 + info_request_id: 105 + raw_email_id: 2 + created_at: 2012-01-26 10:19:23 + updated_at: 2012-01-26 10:19:23 + +another_useful_incoming_message: + id: 3 + info_request_id: 106 + raw_email_id: 3 + created_at: 2007-11-13 18:09:20 + updated_at: 2007-11-13 18:09:20 + +spam_1_incoming_message: + id: 4 + info_request_id: 107 + raw_email_id: 4 + created_at: 2008-11-13 18:09:20 + updated_at: 2008-11-13 18:09:20 +spam_2_incoming_message: + id: 5 + info_request_id: 108 + raw_email_id: 5 + created_at: 2008-11-13 19:09:20 + updated_at: 2008-11-13 19:09:20 diff --git a/spec/fixtures/info_request_events.yml b/spec/fixtures/info_request_events.yml index 5e3c13083..3266ec634 100644 --- a/spec/fixtures/info_request_events.yml +++ b/spec/fixtures/info_request_events.yml @@ -1,41 +1,152 @@ useless_outgoing_message_event: + id: 900 params_yaml: "--- \n\ :outgoing_message_id: 1\n" - id: 900 info_request_id: 101 event_type: sent created_at: 2007-10-12 01:56:58.586598 described_state: outgoing_message_id: 1 silly_outgoing_message_event: + id: 901 params_yaml: "--- \n\ :outgoing_message_id: 2\n" - id: 901 info_request_id: 103 event_type: sent created_at: 2007-10-14 10:41:12.686264 described_state: outgoing_message_id: 2 useless_incoming_message_event: + id: 902 params_yaml: "--- \n\ :incoming_message_id: 1\n" - id: 902 info_request_id: 101 event_type: response created_at: 2007-11-13 18:09:20.042061 described_state: incoming_message_id: 1 silly_comment_event: + id: 903 params_yaml: "--- \n\ :comment_id: 1\n" incoming_message_id: last_described_at: described_state: - id: "903" - info_request_id: "101" - comment_id: "1" + info_request_id: 101 + comment_id: 1 calculated_state: event_type: comment outgoing_message_id: created_at: 2008-08-12 23:05:12.500942 +badger_outgoing_message_event: + id: 904 + params_yaml: "--- \n\ + :outgoing_message_id: 3\n" + info_request_id: 104 + event_type: sent + created_at: 2011-10-12 01:56:58.586598 + described_state: waiting_response + calculated_state: waiting_response + outgoing_message_id: 3 + +# These in chronological order +boring_outgoing_message_event: + id: 905 + params_yaml: "--- \n\ + :outgoing_message_id: 4\n" + outgoing_message_id: 4 + info_request_id: 105 + event_type: sent + created_at: 2006-01-12 01:56:58.586598 + described_state: waiting_response + calculated_state: waiting_response +useful_incoming_message_event: + id: 906 + params_yaml: "--- \n\ + :incoming_message_id: 2\n" + incoming_message_id: 2 + info_request_id: 105 + event_type: response + created_at: 2007-11-13 18:00:20 + described_state: successful + calculated_state: successful + +another_boring_outgoing_message_event: + id: 907 + params_yaml: "--- \n\ + :outgoing_message_id: 5\n" + outgoing_message_id: 5 + info_request_id: 106 + event_type: sent + created_at: 2006-01-12 01:56:58.586598 + described_state: waiting_response + calculated_state: waiting_response +another_useful_incoming_message_event: + id: 908 + params_yaml: "--- \n\ + :incoming_message_id: 3\n" + incoming_message_id: 3 + info_request_id: 106 + event_type: response + created_at: 2007-11-13 18:09:20.042061 + described_state: successful + calculated_state: successful + +another_comment_event: + id: 909 + info_request_id: 105 + comment_id: 2 + params_yaml: "--- \n\ + :comment_id: 2\n" + incoming_message_id: + outgoing_message_id: + last_described_at: + described_state: + calculated_state: + event_type: comment + created_at: 2008-08-12 12:05:12.879634 + + +# The spam requests were both successful +spam_1_outgoing_message_event: + id: 910 + params_yaml: "--- \n\ + :outgoing_message_id: 6\n" + outgoing_message_id: 6 + info_request_id: 107 + event_type: sent + created_at: 2001-01-02 01:23:45.6789100 + described_state: waiting_response + calculated_state: waiting_response +spam_1_incoming_message_event: + id: 911 + params_yaml: "--- \n\ + :incoming_message_id: 4\n" + incoming_message_id: 4 + info_request_id: 107 + event_type: response + created_at: 2001-01-03 01:23:45.6789100 + described_state: successful + calculated_state: successful + +spam_2_outgoing_message_event: + id: 912 + params_yaml: "--- \n\ + :outgoing_message_id: 7\n" + outgoing_message_id: 7 + info_request_id: 108 + event_type: sent + created_at: 2001-01-02 02:23:45.6789100 + described_state: waiting_response + calculated_state: waiting_response +spam_2_incoming_message_event: + id: 913 + params_yaml: "--- \n\ + :incoming_message_id: 5\n" + incoming_message_id: 5 + info_request_id: 108 + event_type: response + created_at: 2001-01-03 02:23:45.6789100 + described_state: successful + calculated_state: successful diff --git a/spec/fixtures/info_requests.yml b/spec/fixtures/info_requests.yml index c1e3c1910..33e9a16f2 100644 --- a/spec/fixtures/info_requests.yml +++ b/spec/fixtures/info_requests.yml @@ -18,5 +18,63 @@ naughty_chicken_request: public_body_id: 2 user_id: 1 described_state: waiting_response - awaiting_description: false + awaiting_description: false idhash: e8d18c84 +badger_request: + id: 104 + title: Are you really a badger? + url_title: are_you_really_a_badger + created_at: 2011-10-13 18:15:57 + updated_at: 2011-10-13 18:15:57 + public_body_id: 3 + user_id: 1 + described_state: waiting_response + awaiting_description: false + idhash: e8d18c84 +boring_request: + id: 105 + title: The cost of boring + url_title: the_cost_of_boring + created_at: 2006-01-12 01:56:58.586598 + updated_at: 2008-08-12 12:05:12.879634 + public_body_id: 3 + user_id: 1 + described_state: successful + awaiting_description: false + idhash: 173fd003 +another_boring_request: + id: 106 + title: The cost of boring + url_title: the_cost_of_boring_two # Not _2, because we want to avoid the search collapsing these two + created_at: 2006-01-12 01:56:58.586598 + updated_at: 2007-11-13 18:09:20.042061 + public_body_id: 5 + user_id: 1 + described_state: successful + awaiting_description: false + idhash: 173fd004 + +# A pair of identical requests (with url_title differing only in the numeric suffix) +# used to test the request de-duplication features. +spam_1_request: + id: 107 + title: Cheap v1agra + url_title: spam_1 + created_at: 2010-01-01 01:23:45.6789100 + created_at: 2010-01-01 01:23:45.6789100 + public_body_id: 5 + user_id: 5 + described_state: successful + awaiting_description: false + idhash: 173fd005 +spam_2_request: + id: 108 + title: Cheap v1agra + url_title: spam_2 + created_at: 2010-01-01 02:23:45.6789100 + created_at: 2010-01-01 02:23:45.6789100 + public_body_id: 6 + user_id: 5 + described_state: successful + awaiting_description: false + idhash: 173fd005 diff --git a/spec/fixtures/outgoing_messages.yml b/spec/fixtures/outgoing_messages.yml index b89492aa5..d33ca4292 100644 --- a/spec/fixtures/outgoing_messages.yml +++ b/spec/fixtures/outgoing_messages.yml @@ -33,4 +33,56 @@ silly_outgoing_message: last_sent_at: 2007-10-14 10:41:12.686264 created_at: 2007-10-14 01:56:58.586598 what_doing: normal_sort +badger_outgoing_message: + id: 3 + info_request_id: 104 + message_type: initial_request + status: sent + updated_at: 2011-10-14 01:56:58.586598 + body: "Is it true that you are really a badger, in fact?" + last_sent_at: 2011-10-14 10:41:12.686264 + created_at: 2011-10-14 01:56:58.586598 + what_doing: normal_sort +boring_outgoing_message: + id: 4 + info_request_id: 105 + message_type: initial_request + status: sent + updated_at: 2012-01-14 01:56:58.586598 + body: "How much was spent on boring equipment in the 2010-2011 financial year?" + last_sent_at: 2012-01-14 10:41:12.686264 + created_at: 2012-01-14 01:56:58.586598 + what_doing: normal_sort + +another_boring_outgoing_message: + id: 5 + info_request_id: 106 + message_type: initial_request + status: sent + body: "How much was spent on boring equipment in the 2010-2011 financial year?" + last_sent_at: 2006-01-12 01:57:58.586598 + created_at: 2006-01-12 01:56:58.586598 + updated_at: 2006-01-12 01:56:58.586598 + what_doing: normal_sort + +spam_1_outgoing_message: + id: 6 + info_request_id: 107 + message_type: initial_request + status: sent + body: "Would you like some cheap v1agra?" + last_sent_at: 2007-01-12 01:57:58.586598 + created_at: 2007-01-12 01:56:58.586598 + updated_at: 2007-01-12 01:56:58.586598 + what_doing: normal_sort +spam_2_outgoing_message: + id: 7 + info_request_id: 108 + message_type: initial_request + status: sent + body: "Would you like some cheap v1agra?" + last_sent_at: 2007-01-12 02:57:58.586598 + created_at: 2007-01-12 02:56:58.586598 + updated_at: 2007-01-12 02:56:58.586598 + what_doing: normal_sort diff --git a/spec/fixtures/public_bodies.yml b/spec/fixtures/public_bodies.yml index 191dd68bb..a0893f1e5 100644 --- a/spec/fixtures/public_bodies.yml +++ b/spec/fixtures/public_bodies.yml @@ -16,10 +16,49 @@ humpadink_public_body: updated_at: 2007-10-25 10:51:01.161639 last_edit_comment: Not sure what this new department does. request_email: humpadink-requests@localhost - id: "3" + id: 3 version: "2" last_edit_editor: "francis" short_name: DfH url_name: dfh created_at: 2007-10-25 10:51:01.161639 notes: An albatross told me!!! +forlorn_public_body: + name: "Department of Loneliness" + first_letter: D + updated_at: 2011-01-26 14:11:02.12345 + last_edit_comment: 'Aw, bless.' + request_email: forlorn-requests@localhost + id: 4 + version: 1 + last_edit_editor: "robin" + short_name: DoL + url_name: lonely + created_at: 2011-01-26 14:11:02.12345 + notes: A very lonely public body that no one has corresponded with +silly_walks_public_body: + id: 5 + version: 1 + name: "Ministry of Silly Walks" + first_letter: M + updated_at: 2007-10-25 10:51:01.161639 + last_edit_comment: Is a comment really required? + request_email: silly-walks-requests@localhost + last_edit_editor: robin + short_name: MSW + url_name: msw + created_at: 2007-10-25 10:51:01.161639 + notes: You know the one. +sensible_walks_public_body: + id: 6 + version: 1 + name: "Ministry of Sensible Walks" + first_letter: M + request_email: sensible-walks-requests@localhost + short_name: SenseWalk + url_name: sensible_walks + notes: I bet you’ve never heard of it. + updated_at: 2008-10-25 10:51:01.161639 + last_edit_comment: Another stunning innovation from your friendly national government + last_edit_editor: robin + created_at: 2008-10-25 10:51:01.161639 diff --git a/spec/fixtures/public_body_translations.yml b/spec/fixtures/public_body_translations.yml index b5e947044..cbb55bb0c 100644 --- a/spec/fixtures/public_body_translations.yml +++ b/spec/fixtures/public_body_translations.yml @@ -24,8 +24,8 @@ humpadink_es_public_body_translation: name: "El Department for Humpadinking" first_letter: E request_email: humpadink-requests@localhost - id: "3" - public_body_id: "3" + id: 3 + public_body_id: 3 short_name: eDfH url_name: edfh locale: es @@ -35,9 +35,42 @@ humpadink_en_public_body_translation: name: "Department for Humpadinking" first_letter: D request_email: humpadink-requests@localhost - id: "4" - public_body_id: "3" + id: 4 + public_body_id: 3 short_name: DfH url_name: dfh locale: en notes: An albatross told me!!! + +forlorn_en_public_body_translation: + name: "Department of Loneliness" + first_letter: D + request_email: forlorn-requests@localhost + id: 5 + public_body_id: 4 + short_name: DoL + url_name: lonely + locale: en + notes: A very lonely public body that no one has corresponded with + +silly_walks_en_public_body_translation: + id: 6 + public_body_id: 5 + locale: en + name: "Ministry of Silly Walks" + first_letter: M + request_email: silly-walks-requests@localhost + short_name: MSW + url_name: msw + notes: You know the one. + +sensible_walks_en_public_body_translation: + id: 7 + public_body_id: 6 + locale: en + name: "Ministry of Sensible Walks" + first_letter: M + request_email: sensible-walks-requests@localhost + short_name: SenseWalk + url_name: sensible_walks + notes: I bet you’ve never heard of it. diff --git a/spec/fixtures/raw_emails.yml b/spec/fixtures/raw_emails.yml index 8ef9248a3..ad2bc0a63 100644 --- a/spec/fixtures/raw_emails.yml +++ b/spec/fixtures/raw_emails.yml @@ -1,2 +1,20 @@ -useless_raw_email: +# The actual email messages are in fixtures/files/raw_emails +# +# Note that the words "money" and "bob" are used in some tests +# of the search functions, so if you use either of these words +# in the email text then some tests will have to be updated. + +useless_raw_email: id: 1 + +useful_raw_email: + id: 2 + +another_useful_raw_email: + id: 3 + +spam_1_raw_email: + id: 4 + +spam_2_raw_email: + id: 5 diff --git a/spec/fixtures/users.yml b/spec/fixtures/users.yml index 16ffec034..8620fb3de 100644 --- a/spec/fixtures/users.yml +++ b/spec/fixtures/users.yml @@ -53,3 +53,16 @@ unconfirmed_user: admin_level: 'none' ban_text: '' about_me: '' +robin_user: + id: 5 + name: Robin Houston + url_name: robin_houston + email: robin@localhost + salt: "-6116981980.392287733335677" + hashed_password: 6b7cd45a5f35fd83febc0452a799530398bfb6e8 # jonespassword + updated_at: 2012-01-01 10:39:15.491593 + created_at: 2012-01-01 10:39:15.491593 + email_confirmed: true + admin_level: 'none' + ban_text: '' + about_me: 'I am the best' diff --git a/spec/helpers/link_to_helper_spec.rb b/spec/helpers/link_to_helper_spec.rb index aae00c298..3fa91a8f8 100644 --- a/spec/helpers/link_to_helper_spec.rb +++ b/spec/helpers/link_to_helper_spec.rb @@ -7,9 +7,14 @@ describe LinkToHelper do describe 'when creating a url for a request' do before do - ActionController::Routing::Routes.filters.clear @mock_request = mock_model(InfoRequest, :url_title => 'test_title') + @old_filters = ActionController::Routing::Routes.filters + ActionController::Routing::Routes.filters = RoutingFilter::Chain.new end + after do + ActionController::Routing::Routes.filters = @old_filters + end + it 'should return a path like /request/test_title' do request_url(@mock_request).should == '/request/test_title' @@ -20,5 +25,17 @@ describe LinkToHelper do end end + + describe "when appending something to a URL" do + it 'should append to things without query strings' do + main_url('/a', '.json').should == 'http://test.localdomain/a.json' + end + it 'should append to things with query strings' do + main_url('/a?z=1', '.json').should == 'http://test.localdomain/a.json?z=1' + end + it 'should fail silently with invalid URLs' do + main_url('/a?z=9%', '.json').should == 'http://test.localdomain/a?z=9%' + end + end end diff --git a/spec/integration/errors_spec.rb b/spec/integration/errors_spec.rb index bfb7e5fb5..ec2e1c376 100644 --- a/spec/integration/errors_spec.rb +++ b/spec/integration/errors_spec.rb @@ -2,22 +2,8 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') describe "When rendering errors" do - fixtures [ - :users, - :public_bodies, - :public_body_translations, - :public_body_versions, - :info_requests, - :raw_emails, - :outgoing_messages, - :incoming_messages, - :comments, - :info_request_events, - :track_things, - ] - before(:each) do - load_raw_emails_data(raw_emails) + load_raw_emails_data ActionController::Base.consider_all_requests_local = false end @@ -45,5 +31,18 @@ describe "When rendering errors" do get("/request/#{ir.url_title}") response.code.should == "500" end + it "should render a 403 for attempts at directory listing for attachments" do + # make a fake cache + foi_cache_path = File.join(File.dirname(__FILE__), '../../cache') + FileUtils.mkdir_p(File.join(foi_cache_path, "views/en/request/101/101/response/1/attach/html/1")) + get("/request/101/response/1/attach/html/1/" ) + response.code.should == "403" + get("/request/101/response/1/attach/html" ) + response.code.should == "403" + end + it "should render a 404 for non-existent 'details' pages for requests" do + get("/details/request/wobble" ) + response.code.should == "404" + end end diff --git a/spec/integration/search_request_spec.rb b/spec/integration/search_request_spec.rb index 07839af32..b62f0a4c4 100644 --- a/spec/integration/search_request_spec.rb +++ b/spec/integration/search_request_spec.rb @@ -2,23 +2,9 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') describe "When searching" do - fixtures [ - :users, - :public_bodies, - :public_body_translations, - :public_body_versions, - :info_requests, - :raw_emails, - :outgoing_messages, - :incoming_messages, - :comments, - :info_request_events, - :track_things, - ] - before(:each) do - emails = raw_emails.clone - load_raw_emails_data(emails) + load_raw_emails_data + rebuild_xapian_index end it "should not strip quotes from quoted query" do @@ -34,33 +20,46 @@ describe "When searching" do end it "should correctly filter searches for requests" do - request_via_redirect("post", "/search/bob/requests") + request_via_redirect("post", "/search/bob/requests") response.body.should_not include("One person found") - response.body.should include("FOI requests 1 to 2 of 2") + n = 4 # The number of requests that contain the word "bob" somewhere + # in the email text. At present this is: + # - fancy_dog_request + # - naughty_chicken_request + # - boring_request + # - another_boring_request + # + # In other words it is all requests made by Bob Smith + # except for badger_request, which he did not sign. + response.body.should include("FOI requests 1 to #{n} of #{n}") end it "should correctly filter searches for users" do - request_via_redirect("post", "/search/bob/users") + request_via_redirect("post", "/search/bob/users") response.body.should include("One person found") - response.body.should_not include("FOI requests 1 to 2 of 2") + response.body.should_not include("FOI requests 1 to") end it "should correctly filter searches for successful requests" do - request_via_redirect("post", "/search", + request_via_redirect("post", "/search/requests", :query => "bob", :latest_status => ['successful']) - response.body.should include("no requests matching your query") + n = 2 # The number of *successful* requests that contain the word "bob" somewhere + # in the email text. At present this is: + # - boring_request + # - another_boring_request + response.body.should include("FOI requests 1 to #{n} of #{n}") end it "should correctly filter searches for comments" do - request_via_redirect("post", "/search", + request_via_redirect("post", "/search/requests", :query => "daftest", :request_variety => ['comments']) response.body.should include("One FOI request found") - request_via_redirect("post", "/search", + request_via_redirect("post", "/search/requests", :query => "daftest", :request_variety => ['response','sent']) - response.body.should include("no requests matching your query") + response.body.should include("no results matching your query") end end diff --git a/spec/integration/view_request_spec.rb b/spec/integration/view_request_spec.rb index cf1e4ca6c..442721890 100644 --- a/spec/integration/view_request_spec.rb +++ b/spec/integration/view_request_spec.rb @@ -2,23 +2,8 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') describe "When viewing requests" do - fixtures [ - :users, - :public_bodies, - :public_body_translations, - :public_body_versions, - :info_requests, - :raw_emails, - :outgoing_messages, - :incoming_messages, - :comments, - :info_request_events, - :track_things, - ] - before(:each) do - emails = raw_emails.clone - load_raw_emails_data(emails) + load_raw_emails_data end it "should not make endlessly recursive JSON <link>s" do diff --git a/spec/lib/sendmail_return_path_spec.rb b/spec/lib/sendmail_return_path_spec.rb index f1a91240b..7708edb35 100644 --- a/spec/lib/sendmail_return_path_spec.rb +++ b/spec/lib/sendmail_return_path_spec.rb @@ -3,6 +3,7 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') describe "when sending email with an altered return path" do + before(:each) { ActionMailer::Base.deliveries = [] } it "should default to delivery method test" do ActionMailer::Base.delivery_method.should == :test diff --git a/spec/lib/tmail_extensions_spec.rb b/spec/lib/tmail_extensions_spec.rb index 6a55c34da..bd89e6a84 100644 --- a/spec/lib/tmail_extensions_spec.rb +++ b/spec/lib/tmail_extensions_spec.rb @@ -6,6 +6,10 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') describe "when using TMail" do + before(:each) do + ActionMailer::Base.deliveries.clear + end + it "should load an email with funny MIME settings" do # just send it to the holding pen InfoRequest.holding_pen_request.incoming_messages.size.should == 0 diff --git a/spec/models/foi_attachment_spec.rb b/spec/models/foi_attachment_spec.rb new file mode 100644 index 000000000..9d44957e4 --- /dev/null +++ b/spec/models/foi_attachment_spec.rb @@ -0,0 +1,35 @@ +require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') + +describe FoiAttachment, " when calculating due date" do + + before(:each) do + load_raw_emails_data + end + + it "sets the body" do + attachment = FoiAttachment.new + attachment.body = "baz" + attachment.body.should == "baz" + end + it "sets the size" do + attachment = FoiAttachment.new + attachment.body = "baz" + attachment.body.should == "baz" + attachment.update_display_size! + attachment.display_size.should == "0K" + end + it "reparses the body if it disappears" do + im = incoming_messages(:useless_incoming_message) + im.extract_attachments! + main = im.get_main_body_text_part + orig_body = main.body + main.delete_cached_file! + lambda { + im.get_main_body_text_part.body + }.should_not raise_error(Errno::ENOENT) + main.delete_cached_file! + main = im.get_main_body_text_part + main.body.should == orig_body + + end +end diff --git a/spec/models/has_tag_string_tag_spec.rb b/spec/models/has_tag_string_tag_spec.rb index 1acd2e27d..57c301471 100644 --- a/spec/models/has_tag_string_tag_spec.rb +++ b/spec/models/has_tag_string_tag_spec.rb @@ -1,7 +1,6 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') describe HasTagString::HasTagStringTag, " when fiddling with tag strings " do - fixtures :public_bodies, :public_body_translations, :public_body_versions, :info_requests, :raw_emails, :incoming_messages, :outgoing_messages, :comments, :info_request_events, :track_things it "should be able to make a new tag and save it" do @tag = HasTagString::HasTagStringTag.new diff --git a/spec/models/holiday_spec.rb b/spec/models/holiday_spec.rb index 973b067d6..00ebc7279 100644 --- a/spec/models/holiday_spec.rb +++ b/spec/models/holiday_spec.rb @@ -1,7 +1,6 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') describe Holiday, " when calculating due date" do - fixtures :holidays def due_date(ymd) return Holiday.due_date_from(Date.strptime(ymd), 20).strftime("%F") diff --git a/spec/models/incoming_message_spec.rb b/spec/models/incoming_message_spec.rb index ed31b7c5c..b6fee7898 100644 --- a/spec/models/incoming_message_spec.rb +++ b/spec/models/incoming_message_spec.rb @@ -2,14 +2,19 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') describe IncomingMessage, " when dealing with incoming mail" do - fixtures :users, :raw_emails, :public_bodies, :public_body_translations, :public_body_versions, :info_requests, :incoming_messages, :outgoing_messages, :comments, :info_request_events, :track_things before(:each) do @im = incoming_messages(:useless_incoming_message) - load_raw_emails_data(raw_emails) + load_raw_emails_data + end + + after(:all) do + ActionMailer::Base.deliveries.clear end it "should return the mail Date header date for sent at" do + @im.parse_raw_email!(true) + @im.reload @im.sent_at.should == @im.mail.date end @@ -27,6 +32,31 @@ describe IncomingMessage, " when dealing with incoming mail" do end end + it "should ensure cached body text has been parsed correctly" do + ir = info_requests(:fancy_dog_request) + receive_incoming_mail('quoted-subject-iso8859-1.email', ir.incoming_email) + message = ir.incoming_messages[1] + message.get_main_body_text_unfolded.should_not include("Email has no body") + end + + it "should correctly convert HTML even when there's a meta tag asserting that it is iso-8859-1 which would normally confuse elinks" do + ir = info_requests(:fancy_dog_request) + receive_incoming_mail('quoted-subject-iso8859-1.email', ir.incoming_email) + message = ir.incoming_messages[1] + message.parse_raw_email! + message.get_main_body_text_part.charset.should == "iso-8859-1" + message.get_main_body_text_internal.should include("política") + end + + it "should unquote RFC 2047 headers" do + ir = info_requests(:fancy_dog_request) + receive_incoming_mail('quoted-subject-iso8859-1.email', ir.incoming_email) + message = ir.incoming_messages[1] + message.mail_from.should == "Coordenação de Relacionamento, Pesquisa e Informação/CEDI" + message.subject.should == "Câmara Responde: Banco de ideias" + end + + it "should fold multiline sections" do { "foo\n--------\nconfidential" => "foo\nFOLDED_QUOTED_SECTION\n", # basic test @@ -102,16 +132,15 @@ describe IncomingMessage, " folding quoted parts of emails" do end describe IncomingMessage, " checking validity to reply to" do - def test_email(result, email, return_path, autosubmitted) + def test_email(result, email, return_path, autosubmitted = nil) @address = mock(TMail::Address) @address.stub!(:spec).and_return(email) @return_path = mock(TMail::ReturnPathHeader) @return_path.stub!(:addr).and_return(return_path) - - @autosubmitted = mock(TMail::KeywordsHeader) - @autosubmitted.stub!(:keys).and_return(autosubmitted) - + if !autosubmitted.nil? + @autosubmitted = TMail::UnstructuredHeader.new("auto-submitted", autosubmitted) + end @mail = mock(TMail::Mail) @mail.stub!(:from_addrs).and_return( [ @address ] ) @mail.stub!(:[]).with("return-path").and_return(@return_path) @@ -123,45 +152,44 @@ describe IncomingMessage, " checking validity to reply to" do end it "says a valid email is fine" do - test_email(true, "team@mysociety.org", nil, []) + test_email(true, "team@mysociety.org", nil) end it "says postmaster email is bad" do - test_email(false, "postmaster@mysociety.org", nil, []) + test_email(false, "postmaster@mysociety.org", nil) end it "says Mailer-Daemon email is bad" do - test_email(false, "Mailer-Daemon@mysociety.org", nil, []) + test_email(false, "Mailer-Daemon@mysociety.org", nil) end it "says case mangled MaIler-DaemOn email is bad" do - test_email(false, "MaIler-DaemOn@mysociety.org", nil, []) + test_email(false, "MaIler-DaemOn@mysociety.org", nil) end it "says Auto_Reply email is bad" do - test_email(false, "Auto_Reply@mysociety.org", nil, []) + test_email(false, "Auto_Reply@mysociety.org", nil) end it "says DoNotReply email is bad" do - test_email(false, "DoNotReply@tube.tfl.gov.uk", nil, []) + test_email(false, "DoNotReply@tube.tfl.gov.uk", nil) end it "says a filled-out return-path is fine" do - test_email(true, "team@mysociety.org", "Return-path: <foo@baz.com>", []) + test_email(true, "team@mysociety.org", "Return-path: <foo@baz.com>") end it "says an empty return-path is bad" do - test_email(false, "team@mysociety.org", "<>", []) + test_email(false, "team@mysociety.org", "<>") end it "says an auto-submitted keyword is bad" do - test_email(false, "team@mysociety.org", nil, ["auto-replied"]) + test_email(false, "team@mysociety.org", nil, "auto-replied") end end describe IncomingMessage, " checking validity to reply to with real emails" do - fixtures :users, :raw_emails, :public_bodies, :public_body_translations, :info_requests, :incoming_messages, :outgoing_messages, :comments, :info_request_events, :track_things after(:all) do ActionMailer::Base.deliveries.clear @@ -185,7 +213,6 @@ describe IncomingMessage, " checking validity to reply to with real emails" do end describe IncomingMessage, " when censoring data" do - fixtures :users, :raw_emails, :public_bodies, :public_body_translations, :public_body_versions, :info_requests, :incoming_messages, :outgoing_messages, :comments, :info_request_events, :track_things before(:each) do @test_data = "There was a mouse called Stilton, he wished that he was blue." @@ -206,7 +233,7 @@ describe IncomingMessage, " when censoring data" do @censor_rule_2.last_edit_comment = "none" @im.info_request.censor_rules << @censor_rule_2 - load_raw_emails_data(raw_emails) + load_raw_emails_data end it "should do nothing to a JPEG" do @@ -293,7 +320,6 @@ describe IncomingMessage, " when censoring data" do end describe IncomingMessage, " when censoring whole users" do - fixtures :users, :raw_emails, :public_bodies, :public_body_translations, :public_body_versions, :info_requests, :incoming_messages, :outgoing_messages, :comments, :info_request_events, :track_things before(:each) do @test_data = "There was a mouse called Stilton, he wished that he was blue." @@ -306,7 +332,7 @@ describe IncomingMessage, " when censoring whole users" do @censor_rule_1.last_edit_editor = "unknown" @censor_rule_1.last_edit_comment = "none" @im.info_request.user.censor_rules << @censor_rule_1 - load_raw_emails_data(raw_emails) + load_raw_emails_data end it "should apply censor rules to HTML files" do @@ -324,10 +350,9 @@ end describe IncomingMessage, " when uudecoding bad messages" do - fixtures :incoming_messages, :raw_emails, :public_bodies, :public_body_translations, :info_requests, :users, :foi_attachments before(:each) do - load_raw_emails_data(raw_emails) + load_raw_emails_data end it "should be able to do it at all" do @@ -368,10 +393,9 @@ describe IncomingMessage, " when uudecoding bad messages" do end describe IncomingMessage, "when messages are attached to messages" do - fixtures :incoming_messages, :raw_emails, :public_bodies, :public_body_translations, :info_requests, :users, :foi_attachments before(:each) do - load_raw_emails_data(raw_emails) + load_raw_emails_data end it "should flatten all the attachments out" do @@ -393,10 +417,9 @@ describe IncomingMessage, "when messages are attached to messages" do end describe IncomingMessage, "when Outlook messages are attached to messages" do - fixtures :incoming_messages, :raw_emails, :public_bodies, :public_body_translations, :info_requests, :users, :foi_attachments before(:each) do - load_raw_emails_data(raw_emails) + load_raw_emails_data end it "should flatten all the attachments out" do @@ -416,10 +439,9 @@ describe IncomingMessage, "when Outlook messages are attached to messages" do end describe IncomingMessage, "when TNEF attachments are attached to messages" do - fixtures :incoming_messages, :raw_emails, :public_bodies, :public_body_translations, :info_requests, :users, :foi_attachments before(:each) do - load_raw_emails_data(raw_emails) + load_raw_emails_data end it "should flatten all the attachments out" do diff --git a/spec/models/info_request_event_spec.rb b/spec/models/info_request_event_spec.rb index 3229284cc..7352f3be0 100644 --- a/spec/models/info_request_event_spec.rb +++ b/spec/models/info_request_event_spec.rb @@ -29,7 +29,8 @@ describe InfoRequestEvent do describe "should know" do it "that it's an incoming message" do - event = InfoRequestEvent.new(:incoming_message => mock_model(IncomingMessage)) + event = InfoRequestEvent.new() + event.stub!(:incoming_message_selective_columns).and_return(1) event.is_incoming_message?.should be_true event.is_outgoing_message?.should be_false event.is_comment?.should be_false @@ -37,6 +38,7 @@ describe InfoRequestEvent do it "that it's an outgoing message" do event = InfoRequestEvent.new(:outgoing_message => mock_model(OutgoingMessage)) + event.id = 1 event.is_incoming_message?.should be_false event.is_outgoing_message?.should be_true event.is_comment?.should be_false @@ -44,6 +46,7 @@ describe InfoRequestEvent do it "that it's a comment" do event = InfoRequestEvent.new(:comment => mock_model(Comment)) + event.id = 1 event.is_incoming_message?.should be_false event.is_outgoing_message?.should be_false event.is_comment?.should be_true @@ -52,10 +55,9 @@ describe InfoRequestEvent do end describe "doing search/index stuff" do - fixtures :public_bodies, :public_body_translations, :public_body_versions, :users, :info_requests, :raw_emails, :incoming_messages, :outgoing_messages, :comments, :info_request_events, :track_things before(:each) do - load_raw_emails_data(raw_emails) + load_raw_emails_data parse_all_incoming_messages end @@ -70,6 +72,14 @@ describe InfoRequestEvent do event.search_text_main.strip.should == "No way! I'm not going to tell you that in a month of Thursdays.\n\nThe Geraldine Quango" end + it 'should get clipped text for incoming messages, and cache it too' do + event = info_request_events(:useless_incoming_message_event) + + event.incoming_message_selective_columns("cached_main_body_text_folded").cached_main_body_text_folded = nil + event.search_text_main(true).strip.should == "No way! I'm not going to tell you that in a month of Thursdays.\n\nThe Geraldine Quango" + event.incoming_message_selective_columns("cached_main_body_text_folded").cached_main_body_text_folded.should_not == nil + end + end diff --git a/spec/models/info_request_spec.rb b/spec/models/info_request_spec.rb index b1baa66a2..a18a4bd1d 100644 --- a/spec/models/info_request_spec.rb +++ b/spec/models/info_request_spec.rb @@ -3,11 +3,10 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') describe InfoRequest do describe "guessing a request from an email" do - fixtures :public_bodies, :public_body_translations, :public_body_versions, :users, :info_requests, :raw_emails, :incoming_messages, :outgoing_messages, :comments, :info_request_events, :track_things before(:each) do @im = incoming_messages(:useless_incoming_message) - load_raw_emails_data(raw_emails) + load_raw_emails_data end it 'should compute a hash' do @@ -73,8 +72,6 @@ describe InfoRequest do end describe " when emailing" do - - fixtures :public_bodies, :public_body_translations, :public_body_versions, :users, :info_requests, :incoming_messages, :outgoing_messages, :comments, :info_request_events, :track_things before do @info_request = info_requests(:fancy_dog_request) @@ -154,7 +151,6 @@ describe InfoRequest do end describe "when calculating the status" do - fixtures :holidays, :public_bodies, :public_body_translations, :public_body_versions, :users, :info_requests, :incoming_messages, :outgoing_messages, :comments, :info_request_events, :track_things before do @ir = info_requests(:naughty_chicken_request) @@ -196,8 +192,6 @@ describe InfoRequest do describe "when using a plugin and calculating the status" do - fixtures :public_bodies, :public_body_translations, :public_body_versions, :users, :info_requests, :incoming_messages, :outgoing_messages, :comments, :info_request_events, :track_things - before do InfoRequest.send(:require, File.expand_path(File.dirname(__FILE__) + '/customstates')) InfoRequest.send(:include, InfoRequestCustomStates) @@ -231,7 +225,6 @@ describe InfoRequest do describe "when calculating the status for a school" do - fixtures :holidays, :public_bodies, :public_body_translations, :public_body_versions, :users, :info_requests, :incoming_messages, :outgoing_messages, :comments, :info_request_events, :track_things before do @ir = info_requests(:naughty_chicken_request) diff --git a/spec/models/outgoing_mailer_spec.rb b/spec/models/outgoing_mailer_spec.rb index 75c8053b4..5d1ea2dfb 100644 --- a/spec/models/outgoing_mailer_spec.rb +++ b/spec/models/outgoing_mailer_spec.rb @@ -4,9 +4,8 @@ describe OutgoingMailer, " when working out follow up addresses" do # This is done with fixtures as the code is a bit tangled with the way it # calls TMail. XXX untangle it and make these tests spread out and using # mocks. Put parts of the tests in spec/lib/tmail_extensions.rb - fixtures :public_bodies, :public_body_translations, :public_body_versions, :info_requests, :raw_emails, :incoming_messages, :outgoing_messages, :comments, :info_request_events, :track_things before(:each) do - load_raw_emails_data(raw_emails) + load_raw_emails_data end it "should parse them right" do @@ -24,6 +23,7 @@ describe OutgoingMailer, " when working out follow up addresses" do im = ir.incoming_messages[0] im.raw_email.data = im.raw_email.data.sub("\"FOI Person\" <foiperson@localhost>", "foiperson@localhost") + im.parse_raw_email! true # check the basic entry in the fixture is fine OutgoingMailer.name_and_email_for_followup(ir, im).should == "foiperson@localhost" @@ -36,6 +36,7 @@ describe OutgoingMailer, " when working out follow up addresses" do im = ir.incoming_messages[0] im.raw_email.data = im.raw_email.data.sub("FOI Person", "FOI [ Person") + im.parse_raw_email! true # check the basic entry in the fixture is fine OutgoingMailer.name_and_email_for_followup(ir, im).should == "\"FOI [ Person\" <foiperson@localhost>" @@ -48,6 +49,7 @@ describe OutgoingMailer, " when working out follow up addresses" do im = ir.incoming_messages[0] im.raw_email.data = im.raw_email.data.sub("FOI Person", "FOI \\\" Person") + im.parse_raw_email! true # check the basic entry in the fixture is fine OutgoingMailer.name_and_email_for_followup(ir, im).should == "\"FOI \\\" Person\" <foiperson@localhost>" @@ -60,6 +62,7 @@ describe OutgoingMailer, " when working out follow up addresses" do im = ir.incoming_messages[0] im.raw_email.data = im.raw_email.data.sub("FOI Person", "FOI @ Person") + im.parse_raw_email! true # check the basic entry in the fixture is fine OutgoingMailer.name_and_email_for_followup(ir, im).should == "\"FOI @ Person\" <foiperson@localhost>" @@ -70,10 +73,9 @@ describe OutgoingMailer, " when working out follow up addresses" do end describe OutgoingMailer, "when working out follow up subjects" do - fixtures :info_requests, :raw_emails, :incoming_messages, :outgoing_messages, :comments, :info_request_events, :track_things before(:each) do - load_raw_emails_data(raw_emails) + load_raw_emails_data end it "should prefix the title with 'Freedom of Information request -' for initial requests" do @@ -116,6 +118,8 @@ describe OutgoingMailer, "when working out follow up subjects" do om.incoming_message_followup = im im.raw_email.data = im.raw_email.data.sub("Subject: Geraldine FOI Code AZXB421", "Subject: re: Geraldine FOI Code AZXB421") + im.parse_raw_email! true + OutgoingMailer.subject_for_followup(ir, om).should == "re: Geraldine FOI Code AZXB421" end @@ -127,6 +131,8 @@ describe OutgoingMailer, "when working out follow up subjects" do im.raw_email.data = im.raw_email.data.sub("foiperson@localhost", "postmaster@localhost") im.raw_email.data = im.raw_email.data.sub("Subject: Geraldine FOI Code AZXB421", "Subject: Delivery Failed") + im.parse_raw_email! true + OutgoingMailer.subject_for_followup(ir, om).should == "Re: Freedom of Information request - Why do you have & such a fancy dog?" end end diff --git a/spec/models/outgoing_message_spec.rb b/spec/models/outgoing_message_spec.rb index 58d9f398e..51bb6fdf5 100644 --- a/spec/models/outgoing_message_spec.rb +++ b/spec/models/outgoing_message_spec.rb @@ -1,7 +1,6 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') describe OutgoingMessage, " when making an outgoing message" do - fixtures :public_bodies, :public_body_translations, :public_body_versions, :info_requests, :incoming_messages, :outgoing_messages, :comments, :info_request_events, :track_things before do @om = outgoing_messages(:useless_outgoing_message) @@ -38,7 +37,6 @@ end describe IncomingMessage, " when censoring data" do - fixtures :info_requests, :incoming_messages, :outgoing_messages, :comments, :info_request_events, :track_things before do @om = outgoing_messages(:useless_outgoing_message) diff --git a/spec/models/public_body_spec.rb b/spec/models/public_body_spec.rb index 07e8f291d..db0de78b2 100644 --- a/spec/models/public_body_spec.rb +++ b/spec/models/public_body_spec.rb @@ -95,7 +95,6 @@ describe PublicBody, " using machine tags" do end describe PublicBody, "when finding_by_tags" do - fixtures :public_bodies, :public_body_translations, :public_body_versions, :info_requests, :incoming_messages, :outgoing_messages, :comments, :info_request_events, :track_things before do @geraldine = public_bodies(:geraldine_public_body) @@ -173,7 +172,6 @@ describe PublicBody, " when saving" do end describe PublicBody, "when searching" do - fixtures :public_bodies, :public_body_translations, :public_body_versions, :info_requests, :incoming_messages, :outgoing_messages, :comments, :info_request_events, :track_things it "should find by existing url name" do body = PublicBody.find_by_url_name_with_historic('dfh') @@ -249,10 +247,8 @@ describe PublicBody, " when loading CSV files" do errors, notes = PublicBody.import_csv("1,aBody", '', 'replace', true, 'someadmin') # true means dry run errors.should == [] notes.size.should == 2 - notes.should == [ - "line 1: creating new authority 'aBody' (locale: en):\n\t{\"name\":\"aBody\"}", - "Notes: Some bodies are in database, but not in CSV file:\n Department for Humpadinking\n Geraldine Quango\nYou may want to delete them manually.\n" - ] + notes[0].should == "line 1: creating new authority 'aBody' (locale: en):\n\t{\"name\":\"aBody\"}" + notes[1].should =~ /Notes: Some bodies are in database, but not in CSV file:\n( [A-Za-z ]+\n)*You may want to delete them manually.\n/ end it "should do a dry run successfully" do @@ -262,12 +258,12 @@ describe PublicBody, " when loading CSV files" do errors, notes = PublicBody.import_csv(csv_contents, '', 'replace', true, 'someadmin') # true means dry run errors.should == [] notes.size.should == 4 - notes.should == [ + notes[0..2].should == [ "line 1: creating new authority 'North West Fake Authority' (locale: en):\n\t\{\"name\":\"North West Fake Authority\",\"request_email\":\"north_west_foi@localhost\"\}", "line 2: creating new authority 'Scottish Fake Authority' (locale: en):\n\t\{\"name\":\"Scottish Fake Authority\",\"request_email\":\"scottish_foi@localhost\"\}", "line 3: creating new authority 'Fake Authority of Northern Ireland' (locale: en):\n\t\{\"name\":\"Fake Authority of Northern Ireland\",\"request_email\":\"ni_foi@localhost\"\}", - "Notes: Some bodies are in database, but not in CSV file:\n Department for Humpadinking\n Geraldine Quango\nYou may want to delete them manually.\n" - ] + ] + notes[3].should =~ /Notes: Some bodies are in database, but not in CSV file:\n( [A-Za-z ]+\n)*You may want to delete them manually.\n/ PublicBody.count.should == original_count end @@ -279,12 +275,12 @@ describe PublicBody, " when loading CSV files" do errors, notes = PublicBody.import_csv(csv_contents, '', 'replace', false, 'someadmin') # false means real run errors.should == [] notes.size.should == 4 - notes.should == [ + notes[0..2].should == [ "line 1: creating new authority 'North West Fake Authority' (locale: en):\n\t\{\"name\":\"North West Fake Authority\",\"request_email\":\"north_west_foi@localhost\"\}", "line 2: creating new authority 'Scottish Fake Authority' (locale: en):\n\t\{\"name\":\"Scottish Fake Authority\",\"request_email\":\"scottish_foi@localhost\"\}", "line 3: creating new authority 'Fake Authority of Northern Ireland' (locale: en):\n\t\{\"name\":\"Fake Authority of Northern Ireland\",\"request_email\":\"ni_foi@localhost\"\}", - "Notes: Some bodies are in database, but not in CSV file:\n Department for Humpadinking\n Geraldine Quango\nYou may want to delete them manually.\n" - ] + ] + notes[3].should =~ /Notes: Some bodies are in database, but not in CSV file:\n( [A-Za-z ]+\n)*You may want to delete them manually.\n/ PublicBody.count.should == original_count + 3 end @@ -296,12 +292,12 @@ describe PublicBody, " when loading CSV files" do errors, notes = PublicBody.import_csv(csv_contents, '', 'replace', false, 'someadmin') # false means real run errors.should == [] notes.size.should == 4 - notes.should == [ + notes[0..2].should == [ "line 1: creating new authority 'North West Fake Authority' (locale: en):\n\t\{\"name\":\"North West Fake Authority\",\"request_email\":\"north_west_foi@localhost\"\}", "line 2: creating new authority 'Scottish Fake Authority' (locale: en):\n\t\{\"name\":\"Scottish Fake Authority\",\"request_email\":\"scottish_foi@localhost\"\}", "line 3: creating new authority 'Fake Authority of Northern Ireland' (locale: en):\n\t\{\"name\":\"Fake Authority of Northern Ireland\",\"request_email\":\"ni_foi@localhost\"\}", - "Notes: Some bodies are in database, but not in CSV file:\n Department for Humpadinking\n Geraldine Quango\nYou may want to delete them manually.\n" - ] + ] + notes[3].should =~ /Notes: Some bodies are in database, but not in CSV file:\n( [A-Za-z ]+\n)*You may want to delete them manually.\n/ PublicBody.count.should == original_count + 3 end @@ -312,12 +308,12 @@ describe PublicBody, " when loading CSV files" do errors, notes = PublicBody.import_csv(csv_contents, '', 'replace', true, 'someadmin') # true means dry run errors.should == [] notes.size.should == 4 - notes.should == [ + notes[0..2].should == [ "line 2: creating new authority 'North West Fake Authority' (locale: en):\n\t\{\"name\":\"North West Fake Authority\",\"request_email\":\"north_west_foi@localhost\",\"home_page\":\"http://northwest.org\"\}", "line 3: creating new authority 'Scottish Fake Authority' (locale: en):\n\t\{\"name\":\"Scottish Fake Authority\",\"request_email\":\"scottish_foi@localhost\",\"home_page\":\"http://scottish.org\",\"tag_string\":\"scottish\"\}", "line 4: creating new authority 'Fake Authority of Northern Ireland' (locale: en):\n\t\{\"name\":\"Fake Authority of Northern Ireland\",\"request_email\":\"ni_foi@localhost\",\"tag_string\":\"fake aTag\"\}", - "Notes: Some bodies are in database, but not in CSV file:\n Department for Humpadinking\n Geraldine Quango\nYou may want to delete them manually.\n" - ] + ] + notes[3].should =~ /Notes: Some bodies are in database, but not in CSV file:\n( [A-Za-z ]+\n)*You may want to delete them manually.\n/ PublicBody.count.should == original_count end @@ -366,15 +362,15 @@ describe PublicBody, " when loading CSV files" do errors, notes = PublicBody.import_csv(csv_contents, '', 'replace', false, 'someadmin', [:en, :es]) errors.should == [] notes.size.should == 7 - notes.should == [ + notes[0..5].should == [ "line 2: creating new authority 'North West Fake Authority' (locale: en):\n\t{\"name\":\"North West Fake Authority\",\"request_email\":\"north_west_foi@localhost\",\"home_page\":\"http://northwest.org\"}", "line 2: creating new authority 'North West Fake Authority' (locale: es):\n\t{\"name\":\"Autoridad del Nordeste\"}", "line 3: creating new authority 'Scottish Fake Authority' (locale: en):\n\t{\"name\":\"Scottish Fake Authority\",\"request_email\":\"scottish_foi@localhost\",\"home_page\":\"http://scottish.org\",\"tag_string\":\"scottish\"}", "line 3: creating new authority 'Scottish Fake Authority' (locale: es):\n\t{\"name\":\"Autoridad Escocesa\"}", "line 4: creating new authority 'Fake Authority of Northern Ireland' (locale: en):\n\t{\"name\":\"Fake Authority of Northern Ireland\",\"request_email\":\"ni_foi@localhost\",\"tag_string\":\"fake aTag\"}", "line 4: creating new authority 'Fake Authority of Northern Ireland' (locale: es):\n\t{\"name\":\"Autoridad Irlandesa\"}", - "Notes: Some bodies are in database, but not in CSV file:\n Department for Humpadinking\n Geraldine Quango\nYou may want to delete them manually.\n" - ] + ] + notes[6].should =~ /Notes: Some bodies are in database, but not in CSV file:\n( [A-Za-z ]+\n)*You may want to delete them manually.\n/ PublicBody.count.should == original_count + 3 @@ -395,12 +391,12 @@ describe PublicBody, " when loading CSV files" do errors, notes = PublicBody.import_csv(csv_contents, '', 'replace', true, 'someadmin', ['en', :xx]) # true means dry run errors.should == [] notes.size.should == 4 - notes.should == [ + notes[0..2].should == [ "line 2: creating new authority 'North West Fake Authority' (locale: en):\n\t{\"name\":\"North West Fake Authority\",\"request_email\":\"north_west_foi@localhost\",\"home_page\":\"http://northwest.org\"}", "line 3: creating new authority 'Scottish Fake Authority' (locale: en):\n\t{\"name\":\"Scottish Fake Authority\",\"request_email\":\"scottish_foi@localhost\",\"home_page\":\"http://scottish.org\",\"tag_string\":\"scottish\"}", "line 4: creating new authority 'Fake Authority of Northern Ireland' (locale: en):\n\t{\"name\":\"Fake Authority of Northern Ireland\",\"request_email\":\"ni_foi@localhost\",\"tag_string\":\"fake aTag\"}", - "Notes: Some bodies are in database, but not in CSV file:\n Department for Humpadinking\n Geraldine Quango\nYou may want to delete them manually.\n" - ] + ] + notes[3].should =~ /Notes: Some bodies are in database, but not in CSV file:\n( [A-Za-z ]+\n)*You may want to delete them manually.\n/ PublicBody.count.should == original_count end diff --git a/spec/models/request_mailer_spec.rb b/spec/models/request_mailer_spec.rb index ef4ed8074..64ac35cf7 100644 --- a/spec/models/request_mailer_spec.rb +++ b/spec/models/request_mailer_spec.rb @@ -1,9 +1,9 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') describe RequestMailer, " when receiving incoming mail" do - fixtures :public_bodies, :public_body_translations, :public_body_versions, :users, :info_requests, :raw_emails, :incoming_messages, :outgoing_messages, :comments, :info_request_events, :track_things before(:each) do - load_raw_emails_data(raw_emails) + load_raw_emails_data + ActionMailer::Base.deliveries = [] end it "should append it to the appropriate request" do diff --git a/spec/models/track_mailer_spec.rb b/spec/models/track_mailer_spec.rb index 67a64ee10..4f5499a90 100644 --- a/spec/models/track_mailer_spec.rb +++ b/spec/models/track_mailer_spec.rb @@ -155,6 +155,7 @@ describe TrackMailer do @post_redirect = mock_model(PostRedirect, :save! => true, :email_token => "token") PostRedirect.stub!(:new).and_return(@post_redirect) + ActionMailer::Base.deliveries = [] end it 'should deliver one email, with right headers' do diff --git a/spec/models/track_thing_spec.rb b/spec/models/track_thing_spec.rb index 4922a96c7..bd122941a 100644 --- a/spec/models/track_thing_spec.rb +++ b/spec/models/track_thing_spec.rb @@ -1,7 +1,6 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') describe TrackThing, "when tracking changes" do - fixtures :users, :info_requests, :incoming_messages, :outgoing_messages, :comments, :info_request_events, :track_things before do @track_thing = track_things(:track_fancy_dog_search) @@ -28,6 +27,13 @@ describe TrackThing, "when tracking changes" do found_track.should == @track_thing end + it "can display the description of a deleted track_thing" do + track_thing = TrackThing.create_track_for_search_query('fancy dog') + description = track_thing.track_query_description + track_thing.destroy + track_thing.track_query_description.should == description + end + it "will make some sane descriptions of search-based tracks" do tests = [['bob variety:user', "users matching text 'bob'"], ['bob (variety:sent OR variety:followup_sent OR variety:response OR variety:comment) (latest_status:successful OR latest_status:partially_successful OR latest_status:rejected OR latest_status:not_held)', "requests which are successful or unsuccessful or comments matching text 'bob'"], diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index e0a6c649e..03b2f34f9 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -29,7 +29,7 @@ describe User, "showing the name" do it 'should show if user has been banned' do @user.ban_text = "Naughty user" - @user.name.should == 'Some Name (Banned)' + @user.name.should == 'Some Name (Account suspended)' end end @@ -193,7 +193,6 @@ describe User, "when reindexing referencing models" do end describe User, "when checking abilities" do - fixtures :users, :info_requests, :raw_emails, :incoming_messages, :outgoing_messages, :comments, :info_request_events, :track_things before do @user = users(:bob_smith_user) @@ -283,7 +282,6 @@ describe User, "when setting a profile photo" do end describe User, "when unconfirmed" do - fixtures :users, :info_requests, :raw_emails, :incoming_messages, :outgoing_messages, :comments, :info_request_events, :track_things before do @user = users(:unconfirmed_user) @@ -295,7 +293,6 @@ describe User, "when unconfirmed" do end describe User, "when emails have bounced" do - fixtures :users, :info_requests, :raw_emails, :incoming_messages, :outgoing_messages, :comments, :info_request_events, :track_things it "should record bounces" do User.record_bounce_for_email("bob@localhost", "The reason we think the email bounced (e.g. a bounce message)") diff --git a/spec/models/xapian_spec.rb b/spec/models/xapian_spec.rb index ec11c944b..81c066184 100644 --- a/spec/models/xapian_spec.rb +++ b/spec/models/xapian_spec.rb @@ -1,19 +1,20 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') describe User, " when indexing users with Xapian" do - fixtures :public_bodies, :public_body_translations, :public_body_versions, :users, :info_requests, :raw_emails, :incoming_messages, :outgoing_messages, :comments, :info_request_events, :track_things - it "should search by name" do - parse_all_incoming_messages + before(:each) do + load_raw_emails_data rebuild_xapian_index - # def InfoRequest.full_search(models, query, order, ascending, collapse, per_page, page) + end + + it "should search by name" do + # def InfoRequest.full_search(models, query, order, ascending, collapse, per_page, page) xapian_object = InfoRequest.full_search([User], "Silly", 'created_at', true, nil, 100, 1) xapian_object.results.size.should == 1 xapian_object.results[0][:model].should == users(:silly_name_user) end it "should search by 'about me' text" do - rebuild_xapian_index user = users(:bob_smith_user) # def InfoRequest.full_search(models, query, order, ascending, collapse, per_page, page) @@ -35,59 +36,51 @@ describe User, " when indexing users with Xapian" do end describe PublicBody, " when indexing public bodies with Xapian" do - fixtures :public_bodies, :public_body_translations, :public_body_versions, :users, :info_requests, :raw_emails, :incoming_messages, :outgoing_messages, :comments, :info_request_events, :track_things before(:each) do - load_raw_emails_data(raw_emails) + load_raw_emails_data + rebuild_xapian_index end it "should search index the main name field" do - rebuild_xapian_index - xapian_object = InfoRequest.full_search([PublicBody], "humpadinking", 'created_at', true, nil, 100, 1) xapian_object.results.size.should == 1 xapian_object.results[0][:model].should == public_bodies(:humpadink_public_body) end it "should search index the notes field" do - rebuild_xapian_index - xapian_object = InfoRequest.full_search([PublicBody], "albatross", 'created_at', true, nil, 100, 1) xapian_object.results.size.should == 1 xapian_object.results[0][:model].should == public_bodies(:humpadink_public_body) end it "should delete public bodies from the index when they are destroyed" do - rebuild_xapian_index - xapian_object = InfoRequest.full_search([PublicBody], "albatross", 'created_at', true, nil, 100, 1) xapian_object.results.size.should == 1 xapian_object.results[0][:model].should == public_bodies(:humpadink_public_body) - public_bodies(:humpadink_public_body).destroy + public_bodies(:forlorn_public_body).destroy update_xapian_index - xapian_object = InfoRequest.full_search([PublicBody], "albatross", 'created_at', true, nil, 100, 1) - xapian_object.results.size.should == 0 + xapian_object = InfoRequest.full_search([PublicBody], "lonely", 'created_at', true, nil, 100, 1) + xapian_object.results.should == [] end end describe PublicBody, " when indexing requests by body they are to" do - fixtures :public_bodies, :public_body_translations, :public_body_versions, :users, :info_requests, :raw_emails, :incoming_messages, :outgoing_messages, :comments, :info_request_events, :track_things before(:each) do - load_raw_emails_data(raw_emails) + load_raw_emails_data + rebuild_xapian_index end it "should find requests to the body" do - rebuild_xapian_index xapian_object = InfoRequest.full_search([InfoRequestEvent], "requested_from:tgq", 'created_at', true, nil, 100, 1) xapian_object.results.size.should == 4 end it "should update index correctly when URL name of body changes" do # initial search - rebuild_xapian_index xapian_object = InfoRequest.full_search([InfoRequestEvent], "requested_from:tgq", 'created_at', true, nil, 100, 1) xapian_object.results.size.should == 4 models_found_before = xapian_object.results.map { |x| x[:model] } @@ -112,8 +105,6 @@ describe PublicBody, " when indexing requests by body they are to" do # if you index via the Xapian TermGenerator, it ignores terms of this length, # this checks we're using Document:::add_term() instead it "should work with URL names that are longer than 64 characters" do - rebuild_xapian_index - # change the URL name of the body body = public_bodies(:geraldine_public_body) body.short_name = 'The Uncensored, Complete Name of the Quasi-Autonomous Public Body Also Known As Geraldine' @@ -133,28 +124,25 @@ describe PublicBody, " when indexing requests by body they are to" do end describe User, " when indexing requests by user they are from" do - fixtures :users, :info_requests, :raw_emails, :incoming_messages, :outgoing_messages, :comments, :info_request_events, :track_things before(:each) do - load_raw_emails_data(raw_emails) + load_raw_emails_data + rebuild_xapian_index end it "should find requests from the user" do - rebuild_xapian_index xapian_object = InfoRequest.full_search([InfoRequestEvent], "requested_by:bob_smith", 'created_at', true, nil, 100, 1) - xapian_object.results.size.should == 4 + xapian_object.results.map{|x|x[:model]}.should =~ InfoRequestEvent.all(:conditions => "info_request_id in (select id from info_requests where user_id = #{users(:bob_smith_user).id})") end it "should find just the sent message events from a particular user" do - rebuild_xapian_index # def InfoRequest.full_search(models, query, order, ascending, collapse, per_page, page) xapian_object = InfoRequest.full_search([InfoRequestEvent], "requested_by:bob_smith variety:sent", 'created_at', true, nil, 100, 1) - xapian_object.results.size.should == 2 - xapian_object.results[1][:model].should == info_request_events(:useless_outgoing_message_event) - xapian_object.results[0][:model].should == info_request_events(:silly_outgoing_message_event) + xapian_object.results.map{|x|x[:model]}.should =~ InfoRequestEvent.all(:conditions => "info_request_id in (select id from info_requests where user_id = #{users(:bob_smith_user).id}) and event_type = 'sent'") + xapian_object.results[2][:model].should == info_request_events(:useless_outgoing_message_event) + xapian_object.results[1][:model].should == info_request_events(:silly_outgoing_message_event) end it "should not find it when one of the request's users is changed" do - rebuild_xapian_index silly_user = users(:silly_name_user) naughty_chicken_request = info_requests(:naughty_chicken_request) naughty_chicken_request.user = silly_user @@ -164,13 +152,10 @@ describe User, " when indexing requests by user they are from" do # def InfoRequest.full_search(models, query, order, ascending, collapse, per_page, page) xapian_object = InfoRequest.full_search([InfoRequestEvent], "requested_by:bob_smith", 'created_at', true, 'request_collapse', 100, 1) - xapian_object.results.size.should == 1 - xapian_object.results[0][:model].should == info_request_events(:silly_comment_event) + xapian_object.results.map{|x|x[:model].info_request}.should =~ InfoRequest.all(:conditions => "user_id = #{users(:bob_smith_user).id}") end it "should not get confused searching for requests when one user has a name which has same stem as another" do - rebuild_xapian_index - bob_smith_user = users(:bob_smith_user) bob_smith_user.name = "John King" bob_smith_user.url_name.should == 'john_king' @@ -196,9 +181,8 @@ describe User, " when indexing requests by user they are from" do it "should update index correctly when URL name of user changes" do # initial search - rebuild_xapian_index xapian_object = InfoRequest.full_search([InfoRequestEvent], "requested_by:bob_smith", 'created_at', true, nil, 100, 1) - xapian_object.results.size.should == 4 + xapian_object.results.map{|x|x[:model]}.should =~ InfoRequestEvent.all(:conditions => "info_request_id in (select id from info_requests where user_id = #{users(:bob_smith_user).id})") models_found_before = xapian_object.results.map { |x| x[:model] } # change the URL name of the body @@ -212,28 +196,24 @@ describe User, " when indexing requests by user they are from" do xapian_object = InfoRequest.full_search([InfoRequestEvent], "requested_by:bob_smith", 'created_at', true, nil, 100, 1) xapian_object.results.size.should == 0 xapian_object = InfoRequest.full_search([InfoRequestEvent], "requested_by:robert_smith", 'created_at', true, nil, 100, 1) - xapian_object.results.size.should == 4 models_found_after = xapian_object.results.map { |x| x[:model] } - models_found_before.should == models_found_after end end describe User, " when indexing comments by user they are by" do - fixtures :users, :info_requests, :raw_emails, :incoming_messages, :outgoing_messages, :comments, :info_request_events, :track_things before(:each) do - load_raw_emails_data(raw_emails) + load_raw_emails_data + rebuild_xapian_index end it "should find requests from the user" do - rebuild_xapian_index xapian_object = InfoRequest.full_search([InfoRequestEvent], "commented_by:silly_emnameem", 'created_at', true, nil, 100, 1) xapian_object.results.size.should == 1 end it "should update index correctly when URL name of user changes" do # initial search - rebuild_xapian_index xapian_object = InfoRequest.full_search([InfoRequestEvent], "commented_by:silly_emnameem", 'created_at', true, nil, 100, 1) xapian_object.results.size.should == 1 models_found_before = xapian_object.results.map { |x| x[:model] } @@ -257,13 +237,12 @@ describe User, " when indexing comments by user they are by" do end describe InfoRequest, " when indexing requests by their title" do - fixtures :users, :info_requests, :raw_emails, :incoming_messages, :outgoing_messages, :comments, :info_request_events, :track_things before(:each) do - load_raw_emails_data(raw_emails) + load_raw_emails_data + rebuild_xapian_index end it "should find events for the request" do - rebuild_xapian_index xapian_object = InfoRequest.full_search([InfoRequestEvent], "request:how_much_public_money_is_wasted_o", 'created_at', true, nil, 100, 1) xapian_object.results.size.should == 1 xapian_object.results[0][:model] == info_request_events(:silly_outgoing_message_event) @@ -271,7 +250,6 @@ describe InfoRequest, " when indexing requests by their title" do it "should update index correctly when URL title of request changes" do # change the URL name of the body - rebuild_xapian_index ir = info_requests(:naughty_chicken_request) ir.title = 'Really naughty' ir.save! @@ -288,13 +266,12 @@ describe InfoRequest, " when indexing requests by their title" do end describe InfoRequest, " when indexing requests by tag" do - fixtures :users, :info_requests, :raw_emails, :incoming_messages, :outgoing_messages, :comments, :info_request_events, :track_things before(:each) do - load_raw_emails_data(raw_emails) + load_raw_emails_data + rebuild_xapian_index end it "should find request by tag, even when changes" do - rebuild_xapian_index ir = info_requests(:naughty_chicken_request) ir.tag_string = 'bunnyrabbit' ir.save! @@ -310,13 +287,12 @@ describe InfoRequest, " when indexing requests by tag" do end describe PublicBody, " when indexing authorities by tag" do - fixtures :public_bodies, :public_body_translations, :public_body_versions, :users, :info_requests, :raw_emails, :incoming_messages, :outgoing_messages, :comments, :info_request_events, :track_things before(:each) do - load_raw_emails_data(raw_emails) + load_raw_emails_data + rebuild_xapian_index end it "should find request by tag, even when changes" do - rebuild_xapian_index body = public_bodies(:geraldine_public_body) body.tag_string = 'mice:3' body.save! @@ -335,13 +311,12 @@ describe PublicBody, " when indexing authorities by tag" do end describe PublicBody, " when only indexing selected things on a rebuild" do - fixtures :public_bodies, :public_body_translations, :public_body_versions, :users, :info_requests, :raw_emails, :incoming_messages, :outgoing_messages, :comments, :info_request_events, :track_things before(:each) do - load_raw_emails_data(raw_emails) + load_raw_emails_data + rebuild_xapian_index end it "should only index what we ask it to" do - rebuild_xapian_index body = public_bodies(:geraldine_public_body) body.tag_string = 'mice:3' body.name = 'frobzn' @@ -357,7 +332,7 @@ describe PublicBody, " when only indexing selected things on a rebuild" do xapian_object = InfoRequest.full_search([PublicBody], "frobzn", 'created_at', true, nil, 100, 1) xapian_object.results.size.should == 0 xapian_object = InfoRequest.full_search([PublicBody], "variety:authority", 'created_at', true, nil, 100, 1) - xapian_object.results.size.should == 2 + xapian_object.results.map{|x|x[:model]}.should =~ PublicBody.all # only reindex 'tag' and text dropfirst = true terms = "U" @@ -380,7 +355,7 @@ describe PublicBody, " when only indexing selected things on a rebuild" do xapian_object = InfoRequest.full_search([PublicBody], "frobzn", 'created_at', true, nil, 100, 1) xapian_object.results.size.should == 1 xapian_object = InfoRequest.full_search([PublicBody], "variety:authority", 'created_at', true, nil, 100, 1) - xapian_object.results.size.should == 2 + xapian_object.results.map{|x|x[:model]}.should =~ PublicBody.all # only reindex 'variety' term, blowing away existing data dropfirst = true rebuild_xapian_index(terms, values, texts, dropfirst) @@ -389,18 +364,7 @@ describe PublicBody, " when only indexing selected things on a rebuild" do xapian_object = InfoRequest.full_search([PublicBody], "frobzn", 'created_at', true, nil, 100, 1) xapian_object.results.size.should == 0 xapian_object = InfoRequest.full_search([PublicBody], "variety:authority", 'created_at', true, nil, 100, 1) - xapian_object.results.size.should == 2 + xapian_object.results.map{|x|x[:model]}.should =~ PublicBody.all end end - - - - - - - - - - - diff --git a/spec/script/handle-mail-replies_spec.rb b/spec/script/handle-mail-replies_spec.rb index eae0b516b..8ed83b31f 100644 --- a/spec/script/handle-mail-replies_spec.rb +++ b/spec/script/handle-mail-replies_spec.rb @@ -54,5 +54,15 @@ describe "When filtering" do r = mail_reply_test("track-response-messageclass-oof.email") r.status.should == 2 end + + it "should detect an Outlook(?)-style out-of-office" do + r = mail_reply_test("track-response-outlook-oof.email") + r.status.should == 2 + end + + it "should detect an ABCMail-style out-of-office" do + r = mail_reply_test("track-response-abcmail-oof.email") + r.status.should == 2 + end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 5c5cd9a7f..c00da48bc 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,6 +1,6 @@ # This file is copied to ~/spec when you run 'ruby script/generate rspec' # from the project root directory. -ENV["RAILS_ENV"] ||= 'test' +ENV["RAILS_ENV"] = 'test' require File.expand_path(File.join('..', '..', 'config', 'environment'), __FILE__) require 'spec/autorun' require 'spec/rails' @@ -24,6 +24,7 @@ Spec::Runner.configure do |config| # fixture_path must end in a separator config.fixture_path = File.join(Rails.root, 'spec', 'fixtures') + File::SEPARATOR + config.global_fixtures = :users, :public_bodies, :public_body_translations, :public_body_versions, :info_requests, :raw_emails, :incoming_messages, :outgoing_messages, :comments, :info_request_events, :track_things, :foi_attachments, :has_tag_string_tags, :holidays, :track_things_sent_emails # == Fixtures # @@ -78,7 +79,6 @@ def load_file_fixture(file_name) end def rebuild_xapian_index(terms = true, values = true, texts = true, dropfirst = true) - parse_all_incoming_messages if dropfirst begin ActsAsXapian.readable_init @@ -86,7 +86,9 @@ def rebuild_xapian_index(terms = true, values = true, texts = true, dropfirst = rescue RuntimeError end ActsAsXapian.writable_init + ActsAsXapian.writable_db.close end + parse_all_incoming_messages verbose = false # safe_rebuild=true, which involves forking to avoid memory leaks, doesn't work well with rspec. # unsafe is significantly faster, and we can afford possible memory leaks while testing. @@ -96,7 +98,7 @@ end def update_xapian_index verbose = false - ActsAsXapian.update_index(flush_to_disk=true, verbose) + ActsAsXapian.update_index(flush_to_disk=false, verbose) end # Validate an entire HTML page @@ -106,7 +108,7 @@ def validate_html(html) File.open(tempfilename, "w+") do |f| f.puts html end - if not system($html_validation_script, tempfilename) + if not system($html_validation_script, *($html_validation_script_options +[tempfilename])) raise "HTML validation error in " + tempfilename + " HTTP status: " + @response.response_code.to_s end File.unlink(tempfilename) @@ -120,30 +122,47 @@ def validate_as_body(html) end def basic_auth_login(request, username = nil, password = nil) - username = MySociety::Config.get('ADMIN_USERNAME') if username.nil? + username = MySociety::Config.get('ADMIN_USERNAME') if username.nil? password = MySociety::Config.get('ADMIN_PASSWORD') if password.nil? request.env["HTTP_AUTHORIZATION"] = "Basic " + Base64::encode64("#{username}:#{password}") end # Monkeypatch! Validate HTML in tests. -$html_validation_script = "/usr/bin/validate" # from Debian package wdg-html-validator +utility_search_path = MySociety::Config.get("UTILITY_SEARCH_PATH", ["/usr/bin", "/usr/local/bin"]) +$html_validation_script_found = false +utility_search_path.each do |d| + $html_validation_script = File.join(d, "validate") + $html_validation_script_options = ["--charset=utf-8"] + if File.file? $html_validation_script and File.executable? $html_validation_script + $html_validation_script_found = true + break + end +end if $tempfilecount.nil? $tempfilecount = 0 - if File.exist?($html_validation_script) + if $html_validation_script_found module ActionController module TestProcess # Hook into the process function, so can automatically get HTML after each request alias :original_process :process - + def is_fragment + # XXX there must be a better way of doing this! + return @request.query_parameters["action"] == "search_typeahead" + end def process(action, parameters = nil, session = nil, flash = nil, http_method = 'GET') self.original_process(action, parameters, session, flash, http_method) - + # don't validate auto-generated HTML + return if @request.query_parameters["action"] == "get_attachment_as_html" # XXX Is there a better way to check this than calling a private method? return unless @response.template.controller.instance_eval { integrate_views? } - # And then if HTML, not a redirect (302, 301) if @response.content_type == "text/html" && ! [301,302,401].include?(@response.response_code) + if !is_fragment validate_html(@response.body) + else + # it's a partial + validate_as_body(@response.body) + end end end end @@ -161,15 +180,22 @@ def safe_mock_model(model, args = {}) mock end -def load_raw_emails_data(raw_emails) - raw_email = raw_emails(:useless_raw_email) - begin - raw_email.destroy_file_representation! - rescue Errno::ENOENT +def load_raw_emails_data + raw_emails_yml = File.join(Spec::Runner.configuration.fixture_path, "raw_emails.yml") + for raw_email_id in YAML::load_file(raw_emails_yml).map{|k,v| v["id"]} do + raw_email = RawEmail.find(raw_email_id) + raw_email.data = load_file_fixture("raw_emails/%d.email" % [raw_email_id]) end - raw_email.data = load_file_fixture("useless_raw_email.email") 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 diff --git a/spec/views/request/list.rhtml_spec.rb b/spec/views/request/list.rhtml_spec.rb index 1f86ec641..c7067294f 100644 --- a/spec/views/request/list.rhtml_spec.rb +++ b/spec/views/request/list.rhtml_spec.rb @@ -33,6 +33,7 @@ describe "when listing recent requests" do it "should be successful" do assigns[:list_results] = [ make_mock_event, make_mock_event ] assigns[:matches_estimated] = 2 + assigns[:show_no_more_than] = 100 render "request/list" response.should have_tag("div.request_listing") response.should_not have_tag("p", /No requests of this sort yet/m) @@ -41,6 +42,7 @@ describe "when listing recent requests" do it "should cope with no results" do assigns[:list_results] = [ ] assigns[:matches_estimated] = 0 + assigns[:show_no_more_than] = 0 render "request/list" response.should have_tag("p", /No requests of this sort yet/m) response.should_not have_tag("div.request_listing") diff --git a/spec/views/request/show.rhtml_spec.rb b/spec/views/request/show.rhtml_spec.rb index adb244f47..ef7d1a47c 100644 --- a/spec/views/request/show.rhtml_spec.rb +++ b/spec/views/request/show.rhtml_spec.rb @@ -84,10 +84,15 @@ describe 'when viewing an information request' do describe 'when there is a last response' do before do - ActionController::Routing::Routes.filters.clear @mock_response = mock_model(IncomingMessage) @mock_request.stub!(:get_last_response).and_return(@mock_response) + @old_filters = ActionController::Routing::Routes.filters + ActionController::Routing::Routes.filters = RoutingFilter::Chain.new end + after do + ActionController::Routing::Routes.filters = @old_filters + end + it 'should show a link to follow up the last response with clarification' do request_page @@ -100,9 +105,14 @@ describe 'when viewing an information request' do describe 'when there is no last response' do before do - ActionController::Routing::Routes.filters.clear @mock_request.stub!(:get_last_response).and_return(nil) + @old_filters = ActionController::Routing::Routes.filters + ActionController::Routing::Routes.filters = RoutingFilter::Chain.new end + after do + ActionController::Routing::Routes.filters = @old_filters + end + it 'should show a link to follow up the request without reference to a specific response' do request_page diff --git a/vendor/gems/fakeweb-1.3.0/.gitignore b/vendor/gems/fakeweb-1.3.0/.gitignore new file mode 100644 index 000000000..63be0c5de --- /dev/null +++ b/vendor/gems/fakeweb-1.3.0/.gitignore @@ -0,0 +1,7 @@ +/doc +/rdoc +/html +/coverage +/pkg +/.idea +*.rbc diff --git a/vendor/gems/fakeweb-1.3.0/.specification b/vendor/gems/fakeweb-1.3.0/.specification new file mode 100644 index 000000000..b69e9d545 --- /dev/null +++ b/vendor/gems/fakeweb-1.3.0/.specification @@ -0,0 +1,135 @@ +--- !ruby/object:Gem::Specification +name: fakeweb +version: !ruby/object:Gem::Version + hash: 27 + prerelease: + segments: + - 1 + - 3 + - 0 + version: 1.3.0 +platform: ruby +authors: +- Chris Kampmeier +- Blaine Cook +autorequire: +bindir: bin +cert_chain: [] + +date: 2010-08-22 00:00:00 +01:00 +default_executable: +dependencies: +- !ruby/object:Gem::Dependency + name: mocha + prerelease: false + requirement: &id001 !ruby/object:Gem::Requirement + none: false + requirements: + - - ">=" + - !ruby/object:Gem::Version + hash: 49 + segments: + - 0 + - 9 + - 5 + version: 0.9.5 + type: :development + version_requirements: *id001 +description: FakeWeb is a helper for faking web requests in Ruby. It works at a global level, without modifying code or writing extensive stubs. +email: +- chris@kampers.net +- romeda@gmail.com +executables: [] + +extensions: [] + +extra_rdoc_files: [] + +files: +- test/test_allow_net_connect.rb +- test/test_deprecations.rb +- test/test_fake_authentication.rb +- test/test_fake_web.rb +- test/test_fake_web_open_uri.rb +- test/test_helper.rb +- test/test_last_request.rb +- test/test_missing_open_uri.rb +- test/test_missing_pathname.rb +- test/test_other_net_http_libraries.rb +- test/test_precedence.rb +- test/test_query_string.rb +- test/test_regexes.rb +- test/test_response_headers.rb +- test/test_trailing_slashes.rb +- test/test_utility.rb +- test/vendor/right_http_connection-1.2.4/lib/net_fix.rb +- test/vendor/right_http_connection-1.2.4/lib/right_http_connection.rb +- test/vendor/right_http_connection-1.2.4/setup.rb +- test/vendor/samuel-0.2.1/lib/samuel/net_http.rb +- test/vendor/samuel-0.2.1/lib/samuel/request.rb +- test/vendor/samuel-0.2.1/lib/samuel.rb +- test/vendor/samuel-0.2.1/test/request_test.rb +- test/vendor/samuel-0.2.1/test/samuel_test.rb +- test/vendor/samuel-0.2.1/test/test_helper.rb +- test/vendor/samuel-0.2.1/test/thread_test.rb +has_rdoc: true +homepage: http://github.com/chrisk/fakeweb +licenses: [] + +post_install_message: +rdoc_options: [] + +require_paths: +- lib +required_ruby_version: !ruby/object:Gem::Requirement + none: false + requirements: + - - ">=" + - !ruby/object:Gem::Version + hash: 3 + segments: + - 0 + version: "0" +required_rubygems_version: !ruby/object:Gem::Requirement + none: false + requirements: + - - ">=" + - !ruby/object:Gem::Version + hash: 3 + segments: + - 0 + version: "0" +requirements: [] + +rubyforge_project: fakeweb +rubygems_version: 1.6.2 +signing_key: +specification_version: 3 +summary: A tool for faking responses to HTTP requests +test_files: +- test/test_allow_net_connect.rb +- test/test_deprecations.rb +- test/test_fake_authentication.rb +- test/test_fake_web.rb +- test/test_fake_web_open_uri.rb +- test/test_helper.rb +- test/test_last_request.rb +- test/test_missing_open_uri.rb +- test/test_missing_pathname.rb +- test/test_other_net_http_libraries.rb +- test/test_precedence.rb +- test/test_query_string.rb +- test/test_regexes.rb +- test/test_response_headers.rb +- test/test_trailing_slashes.rb +- test/test_utility.rb +- test/vendor/right_http_connection-1.2.4/lib/net_fix.rb +- test/vendor/right_http_connection-1.2.4/lib/right_http_connection.rb +- test/vendor/right_http_connection-1.2.4/setup.rb +- test/vendor/samuel-0.2.1/lib/samuel/net_http.rb +- test/vendor/samuel-0.2.1/lib/samuel/request.rb +- test/vendor/samuel-0.2.1/lib/samuel.rb +- test/vendor/samuel-0.2.1/test/request_test.rb +- test/vendor/samuel-0.2.1/test/samuel_test.rb +- test/vendor/samuel-0.2.1/test/test_helper.rb +- test/vendor/samuel-0.2.1/test/thread_test.rb diff --git a/vendor/gems/fakeweb-1.3.0/CHANGELOG b/vendor/gems/fakeweb-1.3.0/CHANGELOG new file mode 100644 index 000000000..e626352f6 --- /dev/null +++ b/vendor/gems/fakeweb-1.3.0/CHANGELOG @@ -0,0 +1,215 @@ +fakeweb (1.3.0) + +* improve response header registration so you can pass an array to set a header + more than once [Myron Marston] + +* fix an exception when the response's :body option was set to nil [Chris Zingel] + +* fix that stubbed requests weren't mutating the Net::HTTP request object to set + the body and content-length, like real requests do [Chris Kampmeier] + +* add FakeWeb.last_request [Chris Kampmeier] + +* assigning a String or Regexp to FakeWeb.allow_net_connect= sets a whitelist + for outbound requests [Dan Dofter, Tim Carey-Smith, Ben Woosley] + + +fakeweb (1.2.8) + +* support Pathname objects where a filename is expected [Chris Kampmeier] + +* fix compatibility with Ruby 1.9.2 [Chris Kampmeier] + +* simplify storage of FakeWeb::VERSION [Josh Peek, Woody Peterson, Ben Woosley] + + +fakeweb (1.2.7) + +* revert to sorting query params before matching requests against regexps, + instead of the 1.2.6 behavior that tried every possible order combination; + that was factorial-time, which made matching hang for requests with long query + strings [Jason Wadsworth, David Dollar, Blaine Cook] + +* print a warning when FakeWeb is loaded before RightHttpConnection or after + Samuel, other libs that patch Net::HTTP [Chris Kampmeier, Ben Brinckerhoff] + + +fakeweb (1.2.6) + +* fix that query params in a regex would have to be sorted for it to ever match + a request URI [Chris Kampmeier, Ben Hall] + +* improve regex handling so registration with an explicit port (like + /example.com:80/) matches a request that uses an implied port + (like "http://example.com/") [Chris Kampmeier, Dan Dofter] + +* refactor URI registry to reduce duplication; now about twice as fast at + handling requests [Chris Kampmeier] + +* Add FakeWeb::VERSION so you can programmatically determine what version of + FakeWeb is loaded without using RubyGems [Chris Kampmeier, Chris Wanstrath] + + +fakeweb (1.2.5) + +* fix handling of userinfo strings that contain percent-encoded unsafe + characters [Chris Kampmeier, Ken Mayer] + +* fix that exact matches against strings/URIs with the :any method had a lower + precedence than regex matches using a real HTTP method (exact matches now + always take precedence) [Chris Kampmeier] + +* change request handling to raise an exception when more than one registered + regex matches a request URI [Chris Kampmeier] + + +fakeweb (1.2.4) + +* add experimental support for matching URIs via regular expressions + [Jacqui Maher, Tiago Albineli Motta, Peter Wagene] + +* fix an exception when registering with the :response option and a string that + is the same as the name of a directory in the current path [Chris Kampmeier] + +* DEPRECATION: Calling FakeWeb.register_uri with a :string or :file option is + now deprecated. Both options have been replaced with a unified :body option, + since they supply the response body (as opposed to :response, which supplies + the full response including headers) [Chris Kampmeier] + +* add support for specifying HTTP headers as options to FakeWeb.register_uri + when using the :string or :file response types, since those methods only + specify a response body [David Michael, Chris Kampmeier] + +* DEPRECATION: Calling FakeWeb.register_uri and FakeWeb.registered_uri? without + an HTTP method as the first argument is now deprecated. To match against any + HTTP method (the pre-1.2.0 behavior), use :any [Chris Kampmeier] + + +fakeweb (1.2.3) + +* fix the #http_version of :file and :string responses, which was returning the + request URI instead of something sensible like "1.0" [Chris Kampmeier] + +* add method aliases in the Net::HTTP patch to eliminate warnings when running + with -w [Joshua Clingenpeel] + +* fix that removing the redefinition of OpenURI::HTTPError in 1.2.0 caused + :exception responses to raise when OpenURI isn't available [Chris Kampmeier] + +* fix registering an :exception response with classes that require arguments for + instantiation, like Interrupt's subclasses [Chris Kampmeier] + + +fakeweb (1.2.2) + +* fix that HTTP Digest and OAuth requests could raise URI::InvalidURIErrors + [Bill Kocik, Chris Kampmeier] + + +fakeweb (1.2.1) + +* fix that query parameters are handled correctly when registering with a URI + object [Anselmo Alves, Chris Kampmeier] + +* fix an exception when registering with the :response option and a string + containing "\0" [Jonathan Baudanza, Chris Kampmeier] + +* fix that trailing slashes were considered significant for requests to the root + of a domain [Chris Kampmeier] + +* add support for HTTP basic authentication via userinfo strings in URIs + [Michael Bleigh] + + +fakeweb (1.2.0) + +* add lib/fakeweb.rb so you can require "fakeweb" as well [Chris Kampmeier] + +* fix compatibility with Ruby 1.9.1 [Chris Kampmeier] + +* fix that newlines in file-based responses could be doubled in the response + object's body [Mark Menard, Chris Kampmeier] + +* fix unnecessary munging of the transfer-encoding header, which improves + compatibility with mechanize [Mark Menard] + +* fix a test and the RCov dependency to be compatible with JRuby [Mark Menard] + +* remove an unnecessary redefinition of OpenURI::HTTPError [Josh Nichols] + +* rearrange implementation code into separate files, one per class [Josh Nichols] + +* fix a bug where FakeWeb.response_for would raise if the request wasn't + registered [Chris Kampmeier] + +* add HTTP method support, so FakeWeb takes both the URI and method into + account for registration, requests, and responses. Backwards-compatible with + the old method signatures, which didn't have a method param. [Chris Kampmeier] + +* start work on Ruby 1.9 compatibility [Chris Kampmeier] + +* add FakeWeb.allow_net_connect= to enable/disable the pass-through to + Net::HTTP for unregistered URIs [Mislav Marohnić, Chris Kampmeier] + +* remove setup.rb, since most people use RubyGems [Mislav Marohnić] + +* fix that 'http://example.com/?' (empty query) matches a registered + 'http://example.com/', and vice-versa [Mislav Marohnić] + +* improve the test suite to not rely on an internet connection [Chris Kampmeier] + +* use `rake test` instead of `rake tests` [Josh Nichols] + +* fix an incompatibility with Ruby 1.8.6 p36 where you'd get "Errno::EINTR: + Interrupted system call" exceptions in Socket#sysread for any non-faked + request [Chris Kampmeier] + +* response rotation: you can now optionally call FakeWeb.register_uri with an + array of options hashes; these are used, in order, to respond to + repeated requests (to repeat a response more than once before rotating, use + the :times option). Once you run out of responses, further requests always + receive the last response. [Michael Shapiro] + +* add support for Net::HTTP's undocumented full-URI request style (fixes + URI::InvalidURIErrors that you might see in older libraries) [Chris Kampmeier] + +* sort query params before storing internally, so that + http://example.com/?a=1&b=2 and http://example.com/?b=2&a=1 are considered the + same URL (although this is technically incorrect, it's much more + convenient--most web apps work that way, and Net::HTTP's use of a hash to pass + query params means that the order in which FakeWeb stores them can be + unpredictable) [Chris Kampmeier] + +* add support for ports in URLs, so that http://example.com/ and + http://example.com:3000/ are not the same [Chris Kampmeier] + +* fix for non-faked SSL requests failing with "Unable to create local socket" + [Chris Kampmeier] + +* update Rakefile to fix warning about deprecated code [Chris Kampmeier] + + +fakeweb (1.1.2) + +* add required dependencies to GemSpec to ensure that tests pass in firebrigade + (http://firebrigade.seattlerb.org/) [Blaine Cook] + + +fakeweb (1.1.1) + +* fix for non-existence of :string method on File as presented by open-uri + [Blaine Cook] + +* fix for curl example test - google redirects to ccTLDs for those outside US + [Blaine Cook] + + +fakeweb (1.1.0) + +* update code to correspond to ruby 1.8.4 (breaks compatibility with ruby 1.8.2) + [Blaine Cook] + + +fakeweb (1.0.0) + + * initial import [Blaine Cook] diff --git a/vendor/gems/fakeweb-1.3.0/LICENSE.txt b/vendor/gems/fakeweb-1.3.0/LICENSE.txt new file mode 100644 index 000000000..ecae84703 --- /dev/null +++ b/vendor/gems/fakeweb-1.3.0/LICENSE.txt @@ -0,0 +1,19 @@ +Copyright 2006-2010 Blaine Cook, Chris Kampmeier, and other contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/gems/fakeweb-1.3.0/README.rdoc b/vendor/gems/fakeweb-1.3.0/README.rdoc new file mode 100644 index 000000000..33115325b --- /dev/null +++ b/vendor/gems/fakeweb-1.3.0/README.rdoc @@ -0,0 +1,189 @@ += FakeWeb + +FakeWeb is a helper for faking web requests in Ruby. It works at a global +level, without modifying code or writing extensive stubs. + + +== Installation + + gem install fakeweb + +Note: the gem was previously available as +FakeWeb+ (capital letters), but now +all versions are simply registered as +fakeweb+. If you have any old +FakeWeb+ +gems lying around, remove them: <tt>gem uninstall FakeWeb</tt> + + +== Help and discussion + +RDocs for the current release are available at http://fakeweb.rubyforge.org. + +There's a mailing list for questions and discussion at +http://groups.google.com/group/fakeweb-users. + +The main source repository is http://github.com/chrisk/fakeweb. + +== Examples + +Start by requiring FakeWeb: + + require 'fakeweb' + +=== Registering basic string responses + + FakeWeb.register_uri(:get, "http://example.com/test1", :body => "Hello World!") + + Net::HTTP.get(URI.parse("http://example.com/test1")) + => "Hello World!" + + Net::HTTP.get(URI.parse("http://example.com/test2")) + => FakeWeb is bypassed and the response from a real request is returned + +You can also call <tt>register_uri</tt> with a regular expression, to match +more than one URI. + + FakeWeb.register_uri(:get, %r|http://example\.com/|, :body => "Hello World!") + + Net::HTTP.get(URI.parse("http://example.com/test3")) + => "Hello World!" + +=== Replaying a recorded response + + page = `curl -is http://www.google.com/` + FakeWeb.register_uri(:get, "http://www.google.com/", :response => page) + + Net::HTTP.get(URI.parse("http://www.google.com/")) + # => Full response, including headers + +=== Adding a custom status to the response + + FakeWeb.register_uri(:get, "http://example.com/", :body => "Nothing to be found 'round here", + :status => ["404", "Not Found"]) + + Net::HTTP.start("example.com") do |req| + response = req.get("/") + response.code # => "404" + response.message # => "Not Found" + response.body # => "Nothing to be found 'round here" + end + +=== Responding to any HTTP method + + FakeWeb.register_uri(:any, "http://example.com", :body => "response for any HTTP method") + +If you use the <tt>:any</tt> symbol, the URI you specify will be completely +stubbed out (regardless of the HTTP method of the request). This can be useful +for RPC-style services, where the HTTP method isn't significant. (Older +versions of FakeWeb always behaved like this, and didn't accept the first ++method+ argument above; this syntax is now deprecated.) + +=== Rotating responses + +You can optionally call <tt>FakeWeb.register_uri</tt> with an array of options +hashes; these are used, in order, to respond to repeated requests. Once you run +out of responses, further requests always receive the last response. (You can +also send a response more than once before rotating, by specifying a +<tt>:times</tt> option for that response.) + + FakeWeb.register_uri(:delete, "http://example.com/posts/1", + [{:body => "Post 1 deleted.", :status => ["200", "OK"]}, + {:body => "Post not found", :status => ["404", "Not Found"]}]) + + Net::HTTP.start("example.com") do |req| + req.delete("/posts/1").body # => "Post 1 deleted" + req.delete("/posts/1").body # => "Post not found" + req.delete("/posts/1").body # => "Post not found" + end + +=== Using HTTP basic authentication + +You can fake requests that use basic authentication by adding +userinfo+ strings +to your URIs: + + FakeWeb.register_uri(:get, "http://example.com/secret", :body => "Unauthorized", :status => ["401", "Unauthorized"]) + FakeWeb.register_uri(:get, "http://user:pass@example.com/secret", :body => "Authorized") + + Net::HTTP.start("example.com") do |http| + req = Net::HTTP::Get.new("/secret") + http.request(req) # => "Unauthorized" + req.basic_auth("user", "pass") + http.request(req) # => "Authorized" + end + +=== Clearing registered URIs + +The FakeWeb registry is a singleton that lasts for the duration of your program, +maintaining every fake response you register. If needed, you can clean out the +registry and remove all registered URIs: + + FakeWeb.clean_registry + +=== Blocking all real requests + +When you're using FakeWeb to replace _all_ of your requests, it's useful to +catch when requests are made for unregistered URIs (unlike the default +behavior, which is to pass those requests through to Net::HTTP as usual). + + FakeWeb.allow_net_connect = false + Net::HTTP.get(URI.parse("http://example.com/")) + => raises FakeWeb::NetConnectNotAllowedError + + FakeWeb.allow_net_connect = true + Net::HTTP.get(URI.parse("http://example.com/")) + => FakeWeb is bypassed and the response from a real request is returned + +It's recommended that you set <tt>FakeWeb.allow_net_connect = false</tt> in the +setup for your tests. + +==== Allowing requests to a specific server + +If you want to prevent your tests from hitting the internet while allowing +access to a specific server for integration testing, you can assign a URI or ++Regexp+ to be used as a whitelist for outbound requests: + + FakeWeb.allow_net_connect = %r[^https?://localhost] + Net::HTTP.get(URI.parse("http://localhost/path")) # => allowed + Net::HTTP.get(URI.parse("http://example.com/")) # => raises FakeWeb::NetConnectNotAllowedError + +=== Specifying HTTP response headers + +When you register a response using the <tt>:body</tt> option, you're only +setting the body of the response. If you want to add headers to these responses, +simply add the header as an option to +register_uri+: + + FakeWeb.register_uri(:get, "http://example.com/hello.txt", :body => "Hello", :content_type => "text/plain") + +This sets the "Content-Type" header in the response. + +=== Checking the last request + +It's often useful to retrieve the last request made by your code, so you can +write tests for its content. FakeWeb keeps track of the last request, whether it +was stubbed or not: + + Net::HTTP.get(URI.parse("http://example.com")) + FakeWeb.last_request # => Net::HTTP::Get request object + +== More info + +FakeWeb lets you decouple your test environment from live services without +modifying code or writing extensive stubs. + +In addition to the conceptual advantage of having idempotent request +behaviour, FakeWeb makes tests run faster than if they were made to remote (or +even local) web servers. It also makes it possible to run tests without a +network connection or in situations where the server is behind a firewall or +has host-based access controls. + +FakeWeb works with anything based on Net::HTTP--both higher-level wrappers, +like OpenURI, as well as a ton of libraries for popular web services. + + +== Known Issues + +* Request bodies are ignored, including PUT and POST parameters. If you need + different responses for different request bodies, you need to request + different URLs, and register different responses for each. (Query strings are + fully supported, though.) We're currently considering how the API should + change to add support for request bodies in 1.3.0. Your input would be really + helpful: see http://groups.google.com/group/fakeweb-users/browse_thread/thread/44d190a6b12e4273 + for a discussion of some different options. Thanks! diff --git a/vendor/gems/fakeweb-1.3.0/Rakefile b/vendor/gems/fakeweb-1.3.0/Rakefile new file mode 100644 index 000000000..e3c5298c6 --- /dev/null +++ b/vendor/gems/fakeweb-1.3.0/Rakefile @@ -0,0 +1,67 @@ +require 'rubygems' +require 'rake' + +version = '1.3.0' + +begin + require 'jeweler' + Jeweler::Tasks.new do |gem| + gem.name = "fakeweb" + gem.rubyforge_project = "fakeweb" + gem.version = version + gem.summary = "A tool for faking responses to HTTP requests" + gem.description = "FakeWeb is a helper for faking web requests in Ruby. It works at a global level, without modifying code or writing extensive stubs." + gem.email = ["chris@kampers.net", "romeda@gmail.com"] + gem.authors = ["Chris Kampmeier", "Blaine Cook"] + gem.homepage = "http://github.com/chrisk/fakeweb" + gem.add_development_dependency "mocha", ">= 0.9.5" + end +rescue LoadError + puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler" +end + + +require 'rake/testtask' +Rake::TestTask.new(:test) do |test| + test.test_files = FileList["test/**/*.rb"].exclude("test/test_helper.rb", "test/vendor") + test.libs << "test" + test.verbose = false + test.warning = true +end + +task :default => [:check_dependencies, :test] + + +begin + require 'rcov/rcovtask' + Rcov::RcovTask.new do |t| + t.test_files = FileList["test/**/*.rb"].exclude("test/test_helper.rb", "test/vendor") + t.libs << "test" + t.rcov_opts << "--sort coverage" + t.rcov_opts << "--exclude gems" + t.warning = true + end +rescue LoadError + print "rcov support disabled " + if RUBY_PLATFORM =~ /java/ + puts "(running under JRuby)" + else + puts "(install RCov to enable the `rcov` task)" + end +end + + +begin + require 'sdoc' + require 'rdoc/task' + Rake::RDocTask.new do |rdoc| + rdoc.main = "README.rdoc" + rdoc.rdoc_files.include("README.rdoc", "CHANGELOG", "LICENSE.txt", "lib/*.rb") + rdoc.title = "FakeWeb #{version} API Documentation" + rdoc.rdoc_dir = "doc" + rdoc.template = "direct" + rdoc.options << "--line-numbers" << "--show-hash" << "--charset=utf-8" + end +rescue LoadError + puts "SDoc (or a dependency) not available. Install it with: gem install sdoc" +end diff --git a/vendor/gems/fakeweb-1.3.0/fakeweb.gemspec b/vendor/gems/fakeweb-1.3.0/fakeweb.gemspec new file mode 100644 index 000000000..39b23f001 --- /dev/null +++ b/vendor/gems/fakeweb-1.3.0/fakeweb.gemspec @@ -0,0 +1,126 @@ +# Generated by jeweler +# DO NOT EDIT THIS FILE DIRECTLY +# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command +# -*- encoding: utf-8 -*- + +Gem::Specification.new do |s| + s.name = %q{fakeweb} + s.version = "1.3.0" + + s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= + s.authors = ["Chris Kampmeier", "Blaine Cook"] + s.date = %q{2010-08-22} + s.description = %q{FakeWeb is a helper for faking web requests in Ruby. It works at a global level, without modifying code or writing extensive stubs.} + s.email = ["chris@kampers.net", "romeda@gmail.com"] + s.extra_rdoc_files = [ + "LICENSE.txt", + "README.rdoc" + ] + s.files = [ + ".autotest", + ".gitignore", + "CHANGELOG", + "LICENSE.txt", + "README.rdoc", + "Rakefile", + "fakeweb.gemspec", + "lib/fake_web.rb", + "lib/fake_web/ext/net_http.rb", + "lib/fake_web/registry.rb", + "lib/fake_web/responder.rb", + "lib/fake_web/response.rb", + "lib/fake_web/stub_socket.rb", + "lib/fake_web/utility.rb", + "lib/fakeweb.rb", + "test/fixtures/google_response_from_curl", + "test/fixtures/google_response_with_transfer_encoding", + "test/fixtures/google_response_without_transfer_encoding", + "test/fixtures/test_example.txt", + "test/fixtures/test_txt_file", + "test/test_allow_net_connect.rb", + "test/test_deprecations.rb", + "test/test_fake_authentication.rb", + "test/test_fake_web.rb", + "test/test_fake_web_open_uri.rb", + "test/test_helper.rb", + "test/test_last_request.rb", + "test/test_missing_open_uri.rb", + "test/test_missing_pathname.rb", + "test/test_other_net_http_libraries.rb", + "test/test_precedence.rb", + "test/test_query_string.rb", + "test/test_regexes.rb", + "test/test_response_headers.rb", + "test/test_trailing_slashes.rb", + "test/test_utility.rb", + "test/vendor/right_http_connection-1.2.4/History.txt", + "test/vendor/right_http_connection-1.2.4/Manifest.txt", + "test/vendor/right_http_connection-1.2.4/README.txt", + "test/vendor/right_http_connection-1.2.4/Rakefile", + "test/vendor/right_http_connection-1.2.4/lib/net_fix.rb", + "test/vendor/right_http_connection-1.2.4/lib/right_http_connection.rb", + "test/vendor/right_http_connection-1.2.4/setup.rb", + "test/vendor/samuel-0.2.1/.document", + "test/vendor/samuel-0.2.1/.gitignore", + "test/vendor/samuel-0.2.1/LICENSE", + "test/vendor/samuel-0.2.1/README.rdoc", + "test/vendor/samuel-0.2.1/Rakefile", + "test/vendor/samuel-0.2.1/VERSION", + "test/vendor/samuel-0.2.1/lib/samuel.rb", + "test/vendor/samuel-0.2.1/lib/samuel/net_http.rb", + "test/vendor/samuel-0.2.1/lib/samuel/request.rb", + "test/vendor/samuel-0.2.1/samuel.gemspec", + "test/vendor/samuel-0.2.1/test/request_test.rb", + "test/vendor/samuel-0.2.1/test/samuel_test.rb", + "test/vendor/samuel-0.2.1/test/test_helper.rb", + "test/vendor/samuel-0.2.1/test/thread_test.rb" + ] + s.homepage = %q{http://github.com/chrisk/fakeweb} + s.rdoc_options = ["--charset=UTF-8"] + s.require_paths = ["lib"] + s.rubyforge_project = %q{fakeweb} + s.rubygems_version = %q{1.3.7} + s.summary = %q{A tool for faking responses to HTTP requests} + s.test_files = [ + "test/test_allow_net_connect.rb", + "test/test_deprecations.rb", + "test/test_fake_authentication.rb", + "test/test_fake_web.rb", + "test/test_fake_web_open_uri.rb", + "test/test_helper.rb", + "test/test_last_request.rb", + "test/test_missing_open_uri.rb", + "test/test_missing_pathname.rb", + "test/test_other_net_http_libraries.rb", + "test/test_precedence.rb", + "test/test_query_string.rb", + "test/test_regexes.rb", + "test/test_response_headers.rb", + "test/test_trailing_slashes.rb", + "test/test_utility.rb", + "test/vendor/right_http_connection-1.2.4/lib/net_fix.rb", + "test/vendor/right_http_connection-1.2.4/lib/right_http_connection.rb", + "test/vendor/right_http_connection-1.2.4/setup.rb", + "test/vendor/samuel-0.2.1/lib/samuel/net_http.rb", + "test/vendor/samuel-0.2.1/lib/samuel/request.rb", + "test/vendor/samuel-0.2.1/lib/samuel.rb", + "test/vendor/samuel-0.2.1/test/request_test.rb", + "test/vendor/samuel-0.2.1/test/samuel_test.rb", + "test/vendor/samuel-0.2.1/test/test_helper.rb", + "test/vendor/samuel-0.2.1/test/thread_test.rb" + ] + + if s.respond_to? :specification_version then + current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION + s.specification_version = 3 + + if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then + s.add_development_dependency(%q<mocha>, [">= 0.9.5"]) + else + s.add_dependency(%q<mocha>, [">= 0.9.5"]) + end + else + s.add_dependency(%q<mocha>, [">= 0.9.5"]) + end +end + diff --git a/vendor/gems/fakeweb-1.3.0/lib/fake_web.rb b/vendor/gems/fakeweb-1.3.0/lib/fake_web.rb new file mode 100644 index 000000000..77fbdaec4 --- /dev/null +++ b/vendor/gems/fakeweb-1.3.0/lib/fake_web.rb @@ -0,0 +1,215 @@ +require 'singleton' + +require 'fake_web/ext/net_http' +require 'fake_web/registry' +require 'fake_web/response' +require 'fake_web/responder' +require 'fake_web/stub_socket' +require 'fake_web/utility' + +FakeWeb::Utility.record_loaded_net_http_replacement_libs +FakeWeb::Utility.puts_warning_for_net_http_around_advice_libs_if_needed + +module FakeWeb + + # Returns the version string for the copy of FakeWeb you have loaded. + VERSION = '1.3.0' + + # Resets the FakeWeb Registry. This will force all subsequent web requests to + # behave as real requests. + def self.clean_registry + Registry.instance.clean_registry + end + + # Enables or disables real HTTP connections for requests that don't match + # registered URIs. + # + # If you set <tt>FakeWeb.allow_net_connect = false</tt> and subsequently try + # to make a request to a URI you haven't registered with #register_uri, a + # NetConnectNotAllowedError will be raised. This is handy when you want to + # make sure your tests are self-contained, or want to catch the scenario + # when a URI is changed in implementation code without a corresponding test + # change. + # + # When <tt>FakeWeb.allow_net_connect = true</tt> (the default), requests to + # URIs not stubbed with FakeWeb are passed through to Net::HTTP. + # + # If you assign a +String+, +URI+, or +Regexp+ object, unstubbed requests + # will be allowed if they match that value. This is useful when you want to + # allow access to a local server for integration testing, while still + # preventing your tests from using the internet. + def self.allow_net_connect=(allowed) + case allowed + when String, URI, Regexp + @allow_all_connections = false + Registry.instance.register_passthrough_uri(allowed) + else + @allow_all_connections = allowed + Registry.instance.remove_passthrough_uri + end + end + + # Enable pass-through to Net::HTTP by default. + self.allow_net_connect = true + + # Returns +true+ if requests to URIs not registered with FakeWeb are passed + # through to Net::HTTP for normal processing (the default). Returns +false+ + # if an exception is raised for these requests. + # + # If you've assigned a +String+, +URI+, or +Regexp+ to + # <tt>FakeWeb.allow_net_connect=</tt>, you must supply a URI to check + # against that filter. Otherwise, an ArgumentError will be raised. + def self.allow_net_connect?(uri = nil) + if Registry.instance.passthrough_uri_map.any? + raise ArgumentError, "You must supply a URI to test" if uri.nil? + Registry.instance.passthrough_uri_matches?(uri) + else + @allow_all_connections + end + end + + # This exception is raised if you set <tt>FakeWeb.allow_net_connect = + # false</tt> and subsequently try to make a request to a URI you haven't + # stubbed. + class NetConnectNotAllowedError < StandardError; end; + + # This exception is raised if a Net::HTTP request matches more than one of + # the stubs you've registered. To fix the problem, remove a duplicate + # registration or disambiguate any regular expressions by making them more + # specific. + class MultipleMatchingURIsError < StandardError; end; + + # call-seq: + # FakeWeb.register_uri(method, uri, options) + # + # Register requests using the HTTP method specified by the symbol +method+ + # for +uri+ to be handled according to +options+. If you specify the method + # <tt>:any</tt>, the response will be reigstered for any request for +uri+. + # +uri+ can be a +String+, +URI+, or +Regexp+ object. +options+ must be either + # a +Hash+ or an +Array+ of +Hashes+ (see below), which must contain one of + # these two keys: + # + # <tt>:body</tt>:: + # A string which is used as the body of the response. If the string refers + # to a valid filesystem path, the contents of that file will be read and used + # as the body of the response instead. (This used to be two options, + # <tt>:string</tt> and <tt>:file</tt>, respectively. These are now deprecated.) + # <tt>:response</tt>:: + # Either a <tt>Net::HTTPResponse</tt>, an +IO+, or a +String+ which is used + # as the full response for the request. + # + # The easier way by far is to pass the <tt>:response</tt> option to + # +register_uri+ as a +String+ or an (open for reads) +IO+ object which + # will be used as the complete HTTP response, including headers and body. + # If the string points to a readable file, this file will be used as the + # content for the request. + # + # To obtain a complete response document, you can use the +curl+ command, + # like so: + # + # curl -i http://example.com > response_from_example.com + # + # which can then be used in your test environment like so: + # + # FakeWeb.register_uri(:get, "http://example.com", :response => "response_from_example.com") + # + # See the <tt>Net::HTTPResponse</tt> + # documentation[http://ruby-doc.org/stdlib/libdoc/net/http/rdoc/classes/Net/HTTPResponse.html] + # for more information on creating custom response objects. + # + # +options+ may also be an +Array+ containing a list of the above-described + # +Hash+. In this case, FakeWeb will rotate through each response. You can + # optionally repeat a response more than once before rotating: + # + # <tt>:times</tt>:: + # The number of times this response will be used before moving on to the + # next one. The last response will be repeated indefinitely, regardless of + # its <tt>:times</tt> parameter. + # + # Two optional arguments are also accepted: + # + # <tt>:status</tt>:: + # Passing <tt>:status</tt> as a two-value array will set the response code + # and message. The defaults are <tt>200</tt> and <tt>OK</tt>, respectively. + # Example: + # FakeWeb.register_uri(:get, "http://example.com", :body => "Go away!", :status => [404, "Not Found"]) + # <tt>:exception</tt>:: + # The argument passed via <tt>:exception</tt> will be raised when the + # specified URL is requested. Any +Exception+ class is valid. Example: + # FakeWeb.register_uri(:get, "http://example.com", :exception => Net::HTTPError) + # + # If you're using the <tt>:body</tt> response type, you can pass additional + # options to specify the HTTP headers to be used in the response. Example: + # + # FakeWeb.register_uri(:get, "http://example.com/index.txt", :body => "Hello", :content_type => "text/plain") + # + # You can also pass an array of header values to include a header in the + # response more than once: + # + # FakeWeb.register_uri(:get, "http://example.com", :set_cookie => ["name=value", "example=1"]) + def self.register_uri(*args) + case args.length + when 3 + Registry.instance.register_uri(*args) + when 2 + print_missing_http_method_deprecation_warning(*args) + Registry.instance.register_uri(:any, *args) + else + raise ArgumentError.new("wrong number of arguments (#{args.length} for 3)") + end + end + + # call-seq: + # FakeWeb.response_for(method, uri) + # + # Returns the faked Net::HTTPResponse object associated with +method+ and +uri+. + def self.response_for(*args, &block) #:nodoc: :yields: response + case args.length + when 2 + Registry.instance.response_for(*args, &block) + when 1 + print_missing_http_method_deprecation_warning(*args) + Registry.instance.response_for(:any, *args, &block) + else + raise ArgumentError.new("wrong number of arguments (#{args.length} for 2)") + end + end + + # call-seq: + # FakeWeb.registered_uri?(method, uri) + # + # Returns true if a +method+ request for +uri+ is registered with FakeWeb. + # Specify a method of <tt>:any</tt> to check against all HTTP methods. + def self.registered_uri?(*args) + case args.length + when 2 + Registry.instance.registered_uri?(*args) + when 1 + print_missing_http_method_deprecation_warning(*args) + Registry.instance.registered_uri?(:any, *args) + else + raise ArgumentError.new("wrong number of arguments (#{args.length} for 2)") + end + end + + # Returns the request object from the last request made via Net::HTTP. + def self.last_request + @last_request + end + + def self.last_request=(request) #:nodoc: + @last_request = request + end + + private + + def self.print_missing_http_method_deprecation_warning(*args) + method = caller.first.match(/`(.*?)'/)[1] + new_args = args.map { |a| a.inspect }.unshift(":any") + new_args.last.gsub!(/^\{|\}$/, "").gsub!("=>", " => ") if args.last.is_a?(Hash) + $stderr.puts + $stderr.puts "Deprecation warning: FakeWeb requires an HTTP method argument (or use :any). Try this:" + $stderr.puts " FakeWeb.#{method}(#{new_args.join(', ')})" + $stderr.puts "Called at #{caller[1]}" + end +end diff --git a/vendor/gems/fakeweb-1.3.0/lib/fake_web/ext/net_http.rb b/vendor/gems/fakeweb-1.3.0/lib/fake_web/ext/net_http.rb new file mode 100644 index 000000000..4ff3e9a10 --- /dev/null +++ b/vendor/gems/fakeweb-1.3.0/lib/fake_web/ext/net_http.rb @@ -0,0 +1,72 @@ +require 'net/http' +require 'net/https' +require 'stringio' + +module Net #:nodoc: all + + class BufferedIO + def initialize_with_fakeweb(io, debug_output = nil) + @read_timeout = 60 + @rbuf = '' + @debug_output = debug_output + + @io = case io + when Socket, OpenSSL::SSL::SSLSocket, IO + io + when String + if !io.include?("\0") && File.exists?(io) && !File.directory?(io) + File.open(io, "r") + else + StringIO.new(io) + end + end + raise "Unable to create local socket" unless @io + end + alias_method :initialize_without_fakeweb, :initialize + alias_method :initialize, :initialize_with_fakeweb + end + + class HTTP + class << self + def socket_type_with_fakeweb + FakeWeb::StubSocket + end + alias_method :socket_type_without_fakeweb, :socket_type + alias_method :socket_type, :socket_type_with_fakeweb + end + + def request_with_fakeweb(request, body = nil, &block) + FakeWeb.last_request = request + + uri = FakeWeb::Utility.request_uri_as_string(self, request) + method = request.method.downcase.to_sym + + if FakeWeb.registered_uri?(method, uri) + @socket = Net::HTTP.socket_type.new + FakeWeb::Utility.produce_side_effects_of_net_http_request(request, body) + FakeWeb.response_for(method, uri, &block) + elsif FakeWeb.allow_net_connect?(uri) + connect_without_fakeweb + request_without_fakeweb(request, body, &block) + else + uri = FakeWeb::Utility.strip_default_port_from_uri(uri) + raise FakeWeb::NetConnectNotAllowedError, + "Real HTTP connections are disabled. Unregistered request: #{request.method} #{uri}" + end + end + alias_method :request_without_fakeweb, :request + alias_method :request, :request_with_fakeweb + + + def connect_with_fakeweb + unless @@alredy_checked_for_net_http_replacement_libs ||= false + FakeWeb::Utility.puts_warning_for_net_http_replacement_libs_if_needed + @@alredy_checked_for_net_http_replacement_libs = true + end + nil + end + alias_method :connect_without_fakeweb, :connect + alias_method :connect, :connect_with_fakeweb + end + +end diff --git a/vendor/gems/fakeweb-1.3.0/lib/fake_web/registry.rb b/vendor/gems/fakeweb-1.3.0/lib/fake_web/registry.rb new file mode 100644 index 000000000..9a4a34e68 --- /dev/null +++ b/vendor/gems/fakeweb-1.3.0/lib/fake_web/registry.rb @@ -0,0 +1,127 @@ +module FakeWeb + class Registry #:nodoc: + include Singleton + + attr_accessor :uri_map, :passthrough_uri_map + + def initialize + clean_registry + end + + def clean_registry + self.uri_map = Hash.new { |hash, key| hash[key] = {} } + end + + def register_uri(method, uri, options) + uri_map[normalize_uri(uri)][method] = [*[options]].flatten.collect do |option| + FakeWeb::Responder.new(method, uri, option, option[:times]) + end + end + + def registered_uri?(method, uri) + !responders_for(method, uri).empty? + end + + def response_for(method, uri, &block) + responders = responders_for(method, uri) + return nil if responders.empty? + + next_responder = responders.last + responders.each do |responder| + if responder.times and responder.times > 0 + responder.times -= 1 + next_responder = responder + break + end + end + + next_responder.response(&block) + end + + def register_passthrough_uri(uri) + self.passthrough_uri_map = {normalize_uri(uri) => {:any => true}} + end + + def remove_passthrough_uri + self.passthrough_uri_map = {} + end + + def passthrough_uri_matches?(uri) + uri = normalize_uri(uri) + uri_map_matches(passthrough_uri_map, :any, uri, URI) || + uri_map_matches(passthrough_uri_map, :any, uri, Regexp) + end + + private + + def responders_for(method, uri) + uri = normalize_uri(uri) + + uri_map_matches(uri_map, method, uri, URI) || + uri_map_matches(uri_map, :any, uri, URI) || + uri_map_matches(uri_map, method, uri, Regexp) || + uri_map_matches(uri_map, :any, uri, Regexp) || + [] + end + + def uri_map_matches(map, method, uri, type_to_check = URI) + uris_to_check = variations_of_uri_as_strings(uri) + + matches = map.select { |registered_uri, method_hash| + registered_uri.is_a?(type_to_check) && method_hash.has_key?(method) + }.select { |registered_uri, method_hash| + if type_to_check == URI + uris_to_check.include?(registered_uri.to_s) + elsif type_to_check == Regexp + uris_to_check.any? { |u| u.match(registered_uri) } + end + } + + if matches.size > 1 + raise MultipleMatchingURIsError, + "More than one registered URI matched this request: #{method.to_s.upcase} #{uri}" + end + + matches.map { |_, method_hash| method_hash[method] }.first + end + + + def variations_of_uri_as_strings(uri_object) + normalized_uri = normalize_uri(uri_object.dup) + normalized_uri_string = normalized_uri.to_s + + variations = [normalized_uri_string] + + # if the port is implied in the original, add a copy with an explicit port + if normalized_uri.default_port == normalized_uri.port + variations << normalized_uri_string.sub( + /#{Regexp.escape(normalized_uri.request_uri)}$/, + ":#{normalized_uri.port}#{normalized_uri.request_uri}") + end + + variations + end + + def normalize_uri(uri) + return uri if uri.is_a?(Regexp) + normalized_uri = + case uri + when URI then uri + when String + uri = 'http://' + uri unless uri.match('^https?://') + URI.parse(uri) + end + normalized_uri.query = sort_query_params(normalized_uri.query) + normalized_uri.normalize + end + + def sort_query_params(query) + if query.nil? || query.empty? + nil + else + query.split('&').sort.join('&') + end + end + + end +end diff --git a/vendor/gems/fakeweb-1.3.0/lib/fake_web/responder.rb b/vendor/gems/fakeweb-1.3.0/lib/fake_web/responder.rb new file mode 100644 index 000000000..573fec3d4 --- /dev/null +++ b/vendor/gems/fakeweb-1.3.0/lib/fake_web/responder.rb @@ -0,0 +1,122 @@ +module FakeWeb + class Responder #:nodoc: + + attr_accessor :method, :uri, :options, :times + KNOWN_OPTIONS = [:body, :exception, :response, :status].freeze + + def initialize(method, uri, options, times) + self.method = method + self.uri = uri + self.options = options + self.times = times ? times : 1 + + if options.has_key?(:file) || options.has_key?(:string) + print_file_string_options_deprecation_warning + options[:body] = options.delete(:file) || options.delete(:string) + end + end + + def response(&block) + if has_baked_response? + response = baked_response + else + code, msg = meta_information + response = Net::HTTPResponse.send(:response_class, code.to_s).new("1.0", code.to_s, msg) + response.instance_variable_set(:@body, body) + headers_extracted_from_options.each do |name, value| + if value.respond_to?(:each) + value.each { |v| response.add_field(name, v) } + else + response[name] = value + end + end + end + + response.instance_variable_set(:@read, true) + response.extend FakeWeb::Response + + optionally_raise(response) + + yield response if block_given? + + response + end + + private + + def headers_extracted_from_options + options.reject {|name, _| KNOWN_OPTIONS.include?(name) }.map { |name, value| + [name.to_s.split("_").map { |segment| segment.capitalize }.join("-"), value] + } + end + + def body + return '' if options[:body].nil? + + options[:body] = options[:body].to_s if defined?(Pathname) && options[:body].is_a?(Pathname) + + if !options[:body].include?("\0") && File.exists?(options[:body]) && !File.directory?(options[:body]) + File.read(options[:body]) + else + options[:body] + end + end + + def baked_response + return options[:response] if options[:response].is_a?(Net::HTTPResponse) + + if options[:response].is_a?(String) || (defined?(Pathname) && options[:response].is_a?(Pathname)) + socket = Net::BufferedIO.new(options[:response].to_s) + r = Net::HTTPResponse.read_new(socket) + + # Store the original transfer-encoding + saved_transfer_encoding = r.instance_eval { + @header['transfer-encoding'] if @header.key?('transfer-encoding') + } + + # Read the body of response + r.instance_eval { @header['transfer-encoding'] = nil } + r.reading_body(socket, true) {} + + # Delete the transfer-encoding key from r.@header if there wasn't one; + # otherwise, restore the saved_transfer_encoding + if saved_transfer_encoding.nil? + r.instance_eval { @header.delete('transfer-encoding') } + else + r.instance_eval { @header['transfer-encoding'] = saved_transfer_encoding } + end + r + else + raise StandardError, "Handler unimplemented for response #{options[:response]}" + end + end + + def has_baked_response? + options.has_key?(:response) + end + + def optionally_raise(response) + return unless options.has_key?(:exception) + + case options[:exception].to_s + when "Net::HTTPError", "OpenURI::HTTPError" + raise options[:exception].new('Exception from FakeWeb', response) + else + raise options[:exception].new('Exception from FakeWeb') + end + end + + def meta_information + options.has_key?(:status) ? options[:status] : [200, 'OK'] + end + + def print_file_string_options_deprecation_warning + which = options.has_key?(:file) ? :file : :string + $stderr.puts + $stderr.puts "Deprecation warning: FakeWeb's :#{which} option has been renamed to :body." + $stderr.puts "Just replace :#{which} with :body in your FakeWeb.register_uri calls." + $stderr.puts "Called at #{caller[6]}" + end + + end +end
\ No newline at end of file diff --git a/vendor/gems/fakeweb-1.3.0/lib/fake_web/response.rb b/vendor/gems/fakeweb-1.3.0/lib/fake_web/response.rb new file mode 100644 index 000000000..41ba2557b --- /dev/null +++ b/vendor/gems/fakeweb-1.3.0/lib/fake_web/response.rb @@ -0,0 +1,10 @@ +module FakeWeb + module Response #:nodoc: + + def read_body(*args, &block) + yield @body if block_given? + @body + end + + end +end
\ No newline at end of file diff --git a/vendor/gems/fakeweb-1.3.0/lib/fake_web/stub_socket.rb b/vendor/gems/fakeweb-1.3.0/lib/fake_web/stub_socket.rb new file mode 100644 index 000000000..008681ca6 --- /dev/null +++ b/vendor/gems/fakeweb-1.3.0/lib/fake_web/stub_socket.rb @@ -0,0 +1,15 @@ +module FakeWeb + class StubSocket #:nodoc: + + def initialize(*args) + end + + def closed? + @closed ||= true + end + + def readuntil(*args) + end + + end +end
\ No newline at end of file diff --git a/vendor/gems/fakeweb-1.3.0/lib/fake_web/utility.rb b/vendor/gems/fakeweb-1.3.0/lib/fake_web/utility.rb new file mode 100644 index 000000000..bd5d7161c --- /dev/null +++ b/vendor/gems/fakeweb-1.3.0/lib/fake_web/utility.rb @@ -0,0 +1,87 @@ +module FakeWeb + module Utility #:nodoc: + + def self.decode_userinfo_from_header(header) + header.sub(/^Basic /, "").unpack("m").first + end + + def self.encode_unsafe_chars_in_userinfo(userinfo) + unsafe_in_userinfo = /[^#{URI::REGEXP::PATTERN::UNRESERVED};&=+$,]|^(#{URI::REGEXP::PATTERN::ESCAPED})/ + userinfo.split(":").map { |part| uri_escape(part, unsafe_in_userinfo) }.join(":") + end + + def self.strip_default_port_from_uri(uri) + case uri + when %r{^http://} then uri.sub(%r{:80(/|$)}, '\1') + when %r{^https://} then uri.sub(%r{:443(/|$)}, '\1') + else uri + end + end + + # Returns a string with a normalized version of a Net::HTTP request's URI. + def self.request_uri_as_string(net_http, request) + protocol = net_http.use_ssl? ? "https" : "http" + + path = request.path + path = URI.parse(request.path).request_uri if request.path =~ /^http/ + + if request["authorization"] =~ /^Basic / + userinfo = FakeWeb::Utility.decode_userinfo_from_header(request["authorization"]) + userinfo = FakeWeb::Utility.encode_unsafe_chars_in_userinfo(userinfo) + "@" + else + userinfo = "" + end + + uri = "#{protocol}://#{userinfo}#{net_http.address}:#{net_http.port}#{path}" + end + + # Wrapper for URI escaping that switches between URI::Parser#escape and + # URI.escape for 1.9-compatibility + def self.uri_escape(*args) + if URI.const_defined?(:Parser) + URI::Parser.new.escape(*args) + else + URI.escape(*args) + end + end + + def self.produce_side_effects_of_net_http_request(request, body) + request.set_body_internal(body) + request.content_length = request.body.length unless request.body.nil? + end + + def self.puts_warning_for_net_http_around_advice_libs_if_needed + libs = {"Samuel" => defined?(Samuel)} + warnings = libs.select { |_, loaded| loaded }.map do |name, _| + <<-TEXT.gsub(/ {10}/, '') + \e[1mWarning: FakeWeb was loaded after #{name}\e[0m + * #{name}'s code is being ignored when a request is handled by FakeWeb, + because both libraries work by patching Net::HTTP. + * To fix this, just reorder your requires so that FakeWeb is before #{name}. + TEXT + end + $stderr.puts "\n" + warnings.join("\n") + "\n" if warnings.any? + end + + def self.record_loaded_net_http_replacement_libs + libs = {"RightHttpConnection" => defined?(RightHttpConnection)} + @loaded_net_http_replacement_libs = libs.map { |name, loaded| name if loaded }.compact + end + + def self.puts_warning_for_net_http_replacement_libs_if_needed + libs = {"RightHttpConnection" => defined?(RightHttpConnection)} + warnings = libs.select { |_, loaded| loaded }. + reject { |name, _| @loaded_net_http_replacement_libs.include?(name) }. + map do |name, _| + <<-TEXT.gsub(/ {10}/, '') + \e[1mWarning: #{name} was loaded after FakeWeb\e[0m + * FakeWeb's code is being ignored, because #{name} replaces parts of + Net::HTTP without deferring to other libraries. This will break Net::HTTP requests. + * To fix this, just reorder your requires so that #{name} is before FakeWeb. + TEXT + end + $stderr.puts "\n" + warnings.join("\n") + "\n" if warnings.any? + end + + end +end diff --git a/vendor/gems/fakeweb-1.3.0/lib/fakeweb.rb b/vendor/gems/fakeweb-1.3.0/lib/fakeweb.rb new file mode 100644 index 000000000..6982966bf --- /dev/null +++ b/vendor/gems/fakeweb-1.3.0/lib/fakeweb.rb @@ -0,0 +1,2 @@ +# So you can require "fakeweb" instead of "fake_web" +require "fake_web"
\ No newline at end of file diff --git a/vendor/gems/fakeweb-1.3.0/test/fixtures/google_response_from_curl b/vendor/gems/fakeweb-1.3.0/test/fixtures/google_response_from_curl new file mode 100644 index 000000000..fe2fe3945 --- /dev/null +++ b/vendor/gems/fakeweb-1.3.0/test/fixtures/google_response_from_curl @@ -0,0 +1,12 @@ +HTTP/1.1 200 OK
+Cache-Control: private, max-age=0
+Date: Sun, 01 Feb 2009 02:16:24 GMT
+Expires: -1
+Content-Type: text/html; charset=ISO-8859-1
+Set-Cookie: PREF=ID=a6d9b5f5a4056dfe:TM=1233454584:LM=1233454584:S=U9pSwSu4eQwOPenX; expires=Tue, 01-Feb-2011 02:16:24 GMT; path=/; domain=.google.com
+Server: gws
+Transfer-Encoding: chunked
+
+<html><head><meta http-equiv="content-type" content="text/html; charset=ISO-8859-1"><title>Google</title><script>var _gjwl=location;function _gjuc(){var a=_gjwl.hash;if(a.indexOf("&q=")>0||a.indexOf("#q=")>=0){a=a.substring(1);if(a.indexOf("#")==-1){for(var c=0;c<a.length;){var d=c;if(a.charAt(d)=="&")++d;var b=a.indexOf("&",d);if(b==-1)b=a.length;var e=a.substring(d,b);if(e.indexOf("fp=")==0){a=a.substring(0,c)+a.substring(b,a.length);b=c}else if(e=="cad=h")return 0;c=b}_gjwl.href="search?"+a+"&cad=h";return 1}}return 0}; +window._gjuc && location.hash && _gjuc();</script><style>body,td,a,p,.h{font-family:arial,sans-serif}.h{color:#36c;font-size:20px}.q{color:#00c}.ts td{padding:0}.ts{border-collapse:collapse}#gbar{height:22px;padding-left:2px}.gbh,.gbd{border-top:1px solid #c9d7f1;font-size:1px}.gbh{height:0;position:absolute;top:24px;width:100%}#gbi,#gbs{background:#fff;left:0;position:absolute;top:24px;visibility:hidden;z-index:1000}#gbi{border:1px solid;border-color:#c9d7f1 #36c #36c #a2bae7;z-index:1001}#guser{padding-bottom:7px !important}#gbar,#guser{font-size:13px;padding-top:1px !important}@media all{.gb1,.gb3{height:22px;margin-right:.73em;vertical-align:top}#gbar{float:left}}.gb2{display:block;padding:.2em .5em}a.gb1,a.gb2,a.gb3{color:#00c !important}.gb2,.gb3{text-decoration:none}a.gb2:hover{background:#36c;color:#fff !important}</style><script>window.google={kEI:"-AWFSZ6qFYuUswO9j5HIDQ",kEXPI:"17259,19547",kHL:"en"}; +google.y={};google.x=function(e,g){google.y[e.id]=[e,g];return false};window.gbar={};(function(){var b=window.gbar,f,h;b.qs=function(a){var c=window.encodeURIComponent&&(document.forms[0].q||"").value;if(c)a.href=a.href.replace(/([?&])q=[^&]*|$/,function(i,g){return(g||"&")+"q="+encodeURIComponent(c)})};function j(a,c){a.visibility=h?"hidden":"visible";a.left=c+"px"}b.tg=function(a){a=a||window.event;var c=0,i,g=window.navExtra,d=document.getElementById("gbi"),e=a.target||a.srcElement;a.cancelBubble=true;if(!f){f=document.createElement(Array.every||window.createPopup?"iframe":"div");f.frameBorder="0";f.src="#";d.parentNode.appendChild(f).id="gbs";if(g)for(i in g)d.insertBefore(g[i],d.firstChild).className="gb2";document.onclick=b.close}if(e.className!="gb3")e=e.parentNode;do c+=e.offsetLeft;while(e=e.offsetParent);j(d.style,c);f.style.width=d.offsetWidth+"px";f.style.height=d.offsetHeight+"px";j(f.style,c);h=!h};b.close=function(a){h&&b.tg(a)}})();</script></head><body bgcolor=#ffffff text=#000000 link=#0000cc vlink=#551a8b alink=#ff0000 onload="document.f.q.focus();if(document.images)new Image().src='/images/nav_logo3.png'" topmargin=3 marginheight=3><div id=gbar><nobr><b class=gb1>Web</b> <a href="http://images.google.com/imghp?hl=en&tab=wi" onclick=gbar.qs(this) class=gb1>Images</a> <a href="http://maps.google.com/maps?hl=en&tab=wl" onclick=gbar.qs(this) class=gb1>Maps</a> <a href="http://news.google.com/nwshp?hl=en&tab=wn" onclick=gbar.qs(this) class=gb1>News</a> <a href="http://www.google.com/prdhp?hl=en&tab=wf" onclick=gbar.qs(this) class=gb1>Shopping</a> <a href="http://mail.google.com/mail/?hl=en&tab=wm" class=gb1>Gmail</a> <a href="http://www.google.com/intl/en/options/" onclick="this.blur();gbar.tg(event);return !1" class=gb3><u>more</u> <small>▼</small></a><div id=gbi> <a href="http://video.google.com/?hl=en&tab=wv" onclick=gbar.qs(this) class=gb2>Video</a> <a href="http://groups.google.com/grphp?hl=en&tab=wg" onclick=gbar.qs(this) class=gb2>Groups</a> <a href="http://books.google.com/bkshp?hl=en&tab=wp" onclick=gbar.qs(this) class=gb2>Books</a> <a href="http://scholar.google.com/schhp?hl=en&tab=ws" onclick=gbar.qs(this) class=gb2>Scholar</a> <a href="http://finance.google.com/finance?hl=en&tab=we" onclick=gbar.qs(this) class=gb2>Finance</a> <a href="http://blogsearch.google.com/?hl=en&tab=wb" onclick=gbar.qs(this) class=gb2>Blogs</a> <div class=gb2><div class=gbd></div></div> <a href="http://www.youtube.com/?hl=en&tab=w1" onclick=gbar.qs(this) class=gb2>YouTube</a> <a href="http://www.google.com/calendar/render?hl=en&tab=wc" class=gb2>Calendar</a> <a href="http://picasaweb.google.com/home?hl=en&tab=wq" onclick=gbar.qs(this) class=gb2>Photos</a> <a href="http://docs.google.com/?hl=en&tab=wo" class=gb2>Documents</a> <a href="http://www.google.com/reader/view/?hl=en&tab=wy" class=gb2>Reader</a> <a href="http://sites.google.com/?hl=en&tab=w3" class=gb2>Sites</a> <div class=gb2><div class=gbd></div></div> <a href="http://www.google.com/intl/en/options/" class=gb2>even more »</a></div> </nobr></div><div class=gbh style=left:0></div><div class=gbh style=right:0></div><div align=right id=guser style="font-size:84%;padding:0 0 4px" width=100%><nobr><a href="/url?sa=p&pref=ig&pval=3&q=http://www.google.com/ig%3Fhl%3Den%26source%3Diglk&usg=AFQjCNFA18XPfgb7dKnXfKz7x7g1GDH1tg">iGoogle</a> | <a href="https://www.google.com/accounts/Login?continue=http://www.google.com/&hl=en">Sign in</a></nobr></div><center><br clear=all id=lgpd><img alt="Google" height=110 src="/intl/en_ALL/images/logo.gif" width=276><br><br><form action="/search" name=f><table cellpadding=0 cellspacing=0><tr valign=top><td width=25%> </td><td align=center nowrap><input name=hl type=hidden value=en><input type=hidden name=ie value="ISO-8859-1"><input autocomplete="off" maxlength=2048 name=q size=55 title="Google Search" value=""><br><input name=btnG type=submit value="Google Search"><input name=btnI type=submit value="I'm Feeling Lucky"></td><td nowrap width=25%><font size=-2> <a href=/advanced_search?hl=en>Advanced Search</a><br> <a href=/preferences?hl=en>Preferences</a><br> <a href=/language_tools?hl=en>Language Tools</a></font></td></tr></table></form><br><font size=-1>Share what you know. <a href="/aclk?sa=L&ai=CYhslHwSFSZH6LIHusAPEsc2eBfv77nqP3YC9CsHZnNkTEAEgwVRQypDftPn_____AWDJBqoECU_QbUVlfOdxZw&num=1&sig=AGiWqtwRgqw8y_kza6RGKxBrCstaXkDJ7A&q=http://knol.google.com">Write a Knol</a>.</font><br><br><br><font size=-1><a href="/intl/en/ads/">Advertising Programs</a> - <a href="/services/">Business Solutions</a> - <a href="/intl/en/about.html">About Google</a></font><p><font size=-2>©2009 - <a href="/intl/en/privacy.html">Privacy</a></font></p></center></body><script>if(google.y)google.y.first=[];window.setTimeout(function(){var xjs=document.createElement('script');xjs.src='/extern_js/f/CgJlbhICdXMgACswCjgVLCswDjgELCswGDgDLA/L3N5xu59nDE.js';document.getElementsByTagName('head')[0].appendChild(xjs)},0);google.y.first.push(function(){google.ac.i(document.f,document.f.q,'','')})</script><script>function _gjp() {!(location.hash && _gjuc()) && setTimeout(_gjp, 500);}window._gjuc && _gjp();</script></html>
\ No newline at end of file diff --git a/vendor/gems/fakeweb-1.3.0/test/fixtures/google_response_with_transfer_encoding b/vendor/gems/fakeweb-1.3.0/test/fixtures/google_response_with_transfer_encoding new file mode 100644 index 000000000..82025d36e --- /dev/null +++ b/vendor/gems/fakeweb-1.3.0/test/fixtures/google_response_with_transfer_encoding @@ -0,0 +1,17 @@ +HTTP/1.1 200 OK +Cache-Control: private, max-age=0 +Date: Sun, 01 Feb 2009 01:54:36 GMT +Expires: -1 +Content-Type: text/html; charset=ISO-8859-1 +Set-Cookie: PREF=ID=4320bcaa30d097de:TM=1233453276:LM=1233453276:S=Eio39bg_nIabTxzL; expires=Tue, 01-Feb-2011 01:54:36 GMT; path=/; domain=.google.com +Server: gws +Transfer-Encoding: chunked + +fef +<html><head><meta http-equiv="content-type" content="text/html; charset=ISO-8859-1"><title>Google</title><script>var _gjwl=location;function _gjuc(){var a=_gjwl.hash;if(a.indexOf("&q=")>0||a.indexOf("#q=")>=0){a=a.substring(1);if(a.indexOf("#")==-1){for(var c=0;c<a.length;){var d=c;if(a.charAt(d)=="&")++d;var b=a.indexOf("&",d);if(b==-1)b=a.length;var e=a.substring(d,b);if(e.indexOf("fp=")==0){a=a.substring(0,c)+a.substring(b,a.length);b=c}else if(e=="cad=h")return 0;c=b}_gjwl.href="search?"+a+"&cad=h";return 1}}return 0}; +window._gjuc && location.hash && _gjuc();</script><style>body,td,a,p,.h{font-family:arial,sans-serif}.h{color:#36c;font-size:20px}.q{color:#00c}.ts td{padding:0}.ts{border-collapse:collapse}#gbar{height:22px;padding-left:2px}.gbh,.gbd{border-top:1px solid #c9d7f1;font-size:1px}.gbh{height:0;position:absolute;top:24px;width:100%}#gbi,#gbs{background:#fff;left:0;position:absolute;top:24px;visibility:hidden;z-index:1000}#gbi{border:1px solid;border-color:#c9d7f1 #36c #36c #a2bae7;z-index:1001}#guser{padding-bottom:7px !important}#gbar,#guser{font-size:13px;padding-top:1px !important}@media all{.gb1,.gb3{height:22px;margin-right:.73em;vertical-align:top}#gbar{float:left}}.gb2{display:block;padding:.2em .5em}a.gb1,a.gb2,a.gb3{color:#00c !important}.gb2,.gb3{text-decoration:none}a.gb2:hover{background:#36c;color:#fff !important}</style><script>window.google={kEI:"3ACFSYC6EKTcswOL4_nBDQ",kEXPI:"17259,19463",kHL:"en"}; +google.y={};google.x=function(e,g){google.y[e.id]=[e,g];return false};window.gbar={};(function(){var b=window.gbar,f,h;b.qs=function(a){var c=window.encodeURIComponent&&(document.forms[0].q||"").value;if(c)a.href=a.href.replace(/([?&])q=[^&]*|$/,function(i,g){return(g||"&")+"q="+encodeURIComponent(c)})};function j(a,c){a.visibility=h?"hidden":"visible";a.left=c+"px"}b.tg=function(a){a=a||window.event;var c=0,i,g=window.navExtra,d=document.getElementById("gbi"),e=a.target||a.srcElement;a.cancelBubble=true;if(!f){f=document.createElement(Array.every||window.createPopup?"iframe":"div");f.frameBorder="0";f.src="#";d.parentNode.appendChild(f).id="gbs";if(g)for(i in g)d.insertBefore(g[i],d.firstChild).className="gb2";document.onclick=b.close}if(e.className!="gb3")e=e.parentNode;do c+=e.offsetLeft;while(e=e.offsetParent);j(d.style,c);f.style.width=d.offsetWidth+"px";f.style.height=d.offsetHeight+"px";j(f.style,c);h=!h};b.close=function(a){h&&b.tg(a)}})();</script></head><body bgcolor=#ffffff text=#000000 link=#0000cc vlink=#551a8b alink=#ff0000 onload="document.f.q.focus();if(document.images)new Image().src='/images/nav_logo3.png'" topmargin=3 marginheight=3><div id=gbar><nobr><b class=gb1>Web</b> <a href="http://images.google.com/imghp?hl=en&tab=wi" onclick=gbar.qs(this) class=gb1>Images</a> <a href="http://maps.google.com/maps?hl=en&tab=wl" onclick=gbar.qs(this) class=gb1>Maps</a> <a href="http://news.google.com/nwshp?hl=en&tab=wn" onclick=gbar.qs(this) class=gb1>News</a> <a href="http://www.google.com/prdhp?hl=en&tab=wf" onclick=gbar.qs(this) class=gb1>Shopping</a> <a href="http://mail.google.com/mail/?hl=en&tab=wm" class=gb1>Gmail</a> <a href="http://www.google.com/intl/en/options/" onclick="this.blur();gbar.tg(event);return !1" class=gb3><u>more</u> <small>▼</small></a><div id=gbi> <a href="http://video.google.com/?hl=en&tab=wv" onclick=gbar.qs(this) class=gb2>Video</a> <a href="http://groups.google.com/grphp?hl=en&tab=wg" onclick=gbar.qs(this) class=gb2>Groups</a> <a href="http://books.google.com/bkshp?hl=en&tab=wp" onclick=gbar.qs(this) class=gb2>Books</a> <a href="http://scholar.google.com/schhp?hl=en&tab=ws" onclick=gbar.qs(this) class=gb2>Scholar</a> <a href="http://finance.google.com/finance?hl=en&tab=we" onclick=gbar.qs(this) class=gb2>Finance</a> <a href="http://blogsearch.google.com/?hl=en&tab=wb" onclick=gbar.qs(this) class=gb2>Blogs</a> <div class=gb2><div class=gbd></div></div> <a href="http://www.youtube.com/?hl=en&tab=w1" onclick=gbar.qs(this) class=gb2>YouTube</a> <a href="http://www.google.com/calendar/render?hl=en&tab=wc" class=gb2>Calendar</a> <a href="http +a27 +://picasaweb.google.com/home?hl=en&tab=wq" onclick=gbar.qs(this) class=gb2>Photos</a> <a href="http://docs.google.com/?hl=en&tab=wo" class=gb2>Documents</a> <a href="http://www.google.com/reader/view/?hl=en&tab=wy" class=gb2>Reader</a> <a href="http://sites.google.com/?hl=en&tab=w3" class=gb2>Sites</a> <div class=gb2><div class=gbd></div></div> <a href="http://www.google.com/intl/en/options/" class=gb2>even more »</a></div> </nobr></div><div class=gbh style=left:0></div><div class=gbh style=right:0></div><div align=right id=guser style="font-size:84%;padding:0 0 4px" width=100%><nobr><a href="/url?sa=p&pref=ig&pval=3&q=http://www.google.com/ig%3Fhl%3Den%26source%3Diglk&usg=AFQjCNFA18XPfgb7dKnXfKz7x7g1GDH1tg">iGoogle</a> | <a href="https://www.google.com/accounts/Login?continue=http://www.google.com/&hl=en">Sign in</a></nobr></div><center><br clear=all id=lgpd><img alt="Google" height=110 src="/intl/en_ALL/images/logo.gif" width=276><br><br><form action="/search" name=f><table cellpadding=0 cellspacing=0><tr valign=top><td width=25%> </td><td align=center nowrap><input name=hl type=hidden value=en><input type=hidden name=ie value="ISO-8859-1"><input autocomplete="off" maxlength=2048 name=q size=55 title="Google Search" value=""><br><input name=btnG type=submit value="Google Search"><input name=btnI type=submit value="I'm Feeling Lucky"></td><td nowrap width=25%><font size=-2> <a href=/advanced_search?hl=en>Advanced Search</a><br> <a href=/preferences?hl=en>Preferences</a><br> <a href=/language_tools?hl=en>Language Tools</a></font></td></tr></table></form><br><font size=-1>Share what you know. <a href="/aclk?sa=L&ai=CFL7HzwCFSZCnCJSwsQPm842HB_v77nqP3YC9CsHZnNkTEAEgwVRQypDftPn_____AWDJBqoECU_Q1sTewQNSbw&num=1&sig=AGiWqtyz-UiOD3EpsSp4k3n8A7zooeg48g&q=http://knol.google.com">Write a Knol</a>.</font><br><br><br><font size=-1><a href="/intl/en/ads/">Advertising Programs</a> - <a href="/services/">Business Solutions</a> - <a href="/intl/en/about.html">About Google</a></font><p><font size=-2>©2009 - <a href="/intl/en/privacy.html">Privacy</a></font></p></center></body><script>if(google.y)google.y.first=[];window.setTimeout(function(){var xjs=document.createElement('script');xjs.src='/extern_js/f/CgJlbhICdXMgACswCjgVLCswDjgELCswGDgDLA/L3N5xu59nDE.js';document.getElementsByTagName('head')[0].appendChild(xjs)},0);google.y.first.push(function(){google.ac.i(document.f,document.f.q,'','')})</script><script>function _gjp() {!(location.hash && _gjuc()) && setTimeout(_gjp, 500);}window._gjuc && _gjp();</script></html> +0 + diff --git a/vendor/gems/fakeweb-1.3.0/test/fixtures/google_response_without_transfer_encoding b/vendor/gems/fakeweb-1.3.0/test/fixtures/google_response_without_transfer_encoding new file mode 100644 index 000000000..51433c990 --- /dev/null +++ b/vendor/gems/fakeweb-1.3.0/test/fixtures/google_response_without_transfer_encoding @@ -0,0 +1,11 @@ +HTTP/1.0 200 OK +Cache-Control: private, max-age=0 +Date: Sun, 01 Feb 2009 01:55:33 GMT +Expires: -1 +Content-Type: text/html; charset=ISO-8859-1 +Set-Cookie: PREF=ID=3c140c3eb4c4f516:TM=1233453333:LM=1233453333:S=OH7sElk2hOWkb9ot; expires=Tue, 01-Feb-2011 01:55:33 GMT; path=/; domain=.google.com +Server: gws + +<html><head><meta http-equiv="content-type" content="text/html; charset=ISO-8859-1"><title>Google</title><script>var _gjwl=location;function _gjuc(){var a=_gjwl.hash;if(a.indexOf("&q=")>0||a.indexOf("#q=")>=0){a=a.substring(1);if(a.indexOf("#")==-1){for(var c=0;c<a.length;){var d=c;if(a.charAt(d)=="&")++d;var b=a.indexOf("&",d);if(b==-1)b=a.length;var e=a.substring(d,b);if(e.indexOf("fp=")==0){a=a.substring(0,c)+a.substring(b,a.length);b=c}else if(e=="cad=h")return 0;c=b}_gjwl.href="search?"+a+"&cad=h";return 1}}return 0}; +window._gjuc && location.hash && _gjuc();</script><style>body,td,a,p,.h{font-family:arial,sans-serif}.h{color:#36c;font-size:20px}.q{color:#00c}.ts td{padding:0}.ts{border-collapse:collapse}#gbar{height:22px;padding-left:2px}.gbh,.gbd{border-top:1px solid #c9d7f1;font-size:1px}.gbh{height:0;position:absolute;top:24px;width:100%}#gbi,#gbs{background:#fff;left:0;position:absolute;top:24px;visibility:hidden;z-index:1000}#gbi{border:1px solid;border-color:#c9d7f1 #36c #36c #a2bae7;z-index:1001}#guser{padding-bottom:7px !important}#gbar,#guser{font-size:13px;padding-top:1px !important}@media all{.gb1,.gb3{height:22px;margin-right:.73em;vertical-align:top}#gbar{float:left}}.gb2{display:block;padding:.2em .5em}a.gb1,a.gb2,a.gb3{color:#00c !important}.gb2,.gb3{text-decoration:none}a.gb2:hover{background:#36c;color:#fff !important}</style><script>window.google={kEI:"FQGFSY2rG5eSswOKpsHeDQ",kEXPI:"17259",kHL:"en"}; +google.y={};google.x=function(e,g){google.y[e.id]=[e,g];return false};window.gbar={};(function(){var b=window.gbar,f,h;b.qs=function(a){var c=window.encodeURIComponent&&(document.forms[0].q||"").value;if(c)a.href=a.href.replace(/([?&])q=[^&]*|$/,function(i,g){return(g||"&")+"q="+encodeURIComponent(c)})};function j(a,c){a.visibility=h?"hidden":"visible";a.left=c+"px"}b.tg=function(a){a=a||window.event;var c=0,i,g=window.navExtra,d=document.getElementById("gbi"),e=a.target||a.srcElement;a.cancelBubble=true;if(!f){f=document.createElement(Array.every||window.createPopup?"iframe":"div");f.frameBorder="0";f.src="#";d.parentNode.appendChild(f).id="gbs";if(g)for(i in g)d.insertBefore(g[i],d.firstChild).className="gb2";document.onclick=b.close}if(e.className!="gb3")e=e.parentNode;do c+=e.offsetLeft;while(e=e.offsetParent);j(d.style,c);f.style.width=d.offsetWidth+"px";f.style.height=d.offsetHeight+"px";j(f.style,c);h=!h};b.close=function(a){h&&b.tg(a)}})();</script></head><body bgcolor=#ffffff text=#000000 link=#0000cc vlink=#551a8b alink=#ff0000 onload="document.f.q.focus();if(document.images)new Image().src='/images/nav_logo3.png'" topmargin=3 marginheight=3><div id=gbar><nobr><b class=gb1>Web</b> <a href="http://images.google.com/imghp?hl=en&tab=wi" onclick=gbar.qs(this) class=gb1>Images</a> <a href="http://maps.google.com/maps?hl=en&tab=wl" onclick=gbar.qs(this) class=gb1>Maps</a> <a href="http://news.google.com/nwshp?hl=en&tab=wn" onclick=gbar.qs(this) class=gb1>News</a> <a href="http://www.google.com/prdhp?hl=en&tab=wf" onclick=gbar.qs(this) class=gb1>Shopping</a> <a href="http://mail.google.com/mail/?hl=en&tab=wm" class=gb1>Gmail</a> <a href="http://www.google.com/intl/en/options/" onclick="this.blur();gbar.tg(event);return !1" class=gb3><u>more</u> <small>▼</small></a><div id=gbi> <a href="http://video.google.com/?hl=en&tab=wv" onclick=gbar.qs(this) class=gb2>Video</a> <a href="http://groups.google.com/grphp?hl=en&tab=wg" onclick=gbar.qs(this) class=gb2>Groups</a> <a href="http://books.google.com/bkshp?hl=en&tab=wp" onclick=gbar.qs(this) class=gb2>Books</a> <a href="http://scholar.google.com/schhp?hl=en&tab=ws" onclick=gbar.qs(this) class=gb2>Scholar</a> <a href="http://finance.google.com/finance?hl=en&tab=we" onclick=gbar.qs(this) class=gb2>Finance</a> <a href="http://blogsearch.google.com/?hl=en&tab=wb" onclick=gbar.qs(this) class=gb2>Blogs</a> <div class=gb2><div class=gbd></div></div> <a href="http://www.youtube.com/?hl=en&tab=w1" onclick=gbar.qs(this) class=gb2>YouTube</a> <a href="http://www.google.com/calendar/render?hl=en&tab=wc" class=gb2>Calendar</a> <a href="http://picasaweb.google.com/home?hl=en&tab=wq" onclick=gbar.qs(this) class=gb2>Photos</a> <a href="http://docs.google.com/?hl=en&tab=wo" class=gb2>Documents</a> <a href="http://www.google.com/reader/view/?hl=en&tab=wy" class=gb2>Reader</a> <a href="http://sites.google.com/?hl=en&tab=w3" class=gb2>Sites</a> <div class=gb2><div class=gbd></div></div> <a href="http://www.google.com/intl/en/options/" class=gb2>even more »</a></div> </nobr></div><div class=gbh style=left:0></div><div class=gbh style=right:0></div><div align=right id=guser style="font-size:84%;padding:0 0 4px" width=100%><nobr><a href="/url?sa=p&pref=ig&pval=3&q=http://www.google.com/ig%3Fhl%3Den%26source%3Diglk&usg=AFQjCNFA18XPfgb7dKnXfKz7x7g1GDH1tg">iGoogle</a> | <a href="https://www.google.com/accounts/Login?continue=http://www.google.com/&hl=en">Sign in</a></nobr></div><center><br clear=all id=lgpd><img alt="Google" height=110 src="/intl/en_ALL/images/logo.gif" width=276><br><br><form action="/search" name=f><table cellpadding=0 cellspacing=0><tr valign=top><td width=25%> </td><td align=center nowrap><input name=hl type=hidden value=en><input type=hidden name=ie value="ISO-8859-1"><input autocomplete="off" maxlength=2048 name=q size=55 title="Google Search" value=""><br><input name=btnG type=submit value="Google Search"><input name=btnI type=submit value="I'm Feeling Lucky"></td><td nowrap width=25%><font size=-2> <a href=/advanced_search?hl=en>Advanced Search</a><br> <a href=/preferences?hl=en>Preferences</a><br> <a href=/language_tools?hl=en>Language Tools</a></font></td></tr></table></form><br><font size=-1>Share what you know. <a href="/aclk?sa=L&ai=ClyBp_v-EScTWD4W2tQOxoqSkB_v77nqP3YC9CsHZnNkTEAEgwVRQypDftPn_____AWDJBqoECU_QphTjHaZ5QA&num=1&sig=AGiWqtwtBqZ-zra3DJd_1chQKhKGf7lMVg&q=http://knol.google.com">Write a Knol</a>.</font><br><br><br><font size=-1><a href="/intl/en/ads/">Advertising Programs</a> - <a href="/services/">Business Solutions</a> - <a href="/intl/en/about.html">About Google</a></font><p><font size=-2>©2009 - <a href="/intl/en/privacy.html">Privacy</a></font></p></center></body><script>if(google.y)google.y.first=[];window.setTimeout(function(){var xjs=document.createElement('script');xjs.src='/extern_js/f/CgJlbhICdXMgACswCjgNLCswDjgELCswGDgDLA/oTKXc0xdkmY.js';document.getElementsByTagName('head')[0].appendChild(xjs)},0);google.y.first.push(function(){google.ac.i(document.f,document.f.q,'','')})</script><script>function _gjp() {!(location.hash && _gjuc()) && setTimeout(_gjp, 500);}window._gjuc && _gjp();</script></html>
\ No newline at end of file diff --git a/vendor/gems/fakeweb-1.3.0/test/fixtures/test_example.txt b/vendor/gems/fakeweb-1.3.0/test/fixtures/test_example.txt new file mode 100644 index 000000000..6310da9df --- /dev/null +++ b/vendor/gems/fakeweb-1.3.0/test/fixtures/test_example.txt @@ -0,0 +1 @@ +test example content
\ No newline at end of file diff --git a/vendor/gems/fakeweb-1.3.0/test/fixtures/test_txt_file b/vendor/gems/fakeweb-1.3.0/test/fixtures/test_txt_file new file mode 100644 index 000000000..8cf2f17fe --- /dev/null +++ b/vendor/gems/fakeweb-1.3.0/test/fixtures/test_txt_file @@ -0,0 +1,3 @@ +line 1 +line 2 +line 3
\ No newline at end of file diff --git a/vendor/gems/fakeweb-1.3.0/test/test_allow_net_connect.rb b/vendor/gems/fakeweb-1.3.0/test/test_allow_net_connect.rb new file mode 100644 index 000000000..25f4d3d64 --- /dev/null +++ b/vendor/gems/fakeweb-1.3.0/test/test_allow_net_connect.rb @@ -0,0 +1,168 @@ +require 'test_helper' + +class TestFakeWebAllowNetConnect < Test::Unit::TestCase + def test_unregistered_requests_are_passed_through_when_allow_net_connect_is_true + FakeWeb.allow_net_connect = true + setup_expectations_for_real_apple_hot_news_request + Net::HTTP.get(URI.parse("http://images.apple.com/main/rss/hotnews/hotnews.rss")) + end + + def test_raises_for_unregistered_requests_when_allow_net_connect_is_false + FakeWeb.allow_net_connect = false + assert_raise FakeWeb::NetConnectNotAllowedError do + Net::HTTP.get(URI.parse("http://example.com/")) + end + end + + def test_unregistered_requests_are_passed_through_when_allow_net_connect_is_the_same_string + FakeWeb.allow_net_connect = "http://images.apple.com/main/rss/hotnews/hotnews.rss" + setup_expectations_for_real_apple_hot_news_request + Net::HTTP.get(URI.parse("http://images.apple.com/main/rss/hotnews/hotnews.rss")) + end + + def test_unregistered_requests_are_passed_through_when_allow_net_connect_is_the_same_string_with_default_port + FakeWeb.allow_net_connect = "http://images.apple.com:80/main/rss/hotnews/hotnews.rss" + setup_expectations_for_real_apple_hot_news_request + Net::HTTP.get(URI.parse("http://images.apple.com/main/rss/hotnews/hotnews.rss")) + end + + def test_unregistered_requests_are_passed_through_when_allow_net_connect_is_the_same_uri + FakeWeb.allow_net_connect = URI.parse("http://images.apple.com/main/rss/hotnews/hotnews.rss") + setup_expectations_for_real_apple_hot_news_request + Net::HTTP.get(URI.parse("http://images.apple.com/main/rss/hotnews/hotnews.rss")) + end + + def test_unregistered_requests_are_passed_through_when_allow_net_connect_is_a_matching_regexp + FakeWeb.allow_net_connect = %r[^http://images\.apple\.com] + setup_expectations_for_real_apple_hot_news_request + Net::HTTP.get(URI.parse("http://images.apple.com/main/rss/hotnews/hotnews.rss")) + end + + def test_raises_for_unregistered_requests_when_allow_net_connect_is_a_different_string + FakeWeb.allow_net_connect = "http://example.com" + assert_raise FakeWeb::NetConnectNotAllowedError do + Net::HTTP.get(URI.parse("http://example.com/path")) + end + end + + def test_raises_for_unregistered_requests_when_allow_net_connect_is_a_different_uri + FakeWeb.allow_net_connect = URI.parse("http://example.com") + assert_raise FakeWeb::NetConnectNotAllowedError do + Net::HTTP.get(URI.parse("http://example.com/path")) + end + end + + def test_raises_for_unregistered_requests_when_allow_net_connect_is_a_non_matching_regexp + FakeWeb.allow_net_connect = %r[example\.net] + assert_raise FakeWeb::NetConnectNotAllowedError do + Net::HTTP.get(URI.parse("http://example.com")) + end + end + + def test_changing_allow_net_connect_from_string_to_false_corretly_removes_whitelist + FakeWeb.allow_net_connect = "http://example.com" + FakeWeb.allow_net_connect = false + assert_raise FakeWeb::NetConnectNotAllowedError do + Net::HTTP.get(URI.parse("http://example.com")) + end + end + + def test_changing_allow_net_connect_from_true_to_string_corretly_limits_connections + FakeWeb.allow_net_connect = true + FakeWeb.allow_net_connect = "http://example.com" + assert_raise FakeWeb::NetConnectNotAllowedError do + Net::HTTP.get(URI.parse("http://example.net")) + end + end + + def test_exception_message_includes_unregistered_request_method_and_uri_but_no_default_port + FakeWeb.allow_net_connect = false + exception = assert_raise FakeWeb::NetConnectNotAllowedError do + Net::HTTP.get(URI.parse("http://example.com/")) + end + assert exception.message.include?("GET http://example.com/") + + exception = assert_raise FakeWeb::NetConnectNotAllowedError do + http = Net::HTTP.new("example.com", 443) + http.use_ssl = true + http.get("/") + end + assert exception.message.include?("GET https://example.com/") + end + + def test_exception_message_includes_unregistered_request_port_when_not_default + FakeWeb.allow_net_connect = false + exception = assert_raise FakeWeb::NetConnectNotAllowedError do + Net::HTTP.start("example.com", 8000) { |http| http.get("/") } + end + assert exception.message.include?("GET http://example.com:8000/") + + exception = assert_raise FakeWeb::NetConnectNotAllowedError do + http = Net::HTTP.new("example.com", 4433) + http.use_ssl = true + http.get("/") + end + assert exception.message.include?("GET https://example.com:4433/") + end + + def test_exception_message_includes_unregistered_request_port_when_not_default_with_path + FakeWeb.allow_net_connect = false + exception = assert_raise FakeWeb::NetConnectNotAllowedError do + Net::HTTP.start("example.com", 8000) { |http| http.get("/test") } + end + assert exception.message.include?("GET http://example.com:8000/test") + + exception = assert_raise FakeWeb::NetConnectNotAllowedError do + http = Net::HTTP.new("example.com", 4433) + http.use_ssl = true + http.get("/test") + end + assert exception.message.include?("GET https://example.com:4433/test") + end + + def test_question_mark_method_returns_true_after_setting_allow_net_connect_to_true + FakeWeb.allow_net_connect = true + assert FakeWeb.allow_net_connect? + end + + def test_question_mark_method_returns_false_after_setting_allow_net_connect_to_false + FakeWeb.allow_net_connect = false + assert !FakeWeb.allow_net_connect? + end + + def test_question_mark_method_raises_with_no_argument_when_allow_net_connect_is_a_whitelist + FakeWeb.allow_net_connect = "http://example.com" + exception = assert_raise ArgumentError do + FakeWeb.allow_net_connect? + end + assert_equal "You must supply a URI to test", exception.message + end + + def test_question_mark_method_returns_true_when_argument_is_same_uri_as_allow_net_connect_string + FakeWeb.allow_net_connect = "http://example.com" + assert FakeWeb.allow_net_connect?("http://example.com/") + end + + def test_question_mark_method_returns_true_when_argument_matches_allow_net_connect_regexp + FakeWeb.allow_net_connect = %r[^https?://example.com/] + assert FakeWeb.allow_net_connect?("http://example.com/path") + assert FakeWeb.allow_net_connect?("https://example.com:443/") + end + + def test_question_mark_method_returns_false_when_argument_does_not_match_allow_net_connect_regexp + FakeWeb.allow_net_connect = %r[^http://example.com/] + assert !FakeWeb.allow_net_connect?("http://example.com:8080") + end +end + + +class TestFakeWebAllowNetConnectWithCleanState < Test::Unit::TestCase + # Our test_helper.rb sets allow_net_connect = false in an inherited #setup + # method. Disable that here to test the default setting. + def setup; end + def teardown; end + + def test_allow_net_connect_is_true_by_default + assert FakeWeb.allow_net_connect? + end +end diff --git a/vendor/gems/fakeweb-1.3.0/test/test_deprecations.rb b/vendor/gems/fakeweb-1.3.0/test/test_deprecations.rb new file mode 100644 index 000000000..e5b8953c5 --- /dev/null +++ b/vendor/gems/fakeweb-1.3.0/test/test_deprecations.rb @@ -0,0 +1,54 @@ +require 'test_helper' + +class TestDeprecations < Test::Unit::TestCase + + def test_register_uri_without_method_argument_prints_deprecation_warning + warning = capture_stderr do + FakeWeb.register_uri("http://example.com", :body => "test") + end + assert_match %r(deprecation warning: fakeweb)i, warning + end + + def test_registered_uri_without_method_argument_prints_deprecation_warning + warning = capture_stderr do + FakeWeb.registered_uri?("http://example.com") + end + assert_match %r(deprecation warning: fakeweb)i, warning + end + + def test_response_for_without_method_argument_prints_deprecation_warning + warning = capture_stderr do + FakeWeb.response_for("http://example.com") + end + assert_match %r(deprecation warning: fakeweb)i, warning + end + + def test_register_uri_without_method_argument_prints_deprecation_warning_with_correct_caller + warning = capture_stderr do + FakeWeb.register_uri("http://example.com", :body => "test") + end + assert_match %r(Called at.*?test_deprecations\.rb)i, warning + end + + def test_register_uri_with_string_option_prints_deprecation_warning + warning = capture_stderr do + FakeWeb.register_uri(:get, "http://example.com", :string => "test") + end + assert_match %r(deprecation warning: fakeweb's :string option)i, warning + end + + def test_register_uri_with_file_option_prints_deprecation_warning + warning = capture_stderr do + FakeWeb.register_uri(:get, "http://example.com", :file => fixture_path("test_example.txt")) + end + assert_match %r(deprecation warning: fakeweb's :file option)i, warning + end + + def test_register_uri_with_string_option_prints_deprecation_warning_with_correct_caller + warning = capture_stderr do + FakeWeb.register_uri(:get, "http://example.com", :string => "test") + end + assert_match %r(Called at.*?test_deprecations\.rb)i, warning + end + +end diff --git a/vendor/gems/fakeweb-1.3.0/test/test_fake_authentication.rb b/vendor/gems/fakeweb-1.3.0/test/test_fake_authentication.rb new file mode 100644 index 000000000..cff276441 --- /dev/null +++ b/vendor/gems/fakeweb-1.3.0/test/test_fake_authentication.rb @@ -0,0 +1,92 @@ +require 'test_helper' + +class TestFakeAuthentication < Test::Unit::TestCase + + def test_register_uri_with_authentication + FakeWeb.register_uri(:get, 'http://user:pass@mock/test_example.txt', :body => "example") + assert FakeWeb.registered_uri?(:get, 'http://user:pass@mock/test_example.txt') + end + + def test_register_uri_with_authentication_doesnt_trigger_without + FakeWeb.register_uri(:get, 'http://user:pass@mock/test_example.txt', :body => "example") + assert !FakeWeb.registered_uri?(:get, 'http://mock/test_example.txt') + end + + def test_register_uri_with_authentication_doesnt_trigger_with_incorrect_credentials + FakeWeb.register_uri(:get, 'http://user:pass@mock/test_example.txt', :body => "example") + assert !FakeWeb.registered_uri?(:get, 'http://user:wrong@mock/test_example.txt') + end + + def test_unauthenticated_request + FakeWeb.register_uri(:get, 'http://mock/auth.txt', :body => 'unauthorized') + http = Net::HTTP.new('mock', 80) + req = Net::HTTP::Get.new('/auth.txt') + assert_equal 'unauthorized', http.request(req).body + end + + def test_authenticated_request + FakeWeb.register_uri(:get, 'http://user:pass@mock/auth.txt', :body => 'authorized') + http = Net::HTTP.new('mock',80) + req = Net::HTTP::Get.new('/auth.txt') + req.basic_auth 'user', 'pass' + assert_equal 'authorized', http.request(req).body + end + + def test_authenticated_request_where_only_userinfo_differs + FakeWeb.register_uri(:get, 'http://user:pass@mock/auth.txt', :body => 'first user') + FakeWeb.register_uri(:get, 'http://user2:pass@mock/auth.txt', :body => 'second user') + http = Net::HTTP.new('mock') + req = Net::HTTP::Get.new('/auth.txt') + req.basic_auth 'user2', 'pass' + assert_equal 'second user', http.request(req).body + end + + def test_basic_auth_support_is_transparent_to_oauth + FakeWeb.register_uri(:get, "http://sp.example.com/protected", :body => "secret") + + # from http://oauth.net/core/1.0/#auth_header + auth_header = <<-HEADER + OAuth realm="http://sp.example.com/", + oauth_consumer_key="0685bd9184jfhq22", + oauth_token="ad180jjd733klru7", + oauth_signature_method="HMAC-SHA1", + oauth_signature="wOJIO9A2W5mFwDgiDvZbTSMK%2FPY%3D", + oauth_timestamp="137131200", + oauth_nonce="4572616e48616d6d65724c61686176", + oauth_version="1.0" + HEADER + auth_header.gsub!(/\s+/, " ").strip! + + http = Net::HTTP.new("sp.example.com", 80) + response = nil + http.start do |request| + response = request.get("/protected", {"authorization" => auth_header}) + end + assert_equal "secret", response.body + end + + def test_basic_auth_when_userinfo_contains_allowed_unencoded_characters + FakeWeb.register_uri(:get, "http://roses&hel1o,(+$):so;longs=@example.com", :body => "authorized") + http = Net::HTTP.new("example.com") + request = Net::HTTP::Get.new("/") + request.basic_auth("roses&hel1o,(+$)", "so;longs=") + assert_equal "authorized", http.request(request).body + end + + def test_basic_auth_when_userinfo_contains_encoded_at_sign + FakeWeb.register_uri(:get, "http://user%40example.com:secret@example.com", :body => "authorized") + http = Net::HTTP.new("example.com") + request = Net::HTTP::Get.new("/") + request.basic_auth("user@example.com", "secret") + assert_equal "authorized", http.request(request).body + end + + def test_basic_auth_when_userinfo_contains_allowed_encoded_characters + FakeWeb.register_uri(:get, "http://us%20er:sec%20%2F%2Fret%3F@example.com", :body => "authorized") + http = Net::HTTP.new("example.com") + request = Net::HTTP::Get.new("/") + request.basic_auth("us er", "sec //ret?") + assert_equal "authorized", http.request(request).body + end + +end diff --git a/vendor/gems/fakeweb-1.3.0/test/test_fake_web.rb b/vendor/gems/fakeweb-1.3.0/test/test_fake_web.rb new file mode 100644 index 000000000..c6e6b59eb --- /dev/null +++ b/vendor/gems/fakeweb-1.3.0/test/test_fake_web.rb @@ -0,0 +1,590 @@ +require 'test_helper' + +class TestFakeWeb < Test::Unit::TestCase + + def test_register_uri + FakeWeb.register_uri(:get, 'http://mock/test_example.txt', :body => "example") + assert FakeWeb.registered_uri?(:get, 'http://mock/test_example.txt') + end + + def test_register_uri_with_wrong_number_of_arguments + assert_raises ArgumentError do + FakeWeb.register_uri("http://example.com") + end + assert_raises ArgumentError do + FakeWeb.register_uri(:get, "http://example.com", "/example", :body => "example") + end + end + + def test_registered_uri_with_wrong_number_of_arguments + assert_raises ArgumentError do + FakeWeb.registered_uri? + end + assert_raises ArgumentError do + FakeWeb.registered_uri?(:get, "http://example.com", "/example") + end + end + + def test_response_for_with_wrong_number_of_arguments + assert_raises ArgumentError do + FakeWeb.response_for + end + assert_raises ArgumentError do + FakeWeb.response_for(:get, "http://example.com", "/example") + end + end + + def test_register_uri_without_domain_name + assert_raises URI::InvalidURIError do + FakeWeb.register_uri(:get, 'test_example2.txt', fixture_path("test_example.txt")) + end + end + + def test_register_uri_with_port_and_check_with_port + FakeWeb.register_uri(:get, 'http://example.com:3000/', :body => 'foo') + assert FakeWeb.registered_uri?(:get, 'http://example.com:3000/') + end + + def test_register_uri_with_port_and_check_without_port + FakeWeb.register_uri(:get, 'http://example.com:3000/', :body => 'foo') + assert !FakeWeb.registered_uri?(:get, 'http://example.com/') + end + + def test_register_uri_with_default_port_for_http_and_check_without_port + FakeWeb.register_uri(:get, 'http://example.com:80/', :body => 'foo') + assert FakeWeb.registered_uri?(:get, 'http://example.com/') + end + + def test_register_uri_with_default_port_for_https_and_check_without_port + FakeWeb.register_uri(:get, 'https://example.com:443/', :body => 'foo') + assert FakeWeb.registered_uri?(:get, 'https://example.com/') + end + + def test_register_uri_with_no_port_for_http_and_check_with_default_port + FakeWeb.register_uri(:get, 'http://example.com/', :body => 'foo') + assert FakeWeb.registered_uri?(:get, 'http://example.com:80/') + end + + def test_register_uri_with_no_port_for_https_and_check_with_default_port + FakeWeb.register_uri(:get, 'https://example.com/', :body => 'foo') + assert FakeWeb.registered_uri?(:get, 'https://example.com:443/') + end + + def test_register_uri_with_no_port_for_https_and_check_with_443_on_http + FakeWeb.register_uri(:get, 'https://example.com/', :body => 'foo') + assert !FakeWeb.registered_uri?(:get, 'http://example.com:443/') + end + + def test_register_uri_with_no_port_for_http_and_check_with_80_on_https + FakeWeb.register_uri(:get, 'http://example.com/', :body => 'foo') + assert !FakeWeb.registered_uri?(:get, 'https://example.com:80/') + end + + def test_register_uri_for_any_method_explicitly + FakeWeb.register_uri(:any, "http://example.com/rpc_endpoint", :body => "OK") + assert FakeWeb.registered_uri?(:get, "http://example.com/rpc_endpoint") + assert FakeWeb.registered_uri?(:post, "http://example.com/rpc_endpoint") + assert FakeWeb.registered_uri?(:put, "http://example.com/rpc_endpoint") + assert FakeWeb.registered_uri?(:delete, "http://example.com/rpc_endpoint") + assert FakeWeb.registered_uri?(:any, "http://example.com/rpc_endpoint") + capture_stderr do # silence deprecation warning + assert FakeWeb.registered_uri?("http://example.com/rpc_endpoint") + end + end + + def test_register_uri_for_get_method_only + FakeWeb.register_uri(:get, "http://example.com/users", :body => "User list") + assert FakeWeb.registered_uri?(:get, "http://example.com/users") + assert !FakeWeb.registered_uri?(:post, "http://example.com/users") + assert !FakeWeb.registered_uri?(:put, "http://example.com/users") + assert !FakeWeb.registered_uri?(:delete, "http://example.com/users") + assert !FakeWeb.registered_uri?(:any, "http://example.com/users") + capture_stderr do # silence deprecation warning + assert !FakeWeb.registered_uri?("http://example.com/users") + end + end + + def test_clean_registry_affects_registered_uri + FakeWeb.register_uri(:get, "http://example.com", :body => "registered") + assert FakeWeb.registered_uri?(:get, "http://example.com") + FakeWeb.clean_registry + assert !FakeWeb.registered_uri?(:get, "http://example.com") + end + + def test_clean_registry_affects_net_http_requests + FakeWeb.register_uri(:get, "http://example.com", :body => "registered") + response = Net::HTTP.start("example.com") { |query| query.get("/") } + assert_equal "registered", response.body + FakeWeb.clean_registry + assert_raise FakeWeb::NetConnectNotAllowedError do + Net::HTTP.start("example.com") { |query| query.get("/") } + end + end + + def test_response_for_with_registered_uri + FakeWeb.register_uri(:get, 'http://mock/test_example.txt', :body => fixture_path("test_example.txt")) + assert_equal 'test example content', FakeWeb.response_for(:get, 'http://mock/test_example.txt').body + end + + def test_response_for_with_unknown_uri + assert_nil FakeWeb.response_for(:get, 'http://example.com/') + end + + def test_response_for_with_put_method + FakeWeb.register_uri(:put, "http://example.com", :body => "response") + assert_equal 'response', FakeWeb.response_for(:put, "http://example.com").body + end + + def test_response_for_with_any_method_explicitly + FakeWeb.register_uri(:any, "http://example.com", :body => "response") + assert_equal 'response', FakeWeb.response_for(:get, "http://example.com").body + assert_equal 'response', FakeWeb.response_for(:any, "http://example.com").body + end + + def test_content_for_registered_uri_with_port_and_request_with_port + FakeWeb.register_uri(:get, 'http://example.com:3000/', :body => 'test example content') + response = Net::HTTP.start('example.com', 3000) { |http| http.get('/') } + assert_equal 'test example content', response.body + end + + def test_content_for_registered_uri_with_default_port_for_http_and_request_without_port + FakeWeb.register_uri(:get, 'http://example.com:80/', :body => 'test example content') + response = Net::HTTP.start('example.com') { |http| http.get('/') } + assert_equal 'test example content', response.body + end + + def test_content_for_registered_uri_with_no_port_for_http_and_request_with_default_port + FakeWeb.register_uri(:get, 'http://example.com/', :body => 'test example content') + response = Net::HTTP.start('example.com', 80) { |http| http.get('/') } + assert_equal 'test example content', response.body + end + + def test_content_for_registered_uri_with_default_port_for_https_and_request_with_default_port + FakeWeb.register_uri(:get, 'https://example.com:443/', :body => 'test example content') + http = Net::HTTP.new('example.com', 443) + http.use_ssl = true + response = http.get('/') + assert_equal 'test example content', response.body + end + + def test_content_for_registered_uri_with_no_port_for_https_and_request_with_default_port + FakeWeb.register_uri(:get, 'https://example.com/', :body => 'test example content') + http = Net::HTTP.new('example.com', 443) + http.use_ssl = true + response = http.get('/') + assert_equal 'test example content', response.body + end + + def test_content_for_registered_uris_with_ports_on_same_domain_and_request_without_port + FakeWeb.register_uri(:get, 'http://example.com:3000/', :body => 'port 3000') + FakeWeb.register_uri(:get, 'http://example.com/', :body => 'port 80') + response = Net::HTTP.start('example.com') { |http| http.get('/') } + assert_equal 'port 80', response.body + end + + def test_content_for_registered_uris_with_ports_on_same_domain_and_request_with_port + FakeWeb.register_uri(:get, 'http://example.com:3000/', :body => 'port 3000') + FakeWeb.register_uri(:get, 'http://example.com/', :body => 'port 80') + response = Net::HTTP.start('example.com', 3000) { |http| http.get('/') } + assert_equal 'port 3000', response.body + end + + def test_content_for_registered_uri_with_get_method_only + FakeWeb.allow_net_connect = false + FakeWeb.register_uri(:get, "http://example.com/", :body => "test example content") + http = Net::HTTP.new('example.com') + assert_equal 'test example content', http.get('/').body + assert_raises(FakeWeb::NetConnectNotAllowedError) { http.post('/', nil) } + assert_raises(FakeWeb::NetConnectNotAllowedError) { http.put('/', nil) } + assert_raises(FakeWeb::NetConnectNotAllowedError) { http.delete('/') } + end + + def test_content_for_registered_uri_with_any_method_explicitly + FakeWeb.allow_net_connect = false + FakeWeb.register_uri(:any, "http://example.com/", :body => "test example content") + http = Net::HTTP.new('example.com') + assert_equal 'test example content', http.get('/').body + assert_equal 'test example content', http.post('/', nil).body + assert_equal 'test example content', http.put('/', nil).body + assert_equal 'test example content', http.delete('/').body + end + + def test_content_for_registered_uri_with_any_method_implicitly + FakeWeb.allow_net_connect = false + capture_stderr do # silence deprecation warning + FakeWeb.register_uri("http://example.com/", :body => "test example content") + end + + http = Net::HTTP.new('example.com') + assert_equal 'test example content', http.get('/').body + assert_equal 'test example content', http.post('/', nil).body + assert_equal 'test example content', http.put('/', nil).body + assert_equal 'test example content', http.delete('/').body + end + + def test_mock_request_with_block + FakeWeb.register_uri(:get, 'http://mock/test_example.txt', :body => fixture_path("test_example.txt")) + response = Net::HTTP.start('mock') { |http| http.get('/test_example.txt') } + assert_equal 'test example content', response.body + end + + def test_request_with_registered_body_yields_the_response_body_to_a_request_block + FakeWeb.register_uri(:get, "http://example.com", :body => "content") + body = nil + Net::HTTP.start("example.com") do |http| + http.get("/") do |response_body| + body = response_body + end + end + assert_equal "content", body + end + + def test_request_with_registered_response_yields_the_response_body_to_a_request_block + fake_response = Net::HTTPOK.new('1.1', '200', 'OK') + fake_response.instance_variable_set(:@body, "content") + FakeWeb.register_uri(:get, 'http://example.com', :response => fake_response) + body = nil + Net::HTTP.start("example.com") do |http| + http.get("/") do |response_body| + body = response_body + end + end + assert_equal "content", body + end + + def test_mock_request_with_undocumented_full_uri_argument_style + FakeWeb.register_uri(:get, 'http://mock/test_example.txt', :body => fixture_path("test_example.txt")) + response = Net::HTTP.start('mock') { |query| query.get('http://mock/test_example.txt') } + assert_equal 'test example content', response.body + end + + def test_mock_request_with_undocumented_full_uri_argument_style_and_query + FakeWeb.register_uri(:get, 'http://mock/test_example.txt?a=b', :body => 'test query content') + response = Net::HTTP.start('mock') { |query| query.get('http://mock/test_example.txt?a=b') } + assert_equal 'test query content', response.body + end + + def test_mock_post + FakeWeb.register_uri(:post, 'http://mock/test_example.txt', :body => fixture_path("test_example.txt")) + response = Net::HTTP.start('mock') { |query| query.post('/test_example.txt', '') } + assert_equal 'test example content', response.body + end + + def test_mock_post_with_string_as_registered_uri + FakeWeb.register_uri(:post, 'http://mock/test_string.txt', :body => 'foo') + response = Net::HTTP.start('mock') { |query| query.post('/test_string.txt', '') } + assert_equal 'foo', response.body + end + + def test_mock_post_with_body_sets_the_request_body + FakeWeb.register_uri(:post, "http://example.com/posts", :status => [201, "Created"]) + http = Net::HTTP.new("example.com") + request = Net::HTTP::Post.new("/posts") + http.request(request, "title=Test") + assert_equal "title=Test", request.body + assert_equal 10, request.content_length + end + + def test_mock_post_with_body_using_other_syntax_sets_the_request_body + FakeWeb.register_uri(:post, "http://example.com/posts", :status => [201, "Created"]) + http = Net::HTTP.new("example.com") + request = Net::HTTP::Post.new("/posts") + request.body = "title=Test" + http.request(request) + assert_equal "title=Test", request.body + assert_equal 10, request.content_length + end + + def test_real_post_with_body_sets_the_request_body + FakeWeb.allow_net_connect = true + setup_expectations_for_real_apple_hot_news_request :method => "POST", + :path => "/posts", :request_body => "title=Test" + http = Net::HTTP.new("images.apple.com") + request = Net::HTTP::Post.new("/posts") + request["Content-Type"] = "application/x-www-form-urlencoded" + http.request(request, "title=Test") + assert_equal "title=Test", request.body + assert_equal 10, request.content_length + end + + def test_mock_get_with_request_as_registered_uri + fake_response = Net::HTTPOK.new('1.1', '200', 'OK') + FakeWeb.register_uri(:get, 'http://mock/test_response', :response => fake_response) + response = Net::HTTP.start('mock') { |query| query.get('/test_response') } + assert_equal fake_response, response + end + + def test_mock_get_with_request_from_file_as_registered_uri + FakeWeb.register_uri(:get, 'http://www.google.com/', :response => fixture_path("google_response_without_transfer_encoding")) + response = Net::HTTP.start('www.google.com') { |query| query.get('/') } + assert_equal '200', response.code + assert response.body.include?('<title>Google</title>') + end + + def test_mock_post_with_request_from_file_as_registered_uri + FakeWeb.register_uri(:post, 'http://www.google.com/', :response => fixture_path("google_response_without_transfer_encoding")) + response = Net::HTTP.start('www.google.com') { |query| query.post('/', '') } + assert_equal "200", response.code + assert response.body.include?('<title>Google</title>') + end + + def test_proxy_request + FakeWeb.register_uri(:get, 'http://www.example.com/', :body => "hello world") + FakeWeb.register_uri(:get, 'http://your.proxy.host/', :body => "lala") + + response = nil + Net::HTTP::Proxy('your.proxy.host', 8080).start('www.example.com') do |http| + response = http.get('/') + end + assert_equal "hello world", response.body + end + + def test_https_request + FakeWeb.register_uri(:get, 'https://www.example.com/', :body => "Hello World") + http = Net::HTTP.new('www.example.com', 443) + http.use_ssl = true + response = http.get('/') + assert_equal "Hello World", response.body + end + + def test_register_unimplemented_response + FakeWeb.register_uri(:get, 'http://mock/unimplemented', :response => 1) + assert_raises StandardError do + Net::HTTP.start('mock') { |q| q.get('/unimplemented') } + end + end + + def test_specifying_nil_for_body + FakeWeb.register_uri(:head, "http://example.com", :body => nil) + response = Net::HTTP.start("example.com") { |query| query.head("/") } + assert_equal "", response.body + end + + def test_real_http_request + FakeWeb.allow_net_connect = true + setup_expectations_for_real_apple_hot_news_request + + resp = nil + Net::HTTP.start('images.apple.com') do |query| + resp = query.get('/main/rss/hotnews/hotnews.rss') + end + assert resp.body.include?('Apple') + assert resp.body.include?('News') + end + + def test_real_http_request_with_undocumented_full_uri_argument_style + FakeWeb.allow_net_connect = true + setup_expectations_for_real_apple_hot_news_request(:path => 'http://images.apple.com/main/rss/hotnews/hotnews.rss') + + resp = nil + Net::HTTP.start('images.apple.com') do |query| + resp = query.get('http://images.apple.com/main/rss/hotnews/hotnews.rss') + end + assert resp.body.include?('Apple') + assert resp.body.include?('News') + end + + def test_real_https_request + FakeWeb.allow_net_connect = true + setup_expectations_for_real_apple_hot_news_request(:port => 443) + + http = Net::HTTP.new('images.apple.com', 443) + http.use_ssl = true + http.verify_mode = OpenSSL::SSL::VERIFY_NONE # silence certificate warning + response = http.get('/main/rss/hotnews/hotnews.rss') + assert response.body.include?('Apple') + assert response.body.include?('News') + end + + def test_real_request_on_same_domain_as_mock + FakeWeb.allow_net_connect = true + setup_expectations_for_real_apple_hot_news_request + + FakeWeb.register_uri(:get, 'http://images.apple.com/test_string.txt', :body => 'foo') + + resp = nil + Net::HTTP.start('images.apple.com') do |query| + resp = query.get('/main/rss/hotnews/hotnews.rss') + end + assert resp.body.include?('Apple') + assert resp.body.include?('News') + end + + def test_mock_request_on_real_domain + FakeWeb.register_uri(:get, 'http://images.apple.com/test_string.txt', :body => 'foo') + resp = nil + Net::HTTP.start('images.apple.com') do |query| + resp = query.get('/test_string.txt') + end + assert_equal 'foo', resp.body + end + + def test_mock_post_that_raises_exception + FakeWeb.register_uri(:post, 'http://mock/raising_exception.txt', :exception => StandardError) + assert_raises(StandardError) do + Net::HTTP.start('mock') do |query| + query.post('/raising_exception.txt', 'some data') + end + end + end + + def test_mock_post_that_raises_an_http_error + FakeWeb.register_uri(:post, 'http://mock/raising_exception.txt', :exception => Net::HTTPError) + assert_raises(Net::HTTPError) do + Net::HTTP.start('mock') do |query| + query.post('/raising_exception.txt', '') + end + end + end + + def test_raising_an_exception_that_requires_an_argument_to_instantiate + FakeWeb.register_uri(:get, "http://example.com/timeout.txt", :exception => Timeout::Error) + assert_raises(Timeout::Error) do + Net::HTTP.get(URI.parse("http://example.com/timeout.txt")) + end + end + + def test_mock_instance_syntax + FakeWeb.register_uri(:get, 'http://mock/test_example.txt', :body => fixture_path("test_example.txt")) + response = nil + uri = URI.parse('http://mock/test_example.txt') + http = Net::HTTP.new(uri.host, uri.port) + response = http.start do + http.get(uri.path) + end + + assert_equal 'test example content', response.body + end + + def test_mock_via_nil_proxy + response = nil + proxy_address = nil + proxy_port = nil + FakeWeb.register_uri(:get, 'http://mock/test_example.txt', :body => fixture_path("test_example.txt")) + uri = URI.parse('http://mock/test_example.txt') + http = Net::HTTP::Proxy(proxy_address, proxy_port).new( + uri.host, (uri.port or 80)) + response = http.start do + http.get(uri.path) + end + + assert_equal 'test example content', response.body + end + + def test_response_type + FakeWeb.register_uri(:get, 'http://mock/test_example.txt', :body => "test") + response = Net::HTTP.start('mock') { |http| http.get('/test_example.txt') } + assert_kind_of Net::HTTPSuccess, response + end + + def test_mock_request_that_raises_an_http_error_with_a_specific_status + FakeWeb.register_uri(:get, 'http://mock/raising_exception.txt', :exception => Net::HTTPError, :status => ['404', 'Not Found']) + exception = assert_raises(Net::HTTPError) do + Net::HTTP.start('mock') { |http| http.get('/raising_exception.txt') } + end + assert_equal '404', exception.response.code + assert_equal 'Not Found', exception.response.msg + end + + def test_mock_rotate_responses + FakeWeb.register_uri(:get, 'http://mock/multiple_test_example.txt', + [ {:body => fixture_path("test_example.txt"), :times => 2}, + {:body => "thrice", :times => 3}, + {:body => "ever_more"} ]) + + uri = URI.parse('http://mock/multiple_test_example.txt') + 2.times { assert_equal 'test example content', Net::HTTP.get(uri) } + 3.times { assert_equal 'thrice', Net::HTTP.get(uri) } + 4.times { assert_equal 'ever_more', Net::HTTP.get(uri) } + end + + def test_mock_request_using_response_with_transfer_encoding_header_has_valid_transfer_encoding_header + FakeWeb.register_uri(:get, 'http://www.google.com/', :response => fixture_path("google_response_with_transfer_encoding")) + response = Net::HTTP.start('www.google.com') { |query| query.get('/') } + assert_not_nil response['transfer-encoding'] + assert response['transfer-encoding'] == 'chunked' + end + + def test_mock_request_using_response_without_transfer_encoding_header_does_not_have_a_transfer_encoding_header + FakeWeb.register_uri(:get, 'http://www.google.com/', :response => fixture_path("google_response_without_transfer_encoding")) + response = nil + response = Net::HTTP.start('www.google.com') { |query| query.get('/') } + assert !response.key?('transfer-encoding') + end + + def test_mock_request_using_response_from_curl_has_original_transfer_encoding_header + FakeWeb.register_uri(:get, 'http://www.google.com/', :response => fixture_path("google_response_from_curl")) + response = Net::HTTP.start('www.google.com') { |query| query.get('/') } + assert_not_nil response['transfer-encoding'] + assert response['transfer-encoding'] == 'chunked' + end + + def test_txt_file_should_have_three_lines + FakeWeb.register_uri(:get, 'http://www.google.com/', :body => fixture_path("test_txt_file")) + response = Net::HTTP.start('www.google.com') { |query| query.get('/') } + assert response.body.split(/\n/).size == 3, "response has #{response.body.split(/\n/).size} lines should have 3" + end + + def test_requiring_fakeweb_instead_of_fake_web + require "fakeweb" + end + + def test_registering_with_string_containing_null_byte + # Regression test for File.exists? raising an ArgumentError ("string + # contains null byte") since :response first tries to find by filename. + # The string should be treated as a response body, instead, and an + # EOFError is raised when the byte is encountered. + FakeWeb.register_uri(:get, "http://example.com", :response => "test\0test") + assert_raise EOFError do + Net::HTTP.get(URI.parse("http://example.com")) + end + + FakeWeb.register_uri(:get, "http://example.com", :body => "test\0test") + body = Net::HTTP.get(URI.parse("http://example.com")) + assert_equal "test\0test", body + end + + def test_registering_with_string_that_is_a_directory_name + # Similar to above, but for Errno::EISDIR being raised since File.exists? + # returns true for directories + FakeWeb.register_uri(:get, "http://example.com", :response => File.dirname(__FILE__)) + assert_raise EOFError do + body = Net::HTTP.get(URI.parse("http://example.com")) + end + + FakeWeb.register_uri(:get, "http://example.com", :body => File.dirname(__FILE__)) + body = Net::HTTP.get(URI.parse("http://example.com")) + assert_equal File.dirname(__FILE__), body + end + + def test_registering_with_a_body_pointing_to_a_pathname + path = Pathname.new(fixture_path("test_example.txt")) + FakeWeb.register_uri(:get, "http://example.com", :body => path) + response = Net::HTTP.start("example.com") { |http| http.get("/") } + assert_equal "test example content", response.body + end + + def test_registering_with_a_response_pointing_to_a_pathname + path = Pathname.new(fixture_path("google_response_without_transfer_encoding")) + FakeWeb.register_uri(:get, "http://google.com", :response => path) + response = Net::HTTP.start("google.com") { |http| http.get("/") } + assert response.body.include?("<title>Google</title>") + end + + def test_http_version_from_string_response + FakeWeb.register_uri(:get, "http://example.com", :body => "example") + response = Net::HTTP.start("example.com") { |http| http.get("/") } + assert_equal "1.0", response.http_version + end + + def test_http_version_from_file_response + FakeWeb.register_uri(:get, "http://example.com", :body => fixture_path("test_example.txt")) + response = Net::HTTP.start("example.com") { |http| http.get("/") } + assert_equal "1.0", response.http_version + end + + def test_version + assert_equal "1.3.0", FakeWeb::VERSION + end + +end diff --git a/vendor/gems/fakeweb-1.3.0/test/test_fake_web_open_uri.rb b/vendor/gems/fakeweb-1.3.0/test/test_fake_web_open_uri.rb new file mode 100644 index 000000000..699a64762 --- /dev/null +++ b/vendor/gems/fakeweb-1.3.0/test/test_fake_web_open_uri.rb @@ -0,0 +1,58 @@ +require 'test_helper' + +class TestFakeWebOpenURI < Test::Unit::TestCase + + def test_content_for_registered_uri + FakeWeb.register_uri(:get, 'http://mock/test_example.txt', :body => fixture_path("test_example.txt")) + assert_equal 'test example content', FakeWeb.response_for(:get, 'http://mock/test_example.txt').body + end + + def test_mock_open + FakeWeb.register_uri(:get, 'http://mock/test_example.txt', :body => fixture_path("test_example.txt")) + assert_equal 'test example content', open('http://mock/test_example.txt').read + end + + def test_mock_open_with_string_as_registered_uri + FakeWeb.register_uri(:get, 'http://mock/test_string.txt', :body => 'foo') + assert_equal 'foo', open('http://mock/test_string.txt').string + end + + def test_real_open + FakeWeb.allow_net_connect = true + setup_expectations_for_real_apple_hot_news_request + resp = open('http://images.apple.com/main/rss/hotnews/hotnews.rss') + assert_equal "200", resp.status.first + body = resp.read + assert body.include?('Apple') + assert body.include?('News') + end + + def test_mock_open_that_raises_exception + FakeWeb.register_uri(:get, 'http://mock/raising_exception.txt', :exception => StandardError) + assert_raises(StandardError) do + open('http://mock/raising_exception.txt') + end + end + + def test_mock_open_that_raises_an_http_error + FakeWeb.register_uri(:get, 'http://mock/raising_exception.txt', :exception => OpenURI::HTTPError) + assert_raises(OpenURI::HTTPError) do + open('http://mock/raising_exception.txt') + end + end + + def test_mock_open_that_raises_an_http_error_with_a_specific_status + FakeWeb.register_uri(:get, 'http://mock/raising_exception.txt', :exception => OpenURI::HTTPError, :status => ['123', 'jodel']) + exception = assert_raises(OpenURI::HTTPError) do + open('http://mock/raising_exception.txt') + end + assert_equal '123', exception.io.code + assert_equal 'jodel', exception.io.message + end + + def test_mock_open_with_block + FakeWeb.register_uri(:get, 'http://mock/test_example.txt', :body => fixture_path("test_example.txt")) + body = open('http://mock/test_example.txt') { |f| f.readlines } + assert_equal 'test example content', body.first + end +end diff --git a/vendor/gems/fakeweb-1.3.0/test/test_helper.rb b/vendor/gems/fakeweb-1.3.0/test/test_helper.rb new file mode 100644 index 000000000..b181391b1 --- /dev/null +++ b/vendor/gems/fakeweb-1.3.0/test/test_helper.rb @@ -0,0 +1,90 @@ +require 'test/unit' +require 'open-uri' +require 'pathname' +require 'fake_web' +require 'rbconfig' +require 'rubygems' +require 'mocha' + + +# Give all tests a common setup and teardown that prevents shared state +class Test::Unit::TestCase + alias setup_without_fakeweb setup + def setup + FakeWeb.clean_registry + @original_allow_net_connect = FakeWeb.allow_net_connect? + FakeWeb.allow_net_connect = false + end + + alias teardown_without_fakeweb teardown + def teardown + FakeWeb.allow_net_connect = @original_allow_net_connect + end +end + + +module FakeWebTestHelper + + def fixture_path(basename) + "test/fixtures/#{basename}" + end + + def capture_stderr + $stderr = StringIO.new + yield + $stderr.rewind && $stderr.read + ensure + $stderr = STDERR + end + + # The path to the current ruby interpreter. Adapted from Rake's FileUtils. + def ruby_path + ext = ((RbConfig::CONFIG['ruby_install_name'] =~ /\.(com|cmd|exe|bat|rb|sh)$/) ? "" : RbConfig::CONFIG['EXEEXT']) + File.join(RbConfig::CONFIG['bindir'], RbConfig::CONFIG['ruby_install_name'] + ext).sub(/.*\s.*/m, '"\&"') + end + + # Sets several expectations (using Mocha) that a real HTTP request makes it + # past FakeWeb to the socket layer. You can use this when you need to check + # that a request isn't handled by FakeWeb. + def setup_expectations_for_real_request(options = {}) + # Socket handling + if options[:port] == 443 + socket = mock("SSLSocket") + OpenSSL::SSL::SSLSocket.expects(:===).with(socket).returns(true).at_least_once + OpenSSL::SSL::SSLSocket.expects(:new).with(socket, instance_of(OpenSSL::SSL::SSLContext)).returns(socket).at_least_once + socket.stubs(:sync_close=).returns(true) + socket.expects(:connect).with().at_least_once + else + socket = mock("TCPSocket") + Socket.expects(:===).with(socket).at_least_once.returns(true) + end + + TCPSocket.expects(:open).with(options[:host], options[:port]).returns(socket).at_least_once + socket.stubs(:closed?).returns(false) + socket.stubs(:close).returns(true) + + # Request/response handling + request_parts = ["#{options[:method]} #{options[:path]} HTTP/1.1", "Host: #{options[:host]}"] + socket.expects(:write).with(all_of(includes(request_parts[0]), includes(request_parts[1]))).returns(100) + if !options[:request_body].nil? + socket.expects(:write).with(options[:request_body]).returns(100) + end + + read_method = RUBY_VERSION >= "1.9.2" ? :read_nonblock : :sysread + socket.expects(read_method).at_least_once.returns("HTTP/1.1 #{options[:response_code]} #{options[:response_message]}\nContent-Length: #{options[:response_body].length}\n\n#{options[:response_body]}").then.raises(EOFError) + end + + + # A helper that calls #setup_expectations_for_real_request for you, using + # defaults for our commonly used test request to images.apple.com. + def setup_expectations_for_real_apple_hot_news_request(options = {}) + defaults = { :host => "images.apple.com", :port => 80, :method => "GET", + :path => "/main/rss/hotnews/hotnews.rss", + :response_code => 200, :response_message => "OK", + :response_body => "<title>Apple Hot News</title>" } + setup_expectations_for_real_request(defaults.merge(options)) + end + +end + +Test::Unit::TestCase.send(:include, FakeWebTestHelper) diff --git a/vendor/gems/fakeweb-1.3.0/test/test_last_request.rb b/vendor/gems/fakeweb-1.3.0/test/test_last_request.rb new file mode 100644 index 000000000..7868c83a1 --- /dev/null +++ b/vendor/gems/fakeweb-1.3.0/test/test_last_request.rb @@ -0,0 +1,29 @@ +require 'test_helper' + +class TestLastRequest < Test::Unit::TestCase + + def test_last_request_returns_correct_net_http_request_class + FakeWeb.register_uri(:get, "http://example.com", :status => [200, "OK"]) + Net::HTTP.start("example.com") { |http| http.get("/") } + assert_instance_of Net::HTTP::Get, FakeWeb.last_request + end + + def test_last_request_has_correct_method_path_and_body_for_get + FakeWeb.register_uri(:get, "http://example.com", :status => [200, "OK"]) + Net::HTTP.start("example.com") { |http| http.get("/") } + assert_equal "GET", FakeWeb.last_request.method + assert_equal "/", FakeWeb.last_request.path + assert_nil FakeWeb.last_request.body + assert_nil FakeWeb.last_request.content_length + end + + def test_last_request_has_correct_method_path_and_body_for_post + FakeWeb.register_uri(:post, "http://example.com/posts", :status => [201, "Created"]) + Net::HTTP.start("example.com") { |http| http.post("/posts", "title=Test") } + assert_equal "POST", FakeWeb.last_request.method + assert_equal "/posts", FakeWeb.last_request.path + assert_equal "title=Test", FakeWeb.last_request.body + assert_equal 10, FakeWeb.last_request.content_length + end + +end diff --git a/vendor/gems/fakeweb-1.3.0/test/test_missing_open_uri.rb b/vendor/gems/fakeweb-1.3.0/test/test_missing_open_uri.rb new file mode 100644 index 000000000..029ba1cab --- /dev/null +++ b/vendor/gems/fakeweb-1.3.0/test/test_missing_open_uri.rb @@ -0,0 +1,25 @@ +require 'test_helper' + +class TestMissingOpenURI < Test::Unit::TestCase + + def setup + super + @saved_open_uri = OpenURI + Object.send(:remove_const, :OpenURI) + end + + def teardown + super + Object.const_set(:OpenURI, @saved_open_uri) + end + + + def test_register_using_exception_without_open_uri + # regression test for Responder needing OpenURI::HTTPError to be defined + FakeWeb.register_uri(:get, "http://example.com/", :exception => StandardError) + assert_raises(StandardError) do + Net::HTTP.start("example.com") { |http| http.get("/") } + end + end + +end diff --git a/vendor/gems/fakeweb-1.3.0/test/test_missing_pathname.rb b/vendor/gems/fakeweb-1.3.0/test/test_missing_pathname.rb new file mode 100644 index 000000000..ee16a0d7b --- /dev/null +++ b/vendor/gems/fakeweb-1.3.0/test/test_missing_pathname.rb @@ -0,0 +1,37 @@ +require 'test_helper' + +class TestMissingPathname < Test::Unit::TestCase + + def setup + super + @saved_pathname = Pathname + Object.send(:remove_const, :Pathname) + end + + def teardown + super + Object.const_set(:Pathname, @saved_pathname) + end + + # FakeWeb supports using Pathname objects where filenames are expected, but + # Pathname isn't required to use FakeWeb. Make sure everything still works + # when Pathname isn't in use. + + def test_register_using_body_without_pathname + FakeWeb.register_uri(:get, "http://example.com/", :body => fixture_path("test_example.txt")) + Net::HTTP.start("example.com") { |http| http.get("/") } + end + + def test_register_using_response_without_pathname + FakeWeb.register_uri(:get, "http://example.com/", :response => fixture_path("google_response_without_transfer_encoding")) + Net::HTTP.start("example.com") { |http| http.get("/") } + end + + def test_register_using_unsupported_response_without_pathname + FakeWeb.register_uri(:get, "http://example.com/", :response => 1) + assert_raise StandardError do + Net::HTTP.start("example.com") { |http| http.get("/") } + end + end + +end diff --git a/vendor/gems/fakeweb-1.3.0/test/test_other_net_http_libraries.rb b/vendor/gems/fakeweb-1.3.0/test/test_other_net_http_libraries.rb new file mode 100644 index 000000000..af7e5e276 --- /dev/null +++ b/vendor/gems/fakeweb-1.3.0/test/test_other_net_http_libraries.rb @@ -0,0 +1,36 @@ +require 'test_helper' + +class TestOtherNetHttpLibraries < Test::Unit::TestCase + + def capture_output_from_requiring(libs, additional_code = "") + requires = libs.map { |lib| "require '#{lib}'" }.join("; ") + fakeweb_dir = "#{File.dirname(__FILE__)}/../lib" + vendor_dirs = Dir["#{File.dirname(__FILE__)}/vendor/*/lib"] + load_path_opts = vendor_dirs.unshift(fakeweb_dir).map { |dir| "-I#{dir}" }.join(" ") + + `#{ruby_path} #{load_path_opts} -e "#{requires}; #{additional_code}" 2>&1` + end + + def test_requiring_samuel_before_fakeweb_prints_warning + output = capture_output_from_requiring %w(samuel fakeweb) + assert_match %r(Warning: FakeWeb was loaded after Samuel), output + end + + def test_requiring_samuel_after_fakeweb_does_not_print_warning + output = capture_output_from_requiring %w(fakeweb samuel) + assert output.empty? + end + + def test_requiring_right_http_connection_before_fakeweb_and_then_connecting_does_not_print_warning + additional_code = "Net::HTTP.start('example.com')" + output = capture_output_from_requiring %w(right_http_connection fakeweb), additional_code + assert output.empty? + end + + def test_requiring_right_http_connection_after_fakeweb_and_then_connecting_prints_warning + additional_code = "Net::HTTP.start('example.com')" + output = capture_output_from_requiring %w(fakeweb right_http_connection), additional_code + assert_match %r(Warning: RightHttpConnection was loaded after FakeWeb), output + end + +end diff --git a/vendor/gems/fakeweb-1.3.0/test/test_precedence.rb b/vendor/gems/fakeweb-1.3.0/test/test_precedence.rb new file mode 100644 index 000000000..388b9f8a1 --- /dev/null +++ b/vendor/gems/fakeweb-1.3.0/test/test_precedence.rb @@ -0,0 +1,79 @@ +require 'test_helper' + +class TestPrecedence < Test::Unit::TestCase + + def test_matching_get_strings_have_precedence_over_matching_get_regexes + FakeWeb.register_uri(:get, "http://example.com/test", :body => "string") + FakeWeb.register_uri(:get, %r|http://example\.com/test|, :body => "regex") + response = Net::HTTP.start("example.com") { |query| query.get('/test') } + assert_equal "string", response.body + end + + def test_matching_any_strings_have_precedence_over_matching_any_regexes + FakeWeb.register_uri(:any, "http://example.com/test", :body => "string") + FakeWeb.register_uri(:any, %r|http://example\.com/test|, :body => "regex") + response = Net::HTTP.start("example.com") { |query| query.get('/test') } + assert_equal "string", response.body + end + + def test_matching_get_strings_have_precedence_over_matching_any_strings + FakeWeb.register_uri(:get, "http://example.com/test", :body => "get method") + FakeWeb.register_uri(:any, "http://example.com/test", :body => "any method") + response = Net::HTTP.start("example.com") { |query| query.get('/test') } + assert_equal "get method", response.body + + # registration order should not matter + FakeWeb.register_uri(:any, "http://example.com/test2", :body => "any method") + FakeWeb.register_uri(:get, "http://example.com/test2", :body => "get method") + response = Net::HTTP.start("example.com") { |query| query.get('/test2') } + assert_equal "get method", response.body + end + + def test_matching_any_strings_have_precedence_over_matching_get_regexes + FakeWeb.register_uri(:any, "http://example.com/test", :body => "any string") + FakeWeb.register_uri(:get, %r|http://example\.com/test|, :body => "get regex") + response = Net::HTTP.start("example.com") { |query| query.get('/test') } + assert_equal "any string", response.body + end + + def test_registered_strings_and_uris_are_equivalent_so_second_takes_precedence + FakeWeb.register_uri(:get, "http://example.com/test", :body => "string") + FakeWeb.register_uri(:get, URI.parse("http://example.com/test"), :body => "uri") + response = Net::HTTP.start("example.com") { |query| query.get('/test') } + assert_equal "uri", response.body + + FakeWeb.register_uri(:get, URI.parse("http://example.com/test2"), :body => "uri") + FakeWeb.register_uri(:get, "http://example.com/test2", :body => "string") + response = Net::HTTP.start("example.com") { |query| query.get('/test2') } + assert_equal "string", response.body + end + + def test_identical_registration_replaces_previous_registration + FakeWeb.register_uri(:get, "http://example.com/test", :body => "first") + FakeWeb.register_uri(:get, "http://example.com/test", :body => "second") + response = Net::HTTP.start("example.com") { |query| query.get('/test') } + assert_equal "second", response.body + end + + def test_identical_registration_replaces_previous_registration_accounting_for_normalization + FakeWeb.register_uri(:get, "http://example.com/test?", :body => "first") + FakeWeb.register_uri(:get, "http://example.com:80/test", :body => "second") + response = Net::HTTP.start("example.com") { |query| query.get('/test') } + assert_equal "second", response.body + end + + def test_identical_registration_replaces_previous_registration_accounting_for_query_params + FakeWeb.register_uri(:get, "http://example.com/test?a=1&b=2", :body => "first") + FakeWeb.register_uri(:get, "http://example.com/test?b=2&a=1", :body => "second") + response = Net::HTTP.start("example.com") { |query| query.get('/test?a=1&b=2') } + assert_equal "second", response.body + end + + def test_identical_registration_replaces_previous_registration_with_regexes + FakeWeb.register_uri(:get, /test/, :body => "first") + FakeWeb.register_uri(:get, /test/, :body => "second") + response = Net::HTTP.start("example.com") { |query| query.get('/test') } + assert_equal "second", response.body + end + +end diff --git a/vendor/gems/fakeweb-1.3.0/test/test_query_string.rb b/vendor/gems/fakeweb-1.3.0/test/test_query_string.rb new file mode 100644 index 000000000..11a211848 --- /dev/null +++ b/vendor/gems/fakeweb-1.3.0/test/test_query_string.rb @@ -0,0 +1,45 @@ +require 'test_helper' + +class TestFakeWebQueryString < Test::Unit::TestCase + + def test_register_uri_string_with_query_params + FakeWeb.register_uri(:get, 'http://example.com/?a=1&b=1', :body => 'foo') + assert FakeWeb.registered_uri?(:get, 'http://example.com/?a=1&b=1') + + FakeWeb.register_uri(:post, URI.parse("http://example.org/?a=1&b=1"), :body => "foo") + assert FakeWeb.registered_uri?(:post, "http://example.org/?a=1&b=1") + end + + def test_register_uri_with_query_params_and_check_in_different_order + FakeWeb.register_uri(:get, 'http://example.com/?a=1&b=1', :body => 'foo') + assert FakeWeb.registered_uri?(:get, 'http://example.com/?b=1&a=1') + + FakeWeb.register_uri(:post, URI.parse('http://example.org/?a=1&b=1'), :body => 'foo') + assert FakeWeb.registered_uri?(:post, 'http://example.org/?b=1&a=1') + end + + def test_registered_uri_gets_recognized_with_empty_query_params + FakeWeb.register_uri(:get, 'http://example.com/', :body => 'foo') + assert FakeWeb.registered_uri?(:get, 'http://example.com/?') + + FakeWeb.register_uri(:post, URI.parse('http://example.org/'), :body => 'foo') + assert FakeWeb.registered_uri?(:post, 'http://example.org/?') + end + + def test_register_uri_with_empty_query_params_and_check_with_none + FakeWeb.register_uri(:get, 'http://example.com/?', :body => 'foo') + assert FakeWeb.registered_uri?(:get, 'http://example.com/') + + FakeWeb.register_uri(:post, URI.parse('http://example.org/?'), :body => 'foo') + assert FakeWeb.registered_uri?(:post, 'http://example.org/') + end + + def test_registry_sort_query_params + assert_equal "a=1&b=2", FakeWeb::Registry.instance.send(:sort_query_params, "b=2&a=1") + end + + def test_registry_sort_query_params_sorts_by_value_if_keys_collide + assert_equal "a=1&a=2&b=2", FakeWeb::Registry.instance.send(:sort_query_params, "a=2&b=2&a=1") + end + +end diff --git a/vendor/gems/fakeweb-1.3.0/test/test_regexes.rb b/vendor/gems/fakeweb-1.3.0/test/test_regexes.rb new file mode 100644 index 000000000..e2eba1db8 --- /dev/null +++ b/vendor/gems/fakeweb-1.3.0/test/test_regexes.rb @@ -0,0 +1,157 @@ +require 'test_helper' + +class TestRegexes < Test::Unit::TestCase + + def test_registered_uri_with_pattern + FakeWeb.register_uri(:get, %r|http://example.com/test_example/\d+|, :body => "example") + assert FakeWeb.registered_uri?(:get, "http://example.com/test_example/25") + assert !FakeWeb.registered_uri?(:get, "http://example.com/test_example/abc") + end + + def test_response_for_with_matching_registered_uri + FakeWeb.register_uri(:get, %r|http://www.google.com|, :body => "Welcome to Google!") + assert_equal "Welcome to Google!", FakeWeb.response_for(:get, "http://www.google.com").body + end + + def test_response_for_with_matching_registered_uri_and_get_method_matching_to_any_method + FakeWeb.register_uri(:any, %r|http://www.example.com|, :body => "example") + assert_equal "example", FakeWeb.response_for(:get, "http://www.example.com").body + end + + def test_registered_uri_with_authentication_and_pattern + FakeWeb.register_uri(:get, %r|http://user:pass@mock/example\.\w+|i, :body => "example") + assert FakeWeb.registered_uri?(:get, 'http://user:pass@mock/example.txt') + end + + def test_registered_uri_with_authentication_and_pattern_handles_case_insensitivity + FakeWeb.register_uri(:get, %r|http://user:pass@mock/example\.\w+|i, :body => "example") + assert FakeWeb.registered_uri?(:get, 'http://uSeR:PAss@mock/example.txt') + end + + def test_request_with_authentication_and_pattern_handles_case_insensitivity + FakeWeb.register_uri(:get, %r|http://user:pass@mock/example\.\w+|i, :body => "example") + http = Net::HTTP.new('mock', 80) + req = Net::HTTP::Get.new('/example.txt') + req.basic_auth 'uSeR', 'PAss' + assert_equal "example", http.request(req).body + end + + def test_requesting_a_uri_that_matches_two_registered_regexes_raises_an_error + FakeWeb.register_uri(:get, %r|http://example\.com/|, :body => "first") + FakeWeb.register_uri(:get, %r|http://example\.com/a|, :body => "second") + assert_raise FakeWeb::MultipleMatchingURIsError do + Net::HTTP.start("example.com") { |query| query.get('/a') } + end + end + + def test_requesting_a_uri_that_matches_two_registered_regexes_raises_an_error_including_request_info + FakeWeb.register_uri(:get, %r|http://example\.com/|, :body => "first") + FakeWeb.register_uri(:get, %r|http://example\.com/a|, :body => "second") + begin + Net::HTTP.start("example.com") { |query| query.get('/a') } + rescue FakeWeb::MultipleMatchingURIsError => exception + end + assert exception.message.include?("GET http://example.com/a") + end + + def test_registry_does_not_find_using_mismatched_protocols_or_ports_when_registered_with_both + FakeWeb.register_uri(:get, %r|http://www.example.com:80|, :body => "example") + assert !FakeWeb.registered_uri?(:get, "https://www.example.com:80") + assert !FakeWeb.registered_uri?(:get, "http://www.example.com:443") + end + + def test_registry_finds_using_non_default_port + FakeWeb.register_uri(:get, %r|example\.com:8080|, :body => "example") + assert FakeWeb.registered_uri?(:get, "http://www.example.com:8080/path") + assert FakeWeb.registered_uri?(:get, "https://www.example.com:8080/path") + end + + def test_registry_finds_using_default_port_and_http_when_registered_with_explicit_port_80 + FakeWeb.register_uri(:get, %r|example\.com:80|, :body => "example") + assert FakeWeb.registered_uri?(:get, "http://www.example.com/path") + + # check other permutations, too + assert FakeWeb.registered_uri?(:get, "http://www.example.com:80/path") + assert FakeWeb.registered_uri?(:get, "http://www.example.com:8080/path") + assert FakeWeb.registered_uri?(:get, "https://www.example.com:80/path") + assert FakeWeb.registered_uri?(:get, "https://www.example.com:8080/path") + assert !FakeWeb.registered_uri?(:get, "https://www.example.com/path") + end + + def test_registry_finds_using_default_port_and_https_when_registered_with_explicit_port_443 + FakeWeb.register_uri(:get, %r|example\.com:443|, :body => "example") + assert FakeWeb.registered_uri?(:get, "https://www.example.com/path") + + # check other permutations, too + assert FakeWeb.registered_uri?(:get, "https://www.example.com:443/path") + assert FakeWeb.registered_uri?(:get, "https://www.example.com:44321/path") + assert FakeWeb.registered_uri?(:get, "http://www.example.com:443/path") + assert FakeWeb.registered_uri?(:get, "http://www.example.com:44321/path") + assert !FakeWeb.registered_uri?(:get, "http://www.example.com/path") + end + + def test_registry_only_finds_using_default_port_when_registered_without_if_protocol_matches + FakeWeb.register_uri(:get, %r|http://www.example.com/test|, :body => "example") + assert FakeWeb.registered_uri?(:get, "http://www.example.com:80/test") + assert !FakeWeb.registered_uri?(:get, "http://www.example.com:443/test") + assert !FakeWeb.registered_uri?(:get, "https://www.example.com:443/test") + FakeWeb.register_uri(:get, %r|https://www.example.org/test|, :body => "example") + assert FakeWeb.registered_uri?(:get, "https://www.example.org:443/test") + assert !FakeWeb.registered_uri?(:get, "https://www.example.org:80/test") + assert !FakeWeb.registered_uri?(:get, "http://www.example.org:80/test") + end + + def test_registry_matches_using_mismatched_port_when_registered_without + FakeWeb.register_uri(:get, %r|http://www.example.com|, :body => "example") + assert FakeWeb.registered_uri?(:get, "http://www.example.com:80") + assert FakeWeb.registered_uri?(:get, "http://www.example.com:443") + assert FakeWeb.registered_uri?(:get, "http://www.example.com:12345") + assert !FakeWeb.registered_uri?(:get, "https://www.example.com:443") + assert !FakeWeb.registered_uri?(:get, "https://www.example.com") + end + + def test_registry_matches_using_default_port_for_protocol_when_registered_without_protocol_or_port + FakeWeb.register_uri(:get, %r|www.example.com/home|, :body => "example") + assert FakeWeb.registered_uri?(:get, "http://www.example.com/home") + assert FakeWeb.registered_uri?(:get, "https://www.example.com/home") + assert FakeWeb.registered_uri?(:get, "http://www.example.com:80/home") + assert FakeWeb.registered_uri?(:get, "https://www.example.com:443/home") + assert !FakeWeb.registered_uri?(:get, "https://www.example.com:80/home") + assert !FakeWeb.registered_uri?(:get, "http://www.example.com:443/home") + end + + def test_registry_matches_with_query_params + FakeWeb.register_uri(:get, %r[example.com/list\?(.*&|)important=1], :body => "example") + assert FakeWeb.registered_uri?(:get, "http://example.com/list?hash=123&important=1&unimportant=2") + assert FakeWeb.registered_uri?(:get, "http://example.com/list?hash=123&important=12&unimportant=2") + assert FakeWeb.registered_uri?(:get, "http://example.com/list?important=1&unimportant=2") + assert !FakeWeb.registered_uri?(:get, "http://example.com/list?important=2") + assert !FakeWeb.registered_uri?(:get, "http://example.com/list?important=2&unimportant=1") + assert !FakeWeb.registered_uri?(:get, "http://example.com/list?hash=123&important=2&unimportant=1") + assert !FakeWeb.registered_uri?(:get, "http://example.com/list?notimportant=1&unimportant=1") + end + + def test_registry_does_not_match_when_regex_has_unsorted_query_params + FakeWeb.register_uri(:get, %r[example\.com/list\?b=2&a=1], :body => "example") + assert !FakeWeb.registered_uri?(:get, "http://example.com/list?b=2&a=1") + assert !FakeWeb.registered_uri?(:get, "http://example.com/list?a=1&b=2") + assert !FakeWeb.registered_uri?(:get, "https://example.com:443/list?b=2&a=1") + end + + def test_registry_matches_when_regex_has_sorted_query_params + FakeWeb.register_uri(:get, %r[example\.com/list\?a=1&b=2], :body => "example") + assert FakeWeb.registered_uri?(:get, "http://example.com/list?b=2&a=1") + assert FakeWeb.registered_uri?(:get, "http://example.com/list?a=1&b=2") + assert FakeWeb.registered_uri?(:get, "https://example.com:443/list?b=2&a=1") + end + + def test_registry_matches_quickly_with_lots_of_query_params + # regression test for code that tried to calculate the permutations of the + # query params, which hangs with a large number of params + FakeWeb.register_uri(:get, %r[example.com], :body => "example") + Timeout::timeout(1) do + FakeWeb.registered_uri?(:get, "http://example.com/?a=1&b=2&c=3&d=4&e=5&f=6&g=7&h=8") + end + end + +end diff --git a/vendor/gems/fakeweb-1.3.0/test/test_response_headers.rb b/vendor/gems/fakeweb-1.3.0/test/test_response_headers.rb new file mode 100644 index 000000000..45f3f5a99 --- /dev/null +++ b/vendor/gems/fakeweb-1.3.0/test/test_response_headers.rb @@ -0,0 +1,79 @@ +require 'test_helper' + +class TestResponseHeaders < Test::Unit::TestCase + def test_content_type_when_registering_with_string_and_content_type_header_as_symbol_option + FakeWeb.register_uri(:get, "http://example.com/users.json", :body => '[{"username": "chrisk"}]', :content_type => "application/json") + response = Net::HTTP.start("example.com") { |query| query.get("/users.json") } + assert_equal '[{"username": "chrisk"}]', response.body + assert_equal "application/json", response['Content-Type'] + end + + def test_content_type_when_registering_with_string_and_content_type_header_as_string_option + FakeWeb.register_uri(:get, "http://example.com/users.json", :body => '[{"username": "chrisk"}]', 'Content-Type' => "application/json") + response = Net::HTTP.start("example.com") { |query| query.get("/users.json") } + assert_equal "application/json", response['Content-Type'] + end + + def test_content_type_when_registering_with_string_only + FakeWeb.register_uri(:get, "http://example.com/users.json", :body => '[{"username": "chrisk"}]') + response = Net::HTTP.start("example.com") { |query| query.get("/users.json") } + assert_equal '[{"username": "chrisk"}]', response.body + assert_nil response['Content-Type'] + end + + def test_cookies_when_registering_with_file_and_set_cookie_header + FakeWeb.register_uri(:get, "http://example.com/", :body => fixture_path("test_example.txt"), + :set_cookie => "user_id=1; example=yes") + response = Net::HTTP.start("example.com") { |query| query.get("/") } + assert_equal "test example content", response.body + assert_equal "user_id=1; example=yes", response['Set-Cookie'] + end + + def test_multiple_set_cookie_headers + FakeWeb.register_uri(:get, "http://example.com", :set_cookie => ["user_id=1", "example=yes"]) + response = Net::HTTP.start("example.com") { |query| query.get("/") } + assert_equal ["user_id=1", "example=yes"], response.get_fields('Set-Cookie') + assert_equal "user_id=1, example=yes", response['Set-Cookie'] + end + + def test_registering_with_baked_response_ignores_header_options + fake_response = Net::HTTPOK.new('1.1', '200', 'OK') + fake_response["Server"] = "Apache/1.3.27 (Unix)" + FakeWeb.register_uri(:get, "http://example.com/", :response => fake_response, + :server => "FakeWeb/1.2.3 (Ruby)") + response = Net::HTTP.start("example.com") { |query| query.get("/") } + assert_equal "200", response.code + assert_equal "OK", response.message + assert_equal "Apache/1.3.27 (Unix)", response["Server"] + end + + def test_headers_are_rotated_when_registering_with_response_rotation + FakeWeb.register_uri(:get, "http://example.com", + [{:body => 'test1', :expires => "Thu, 14 Jun 2009 16:00:00 GMT", + :content_type => "text/plain"}, + {:body => 'test2', :expires => "Thu, 14 Jun 2009 16:00:01 GMT"}]) + + first_response = second_response = nil + Net::HTTP.start("example.com") do |query| + first_response = query.get("/") + second_response = query.get("/") + end + assert_equal 'test1', first_response.body + assert_equal "Thu, 14 Jun 2009 16:00:00 GMT", first_response['Expires'] + assert_equal "text/plain", first_response['Content-Type'] + assert_equal 'test2', second_response.body + assert_equal "Thu, 14 Jun 2009 16:00:01 GMT", second_response['Expires'] + assert_nil second_response['Content-Type'] + end + + def test_registering_with_status_option_and_response_headers + FakeWeb.register_uri(:get, "http://example.com", :status => ["301", "Moved Permanently"], + :location => "http://www.example.com") + + response = Net::HTTP.start("example.com") { |query| query.get("/") } + assert_equal "301", response.code + assert_equal "Moved Permanently", response.message + assert_equal "http://www.example.com", response["Location"] + end + +end diff --git a/vendor/gems/fakeweb-1.3.0/test/test_trailing_slashes.rb b/vendor/gems/fakeweb-1.3.0/test/test_trailing_slashes.rb new file mode 100644 index 000000000..564d807dc --- /dev/null +++ b/vendor/gems/fakeweb-1.3.0/test/test_trailing_slashes.rb @@ -0,0 +1,53 @@ +require 'test_helper' + +class TestFakeWebTrailingSlashes < Test::Unit::TestCase + + def test_registering_root_without_slash_and_ask_predicate_method_with_slash + FakeWeb.register_uri(:get, "http://www.example.com", :body => "root") + assert FakeWeb.registered_uri?(:get, "http://www.example.com/") + end + + def test_registering_root_without_slash_and_request + FakeWeb.register_uri(:get, "http://www.example.com", :body => "root") + response = Net::HTTP.start("www.example.com") { |query| query.get('/') } + assert_equal "root", response.body + end + + def test_registering_root_with_slash_and_ask_predicate_method_without_slash + FakeWeb.register_uri(:get, "http://www.example.com/", :body => "root") + assert FakeWeb.registered_uri?(:get, "http://www.example.com") + end + + def test_registering_root_with_slash_and_request + FakeWeb.register_uri(:get, "http://www.example.com/", :body => "root") + response = Net::HTTP.start("www.example.com") { |query| query.get('/') } + assert_equal "root", response.body + end + + def test_registering_path_without_slash_and_ask_predicate_method_with_slash + FakeWeb.register_uri(:get, "http://www.example.com/users", :body => "User list") + assert !FakeWeb.registered_uri?(:get, "http://www.example.com/users/") + end + + def test_registering_path_without_slash_and_request_with_slash + FakeWeb.allow_net_connect = false + FakeWeb.register_uri(:get, "http://www.example.com/users", :body => "User list") + assert_raise FakeWeb::NetConnectNotAllowedError do + response = Net::HTTP.start("www.example.com") { |query| query.get('/users/') } + end + end + + def test_registering_path_with_slash_and_ask_predicate_method_without_slash + FakeWeb.register_uri(:get, "http://www.example.com/users/", :body => "User list") + assert !FakeWeb.registered_uri?(:get, "http://www.example.com/users") + end + + def test_registering_path_with_slash_and_request_without_slash + FakeWeb.allow_net_connect = false + FakeWeb.register_uri(:get, "http://www.example.com/users/", :body => "User list") + assert_raise FakeWeb::NetConnectNotAllowedError do + response = Net::HTTP.start("www.example.com") { |query| query.get('/users') } + end + end + +end diff --git a/vendor/gems/fakeweb-1.3.0/test/test_utility.rb b/vendor/gems/fakeweb-1.3.0/test/test_utility.rb new file mode 100644 index 000000000..891de875b --- /dev/null +++ b/vendor/gems/fakeweb-1.3.0/test/test_utility.rb @@ -0,0 +1,83 @@ +require 'test_helper' + +class TestUtility < Test::Unit::TestCase + + def test_decode_userinfo_from_header_handles_basic_auth + authorization_header = "Basic dXNlcm5hbWU6c2VjcmV0" + userinfo = FakeWeb::Utility.decode_userinfo_from_header(authorization_header) + assert_equal "username:secret", userinfo + end + + def test_encode_unsafe_chars_in_userinfo_does_not_encode_userinfo_safe_punctuation + userinfo = "user;&=+$,:secret" + assert_equal userinfo, FakeWeb::Utility.encode_unsafe_chars_in_userinfo(userinfo) + end + + def test_encode_unsafe_chars_in_userinfo_does_not_encode_rfc_3986_unreserved_characters + userinfo = "-_.!~*'()abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789:secret" + assert_equal userinfo, FakeWeb::Utility.encode_unsafe_chars_in_userinfo(userinfo) + end + + def test_encode_unsafe_chars_in_userinfo_does_encode_other_characters + userinfo, safe_userinfo = 'us#rn@me:sec//ret?"', 'us%23rn%40me:sec%2F%2Fret%3F%22' + assert_equal safe_userinfo, FakeWeb::Utility.encode_unsafe_chars_in_userinfo(userinfo) + end + + def test_strip_default_port_from_uri_strips_80_from_http_with_path + uri = "http://example.com:80/foo/bar" + stripped_uri = FakeWeb::Utility.strip_default_port_from_uri(uri) + assert_equal "http://example.com/foo/bar", stripped_uri + end + + def test_strip_default_port_from_uri_strips_80_from_http_without_path + uri = "http://example.com:80" + stripped_uri = FakeWeb::Utility.strip_default_port_from_uri(uri) + assert_equal "http://example.com", stripped_uri + end + + def test_strip_default_port_from_uri_strips_443_from_https_without_path + uri = "https://example.com:443" + stripped_uri = FakeWeb::Utility.strip_default_port_from_uri(uri) + assert_equal "https://example.com", stripped_uri + end + + def test_strip_default_port_from_uri_strips_443_from_https + uri = "https://example.com:443/foo/bar" + stripped_uri = FakeWeb::Utility.strip_default_port_from_uri(uri) + assert_equal "https://example.com/foo/bar", stripped_uri + end + + def test_strip_default_port_from_uri_does_not_strip_8080_from_http + uri = "http://example.com:8080/foo/bar" + assert_equal uri, FakeWeb::Utility.strip_default_port_from_uri(uri) + end + + def test_strip_default_port_from_uri_does_not_strip_443_from_http + uri = "http://example.com:443/foo/bar" + assert_equal uri, FakeWeb::Utility.strip_default_port_from_uri(uri) + end + + def test_strip_default_port_from_uri_does_not_strip_80_from_query_string + uri = "http://example.com/?a=:80&b=c" + assert_equal uri, FakeWeb::Utility.strip_default_port_from_uri(uri) + end + + def test_strip_default_port_from_uri_does_not_modify_strings_that_do_not_start_with_http_or_https + uri = "httpz://example.com:80/" + assert_equal uri, FakeWeb::Utility.strip_default_port_from_uri(uri) + end + + def test_request_uri_as_string + http = Net::HTTP.new("www.example.com", 80) + request = Net::HTTP::Get.new("/index.html") + expected = "http://www.example.com:80/index.html" + assert_equal expected, FakeWeb::Utility.request_uri_as_string(http, request) + end + + def test_uri_escape_delegates_to_uri_parser_when_available + parsing_object = URI.const_defined?(:Parser) ? URI::Parser.any_instance : URI + parsing_object.expects(:escape).with("string", /unsafe/).returns("escaped") + assert_equal "escaped", FakeWeb::Utility.uri_escape("string", /unsafe/) + end + +end diff --git a/vendor/gems/fakeweb-1.3.0/test/vendor/right_http_connection-1.2.4/History.txt b/vendor/gems/fakeweb-1.3.0/test/vendor/right_http_connection-1.2.4/History.txt new file mode 100644 index 000000000..e06bcd0a2 --- /dev/null +++ b/vendor/gems/fakeweb-1.3.0/test/vendor/right_http_connection-1.2.4/History.txt @@ -0,0 +1,59 @@ +== 0.0.1 2007-05-15 +* 1 major enhancement: + * Initial release + +== 0.1.2 2007-06-27 + +* No major changes. + +== 0.1.3 2007-07-09 + +* No change. + +== 0.1.4 2007-08-10 + +* r1442, todd, 2007-08-07 15:45:24 + * # 373, Add support in right_http_connection for bailing out to a block while + reading the HTTP response (to support GET streaming...) + +* r1411, todd, 2007-08-03 15:14:45 + * # 373, Stream uploads (PUTs) if the source is a file, stream, or anything + read()-able + +== 1.1.0 2007-08-15 +Initial public release + +== 1.2.0 2007-10-05 + +* r1867, konstantin, 2007-10-05 06:19:45 + * # 220, (re)open connection to server if none exists or connection params + have changed + +== 1.2.1 + +* r2648, konstantin, 01-24-08 11:12:00 + * net_fix.rb moved from right_aws gem to fix the problem with uploading the streamable + objects to S3 + +* r2764, konstantin, 02-08-08 00:05:00 +03:00 + * "RightAws: incompatible Net::HTTP monkey-patch" exception is raised if our net_fix + patch was overriden (by attachment_fu for example, to avoid this load attachment_fu + before loading the right_http_connection gem). + +== 1.2.2 + +* r3524, konstantin, 2008-04-17 11:35:42 +0400 + * Fixed a problem with incorrect error handling (connection retries always failed). + +== 1.2.3 + +- Added support for setting retry & timeout parameters in the constructor +- Improve handling of data streams during upload: if there is a failure and a retry, reset + the seek pointer for the subsequent re-request + +== 1.2.4 + +* r4984, konstantin, 2008-08-11 14:49:18 +0400 + * fixed a bug: <NoMethodError: You have a nil object when you didn't expect it! + The error occurred while evaluating nil.body_stream> + diff --git a/vendor/gems/fakeweb-1.3.0/test/vendor/right_http_connection-1.2.4/Manifest.txt b/vendor/gems/fakeweb-1.3.0/test/vendor/right_http_connection-1.2.4/Manifest.txt new file mode 100644 index 000000000..20f193b21 --- /dev/null +++ b/vendor/gems/fakeweb-1.3.0/test/vendor/right_http_connection-1.2.4/Manifest.txt @@ -0,0 +1,7 @@ +History.txt +Manifest.txt +README.txt +Rakefile +lib/net_fix.rb +lib/right_http_connection.rb +setup.rb diff --git a/vendor/gems/fakeweb-1.3.0/test/vendor/right_http_connection-1.2.4/README.txt b/vendor/gems/fakeweb-1.3.0/test/vendor/right_http_connection-1.2.4/README.txt new file mode 100644 index 000000000..46c97e57a --- /dev/null +++ b/vendor/gems/fakeweb-1.3.0/test/vendor/right_http_connection-1.2.4/README.txt @@ -0,0 +1,54 @@ +RightScale::HttpConnection + by RightScale, Inc. + www.RightScale.com + +== DESCRIPTION: + +Rightscale::HttpConnection is a robust HTTP/S library. It implements a retry +algorithm for low-level network errors. + +== FEATURES: + +- provides put/get streaming +- does configurable retries on connect and read timeouts, DNS failures, etc. +- HTTPS certificate checking + +== SYNOPSIS: + + +== REQUIREMENTS: + +- 2/11/08: If you use RightScale::HttpConnection in conjunction with attachment_fu, the + HttpConnection gem must be included (using the require statement) AFTER + attachment_fu. + This is due to a conflict between the HttpConnection gem and another + gem required by attachment_fu. + + + +== INSTALL: + +sudo gem install right_http_connection + +== LICENSE: + +Copyright (c) 2007-2008 RightScale, Inc. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/gems/fakeweb-1.3.0/test/vendor/right_http_connection-1.2.4/Rakefile b/vendor/gems/fakeweb-1.3.0/test/vendor/right_http_connection-1.2.4/Rakefile new file mode 100644 index 000000000..0ae50977c --- /dev/null +++ b/vendor/gems/fakeweb-1.3.0/test/vendor/right_http_connection-1.2.4/Rakefile @@ -0,0 +1,103 @@ +require 'rubygems' +require 'rake' +require 'rake/clean' +require 'rake/testtask' +require 'rake/packagetask' +require 'rake/gempackagetask' +require 'rake/rdoctask' +require 'rake/contrib/rubyforgepublisher' +require 'fileutils' +require 'hoe' +include FileUtils +require File.join(File.dirname(__FILE__), 'lib', 'right_http_connection') + +AUTHOR = 'RightScale' # can also be an array of Authors +EMAIL = "rubygems@rightscale.com" +DESCRIPTION = "RightScale's robust HTTP/S connection module" +GEM_NAME = 'right_http_connection' # what ppl will type to install your gem +RUBYFORGE_PROJECT = 'rightscale' # The unix name for your project +HOMEPATH = "http://#{RUBYFORGE_PROJECT}.rubyforge.org" +DOWNLOAD_PATH = "http://rubyforge.org/projects/#{RUBYFORGE_PROJECT}" + +NAME = "right_http_connection" +REV = nil # UNCOMMENT IF REQUIRED: File.read(".svn/entries")[/committed-rev="(d+)"/, 1] rescue nil +VERS = RightHttpConnection::VERSION::STRING + (REV ? ".#{REV}" : "") +CLEAN.include ['**/.*.sw?', '*.gem', '.config', '**/.DS_Store'] +RDOC_OPTS = ['--quiet', '--title', 'right_http_connection documentation', + "--opname", "index.html", + "--line-numbers", + "--main", "README", + "--inline-source"] + +# Suppress Hoe's self-inclusion as a dependency for our Gem. This also keeps +# Rake & rubyforge out of the dependency list. Users must manually install +# these gems to run tests, etc. +# TRB 2/19/09: also do this for the extra_dev_deps array present in newer hoes. +# Older versions of RubyGems will try to install developer-dependencies as +# required runtime dependencies.... +class Hoe + def extra_deps + @extra_deps.reject do |x| + Array(x).first == 'hoe' + end + end + def extra_dev_deps + @extra_dev_deps.reject do |x| + Array(x).first == 'hoe' + end + end +end + +# Generate all the Rake tasks +# Run 'rake -T' to see list of generated tasks (from gem root directory) +hoe = Hoe.new(GEM_NAME, VERS) do |p| + p.author = AUTHOR + p.description = DESCRIPTION + p.email = EMAIL + p.summary = DESCRIPTION + p.url = HOMEPATH + p.rubyforge_name = RUBYFORGE_PROJECT if RUBYFORGE_PROJECT + p.test_globs = ["test/**/test_*.rb"] + p.clean_globs = CLEAN #An array of file patterns to delete on clean. + p.remote_rdoc_dir = "right_http_gem_doc" + + # == Optional + p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n") + #p.extra_deps = [] # An array of rubygem dependencies [name, version], e.g. [ ['active_support', '>= 1.3.1'] ] + #p.spec_extras = {} # A hash of extra values to set in the gemspec. +end + + +desc 'Generate website files' +task :website_generate do + Dir['website/**/*.txt'].each do |txt| + sh %{ ruby scripts/txt2html #{txt} > #{txt.gsub(/txt$/,'html')} } + end +end + +desc 'Upload website files to rubyforge' +task :website_upload do + config = YAML.load(File.read(File.expand_path("~/.rubyforge/user-config.yml"))) + host = "#{config["username"]}@rubyforge.org" + remote_dir = "/var/www/gforge-projects/#{RUBYFORGE_PROJECT}/" + # remote_dir = "/var/www/gforge-projects/#{RUBYFORGE_PROJECT}/#{GEM_NAME}" + local_dir = 'website' + sh %{rsync -av #{local_dir}/ #{host}:#{remote_dir}} +end + +desc 'Generate and upload website files' +task :website => [:website_generate, :website_upload] + +desc 'Release the website and new gem version' +task :deploy => [:check_version, :website, :release] + +task :check_version do + unless ENV['VERSION'] + puts 'Must pass a VERSION=x.y.z release version' + exit + end + unless ENV['VERSION'] == VERS + puts "Please update your version.rb to match the release version, currently #{VERS}" + exit + end +end diff --git a/vendor/gems/fakeweb-1.3.0/test/vendor/right_http_connection-1.2.4/lib/net_fix.rb b/vendor/gems/fakeweb-1.3.0/test/vendor/right_http_connection-1.2.4/lib/net_fix.rb new file mode 100644 index 000000000..ad54f8a2a --- /dev/null +++ b/vendor/gems/fakeweb-1.3.0/test/vendor/right_http_connection-1.2.4/lib/net_fix.rb @@ -0,0 +1,160 @@ +# +# Copyright (c) 2008 RightScale Inc +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# + +# Net::HTTP and Net::HTTPGenericRequest fixes to support 100-continue on +# POST and PUT. The request must have 'expect' field set to '100-continue'. + + +module Net + + class BufferedIO #:nodoc: + # Monkey-patch Net::BufferedIO to read > 1024 bytes from the socket at a time + + # Default size (in bytes) of the max read from a socket into the user space read buffers for socket IO + DEFAULT_SOCKET_READ_SIZE = 16*1024 + + @@socket_read_size = DEFAULT_SOCKET_READ_SIZE + + def self.socket_read_size=(readsize) + if(readsize <= 0) + return + end + @@socket_read_size = readsize + end + + def self.socket_read_size?() + @@socket_read_size + end + + def rbuf_fill + timeout(@read_timeout) { + @rbuf << @io.sysread(@@socket_read_size) + } + end + end + + + #-- Net::HTTPGenericRequest -- + + class HTTPGenericRequest + # Monkey-patch Net::HTTPGenericRequest to read > 1024 bytes from the local data + # source at a time (used in streaming PUTs) + + # Default size (in bytes) of the max read from a local source (File, String, + # etc.) to the user space write buffers for socket IO. + DEFAULT_LOCAL_READ_SIZE = 16*1024 + + @@local_read_size = DEFAULT_LOCAL_READ_SIZE + + def self.local_read_size=(readsize) + if(readsize <= 0) + return + end + @@local_read_size = readsize + end + + def self.local_read_size?() + @@local_read_size + end + + def exec(sock, ver, path, send_only=nil) #:nodoc: internal use only + if @body + send_request_with_body sock, ver, path, @body, send_only + elsif @body_stream + send_request_with_body_stream sock, ver, path, @body_stream, send_only + else + write_header(sock, ver, path) + end + end + + private + + def send_request_with_body(sock, ver, path, body, send_only=nil) + self.content_length = body.length + delete 'Transfer-Encoding' + supply_default_content_type + write_header(sock, ver, path) unless send_only == :body + sock.write(body) unless send_only == :header + end + + def send_request_with_body_stream(sock, ver, path, f, send_only=nil) + unless content_length() or chunked? + raise ArgumentError, + "Content-Length not given and Transfer-Encoding is not `chunked'" + end + supply_default_content_type + write_header(sock, ver, path) unless send_only == :body + unless send_only == :header + if chunked? + while s = f.read(@@local_read_size) + sock.write(sprintf("%x\r\n", s.length) << s << "\r\n") + end + sock.write "0\r\n\r\n" + else + while s = f.read(@@local_read_size) + sock.write s + end + end + end + end + end + + + #-- Net::HTTP -- + + class HTTP + def request(req, body = nil, &block) # :yield: +response+ + unless started? + start { + req['connection'] ||= 'close' + return request(req, body, &block) + } + end + if proxy_user() + unless use_ssl? + req.proxy_basic_auth proxy_user(), proxy_pass() + end + end + # set body + req.set_body_internal body + begin_transport req + # if we expect 100-continue then send a header first + send_only = ((req.is_a?(Post)||req.is_a?(Put)) && (req['expect']=='100-continue')) ? :header : nil + req.exec @socket, @curr_http_version, edit_path(req.path), send_only + begin + res = HTTPResponse.read_new(@socket) + # if we expected 100-continue then send a body + if res.is_a?(HTTPContinue) && send_only && req['content-length'].to_i > 0 + req.exec @socket, @curr_http_version, edit_path(req.path), :body + end + end while res.kind_of?(HTTPContinue) + res.reading_body(@socket, req.response_body_permitted?) { + yield res if block_given? + } + end_transport req, res + res + end + end + +end diff --git a/vendor/gems/fakeweb-1.3.0/test/vendor/right_http_connection-1.2.4/lib/right_http_connection.rb b/vendor/gems/fakeweb-1.3.0/test/vendor/right_http_connection-1.2.4/lib/right_http_connection.rb new file mode 100644 index 000000000..0151ae685 --- /dev/null +++ b/vendor/gems/fakeweb-1.3.0/test/vendor/right_http_connection-1.2.4/lib/right_http_connection.rb @@ -0,0 +1,435 @@ +# +# Copyright (c) 2007-2008 RightScale Inc +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +require "net/https" +require "uri" +require "time" +require "logger" + +$:.unshift(File.dirname(__FILE__)) +require "net_fix" + + +module RightHttpConnection #:nodoc: + module VERSION #:nodoc: + MAJOR = 1 + MINOR = 2 + TINY = 4 + + STRING = [MAJOR, MINOR, TINY].join('.') + end +end + + +module Rightscale + +=begin rdoc +HttpConnection maintains a persistent HTTP connection to a remote +server. Each instance maintains its own unique connection to the +HTTP server. HttpConnection makes a best effort to receive a proper +HTTP response from the server, although it does not guarantee that +this response contains a HTTP Success code. + +On low-level errors (TCP/IP errors) HttpConnection invokes a reconnect +and retry algorithm. Note that although each HttpConnection object +has its own connection to the HTTP server, error handling is shared +across all connections to a server. For example, if there are three +connections to www.somehttpserver.com, a timeout error on one of those +connections will cause all three connections to break and reconnect. +A connection will not break and reconnect, however, unless a request +becomes active on it within a certain amount of time after the error +(as specified by HTTP_CONNECTION_RETRY_DELAY). An idle connection will not +break even if other connections to the same server experience errors. + +A HttpConnection will retry a request a certain number of times (as +defined by HTTP_CONNNECTION_RETRY_COUNT). If all the retries fail, +an exception is thrown and all HttpConnections associated with a +server enter a probationary period defined by HTTP_CONNECTION_RETRY_DELAY. +If the user makes a new request subsequent to entering probation, +the request will fail immediately with the same exception thrown +on probation entry. This is so that if the HTTP server has gone +down, not every subsequent request must wait for a connect timeout +before failing. After the probation period expires, the internal +state of the HttpConnection is reset and subsequent requests have +the full number of potential reconnects and retries available to +them. +=end + + class HttpConnection + + # Number of times to retry the request after encountering the first error + HTTP_CONNECTION_RETRY_COUNT = 3 + # Throw a Timeout::Error if a connection isn't established within this number of seconds + HTTP_CONNECTION_OPEN_TIMEOUT = 5 + # Throw a Timeout::Error if no data have been read on this connnection within this number of seconds + HTTP_CONNECTION_READ_TIMEOUT = 120 + # Length of the post-error probationary period during which all requests will fail + HTTP_CONNECTION_RETRY_DELAY = 15 + + #-------------------- + # class methods + #-------------------- + # + @@params = {} + @@params[:http_connection_retry_count] = HTTP_CONNECTION_RETRY_COUNT + @@params[:http_connection_open_timeout] = HTTP_CONNECTION_OPEN_TIMEOUT + @@params[:http_connection_read_timeout] = HTTP_CONNECTION_READ_TIMEOUT + @@params[:http_connection_retry_delay] = HTTP_CONNECTION_RETRY_DELAY + + # Query the global (class-level) parameters: + # + # :user_agent => 'www.HostName.com' # String to report as HTTP User agent + # :ca_file => 'path_to_file' # Path to a CA certification file in PEM format. The file can contain several CA certificates. If this parameter isn't set, HTTPS certs won't be verified. + # :logger => Logger object # If omitted, HttpConnection logs to STDOUT + # :exception => Exception to raise # The type of exception to raise + # # if a request repeatedly fails. RuntimeError is raised if this parameter is omitted. + # :http_connection_retry_count # by default == Rightscale::HttpConnection::HTTP_CONNECTION_RETRY_COUNT + # :http_connection_open_timeout # by default == Rightscale::HttpConnection::HTTP_CONNECTION_OPEN_TIMEOUT + # :http_connection_read_timeout # by default == Rightscale::HttpConnection::HTTP_CONNECTION_READ_TIMEOUT + # :http_connection_retry_delay # by default == Rightscale::HttpConnection::HTTP_CONNECTION_RETRY_DELAY + def self.params + @@params + end + + # Set the global (class-level) parameters + def self.params=(params) + @@params = params + end + + #------------------ + # instance methods + #------------------ + attr_accessor :http + attr_accessor :server + attr_accessor :params # see @@params + attr_accessor :logger + + # Params hash: + # :user_agent => 'www.HostName.com' # String to report as HTTP User agent + # :ca_file => 'path_to_file' # A path of a CA certification file in PEM format. The file can contain several CA certificates. + # :logger => Logger object # If omitted, HttpConnection logs to STDOUT + # :exception => Exception to raise # The type of exception to raise if a request repeatedly fails. RuntimeError is raised if this parameter is omitted. + # :http_connection_retry_count # by default == Rightscale::HttpConnection.params[:http_connection_retry_count] + # :http_connection_open_timeout # by default == Rightscale::HttpConnection.params[:http_connection_open_timeout] + # :http_connection_read_timeout # by default == Rightscale::HttpConnection.params[:http_connection_read_timeout] + # :http_connection_retry_delay # by default == Rightscale::HttpConnection.params[:http_connection_retry_delay] + # + def initialize(params={}) + @params = params + @params[:http_connection_retry_count] ||= @@params[:http_connection_retry_count] + @params[:http_connection_open_timeout] ||= @@params[:http_connection_open_timeout] + @params[:http_connection_read_timeout] ||= @@params[:http_connection_read_timeout] + @params[:http_connection_retry_delay] ||= @@params[:http_connection_retry_delay] + @http = nil + @server = nil + @logger = get_param(:logger) || + (RAILS_DEFAULT_LOGGER if defined?(RAILS_DEFAULT_LOGGER)) || + Logger.new(STDOUT) + end + + def get_param(name) + @params[name] || @@params[name] + end + + # Query for the maximum size (in bytes) of a single read from the underlying + # socket. For bulk transfer, especially over fast links, this is value is + # critical to performance. + def socket_read_size? + Net::BufferedIO.socket_read_size? + end + + # Set the maximum size (in bytes) of a single read from the underlying + # socket. For bulk transfer, especially over fast links, this is value is + # critical to performance. + def socket_read_size=(newsize) + Net::BufferedIO.socket_read_size=(newsize) + end + + # Query for the maximum size (in bytes) of a single read from local data + # sources like files. This is important, for example, in a streaming PUT of a + # large buffer. + def local_read_size? + Net::HTTPGenericRequest.local_read_size? + end + + # Set the maximum size (in bytes) of a single read from local data + # sources like files. This can be used to tune the performance of, for example, a streaming PUT of a + # large buffer. + def local_read_size=(newsize) + Net::HTTPGenericRequest.local_read_size=(newsize) + end + + private + #-------------- + # Retry state - Keep track of errors on a per-server basis + #-------------- + @@state = {} # retry state indexed by server: consecutive error count, error time, and error + @@eof = {} + + # number of consecutive errors seen for server, 0 all is ok + def error_count + @@state[@server] ? @@state[@server][:count] : 0 + end + + # time of last error for server, nil if all is ok + def error_time + @@state[@server] && @@state[@server][:time] + end + + # message for last error for server, "" if all is ok + def error_message + @@state[@server] ? @@state[@server][:message] : "" + end + + # add an error for a server + def error_add(message) + @@state[@server] = { :count => error_count+1, :time => Time.now, :message => message } + end + + # reset the error state for a server (i.e. a request succeeded) + def error_reset + @@state.delete(@server) + end + + # Error message stuff... + def banana_message + return "#{@server} temporarily unavailable: (#{error_message})" + end + + def err_header + return "#{self.class.name} :" + end + + # Adds new EOF timestamp. + # Returns the number of seconds to wait before new conection retry: + # 0.5, 1, 2, 4, 8 + def add_eof + (@@eof[@server] ||= []).unshift Time.now + 0.25 * 2 ** @@eof[@server].size + end + + # Returns first EOF timestamp or nul if have no EOFs being tracked. + def eof_time + @@eof[@server] && @@eof[@server].last + end + + # Returns true if we are receiving EOFs during last @params[:http_connection_retry_delay] seconds + # and there were no successful response from server + def raise_on_eof_exception? + @@eof[@server].blank? ? false : ( (Time.now.to_i-@params[:http_connection_retry_delay]) > @@eof[@server].last.to_i ) + end + + # Reset a list of EOFs for this server. + # This is being called when we have got an successful response from server. + def eof_reset + @@eof.delete(@server) + end + + # Detects if an object is 'streamable' - can we read from it, and can we know the size? + def setup_streaming(request) + if(request.body && request.body.respond_to?(:read)) + body = request.body + request.content_length = body.respond_to?(:lstat) ? body.lstat.size : body.size + request.body_stream = request.body + true + end + end + + def get_fileptr_offset(request_params) + request_params[:request].body.pos + rescue Exception => e + # Probably caught this because the body doesn't support the pos() method, like if it is a socket. + # Just return 0 and get on with life. + 0 + end + + def reset_fileptr_offset(request, offset = 0) + if(request.body_stream && request.body_stream.respond_to?(:pos)) + begin + request.body_stream.pos = offset + rescue Exception => e + @logger.warn("Failed file pointer reset; aborting HTTP retries." + + " -- #{err_header} #{e.inspect}") + raise e + end + end + end + + # Start a fresh connection. The object closes any existing connection and + # opens a new one. + def start(request_params) + # close the previous if exists + finish + # create new connection + @server = request_params[:server] + @port = request_params[:port] + @protocol = request_params[:protocol] + + @logger.info("Opening new #{@protocol.upcase} connection to #@server:#@port") + @http = Net::HTTP.new(@server, @port) + @http.open_timeout = @params[:http_connection_open_timeout] + @http.read_timeout = @params[:http_connection_read_timeout] + + if @protocol == 'https' + verifyCallbackProc = Proc.new{ |ok, x509_store_ctx| + code = x509_store_ctx.error + msg = x509_store_ctx.error_string + #debugger + @logger.warn("##### #{@server} certificate verify failed: #{msg}") unless code == 0 + true + } + @http.use_ssl = true + ca_file = get_param(:ca_file) + if ca_file + @http.verify_mode = OpenSSL::SSL::VERIFY_PEER + @http.verify_callback = verifyCallbackProc + @http.ca_file = ca_file + end + end + # open connection + @http.start + end + + public + +=begin rdoc + Send HTTP request to server + + request_params hash: + :server => 'www.HostName.com' # Hostname or IP address of HTTP server + :port => '80' # Port of HTTP server + :protocol => 'https' # http and https are supported on any port + :request => 'requeststring' # Fully-formed HTTP request to make + + Raises RuntimeError, Interrupt, and params[:exception] (if specified in new). + +=end + def request(request_params, &block) + # We save the offset here so that if we need to retry, we can return the file pointer to its initial position + mypos = get_fileptr_offset(request_params) + loop do + # if we are inside a delay between retries: no requests this time! + if error_count > @params[:http_connection_retry_count] && + error_time + @params[:http_connection_retry_delay] > Time.now + # store the message (otherwise it will be lost after error_reset and + # we will raise an exception with an empty text) + banana_message_text = banana_message + @logger.warn("#{err_header} re-raising same error: #{banana_message_text} " + + "-- error count: #{error_count}, error age: #{Time.now.to_i - error_time.to_i}") + exception = get_param(:exception) || RuntimeError + raise exception.new(banana_message_text) + end + + # try to connect server(if connection does not exist) and get response data + begin + request_params[:protocol] ||= (request_params[:port] == 443 ? 'https' : 'http') + + request = request_params[:request] + request['User-Agent'] = get_param(:user_agent) || '' + + # (re)open connection to server if none exists or params has changed + unless @http && + @http.started? && + @server == request_params[:server] && + @port == request_params[:port] && + @protocol == request_params[:protocol] + start(request_params) + end + + # Detect if the body is a streamable object like a file or socket. If so, stream that + # bad boy. + setup_streaming(request) + response = @http.request(request, &block) + + error_reset + eof_reset + return response + + # We treat EOF errors and the timeout/network errors differently. Both + # are tracked in different statistics blocks. Note below that EOF + # errors will sleep for a certain (exponentially increasing) period. + # Other errors don't sleep because there is already an inherent delay + # in them; connect and read timeouts (for example) have already + # 'slept'. It is still not clear which way we should treat errors + # like RST and resolution failures. For now, there is no additional + # delay for these errors although this may change in the future. + + # EOFError means the server closed the connection on us. + rescue EOFError => e + @logger.debug("#{err_header} server #{@server} closed connection") + @http = nil + + # if we have waited long enough - raise an exception... + if raise_on_eof_exception? + exception = get_param(:exception) || RuntimeError + @logger.warn("#{err_header} raising #{exception} due to permanent EOF being received from #{@server}, error age: #{Time.now.to_i - eof_time.to_i}") + raise exception.new("Permanent EOF is being received from #{@server}.") + else + # ... else just sleep a bit before new retry + sleep(add_eof) + # We will be retrying the request, so reset the file pointer + reset_fileptr_offset(request, mypos) + end + rescue Exception => e # See comment at bottom for the list of errors seen... + @http = nil + # if ctrl+c is pressed - we have to reraise exception to terminate proggy + if e.is_a?(Interrupt) && !( e.is_a?(Errno::ETIMEDOUT) || e.is_a?(Timeout::Error)) + @logger.debug( "#{err_header} request to server #{@server} interrupted by ctrl-c") + raise + elsif e.is_a?(ArgumentError) && e.message.include?('wrong number of arguments (5 for 4)') + # seems our net_fix patch was overriden... + exception = get_param(:exception) || RuntimeError + raise exception.new('incompatible Net::HTTP monkey-patch') + end + # oops - we got a banana: log it + error_add(e.message) + @logger.warn("#{err_header} request failure count: #{error_count}, exception: #{e.inspect}") + + # We will be retrying the request, so reset the file pointer + reset_fileptr_offset(request, mypos) + + end + end + end + + def finish(reason = '') + if @http && @http.started? + reason = ", reason: '#{reason}'" unless reason.blank? + @logger.info("Closing #{@http.use_ssl? ? 'HTTPS' : 'HTTP'} connection to #{@http.address}:#{@http.port}#{reason}") + @http.finish + end + end + + # Errors received during testing: + # + # #<Timeout::Error: execution expired> + # #<Errno::ETIMEDOUT: Connection timed out - connect(2)> + # #<SocketError: getaddrinfo: Name or service not known> + # #<SocketError: getaddrinfo: Temporary failure in name resolution> + # #<EOFError: end of file reached> + # #<Errno::ECONNRESET: Connection reset by peer> + # #<OpenSSL::SSL::SSLError: SSL_write:: bad write retry> + end + +end + diff --git a/vendor/gems/fakeweb-1.3.0/test/vendor/right_http_connection-1.2.4/setup.rb b/vendor/gems/fakeweb-1.3.0/test/vendor/right_http_connection-1.2.4/setup.rb new file mode 100644 index 000000000..424a5f37c --- /dev/null +++ b/vendor/gems/fakeweb-1.3.0/test/vendor/right_http_connection-1.2.4/setup.rb @@ -0,0 +1,1585 @@ +# +# setup.rb +# +# Copyright (c) 2000-2005 Minero Aoki +# +# This program is free software. +# You can distribute/modify this program under the terms of +# the GNU LGPL, Lesser General Public License version 2.1. +# + +unless Enumerable.method_defined?(:map) # Ruby 1.4.6 + module Enumerable + alias map collect + end +end + +unless File.respond_to?(:read) # Ruby 1.6 + def File.read(fname) + open(fname) {|f| + return f.read + } + end +end + +unless Errno.const_defined?(:ENOTEMPTY) # Windows? + module Errno + class ENOTEMPTY + # We do not raise this exception, implementation is not needed. + end + end +end + +def File.binread(fname) + open(fname, 'rb') {|f| + return f.read + } +end + +# for corrupted Windows' stat(2) +def File.dir?(path) + File.directory?((path[-1,1] == '/') ? path : path + '/') +end + + +class ConfigTable + + include Enumerable + + def initialize(rbconfig) + @rbconfig = rbconfig + @items = [] + @table = {} + # options + @install_prefix = nil + @config_opt = nil + @verbose = true + @no_harm = false + end + + attr_accessor :install_prefix + attr_accessor :config_opt + + attr_writer :verbose + + def verbose? + @verbose + end + + attr_writer :no_harm + + def no_harm? + @no_harm + end + + def [](key) + lookup(key).resolve(self) + end + + def []=(key, val) + lookup(key).set val + end + + def names + @items.map {|i| i.name } + end + + def each(&block) + @items.each(&block) + end + + def key?(name) + @table.key?(name) + end + + def lookup(name) + @table[name] or setup_rb_error "no such config item: #{name}" + end + + def add(item) + @items.push item + @table[item.name] = item + end + + def remove(name) + item = lookup(name) + @items.delete_if {|i| i.name == name } + @table.delete_if {|name, i| i.name == name } + item + end + + def load_script(path, inst = nil) + if File.file?(path) + MetaConfigEnvironment.new(self, inst).instance_eval File.read(path), path + end + end + + def savefile + '.config' + end + + def load_savefile + begin + File.foreach(savefile()) do |line| + k, v = *line.split(/=/, 2) + self[k] = v.strip + end + rescue Errno::ENOENT + setup_rb_error $!.message + "\n#{File.basename($0)} config first" + end + end + + def save + @items.each {|i| i.value } + File.open(savefile(), 'w') {|f| + @items.each do |i| + f.printf "%s=%s\n", i.name, i.value if i.value? and i.value + end + } + end + + def load_standard_entries + standard_entries(@rbconfig).each do |ent| + add ent + end + end + + def standard_entries(rbconfig) + c = rbconfig + + rubypath = File.join(c['bindir'], c['ruby_install_name'] + c['EXEEXT']) + + major = c['MAJOR'].to_i + minor = c['MINOR'].to_i + teeny = c['TEENY'].to_i + version = "#{major}.#{minor}" + + # ruby ver. >= 1.4.4? + newpath_p = ((major >= 2) or + ((major == 1) and + ((minor >= 5) or + ((minor == 4) and (teeny >= 4))))) + + if c['rubylibdir'] + # V > 1.6.3 + libruby = "#{c['prefix']}/lib/ruby" + librubyver = c['rubylibdir'] + librubyverarch = c['archdir'] + siteruby = c['sitedir'] + siterubyver = c['sitelibdir'] + siterubyverarch = c['sitearchdir'] + elsif newpath_p + # 1.4.4 <= V <= 1.6.3 + libruby = "#{c['prefix']}/lib/ruby" + librubyver = "#{c['prefix']}/lib/ruby/#{version}" + librubyverarch = "#{c['prefix']}/lib/ruby/#{version}/#{c['arch']}" + siteruby = c['sitedir'] + siterubyver = "$siteruby/#{version}" + siterubyverarch = "$siterubyver/#{c['arch']}" + else + # V < 1.4.4 + libruby = "#{c['prefix']}/lib/ruby" + librubyver = "#{c['prefix']}/lib/ruby/#{version}" + librubyverarch = "#{c['prefix']}/lib/ruby/#{version}/#{c['arch']}" + siteruby = "#{c['prefix']}/lib/ruby/#{version}/site_ruby" + siterubyver = siteruby + siterubyverarch = "$siterubyver/#{c['arch']}" + end + parameterize = lambda {|path| + path.sub(/\A#{Regexp.quote(c['prefix'])}/, '$prefix') + } + + if arg = c['configure_args'].split.detect {|arg| /--with-make-prog=/ =~ arg } + makeprog = arg.sub(/'/, '').split(/=/, 2)[1] + else + makeprog = 'make' + end + + [ + ExecItem.new('installdirs', 'std/site/home', + 'std: install under libruby; site: install under site_ruby; home: install under $HOME')\ + {|val, table| + case val + when 'std' + table['rbdir'] = '$librubyver' + table['sodir'] = '$librubyverarch' + when 'site' + table['rbdir'] = '$siterubyver' + table['sodir'] = '$siterubyverarch' + when 'home' + setup_rb_error '$HOME was not set' unless ENV['HOME'] + table['prefix'] = ENV['HOME'] + table['rbdir'] = '$libdir/ruby' + table['sodir'] = '$libdir/ruby' + end + }, + PathItem.new('prefix', 'path', c['prefix'], + 'path prefix of target environment'), + PathItem.new('bindir', 'path', parameterize.call(c['bindir']), + 'the directory for commands'), + PathItem.new('libdir', 'path', parameterize.call(c['libdir']), + 'the directory for libraries'), + PathItem.new('datadir', 'path', parameterize.call(c['datadir']), + 'the directory for shared data'), + PathItem.new('mandir', 'path', parameterize.call(c['mandir']), + 'the directory for man pages'), + PathItem.new('sysconfdir', 'path', parameterize.call(c['sysconfdir']), + 'the directory for system configuration files'), + PathItem.new('localstatedir', 'path', parameterize.call(c['localstatedir']), + 'the directory for local state data'), + PathItem.new('libruby', 'path', libruby, + 'the directory for ruby libraries'), + PathItem.new('librubyver', 'path', librubyver, + 'the directory for standard ruby libraries'), + PathItem.new('librubyverarch', 'path', librubyverarch, + 'the directory for standard ruby extensions'), + PathItem.new('siteruby', 'path', siteruby, + 'the directory for version-independent aux ruby libraries'), + PathItem.new('siterubyver', 'path', siterubyver, + 'the directory for aux ruby libraries'), + PathItem.new('siterubyverarch', 'path', siterubyverarch, + 'the directory for aux ruby binaries'), + PathItem.new('rbdir', 'path', '$siterubyver', + 'the directory for ruby scripts'), + PathItem.new('sodir', 'path', '$siterubyverarch', + 'the directory for ruby extentions'), + PathItem.new('rubypath', 'path', rubypath, + 'the path to set to #! line'), + ProgramItem.new('rubyprog', 'name', rubypath, + 'the ruby program using for installation'), + ProgramItem.new('makeprog', 'name', makeprog, + 'the make program to compile ruby extentions'), + SelectItem.new('shebang', 'all/ruby/never', 'ruby', + 'shebang line (#!) editing mode'), + BoolItem.new('without-ext', 'yes/no', 'no', + 'does not compile/install ruby extentions') + ] + end + private :standard_entries + + def load_multipackage_entries + multipackage_entries().each do |ent| + add ent + end + end + + def multipackage_entries + [ + PackageSelectionItem.new('with', 'name,name...', '', 'ALL', + 'package names that you want to install'), + PackageSelectionItem.new('without', 'name,name...', '', 'NONE', + 'package names that you do not want to install') + ] + end + private :multipackage_entries + + ALIASES = { + 'std-ruby' => 'librubyver', + 'stdruby' => 'librubyver', + 'rubylibdir' => 'librubyver', + 'archdir' => 'librubyverarch', + 'site-ruby-common' => 'siteruby', # For backward compatibility + 'site-ruby' => 'siterubyver', # For backward compatibility + 'bin-dir' => 'bindir', + 'bin-dir' => 'bindir', + 'rb-dir' => 'rbdir', + 'so-dir' => 'sodir', + 'data-dir' => 'datadir', + 'ruby-path' => 'rubypath', + 'ruby-prog' => 'rubyprog', + 'ruby' => 'rubyprog', + 'make-prog' => 'makeprog', + 'make' => 'makeprog' + } + + def fixup + ALIASES.each do |ali, name| + @table[ali] = @table[name] + end + @items.freeze + @table.freeze + @options_re = /\A--(#{@table.keys.join('|')})(?:=(.*))?\z/ + end + + def parse_opt(opt) + m = @options_re.match(opt) or setup_rb_error "config: unknown option #{opt}" + m.to_a[1,2] + end + + def dllext + @rbconfig['DLEXT'] + end + + def value_config?(name) + lookup(name).value? + end + + class Item + def initialize(name, template, default, desc) + @name = name.freeze + @template = template + @value = default + @default = default + @description = desc + end + + attr_reader :name + attr_reader :description + + attr_accessor :default + alias help_default default + + def help_opt + "--#{@name}=#{@template}" + end + + def value? + true + end + + def value + @value + end + + def resolve(table) + @value.gsub(%r<\$([^/]+)>) { table[$1] } + end + + def set(val) + @value = check(val) + end + + private + + def check(val) + setup_rb_error "config: --#{name} requires argument" unless val + val + end + end + + class BoolItem < Item + def config_type + 'bool' + end + + def help_opt + "--#{@name}" + end + + private + + def check(val) + return 'yes' unless val + case val + when /\Ay(es)?\z/i, /\At(rue)?\z/i then 'yes' + when /\An(o)?\z/i, /\Af(alse)\z/i then 'no' + else + setup_rb_error "config: --#{@name} accepts only yes/no for argument" + end + end + end + + class PathItem < Item + def config_type + 'path' + end + + private + + def check(path) + setup_rb_error "config: --#{@name} requires argument" unless path + path[0,1] == '$' ? path : File.expand_path(path) + end + end + + class ProgramItem < Item + def config_type + 'program' + end + end + + class SelectItem < Item + def initialize(name, selection, default, desc) + super + @ok = selection.split('/') + end + + def config_type + 'select' + end + + private + + def check(val) + unless @ok.include?(val.strip) + setup_rb_error "config: use --#{@name}=#{@template} (#{val})" + end + val.strip + end + end + + class ExecItem < Item + def initialize(name, selection, desc, &block) + super name, selection, nil, desc + @ok = selection.split('/') + @action = block + end + + def config_type + 'exec' + end + + def value? + false + end + + def resolve(table) + setup_rb_error "$#{name()} wrongly used as option value" + end + + undef set + + def evaluate(val, table) + v = val.strip.downcase + unless @ok.include?(v) + setup_rb_error "invalid option --#{@name}=#{val} (use #{@template})" + end + @action.call v, table + end + end + + class PackageSelectionItem < Item + def initialize(name, template, default, help_default, desc) + super name, template, default, desc + @help_default = help_default + end + + attr_reader :help_default + + def config_type + 'package' + end + + private + + def check(val) + unless File.dir?("packages/#{val}") + setup_rb_error "config: no such package: #{val}" + end + val + end + end + + class MetaConfigEnvironment + def initialize(config, installer) + @config = config + @installer = installer + end + + def config_names + @config.names + end + + def config?(name) + @config.key?(name) + end + + def bool_config?(name) + @config.lookup(name).config_type == 'bool' + end + + def path_config?(name) + @config.lookup(name).config_type == 'path' + end + + def value_config?(name) + @config.lookup(name).config_type != 'exec' + end + + def add_config(item) + @config.add item + end + + def add_bool_config(name, default, desc) + @config.add BoolItem.new(name, 'yes/no', default ? 'yes' : 'no', desc) + end + + def add_path_config(name, default, desc) + @config.add PathItem.new(name, 'path', default, desc) + end + + def set_config_default(name, default) + @config.lookup(name).default = default + end + + def remove_config(name) + @config.remove(name) + end + + # For only multipackage + def packages + raise '[setup.rb fatal] multi-package metaconfig API packages() called for single-package; contact application package vendor' unless @installer + @installer.packages + end + + # For only multipackage + def declare_packages(list) + raise '[setup.rb fatal] multi-package metaconfig API declare_packages() called for single-package; contact application package vendor' unless @installer + @installer.packages = list + end + end + +end # class ConfigTable + + +# This module requires: #verbose?, #no_harm? +module FileOperations + + def mkdir_p(dirname, prefix = nil) + dirname = prefix + File.expand_path(dirname) if prefix + $stderr.puts "mkdir -p #{dirname}" if verbose? + return if no_harm? + + # Does not check '/', it's too abnormal. + dirs = File.expand_path(dirname).split(%r<(?=/)>) + if /\A[a-z]:\z/i =~ dirs[0] + disk = dirs.shift + dirs[0] = disk + dirs[0] + end + dirs.each_index do |idx| + path = dirs[0..idx].join('') + Dir.mkdir path unless File.dir?(path) + end + end + + def rm_f(path) + $stderr.puts "rm -f #{path}" if verbose? + return if no_harm? + force_remove_file path + end + + def rm_rf(path) + $stderr.puts "rm -rf #{path}" if verbose? + return if no_harm? + remove_tree path + end + + def remove_tree(path) + if File.symlink?(path) + remove_file path + elsif File.dir?(path) + remove_tree0 path + else + force_remove_file path + end + end + + def remove_tree0(path) + Dir.foreach(path) do |ent| + next if ent == '.' + next if ent == '..' + entpath = "#{path}/#{ent}" + if File.symlink?(entpath) + remove_file entpath + elsif File.dir?(entpath) + remove_tree0 entpath + else + force_remove_file entpath + end + end + begin + Dir.rmdir path + rescue Errno::ENOTEMPTY + # directory may not be empty + end + end + + def move_file(src, dest) + force_remove_file dest + begin + File.rename src, dest + rescue + File.open(dest, 'wb') {|f| + f.write File.binread(src) + } + File.chmod File.stat(src).mode, dest + File.unlink src + end + end + + def force_remove_file(path) + begin + remove_file path + rescue + end + end + + def remove_file(path) + File.chmod 0777, path + File.unlink path + end + + def install(from, dest, mode, prefix = nil) + $stderr.puts "install #{from} #{dest}" if verbose? + return if no_harm? + + realdest = prefix ? prefix + File.expand_path(dest) : dest + realdest = File.join(realdest, File.basename(from)) if File.dir?(realdest) + str = File.binread(from) + if diff?(str, realdest) + verbose_off { + rm_f realdest if File.exist?(realdest) + } + File.open(realdest, 'wb') {|f| + f.write str + } + File.chmod mode, realdest + + File.open("#{objdir_root()}/InstalledFiles", 'a') {|f| + if prefix + f.puts realdest.sub(prefix, '') + else + f.puts realdest + end + } + end + end + + def diff?(new_content, path) + return true unless File.exist?(path) + new_content != File.binread(path) + end + + def command(*args) + $stderr.puts args.join(' ') if verbose? + system(*args) or raise RuntimeError, + "system(#{args.map{|a| a.inspect }.join(' ')}) failed" + end + + def ruby(*args) + command config('rubyprog'), *args + end + + def make(task = nil) + command(*[config('makeprog'), task].compact) + end + + def extdir?(dir) + File.exist?("#{dir}/MANIFEST") or File.exist?("#{dir}/extconf.rb") + end + + def files_of(dir) + Dir.open(dir) {|d| + return d.select {|ent| File.file?("#{dir}/#{ent}") } + } + end + + DIR_REJECT = %w( . .. CVS SCCS RCS CVS.adm .svn ) + + def directories_of(dir) + Dir.open(dir) {|d| + return d.select {|ent| File.dir?("#{dir}/#{ent}") } - DIR_REJECT + } + end + +end + + +# This module requires: #srcdir_root, #objdir_root, #relpath +module HookScriptAPI + + def get_config(key) + @config[key] + end + + alias config get_config + + # obsolete: use metaconfig to change configuration + def set_config(key, val) + @config[key] = val + end + + # + # srcdir/objdir (works only in the package directory) + # + + def curr_srcdir + "#{srcdir_root()}/#{relpath()}" + end + + def curr_objdir + "#{objdir_root()}/#{relpath()}" + end + + def srcfile(path) + "#{curr_srcdir()}/#{path}" + end + + def srcexist?(path) + File.exist?(srcfile(path)) + end + + def srcdirectory?(path) + File.dir?(srcfile(path)) + end + + def srcfile?(path) + File.file?(srcfile(path)) + end + + def srcentries(path = '.') + Dir.open("#{curr_srcdir()}/#{path}") {|d| + return d.to_a - %w(. ..) + } + end + + def srcfiles(path = '.') + srcentries(path).select {|fname| + File.file?(File.join(curr_srcdir(), path, fname)) + } + end + + def srcdirectories(path = '.') + srcentries(path).select {|fname| + File.dir?(File.join(curr_srcdir(), path, fname)) + } + end + +end + + +class ToplevelInstaller + + Version = '3.4.1' + Copyright = 'Copyright (c) 2000-2005 Minero Aoki' + + TASKS = [ + [ 'all', 'do config, setup, then install' ], + [ 'config', 'saves your configurations' ], + [ 'show', 'shows current configuration' ], + [ 'setup', 'compiles ruby extentions and others' ], + [ 'install', 'installs files' ], + [ 'test', 'run all tests in test/' ], + [ 'clean', "does `make clean' for each extention" ], + [ 'distclean',"does `make distclean' for each extention" ] + ] + + def ToplevelInstaller.invoke + config = ConfigTable.new(load_rbconfig()) + config.load_standard_entries + config.load_multipackage_entries if multipackage? + config.fixup + klass = (multipackage?() ? ToplevelInstallerMulti : ToplevelInstaller) + klass.new(File.dirname($0), config).invoke + end + + def ToplevelInstaller.multipackage? + File.dir?(File.dirname($0) + '/packages') + end + + def ToplevelInstaller.load_rbconfig + if arg = ARGV.detect {|arg| /\A--rbconfig=/ =~ arg } + ARGV.delete(arg) + load File.expand_path(arg.split(/=/, 2)[1]) + $".push 'rbconfig.rb' + else + require 'rbconfig' + end + ::Config::CONFIG + end + + def initialize(ardir_root, config) + @ardir = File.expand_path(ardir_root) + @config = config + # cache + @valid_task_re = nil + end + + def config(key) + @config[key] + end + + def inspect + "#<#{self.class} #{__id__()}>" + end + + def invoke + run_metaconfigs + case task = parsearg_global() + when nil, 'all' + parsearg_config + init_installers + exec_config + exec_setup + exec_install + else + case task + when 'config', 'test' + ; + when 'clean', 'distclean' + @config.load_savefile if File.exist?(@config.savefile) + else + @config.load_savefile + end + __send__ "parsearg_#{task}" + init_installers + __send__ "exec_#{task}" + end + end + + def run_metaconfigs + @config.load_script "#{@ardir}/metaconfig" + end + + def init_installers + @installer = Installer.new(@config, @ardir, File.expand_path('.')) + end + + # + # Hook Script API bases + # + + def srcdir_root + @ardir + end + + def objdir_root + '.' + end + + def relpath + '.' + end + + # + # Option Parsing + # + + def parsearg_global + while arg = ARGV.shift + case arg + when /\A\w+\z/ + setup_rb_error "invalid task: #{arg}" unless valid_task?(arg) + return arg + when '-q', '--quiet' + @config.verbose = false + when '--verbose' + @config.verbose = true + when '--help' + print_usage $stdout + exit 0 + when '--version' + puts "#{File.basename($0)} version #{Version}" + exit 0 + when '--copyright' + puts Copyright + exit 0 + else + setup_rb_error "unknown global option '#{arg}'" + end + end + nil + end + + def valid_task?(t) + valid_task_re() =~ t + end + + def valid_task_re + @valid_task_re ||= /\A(?:#{TASKS.map {|task,desc| task }.join('|')})\z/ + end + + def parsearg_no_options + unless ARGV.empty? + task = caller(0).first.slice(%r<`parsearg_(\w+)'>, 1) + setup_rb_error "#{task}: unknown options: #{ARGV.join(' ')}" + end + end + + alias parsearg_show parsearg_no_options + alias parsearg_setup parsearg_no_options + alias parsearg_test parsearg_no_options + alias parsearg_clean parsearg_no_options + alias parsearg_distclean parsearg_no_options + + def parsearg_config + evalopt = [] + set = [] + @config.config_opt = [] + while i = ARGV.shift + if /\A--?\z/ =~ i + @config.config_opt = ARGV.dup + break + end + name, value = *@config.parse_opt(i) + if @config.value_config?(name) + @config[name] = value + else + evalopt.push [name, value] + end + set.push name + end + evalopt.each do |name, value| + @config.lookup(name).evaluate value, @config + end + # Check if configuration is valid + set.each do |n| + @config[n] if @config.value_config?(n) + end + end + + def parsearg_install + @config.no_harm = false + @config.install_prefix = '' + while a = ARGV.shift + case a + when '--no-harm' + @config.no_harm = true + when /\A--prefix=/ + path = a.split(/=/, 2)[1] + path = File.expand_path(path) unless path[0,1] == '/' + @config.install_prefix = path + else + setup_rb_error "install: unknown option #{a}" + end + end + end + + def print_usage(out) + out.puts 'Typical Installation Procedure:' + out.puts " $ ruby #{File.basename $0} config" + out.puts " $ ruby #{File.basename $0} setup" + out.puts " # ruby #{File.basename $0} install (may require root privilege)" + out.puts + out.puts 'Detailed Usage:' + out.puts " ruby #{File.basename $0} <global option>" + out.puts " ruby #{File.basename $0} [<global options>] <task> [<task options>]" + + fmt = " %-24s %s\n" + out.puts + out.puts 'Global options:' + out.printf fmt, '-q,--quiet', 'suppress message outputs' + out.printf fmt, ' --verbose', 'output messages verbosely' + out.printf fmt, ' --help', 'print this message' + out.printf fmt, ' --version', 'print version and quit' + out.printf fmt, ' --copyright', 'print copyright and quit' + out.puts + out.puts 'Tasks:' + TASKS.each do |name, desc| + out.printf fmt, name, desc + end + + fmt = " %-24s %s [%s]\n" + out.puts + out.puts 'Options for CONFIG or ALL:' + @config.each do |item| + out.printf fmt, item.help_opt, item.description, item.help_default + end + out.printf fmt, '--rbconfig=path', 'rbconfig.rb to load',"running ruby's" + out.puts + out.puts 'Options for INSTALL:' + out.printf fmt, '--no-harm', 'only display what to do if given', 'off' + out.printf fmt, '--prefix=path', 'install path prefix', '' + out.puts + end + + # + # Task Handlers + # + + def exec_config + @installer.exec_config + @config.save # must be final + end + + def exec_setup + @installer.exec_setup + end + + def exec_install + @installer.exec_install + end + + def exec_test + @installer.exec_test + end + + def exec_show + @config.each do |i| + printf "%-20s %s\n", i.name, i.value if i.value? + end + end + + def exec_clean + @installer.exec_clean + end + + def exec_distclean + @installer.exec_distclean + end + +end # class ToplevelInstaller + + +class ToplevelInstallerMulti < ToplevelInstaller + + include FileOperations + + def initialize(ardir_root, config) + super + @packages = directories_of("#{@ardir}/packages") + raise 'no package exists' if @packages.empty? + @root_installer = Installer.new(@config, @ardir, File.expand_path('.')) + end + + def run_metaconfigs + @config.load_script "#{@ardir}/metaconfig", self + @packages.each do |name| + @config.load_script "#{@ardir}/packages/#{name}/metaconfig" + end + end + + attr_reader :packages + + def packages=(list) + raise 'package list is empty' if list.empty? + list.each do |name| + raise "directory packages/#{name} does not exist"\ + unless File.dir?("#{@ardir}/packages/#{name}") + end + @packages = list + end + + def init_installers + @installers = {} + @packages.each do |pack| + @installers[pack] = Installer.new(@config, + "#{@ardir}/packages/#{pack}", + "packages/#{pack}") + end + with = extract_selection(config('with')) + without = extract_selection(config('without')) + @selected = @installers.keys.select {|name| + (with.empty? or with.include?(name)) \ + and not without.include?(name) + } + end + + def extract_selection(list) + a = list.split(/,/) + a.each do |name| + setup_rb_error "no such package: #{name}" unless @installers.key?(name) + end + a + end + + def print_usage(f) + super + f.puts 'Inluded packages:' + f.puts ' ' + @packages.sort.join(' ') + f.puts + end + + # + # Task Handlers + # + + def exec_config + run_hook 'pre-config' + each_selected_installers {|inst| inst.exec_config } + run_hook 'post-config' + @config.save # must be final + end + + def exec_setup + run_hook 'pre-setup' + each_selected_installers {|inst| inst.exec_setup } + run_hook 'post-setup' + end + + def exec_install + run_hook 'pre-install' + each_selected_installers {|inst| inst.exec_install } + run_hook 'post-install' + end + + def exec_test + run_hook 'pre-test' + each_selected_installers {|inst| inst.exec_test } + run_hook 'post-test' + end + + def exec_clean + rm_f @config.savefile + run_hook 'pre-clean' + each_selected_installers {|inst| inst.exec_clean } + run_hook 'post-clean' + end + + def exec_distclean + rm_f @config.savefile + run_hook 'pre-distclean' + each_selected_installers {|inst| inst.exec_distclean } + run_hook 'post-distclean' + end + + # + # lib + # + + def each_selected_installers + Dir.mkdir 'packages' unless File.dir?('packages') + @selected.each do |pack| + $stderr.puts "Processing the package `#{pack}' ..." if verbose? + Dir.mkdir "packages/#{pack}" unless File.dir?("packages/#{pack}") + Dir.chdir "packages/#{pack}" + yield @installers[pack] + Dir.chdir '../..' + end + end + + def run_hook(id) + @root_installer.run_hook id + end + + # module FileOperations requires this + def verbose? + @config.verbose? + end + + # module FileOperations requires this + def no_harm? + @config.no_harm? + end + +end # class ToplevelInstallerMulti + + +class Installer + + FILETYPES = %w( bin lib ext data conf man ) + + include FileOperations + include HookScriptAPI + + def initialize(config, srcroot, objroot) + @config = config + @srcdir = File.expand_path(srcroot) + @objdir = File.expand_path(objroot) + @currdir = '.' + end + + def inspect + "#<#{self.class} #{File.basename(@srcdir)}>" + end + + def noop(rel) + end + + # + # Hook Script API base methods + # + + def srcdir_root + @srcdir + end + + def objdir_root + @objdir + end + + def relpath + @currdir + end + + # + # Config Access + # + + # module FileOperations requires this + def verbose? + @config.verbose? + end + + # module FileOperations requires this + def no_harm? + @config.no_harm? + end + + def verbose_off + begin + save, @config.verbose = @config.verbose?, false + yield + ensure + @config.verbose = save + end + end + + # + # TASK config + # + + def exec_config + exec_task_traverse 'config' + end + + alias config_dir_bin noop + alias config_dir_lib noop + + def config_dir_ext(rel) + extconf if extdir?(curr_srcdir()) + end + + alias config_dir_data noop + alias config_dir_conf noop + alias config_dir_man noop + + def extconf + ruby "#{curr_srcdir()}/extconf.rb", *@config.config_opt + end + + # + # TASK setup + # + + def exec_setup + exec_task_traverse 'setup' + end + + def setup_dir_bin(rel) + files_of(curr_srcdir()).each do |fname| + update_shebang_line "#{curr_srcdir()}/#{fname}" + end + end + + alias setup_dir_lib noop + + def setup_dir_ext(rel) + make if extdir?(curr_srcdir()) + end + + alias setup_dir_data noop + alias setup_dir_conf noop + alias setup_dir_man noop + + def update_shebang_line(path) + return if no_harm? + return if config('shebang') == 'never' + old = Shebang.load(path) + if old + $stderr.puts "warning: #{path}: Shebang line includes too many args. It is not portable and your program may not work." if old.args.size > 1 + new = new_shebang(old) + return if new.to_s == old.to_s + else + return unless config('shebang') == 'all' + new = Shebang.new(config('rubypath')) + end + $stderr.puts "updating shebang: #{File.basename(path)}" if verbose? + open_atomic_writer(path) {|output| + File.open(path, 'rb') {|f| + f.gets if old # discard + output.puts new.to_s + output.print f.read + } + } + end + + def new_shebang(old) + if /\Aruby/ =~ File.basename(old.cmd) + Shebang.new(config('rubypath'), old.args) + elsif File.basename(old.cmd) == 'env' and old.args.first == 'ruby' + Shebang.new(config('rubypath'), old.args[1..-1]) + else + return old unless config('shebang') == 'all' + Shebang.new(config('rubypath')) + end + end + + def open_atomic_writer(path, &block) + tmpfile = File.basename(path) + '.tmp' + begin + File.open(tmpfile, 'wb', &block) + File.rename tmpfile, File.basename(path) + ensure + File.unlink tmpfile if File.exist?(tmpfile) + end + end + + class Shebang + def Shebang.load(path) + line = nil + File.open(path) {|f| + line = f.gets + } + return nil unless /\A#!/ =~ line + parse(line) + end + + def Shebang.parse(line) + cmd, *args = *line.strip.sub(/\A\#!/, '').split(' ') + new(cmd, args) + end + + def initialize(cmd, args = []) + @cmd = cmd + @args = args + end + + attr_reader :cmd + attr_reader :args + + def to_s + "#! #{@cmd}" + (@args.empty? ? '' : " #{@args.join(' ')}") + end + end + + # + # TASK install + # + + def exec_install + rm_f 'InstalledFiles' + exec_task_traverse 'install' + end + + def install_dir_bin(rel) + install_files targetfiles(), "#{config('bindir')}/#{rel}", 0755 + end + + def install_dir_lib(rel) + install_files libfiles(), "#{config('rbdir')}/#{rel}", 0644 + end + + def install_dir_ext(rel) + return unless extdir?(curr_srcdir()) + install_files rubyextentions('.'), + "#{config('sodir')}/#{File.dirname(rel)}", + 0555 + end + + def install_dir_data(rel) + install_files targetfiles(), "#{config('datadir')}/#{rel}", 0644 + end + + def install_dir_conf(rel) + # FIXME: should not remove current config files + # (rename previous file to .old/.org) + install_files targetfiles(), "#{config('sysconfdir')}/#{rel}", 0644 + end + + def install_dir_man(rel) + install_files targetfiles(), "#{config('mandir')}/#{rel}", 0644 + end + + def install_files(list, dest, mode) + mkdir_p dest, @config.install_prefix + list.each do |fname| + install fname, dest, mode, @config.install_prefix + end + end + + def libfiles + glob_reject(%w(*.y *.output), targetfiles()) + end + + def rubyextentions(dir) + ents = glob_select("*.#{@config.dllext}", targetfiles()) + if ents.empty? + setup_rb_error "no ruby extention exists: 'ruby #{$0} setup' first" + end + ents + end + + def targetfiles + mapdir(existfiles() - hookfiles()) + end + + def mapdir(ents) + ents.map {|ent| + if File.exist?(ent) + then ent # objdir + else "#{curr_srcdir()}/#{ent}" # srcdir + end + } + end + + # picked up many entries from cvs-1.11.1/src/ignore.c + JUNK_FILES = %w( + core RCSLOG tags TAGS .make.state + .nse_depinfo #* .#* cvslog.* ,* .del-* *.olb + *~ *.old *.bak *.BAK *.orig *.rej _$* *$ + + *.org *.in .* + ) + + def existfiles + glob_reject(JUNK_FILES, (files_of(curr_srcdir()) | files_of('.'))) + end + + def hookfiles + %w( pre-%s post-%s pre-%s.rb post-%s.rb ).map {|fmt| + %w( config setup install clean ).map {|t| sprintf(fmt, t) } + }.flatten + end + + def glob_select(pat, ents) + re = globs2re([pat]) + ents.select {|ent| re =~ ent } + end + + def glob_reject(pats, ents) + re = globs2re(pats) + ents.reject {|ent| re =~ ent } + end + + GLOB2REGEX = { + '.' => '\.', + '$' => '\$', + '#' => '\#', + '*' => '.*' + } + + def globs2re(pats) + /\A(?:#{ + pats.map {|pat| pat.gsub(/[\.\$\#\*]/) {|ch| GLOB2REGEX[ch] } }.join('|') + })\z/ + end + + # + # TASK test + # + + TESTDIR = 'test' + + def exec_test + unless File.directory?('test') + $stderr.puts 'no test in this package' if verbose? + return + end + $stderr.puts 'Running tests...' if verbose? + begin + require 'test/unit' + rescue LoadError + setup_rb_error 'test/unit cannot loaded. You need Ruby 1.8 or later to invoke this task.' + end + runner = Test::Unit::AutoRunner.new(true) + runner.to_run << TESTDIR + runner.run + end + + # + # TASK clean + # + + def exec_clean + exec_task_traverse 'clean' + rm_f @config.savefile + rm_f 'InstalledFiles' + end + + alias clean_dir_bin noop + alias clean_dir_lib noop + alias clean_dir_data noop + alias clean_dir_conf noop + alias clean_dir_man noop + + def clean_dir_ext(rel) + return unless extdir?(curr_srcdir()) + make 'clean' if File.file?('Makefile') + end + + # + # TASK distclean + # + + def exec_distclean + exec_task_traverse 'distclean' + rm_f @config.savefile + rm_f 'InstalledFiles' + end + + alias distclean_dir_bin noop + alias distclean_dir_lib noop + + def distclean_dir_ext(rel) + return unless extdir?(curr_srcdir()) + make 'distclean' if File.file?('Makefile') + end + + alias distclean_dir_data noop + alias distclean_dir_conf noop + alias distclean_dir_man noop + + # + # Traversing + # + + def exec_task_traverse(task) + run_hook "pre-#{task}" + FILETYPES.each do |type| + if type == 'ext' and config('without-ext') == 'yes' + $stderr.puts 'skipping ext/* by user option' if verbose? + next + end + traverse task, type, "#{task}_dir_#{type}" + end + run_hook "post-#{task}" + end + + def traverse(task, rel, mid) + dive_into(rel) { + run_hook "pre-#{task}" + __send__ mid, rel.sub(%r[\A.*?(?:/|\z)], '') + directories_of(curr_srcdir()).each do |d| + traverse task, "#{rel}/#{d}", mid + end + run_hook "post-#{task}" + } + end + + def dive_into(rel) + return unless File.dir?("#{@srcdir}/#{rel}") + + dir = File.basename(rel) + Dir.mkdir dir unless File.dir?(dir) + prevdir = Dir.pwd + Dir.chdir dir + $stderr.puts '---> ' + rel if verbose? + @currdir = rel + yield + Dir.chdir prevdir + $stderr.puts '<--- ' + rel if verbose? + @currdir = File.dirname(rel) + end + + def run_hook(id) + path = [ "#{curr_srcdir()}/#{id}", + "#{curr_srcdir()}/#{id}.rb" ].detect {|cand| File.file?(cand) } + return unless path + begin + instance_eval File.read(path), path, 1 + rescue + raise if $DEBUG + setup_rb_error "hook #{path} failed:\n" + $!.message + end + end + +end # class Installer + + +class SetupError < StandardError; end + +def setup_rb_error(msg) + raise SetupError, msg +end + +if $0 == __FILE__ + begin + ToplevelInstaller.invoke + rescue SetupError + raise if $DEBUG + $stderr.puts $!.message + $stderr.puts "Try 'ruby #{$0} --help' for detailed usage." + exit 1 + end +end diff --git a/vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/.document b/vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/.document new file mode 100644 index 000000000..ecf367319 --- /dev/null +++ b/vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/.document @@ -0,0 +1,5 @@ +README.rdoc +lib/**/*.rb +bin/* +features/**/*.feature +LICENSE diff --git a/vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/.gitignore b/vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/.gitignore new file mode 100644 index 000000000..482f92bf7 --- /dev/null +++ b/vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/.gitignore @@ -0,0 +1,5 @@ +.DS_Store +.yardoc +/coverage +/doc +/pkg diff --git a/vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/LICENSE b/vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/LICENSE new file mode 100644 index 000000000..590bcb6fa --- /dev/null +++ b/vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/LICENSE @@ -0,0 +1,20 @@ +Copyright 2009 Chris Kampmeier + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/README.rdoc b/vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/README.rdoc new file mode 100644 index 000000000..cfab5434f --- /dev/null +++ b/vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/README.rdoc @@ -0,0 +1,70 @@ += Samuel + +Samuel is a gem for automatic logging of your Net::HTTP requests. It's named for +the serial diarist Mr. Pepys, who was known to reliably record events both +quotidian and remarkable. + +Should a Great Plague, Fire, or Whale befall an important external web service +you use, you'll be sure to have a tidy record of it. + +== Usage: + +When Rails is loaded, Samuel configures a few things automatically. So all you +need to do is this: + + # config/environment.rb + config.gem "samuel" + +And Samuel will automatically use Rails's logger and an ActiveRecord-like format. + +For non-Rails projects, you'll have to manually configure logging, like this: + + require 'samuel' + Samuel.logger = Logger.new('http_requests.log') + +If you don't assign a logger, Samuel will configure a default logger on +STDOUT+. + +== Configuration + +There are two ways to specify configuration options for Samuel: global and +inline. Global configs look like this: + + Samuel.config[:labels] = {"example.com" => "Example API"} + Samuel.config[:filtered_params] = :password + +You should put global configuration somewhere early-on in your program. If +you're using Rails, <tt>config/initializers/samuel.rb</tt> will do the trick. + +Alternatively, an inline configuration block temporarily overrides any global +configuration for a set of HTTP requests: + + Samuel.with_config :label => "Twitter API" do + Net::HTTP.start("twitter.com") { |http| http.get("/help/test") } + end + +Right now, there are three configuration changes you can make in either style: + +* +:labels+ - This is a hash with domain substrings as keys and log labels as + values. If a request domain includes one of the domain substrings, the + corresponding label will be used for the first part of that log entry. By + default this is set to <tt>\{"" => "HTTP"}</tt>, so that all requests are + labeled with <tt>"HTTP Request"</tt>. +* +:label+ - As an alternative to the +:labels+ hash, this is simply a string. + If set, it takes precedence over any +:labels+ (by default, it's not set). It + gets <tt>"Request"</tt> appended to it as well -- so if you want your log to + always say +Twitter API Request+ instead of the default +HTTP Request+, you + can set this to <tt>"Twitter API"</tt>. I'd recommend using this setting + globally if you're only making requests to one service, or inline if you just + need to temporarily override the global +:labels+. +* +:filtered_params+ - This works just like Rails's +filter_parameter_logging+ + method. Set it to a symbol, string, or array of them, and Samuel will filter + the value of query parameters that have any of these patterns as a substring + by replacing the value with <tt>[FILTERED]</tt> in your logs. By default, no + filtering is enabled. + +Samuel logs successful HTTP requests at the +INFO+ level; Failed requests log at +the +WARN+ level. This isn't currently configurable, but it's on the list. + +== License + +Copyright 2009 Chris Kampmeier. See +LICENSE+ for details. diff --git a/vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/Rakefile b/vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/Rakefile new file mode 100644 index 000000000..ffbe60384 --- /dev/null +++ b/vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/Rakefile @@ -0,0 +1,62 @@ +require 'rubygems' +require 'rake' + +begin + require 'jeweler' + Jeweler::Tasks.new do |gem| + gem.name = "samuel" + gem.summary = %Q{An automatic logger for HTTP requests in Ruby} + gem.description = %Q{An automatic logger for HTTP requests in Ruby. Adds Net::HTTP request logging to your Rails logs, and more.} + gem.email = "chris@kampers.net" + gem.homepage = "http://github.com/chrisk/samuel" + gem.authors = ["Chris Kampmeier"] + gem.rubyforge_project = "samuel" + gem.add_development_dependency "thoughtbot-shoulda" + gem.add_development_dependency "yard" + gem.add_development_dependency "mocha" + gem.add_development_dependency "fakeweb" + end + Jeweler::GemcutterTasks.new + Jeweler::RubyforgeTasks.new do |rubyforge| + rubyforge.doc_task = "yardoc" + end +rescue LoadError + puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler" +end + +require 'rake/testtask' +Rake::TestTask.new(:test) do |test| + test.libs << 'lib' << 'test' + test.pattern = 'test/**/*_test.rb' + test.verbose = false + test.warning = true +end + +begin + require 'rcov/rcovtask' + Rcov::RcovTask.new do |test| + test.libs << 'test' + test.pattern = 'test/**/*_test.rb' + test.rcov_opts << "--sort coverage" + test.rcov_opts << "--exclude gems" + test.verbose = false + test.warning = true + end +rescue LoadError + task :rcov do + abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov" + end +end + +task :test => :check_dependencies + +task :default => :test + +begin + require 'yard' + YARD::Rake::YardocTask.new +rescue LoadError + task :yardoc do + abort "YARD is not available. In order to run yardoc, you must: sudo gem install yard" + end +end diff --git a/vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/VERSION b/vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/VERSION new file mode 100644 index 000000000..0c62199f1 --- /dev/null +++ b/vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/VERSION @@ -0,0 +1 @@ +0.2.1 diff --git a/vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/lib/samuel.rb b/vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/lib/samuel.rb new file mode 100644 index 000000000..5c8fed6f6 --- /dev/null +++ b/vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/lib/samuel.rb @@ -0,0 +1,52 @@ +require "logger" +require "net/http" +require "net/https" +require "benchmark" + +require "samuel/net_http" +require "samuel/request" + + +module Samuel + extend self + + attr_writer :config, :logger + + def logger + @logger = nil if !defined?(@logger) + return @logger if !@logger.nil? + + if defined?(RAILS_DEFAULT_LOGGER) + @logger = RAILS_DEFAULT_LOGGER + else + @logger = Logger.new(STDOUT) + end + end + + def config + Thread.current[:__samuel_config] ? Thread.current[:__samuel_config] : @config + end + + def log_request(http, request, &block) + request = Request.new(http, request, block) + request.perform_and_log! + request.response + end + + def with_config(options = {}) + original_config = config.dup + nested = !Thread.current[:__samuel_config].nil? + + Thread.current[:__samuel_config] = original_config.merge(options) + yield + Thread.current[:__samuel_config] = nested ? original_config : nil + end + + def reset_config + Thread.current[:__samuel_config] = nil + @config = {:label => nil, :labels => {"" => "HTTP"}, :filtered_params => []} + end + +end + +Samuel.reset_config diff --git a/vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/lib/samuel/net_http.rb b/vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/lib/samuel/net_http.rb new file mode 100644 index 000000000..2ffadf220 --- /dev/null +++ b/vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/lib/samuel/net_http.rb @@ -0,0 +1,10 @@ +class Net::HTTP + + alias request_without_samuel request + def request(req, body = nil, &block) + Samuel.log_request(self, req) do + request_without_samuel(req, body, &block) + end + end + +end diff --git a/vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/lib/samuel/request.rb b/vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/lib/samuel/request.rb new file mode 100644 index 000000000..e10ecb44e --- /dev/null +++ b/vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/lib/samuel/request.rb @@ -0,0 +1,96 @@ +module Samuel + class Request + + attr_accessor :response + + def initialize(http, request, proc) + @http, @request, @proc = http, request, proc + end + + def perform_and_log! + # If an exception is raised in the Benchmark block, it'll interrupt the + # benchmark. Instead, use an inner block to record it as the "response" + # for raising after the benchmark (and logging) is done. + @seconds = Benchmark.realtime do + begin; @response = @proc.call; rescue Exception => @response; end + end + Samuel.logger.add(log_level, log_message) + raise @response if @response.is_a?(Exception) + end + + private + + def log_message + bold = "\e[1m" + blue = "\e[34m" + underline = "\e[4m" + reset = "\e[0m" + " #{bold}#{blue}#{underline}#{label} request (#{milliseconds}ms) " + + "#{response_summary}#{reset} #{method} #{uri}" + end + + def milliseconds + (@seconds * 1000).round + end + + def uri + "#{scheme}://#{@http.address}#{port_if_not_default}#{filtered_path}" + end + + def filtered_path + path_without_query, query = @request.path.split("?") + if query + patterns = [Samuel.config[:filtered_params]].flatten + patterns.map { |pattern| + pattern_for_regex = Regexp.escape(pattern.to_s) + [/([^&]*#{pattern_for_regex}[^&=]*)=(?:[^&]+)/, '\1=[FILTERED]'] + }.each { |filter| query.gsub!(*filter) } + "#{path_without_query}?#{query}" + else + @request.path + end + end + + def scheme + @http.use_ssl? ? "https" : "http" + end + + def port_if_not_default + ssl, port = @http.use_ssl?, @http.port + if (!ssl && port == 80) || (ssl && port == 443) + "" + else + ":#{port}" + end + end + + def method + @request.method.to_s.upcase + end + + def label + return Samuel.config[:label] if Samuel.config[:label] + + pair = Samuel.config[:labels].detect { |domain, label| @http.address.include?(domain) } + pair[1] if pair + end + + def response_summary + if response.is_a?(Exception) + response.class + else + "[#{response.code} #{response.message}]" + end + end + + def log_level + error_classes = [Exception, Net::HTTPClientError, Net::HTTPServerError] + if error_classes.any? { |klass| response.is_a?(klass) } + level = Logger::WARN + else + level = Logger::INFO + end + end + + end +end diff --git a/vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/samuel.gemspec b/vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/samuel.gemspec new file mode 100644 index 000000000..3a3719bf8 --- /dev/null +++ b/vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/samuel.gemspec @@ -0,0 +1,69 @@ +# Generated by jeweler +# DO NOT EDIT THIS FILE +# Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec` +# -*- encoding: utf-8 -*- + +Gem::Specification.new do |s| + s.name = %q{samuel} + s.version = "0.2.1" + + s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= + s.authors = ["Chris Kampmeier"] + s.date = %q{2009-09-15} + s.description = %q{An automatic logger for HTTP requests in Ruby. Adds Net::HTTP request logging to your Rails logs, and more.} + s.email = %q{chris@kampers.net} + s.extra_rdoc_files = [ + "LICENSE", + "README.rdoc" + ] + s.files = [ + ".document", + ".gitignore", + "LICENSE", + "README.rdoc", + "Rakefile", + "VERSION", + "lib/samuel.rb", + "lib/samuel/net_http.rb", + "lib/samuel/request.rb", + "samuel.gemspec", + "test/request_test.rb", + "test/samuel_test.rb", + "test/test_helper.rb", + "test/thread_test.rb" + ] + s.homepage = %q{http://github.com/chrisk/samuel} + s.rdoc_options = ["--charset=UTF-8"] + s.require_paths = ["lib"] + s.rubyforge_project = %q{samuel} + s.rubygems_version = %q{1.3.5} + s.summary = %q{An automatic logger for HTTP requests in Ruby} + s.test_files = [ + "test/request_test.rb", + "test/samuel_test.rb", + "test/test_helper.rb", + "test/thread_test.rb" + ] + + if s.respond_to? :specification_version then + current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION + s.specification_version = 3 + + if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then + s.add_development_dependency(%q<thoughtbot-shoulda>, [">= 0"]) + s.add_development_dependency(%q<yard>, [">= 0"]) + s.add_development_dependency(%q<mocha>, [">= 0"]) + s.add_development_dependency(%q<fakeweb>, [">= 0"]) + else + s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"]) + s.add_dependency(%q<yard>, [">= 0"]) + s.add_dependency(%q<mocha>, [">= 0"]) + s.add_dependency(%q<fakeweb>, [">= 0"]) + end + else + s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"]) + s.add_dependency(%q<yard>, [">= 0"]) + s.add_dependency(%q<mocha>, [">= 0"]) + s.add_dependency(%q<fakeweb>, [">= 0"]) + end +end diff --git a/vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/test/request_test.rb b/vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/test/request_test.rb new file mode 100644 index 000000000..4e905d1ec --- /dev/null +++ b/vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/test/request_test.rb @@ -0,0 +1,193 @@ +require 'test_helper' + +class RequestTest < Test::Unit::TestCase + + context "making an HTTP request" do + setup { setup_test_logger + FakeWeb.clean_registry + Samuel.reset_config } + teardown { teardown_test_logger } + + context "to GET http://example.com/test, responding with a 200 in 53ms" do + setup do + FakeWeb.register_uri(:get, "http://example.com/test", :status => [200, "OK"]) + Benchmark.stubs(:realtime).yields.returns(0.053) + open "http://example.com/test" + end + + should_log_lines 1 + should_log_at_level :info + should_log_including "HTTP request" + should_log_including "(53ms)" + should_log_including "[200 OK]" + should_log_including "GET http://example.com/test" + end + + context "on a non-standard port" do + setup do + FakeWeb.register_uri(:get, "http://example.com:8080/test", :status => [200, "OK"]) + open "http://example.com:8080/test" + end + + should_log_including "GET http://example.com:8080/test" + end + + context "with SSL" do + setup do + FakeWeb.register_uri(:get, "https://example.com/test", :status => [200, "OK"]) + open "https://example.com/test" + end + + should_log_including "HTTP request" + should_log_including "GET https://example.com/test" + end + + context "with SSL on a non-standard port" do + setup do + FakeWeb.register_uri(:get, "https://example.com:80/test", :status => [200, "OK"]) + open "https://example.com:80/test" + end + + should_log_including "HTTP request" + should_log_including "GET https://example.com:80/test" + end + + context "that raises" do + setup do + FakeWeb.register_uri(:get, "http://example.com/test", :exception => Errno::ECONNREFUSED) + begin + Net::HTTP.start("example.com") { |http| http.get("/test") } + rescue Errno::ECONNREFUSED => @exception + end + end + + should_log_at_level :warn + should_log_including "HTTP request" + should_log_including "GET http://example.com/test" + should_log_including "Errno::ECONNREFUSED" + should_log_including %r|\d+ms| + should_raise_exception Errno::ECONNREFUSED + end + + context "that responds with a 500-level code" do + setup do + FakeWeb.register_uri(:get, "http://example.com/test", :status => [502, "Bad Gateway"]) + Net::HTTP.start("example.com") { |http| http.get("/test") } + end + + should_log_at_level :warn + end + + context "that responds with a 400-level code" do + setup do + FakeWeb.register_uri(:get, "http://example.com/test", :status => [404, "Not Found"]) + Net::HTTP.start("example.com") { |http| http.get("/test") } + end + + should_log_at_level :warn + end + + context "inside a configuration block with :label => 'Example'" do + setup do + FakeWeb.register_uri(:get, "http://example.com/test", :status => [200, "OK"]) + Samuel.with_config :label => "Example" do + open "http://example.com/test" + end + end + + should_log_including "Example request" + should_have_config_afterwards_including :labels => {"" => "HTTP"}, + :label => nil + end + + context "inside a configuration block with :filter_params" do + setup do + FakeWeb.register_uri(:get, "http://example.com/test?password=secret&username=chrisk", + :status => [200, "OK"]) + @uri = "http://example.com/test?password=secret&username=chrisk" + end + + context "=> :password" do + setup { Samuel.with_config(:filtered_params => :password) { open @uri } } + should_log_including "http://example.com/test?password=[FILTERED]&username=chrisk" + end + + context "=> :as" do + setup { Samuel.with_config(:filtered_params => :ass) { open @uri } } + should_log_including "http://example.com/test?password=[FILTERED]&username=chrisk" + end + + context "=> ['pass', 'name']" do + setup { Samuel.with_config(:filtered_params => %w(pass name)) { open @uri } } + should_log_including "http://example.com/test?password=[FILTERED]&username=[FILTERED]" + end + end + + context "with a global config including :label => 'Example'" do + setup do + FakeWeb.register_uri(:get, "http://example.com/test", :status => [200, "OK"]) + Samuel.config[:label] = "Example" + open "http://example.com/test" + end + + should_log_including "Example request" + should_have_config_afterwards_including :labels => {"" => "HTTP"}, + :label => "Example" + end + + context "with a global config including :label => 'Example' but inside config block that changes it to 'Example 2'" do + setup do + FakeWeb.register_uri(:get, "http://example.com/test", :status => [200, "OK"]) + Samuel.config[:label] = "Example" + Samuel.with_config(:label => "Example 2") { open "http://example.com/test" } + end + + should_log_including "Example 2 request" + should_have_config_afterwards_including :labels => {"" => "HTTP"}, + :label => "Example" + end + + context "inside a config block of :label => 'Example 2' nested inside a config block of :label => 'Example'" do + setup do + FakeWeb.register_uri(:get, "http://example.com/test", :status => [200, "OK"]) + Samuel.with_config :label => "Example" do + Samuel.with_config :label => "Example 2" do + open "http://example.com/test" + end + end + end + + should_log_including "Example 2 request" + should_have_config_afterwards_including :labels => {"" => "HTTP"}, + :label => nil + end + + context "wth a global config including :labels => {'example.com' => 'Example'} but inside a config block of :label => 'Example 3' nested inside a config block of :label => 'Example 2'" do + setup do + FakeWeb.register_uri(:get, "http://example.com/test", :status => [200, "OK"]) + Samuel.config[:labels] = {'example.com' => 'Example'} + Samuel.with_config :label => "Example 2" do + Samuel.with_config :label => "Example 3" do + open "http://example.com/test" + end + end + end + + should_log_including "Example 3 request" + should_have_config_afterwards_including :labels => {'example.com' => 'Example'}, + :label => nil + end + + context "with a global config including :labels => {'example.com' => 'Example API'}" do + setup do + FakeWeb.register_uri(:get, "http://example.com/test", :status => [200, "OK"]) + Samuel.config[:labels] = {'example.com' => 'Example API'} + open "http://example.com/test" + end + + should_log_including "Example API request" + end + + end + +end diff --git a/vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/test/samuel_test.rb b/vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/test/samuel_test.rb new file mode 100644 index 000000000..4a3665fa6 --- /dev/null +++ b/vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/test/samuel_test.rb @@ -0,0 +1,42 @@ +require 'test_helper' + +class SamuelTest < Test::Unit::TestCase + + context "logger configuration" do + setup do + Samuel.logger = nil + if Object.const_defined?(:RAILS_DEFAULT_LOGGER) + Object.send(:remove_const, :RAILS_DEFAULT_LOGGER) + end + end + + teardown do + Samuel.logger = nil + end + + context "when Rails's logger is available" do + setup { Object.const_set(:RAILS_DEFAULT_LOGGER, :mock_logger) } + + should "use the same logger" do + assert_equal :mock_logger, Samuel.logger + end + end + + context "when Rails's logger is not available" do + should "use a new Logger instance pointed to STDOUT" do + assert_instance_of Logger, Samuel.logger + assert_equal STDOUT, Samuel.logger.instance_variable_get(:"@logdev").dev + end + end + end + + + context ".reset_config" do + should "reset the config to default vaules" do + Samuel.config = {:foo => "bar"} + Samuel.reset_config + assert_equal({:label => nil, :labels => {"" => "HTTP"}, :filtered_params => []}, Samuel.config) + end + end + +end diff --git a/vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/test/test_helper.rb b/vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/test/test_helper.rb new file mode 100644 index 000000000..2862051b9 --- /dev/null +++ b/vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/test/test_helper.rb @@ -0,0 +1,66 @@ +require 'rubygems' +require 'test/unit' +require 'shoulda' +require 'mocha' +require 'open-uri' +require 'fakeweb' + +FakeWeb.allow_net_connect = false + +$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib')) +$LOAD_PATH.unshift(File.dirname(__FILE__)) +require 'samuel' + +class Test::Unit::TestCase + TEST_LOG_PATH = File.join(File.dirname(__FILE__), 'test.log') + + def self.should_log_lines(expected_count) + should "log #{expected_count} line#{'s' unless expected_count == 1}" do + lines = File.readlines(TEST_LOG_PATH) + assert_equal expected_count, lines.length + end + end + + def self.should_log_including(what) + should "log a line including #{what.inspect}" do + contents = File.read(TEST_LOG_PATH) + if what.is_a?(Regexp) + assert_match what, contents + else + assert contents.include?(what), + "Expected #{contents.inspect} to include #{what.inspect}" + end + end + end + + def self.should_log_at_level(level) + level = level.to_s.upcase + should "log at the #{level} level" do + assert File.read(TEST_LOG_PATH).include?(" #{level} -- :") + end + end + + def self.should_raise_exception(klass) + should "raise an #{klass} exception" do + assert @exception.is_a?(klass) + end + end + + def self.should_have_config_afterwards_including(config) + config.each_pair do |key, value| + should "continue afterwards with Samuel.config[#{key.inspect}] set to #{value.inspect}" do + assert_equal value, Samuel.config[key] + end + end + end + + def setup_test_logger + FileUtils.rm_rf TEST_LOG_PATH + FileUtils.touch TEST_LOG_PATH + Samuel.logger = Logger.new(TEST_LOG_PATH) + end + + def teardown_test_logger + FileUtils.rm_rf TEST_LOG_PATH + end +end diff --git a/vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/test/thread_test.rb b/vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/test/thread_test.rb new file mode 100644 index 000000000..d030cb973 --- /dev/null +++ b/vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/test/thread_test.rb @@ -0,0 +1,32 @@ +require 'test_helper' + +class ThreadTest < Test::Unit::TestCase + + context "when logging multiple requests at once" do + setup do + @log = StringIO.new + Samuel.logger = Logger.new(@log) + FakeWeb.register_uri(:get, /example\.com/, :status => [200, "OK"]) + threads = [] + 5.times do |i| + threads << Thread.new(i) do |n| + Samuel.with_config :label => "Example #{n}" do + Thread.pass + open "http://example.com/#{n}" + end + end + end + threads.each { |t| t.join } + @log.rewind + end + + should "not let configuration blocks interfere with eachother" do + @log.each_line do |line| + matches = %r|Example (\d+).*example\.com/(\d+)|.match(line) + assert_not_nil matches + assert_equal matches[1], matches[2] + end + end + end + +end diff --git a/vendor/plugins/acts_as_xapian/lib/acts_as_xapian.rb b/vendor/plugins/acts_as_xapian/lib/acts_as_xapian.rb index fb6a08979..d5c0e89c6 100644 --- a/vendor/plugins/acts_as_xapian/lib/acts_as_xapian.rb +++ b/vendor/plugins/acts_as_xapian/lib/acts_as_xapian.rb @@ -30,14 +30,19 @@ module ActsAsXapian class NoXapianRubyBindingsError < StandardError end - # XXX global class intializers here get loaded more than once, don't know why. Protect them. - if not $acts_as_xapian_class_var_init - @@db = nil - @@db_path = nil - @@writable_db = nil - @@init_values = [] + @@db = nil + @@db_path = nil + @@writable_db = nil + @@init_values = [] + + # There used to be a problem with this module being loaded more than once. + # Keep a check here, so we can tell if the problem recurs. + if $acts_as_xapian_class_var_init + raise "The acts_as_xapian module has already been loaded" + else $acts_as_xapian_class_var_init = true end + def ActsAsXapian.db @@db end @@ -111,14 +116,17 @@ module ActsAsXapian raise NoXapianRubyBindingsError.new("Xapian Ruby bindings not installed") unless ActsAsXapian.bindings_available raise "acts_as_xapian hasn't been called in any models" if @@init_values.empty? - # if DB is not nil, then we're already initialised, so don't do it again - # XXX we need to reopen the database each time, so Xapian gets changes to it. - # Hopefully in later version of Xapian it will autodetect this, and this can - # be commented back in again. - # return unless @@db.nil? - prepare_environment + # We need to reopen the database each time, so Xapian gets changes to it. + # Calling reopen() does not always pick up changes for reasons that I can + # only speculate about at the moment. (It is easy to reproduce this by + # changing the code below to use reopen() rather than open() followed by + # close(), and running rake spec.) + if !@@db.nil? + @@db.close + end + # basic Xapian objects begin @@db = Xapian::Database.new(@@db_path) @@ -138,6 +146,16 @@ module ActsAsXapian @@query_parser.stemming_strategy = Xapian::QueryParser::STEM_SOME @@query_parser.database = @@db @@query_parser.default_op = Xapian::Query::OP_AND + begin + @@query_parser.set_max_wildcard_expansion(1000) + rescue NoMethodError + # The set_max_wildcard_expansion method was introduced in Xapian 1.2.7, + # so may legitimately not be available. + # + # Large installations of Alaveteli should consider + # upgrading, because uncontrolled wildcard expansion + # can crash the whole server: see http://trac.xapian.org/ticket/350 + end @@stopper = Xapian::SimpleStopper.new @@stopper.add("and") @@ -218,7 +236,8 @@ module ActsAsXapian full_path = @@db_path + suffix # for indexing - @@writable_db = Xapian::flint_open(full_path, Xapian::DB_CREATE_OR_OPEN) + @@writable_db = Xapian::WritableDatabase.new(full_path, Xapian::DB_CREATE_OR_OPEN) + @@enquire = Xapian::Enquire.new(@@writable_db) @@term_generator = Xapian::TermGenerator.new() @@term_generator.set_flags(Xapian::TermGenerator::FLAG_SPELLING, 0) @@term_generator.database = @@writable_db @@ -247,6 +266,8 @@ module ActsAsXapian end end + MSET_MAX_TRIES = 5 + MSET_MAX_DELAY = 5 # Set self.query before calling this def initialize_query(options) #raise options.to_yaml @@ -266,7 +287,7 @@ module ActsAsXapian ActsAsXapian.enquire.sort_by_relevance! else value = ActsAsXapian.values_by_prefix[sort_by_prefix] - raise "couldn't find prefix '" + sort_by_prefix + "'" if value.nil? + raise "couldn't find prefix '" + sort_by_prefix.to_s + "'" if value.nil? ActsAsXapian.enquire.sort_by_value_then_relevance!(value, sort_by_ascending) end if collapse_by_prefix.nil? @@ -277,7 +298,28 @@ module ActsAsXapian ActsAsXapian.enquire.collapse_key = value end - self.matches = ActsAsXapian.enquire.mset(offset, limit, 100) + tries = 0 + delay = 1 + begin + self.matches = ActsAsXapian.enquire.mset(offset, limit, 100) + rescue IOError => e + if e.message =~ /DatabaseModifiedError: / + # This should be a transient error, so back off and try again, up to a point + if tries > MSET_MAX_TRIES + raise "Received DatabaseModifiedError from Xapian even after retrying #{MSET_MAX_TRIES} times" + else + sleep delay + end + tries += 1 + delay *= 2 + delay = MSET_MAX_DELAY if delay > MSET_MAX_DELAY + + ActsAsXapian.db.reopen() + retry + else + raise + end + end self.cached_results = nil } end @@ -391,7 +433,7 @@ module ActsAsXapian # User]. Can take a single model class, or you can express the model # class names in strings if you like. # query_string - user inputed query string, with syntax much like Google Search - def initialize(model_classes, query_string, options = {}) + def initialize(model_classes, query_string, options = {}, user_query = nil) # Check parameters, convert to actual array of model classes new_model_classes = [] model_classes = [model_classes] if model_classes.class != Array @@ -410,10 +452,13 @@ module ActsAsXapian # Construct query which only finds things from specified models model_query = Xapian::Query.new(Xapian::Query::OP_OR, model_classes.map{|mc| "M" + mc.to_s}) - user_query = ActsAsXapian.query_parser.parse_query(self.query_string, - Xapian::QueryParser::FLAG_BOOLEAN | Xapian::QueryParser::FLAG_PHRASE | - Xapian::QueryParser::FLAG_LOVEHATE | Xapian::QueryParser::FLAG_WILDCARD | - Xapian::QueryParser::FLAG_SPELLING_CORRECTION) + if user_query.nil? + user_query = ActsAsXapian.query_parser.parse_query( + self.query_string, + Xapian::QueryParser::FLAG_BOOLEAN | Xapian::QueryParser::FLAG_PHRASE | + Xapian::QueryParser::FLAG_LOVEHATE | + Xapian::QueryParser::FLAG_SPELLING_CORRECTION) + end self.query = Xapian::Query.new(Xapian::Query::OP_AND, model_query, user_query) # Call base class constructor @@ -525,7 +570,6 @@ module ActsAsXapian return if model_classes.size == 0 ActsAsXapian.writable_init - # Abort if full rebuild is going on new_path = ActsAsXapian.db_path + ".new" if File.exist?(new_path) @@ -544,10 +588,11 @@ module ActsAsXapian # was updated a second time by another process. In that case # ActsAsXapianJob.delete_all in xapian_mark_needs_index below # might have removed the first job record while we are working on it. - STDOUT.puts("job with #{id} vanished under foot") if verbose + #STDERR.puts("job with #{id} vanished under foot") if verbose next end STDOUT.puts("ActsAsXapian.update_index #{job.action} #{job.model} #{job.model_id.to_s} #{Time.now.to_s}") if verbose + begin if job.action == 'update' # XXX Index functions may reference other models, so we could eager load here too? @@ -566,47 +611,58 @@ module ActsAsXapian job.action = 'destroy' retry end - job.destroy - if flush ActsAsXapian.writable_db.flush end + job.destroy end rescue => detail # print any error, and carry on so other things are indexed STDERR.puts(detail.backtrace.join("\n") + "\nFAILED ActsAsXapian.update_index job #{id} #{$!} " + (job.nil? ? "" : "model " + job.model + " id " + job.model_id.to_s)) end end - # We close the database when we're finished to remove the lock file. Since writable_init # reopens it and recreates the environment every time we don't need to do further cleanup + ActsAsXapian.writable_db.flush ActsAsXapian.writable_db.close end + def ActsAsXapian._is_xapian_db(path) + is_db = File.exist?(File.join(path, "iamflint")) || File.exist?(File.join(path, "iamchert")) + return is_db + end + # You must specify *all* the models here, this totally rebuilds the Xapian # database. You'll want any readers to reopen the database after this. # # Incremental update_index calls above are suspended while this rebuild # happens (i.e. while the .new database is there) - any index update jobs # are left in the database, and will run after the rebuild has finished. + def ActsAsXapian.rebuild_index(model_classes, verbose = false, terms = true, values = true, texts = true, safe_rebuild = true) #raise "when rebuilding all, please call as first and only thing done in process / task" if not ActsAsXapian.writable_db.nil? - prepare_environment - - # Delete any existing .new database, and open a new one + + update_existing = !(terms == true && values == true && texts == true) + # Delete any existing .new database, and open a new one which is a copy of the current one new_path = ActsAsXapian.db_path + ".new" + old_path = ActsAsXapian.db_path if File.exist?(new_path) - raise "found existing " + new_path + " which is not Xapian flint database, please delete for me" if not File.exist?(File.join(new_path, "iamflint")) + raise "found existing " + new_path + " which is not Xapian flint database, please delete for me" if not ActsAsXapian._is_xapian_db(new_path) FileUtils.rm_r(new_path) end - + if update_existing + FileUtils.cp_r(old_path, new_path) + end + ActsAsXapian.writable_init + ActsAsXapian.writable_db.close # just to make an empty one to read # Index everything if safe_rebuild _rebuild_index_safely(model_classes, verbose, terms, values, texts) else + @@db_path = ActsAsXapian.db_path + ".new" + ActsAsXapian.writable_init # Save time by running the indexing in one go and in-process - ActsAsXapian.writable_init(".new") for model_class in model_classes STDOUT.puts("ActsAsXapian.rebuild_index: Rebuilding #{model_class.to_s}") if verbose model_class.find(:all).each do |model| @@ -614,16 +670,15 @@ module ActsAsXapian model.xapian_index(terms, values, texts) end end - # make sure everything is written and close ActsAsXapian.writable_db.flush ActsAsXapian.writable_db.close end # Rename into place - old_path = ActsAsXapian.db_path - temp_path = ActsAsXapian.db_path + ".tmp" + temp_path = old_path + ".tmp" if File.exist?(temp_path) - raise "temporary database found " + temp_path + " which is not Xapian flint database, please delete for me" if not File.exist?(File.join(temp_path, "iamflint")) + @@db_path = old_path + raise "temporary database found " + temp_path + " which is not Xapian flint database, please delete for me" if not ActsAsXapian._is_xapian_db(temp_path) FileUtils.rm_r(temp_path) end if File.exist?(old_path) @@ -633,12 +688,16 @@ module ActsAsXapian # Delete old database if File.exist?(temp_path) - raise "old database now at " + temp_path + " is not Xapian flint database, please delete for me" if not File.exist?(File.join(temp_path, "iamflint")) + if not ActsAsXapian._is_xapian_db(temp_path) + @@db_path = old_path + raise "old database now at " + temp_path + " is not Xapian flint database, please delete for me" + end FileUtils.rm_r(temp_path) end # You'll want to restart your FastCGI or Mongrel processes after this, # so they get the new db + @@db_path = old_path end def ActsAsXapian._rebuild_index_safely(model_classes, verbose, terms, values, texts) @@ -658,18 +717,18 @@ module ActsAsXapian # database connection doesn't survive a fork, rebuild it ActiveRecord::Base.connection.reconnect! else + # fully reopen the database each time (with a new object) # (so doc ids and so on aren't preserved across the fork) - ActsAsXapian.writable_init(".new") + @@db_path = ActsAsXapian.db_path + ".new" + ActsAsXapian.writable_init STDOUT.puts("ActsAsXapian.rebuild_index: New batch. #{model_class.to_s} from #{i} to #{i + batch_size} of #{model_class_count} pid #{Process.pid.to_s}") if verbose model_class.find(:all, :limit => batch_size, :offset => i, :order => :id).each do |model| STDOUT.puts("ActsAsXapian.rebuild_index #{model_class} #{model.id}") if verbose model.xapian_index(terms, values, texts) end - # make sure everything is written ActsAsXapian.writable_db.flush - # close database - ActsAsXapian.writable_db.close + ActsAsXapian.writable_db.close # database connection won't survive a fork, so shut it down ActiveRecord::Base.connection.disconnect! # brutal exit, so other shutdown code not run (for speed and safety) @@ -739,7 +798,7 @@ module ActsAsXapian # Store record in the Xapian database def xapian_index(terms = true, values = true, texts = true) - # if we have a conditional function for indexing, call it and destory object if failed + # if we have a conditional function for indexing, call it and destroy object if failed if self.class.xapian_options.include?(:if) if_value = xapian_value(self.class.xapian_options[:if], :boolean) if not if_value @@ -748,13 +807,6 @@ module ActsAsXapian end end - if self.class.to_s == "PublicBody" and self.url_name == "tgq" - -#require 'ruby-debug' -#debugger - end - # otherwise (re)write the Xapian record for the object - ActsAsXapian.readable_init existing_query = Xapian::Query.new("I" + self.xapian_document_term) ActsAsXapian.enquire.query = existing_query match = ActsAsXapian.enquire.mset(0,1,1).matches[0] @@ -767,8 +819,8 @@ module ActsAsXapian doc.add_term("M" + self.class.to_s) doc.add_term("I" + doc.data) end - ActsAsXapian.term_generator.document = doc - # work out what to index. XXX for now, this is only selective on "terms". + # work out what to index + # 1. Which terms to index? We allow the user to specify particular ones terms_to_index = [] drop_all_terms = false if terms and self.xapian_options[:terms] @@ -782,16 +834,18 @@ module ActsAsXapian drop_all_terms = true end end + # 2. Texts to index? Currently, it's all or nothing texts_to_index = [] if texts and self.xapian_options[:texts] texts_to_index = self.xapian_options[:texts] end + # 3. Values to index? Currently, it's all or nothing values_to_index = [] if values and self.xapian_options[:values] values_to_index = self.xapian_options[:values] end - # clear any existing values that we might want to replace + # clear any existing data that we might want to replace if drop_all_terms && texts # as an optimisation, if we're reindexing all of both, we remove everything doc.clear_terms @@ -801,17 +855,17 @@ module ActsAsXapian term_prefixes_to_index = terms_to_index.map {|x| x[1]} for existing_term in doc.terms first_letter = existing_term.term[0...1] - if !"MI".include?(first_letter) - if first_letter.match("^[A-Z]+") && terms_to_index.include?(first_letter) - doc.remove_term(existing_term.term) + if !"MI".include?(first_letter) # it's not one of the reserved value + if first_letter.match("^[A-Z]+") # it's a "value" (rather than indexed text) + if term_prefixes_to_index.include?(first_letter) # it's a value that we've been asked to index + doc.remove_term(existing_term.term) + end elsif texts - doc.remove_term(existing_term.term) + doc.remove_term(existing_term.term) # it's text and we've been asked to reindex it end end end end - # for now, we always clear values - doc.clear_values for term in terms_to_index value = xapian_value(term[0]) @@ -823,15 +877,20 @@ module ActsAsXapian doc.add_term(term[1] + value) end end - # values - for value in values_to_index - doc.add_value(value[1], xapian_value(value[0], value[3])) + + if values + doc.clear_values + for value in values_to_index + doc.add_value(value[1], xapian_value(value[0], value[3])) + end end - # texts - for text in texts_to_index - ActsAsXapian.term_generator.increase_termpos # stop phrases spanning different text fields - # XXX the "1" here is a weight that could be varied for a boost function - ActsAsXapian.term_generator.index_text(xapian_value(text, nil, true), 1) + if texts + ActsAsXapian.term_generator.document = doc + for text in texts_to_index + ActsAsXapian.term_generator.increase_termpos # stop phrases spanning different text fields + # XXX the "1" here is a weight that could be varied for a boost function + ActsAsXapian.term_generator.index_text(xapian_value(text, nil, true), 1) + end end ActsAsXapian.writable_db.replace_document("I" + doc.data, doc) diff --git a/vendor/plugins/acts_as_xapian/lib/tasks/xapian.rake b/vendor/plugins/acts_as_xapian/lib/tasks/xapian.rake index d18cd07d5..c1986ce1e 100644 --- a/vendor/plugins/acts_as_xapian/lib/tasks/xapian.rake +++ b/vendor/plugins/acts_as_xapian/lib/tasks/xapian.rake @@ -2,7 +2,6 @@ require 'rubygems' require 'rake' require 'rake/testtask' require 'active_record' -require File.dirname(__FILE__) + '/../acts_as_xapian.rb' namespace :xapian do # Parameters - specify "flush=true" to save changes to the Xapian database @@ -30,12 +29,23 @@ namespace :xapian do desc 'Completely rebuilds Xapian search index (must specify all models)' task :rebuild_index => :environment do + def coerce_arg(arg, default) + if arg == "false" + return false + elsif arg == "true" + return true + elsif arg.nil? + return default + else + return arg + end + end raise "specify ALL your models with models=\"ModelName1 ModelName2\" as parameter" if ENV['models'].nil? ActsAsXapian.rebuild_index(ENV['models'].split(" ").map{|m| m.constantize}, - ENV['verbose'] ? true : false, - ENV['terms'] == "false" ? false : ENV['terms'], - ENV['values'] == "false" ? false : ENV['values'], - ENV['texts'] == "false" ? false : true) + coerce_arg(ENV['verbose'], false), + coerce_arg(ENV['terms'], true), + coerce_arg(ENV['values'], true), + coerce_arg(ENV['texts'], true)) end # Parameters - are models, query, offset, limit, sort_by_prefix, diff --git a/vendor/plugins/exception_notification/README b/vendor/plugins/exception_notification/README new file mode 100644 index 000000000..d5e343630 --- /dev/null +++ b/vendor/plugins/exception_notification/README @@ -0,0 +1,144 @@ += Exception Notifier Plugin for Rails + +The Exception Notifier plugin provides a mailer object and a default set of +templates for sending email notifications when errors occur in a Rails +application. The plugin is configurable, allowing programmers to specify: + +* the sender address of the email +* the recipient addresses +* the text used to prefix the subject line + +The email includes information about the current request, session, and +environment, and also gives a backtrace of the exception. + +== Usage + +First, include the ExceptionNotifiable mixin in whichever controller you want +to generate error emails (typically ApplicationController): + + class ApplicationController < ActionController::Base + include ExceptionNotification::Notifiable + ... + end + +Then, specify the email recipients in your environment: + + ExceptionNotification::Notifier.exception_recipients = %w(joe@schmoe.com bill@schmoe.com) + +And that's it! The defaults take care of the rest. + +== Configuration + +You can tweak other values to your liking, as well. In your environment file, +just set any or all of the following values: + + # defaults to exception.notifier@default.com + ExceptionNotification::Notifier.sender_address = + %("Application Error" <app.error@myapp.com>) + + # defaults to "[ERROR] " + ExceptionNotification::Notifier.email_prefix = "[APP] " + +Even if you have mixed into ApplicationController you can skip notification in +some controllers by + + class MyController < ApplicationController + skip_exception_notifications + end + +== Deprecated local_request? overriding + +Email notifications will only occur when the IP address is determined not to +be local. You can specify certain addresses to always be local so that you'll +get a detailed error instead of the generic error page. You do this in your +controller (or even per-controller): + + consider_local "64.72.18.143", "14.17.21.25" + +You can specify subnet masks as well, so that all matching addresses are +considered local: + + consider_local "64.72.18.143/24" + +The address "127.0.0.1" is always considered local. If you want to completely +reset the list of all addresses (for instance, if you wanted "127.0.0.1" to +NOT be considered local), you can simply do, somewhere in your controller: + + local_addresses.clear + +NOTE: The above functionality has has been pulled out to consider_local.rb, +as interfering with rails local determination is orthogonal to notification, +unnecessarily clutters backtraces, and even occasionally errs on odd ip or +requests bugs. To return original functionality add an initializer with: + + ActionController::Base.send :include, ConsiderLocal + +or just include it per controller that wants it + + class MyController < ApplicationController + include ExceptionNotification::ConsiderLocal + end + +== Customization + +By default, the notification email includes four parts: request, session, +environment, and backtrace (in that order). You can customize how each of those +sections are rendered by placing a partial named for that part in your +app/views/exception_notifier directory (e.g., _session.rhtml). Each partial has +access to the following variables: + +* @controller: the controller that caused the error +* @request: the current request object +* @exception: the exception that was raised +* @host: the name of the host that made the request +* @backtrace: a sanitized version of the exception's backtrace +* @rails_root: a sanitized version of RAILS_ROOT +* @data: a hash of optional data values that were passed to the notifier +* @sections: the array of sections to include in the email + +You can reorder the sections, or exclude sections completely, by altering the +ExceptionNotification::Notifier.sections variable. You can even add new sections that +describe application-specific data--just add the section's name to the list +(whereever you'd like), and define the corresponding partial. Then, if your +new section requires information that isn't available by default, make sure +it is made available to the email using the exception_data macro: + + class ApplicationController < ActionController::Base + ... + protected + exception_data :additional_data + + def additional_data + { :document => @document, + :person => @person } + end + ... + end + +In the above case, @document and @person would be made available to the email +renderer, allowing your new section(s) to access and display them. See the +existing sections defined by the plugin for examples of how to write your own. + +== 404s errors + +Notification is skipped if you return a 404 status, which happens by default +for an ActiveRecord::RecordNotFound or ActionController::UnknownAction error. + +== Manually notifying of error in a rescue block + +If your controller action manually handles an error, the notifier will never be +run. To manually notify of an error call notify_about_exception from within the +rescue block + + def index + #risky operation here + rescue StandardError => error + #custom error handling here + notify_about_exception(error) + end + +== Support and tickets + +https://rails.lighthouseapp.com/projects/8995-rails-plugins + +Copyright (c) 2005 Jamis Buck, released under the MIT license
\ No newline at end of file diff --git a/vendor/plugins/exception_notification/exception_notification.gemspec b/vendor/plugins/exception_notification/exception_notification.gemspec new file mode 100644 index 000000000..b3ff82322 --- /dev/null +++ b/vendor/plugins/exception_notification/exception_notification.gemspec @@ -0,0 +1,11 @@ +Gem::Specification.new do |s| + s.name = 'exception_notification' + s.version = '2.3.3.0' + s.authors = ["Jamis Buck", "Josh Peek", "Tim Connor"] + s.date = %q{2010-03-13} + s.summary = "Exception notification by email for Rails apps - 2.3-stable compatible version" + s.email = "timocratic@gmail.com" + + s.files = ['README'] + Dir['lib/**/*'] + Dir['views/**/*'] + s.require_path = 'lib' +end diff --git a/vendor/plugins/exception_notification/init.rb b/vendor/plugins/exception_notification/init.rb new file mode 100644 index 000000000..ef215f809 --- /dev/null +++ b/vendor/plugins/exception_notification/init.rb @@ -0,0 +1 @@ +require "exception_notification" diff --git a/vendor/plugins/exception_notification/lib/exception_notification.rb b/vendor/plugins/exception_notification/lib/exception_notification.rb new file mode 100644 index 000000000..bf5975201 --- /dev/null +++ b/vendor/plugins/exception_notification/lib/exception_notification.rb @@ -0,0 +1,7 @@ +require "action_mailer" +module ExceptionNotification + autoload :Notifiable, 'exception_notification/notifiable' + autoload :Notifier, 'exception_notification/notifier' + #autoload :NotifierHelper, 'exception_notification/notifier_helper' + autoload :ConsiderLocal, 'exception_notification/consider_local' +end
\ No newline at end of file diff --git a/vendor/plugins/exception_notification/lib/exception_notification/consider_local.rb b/vendor/plugins/exception_notification/lib/exception_notification/consider_local.rb new file mode 100644 index 000000000..6b9e236f7 --- /dev/null +++ b/vendor/plugins/exception_notification/lib/exception_notification/consider_local.rb @@ -0,0 +1,31 @@ +#This didn't belong on ExceptionNotifier and made backtraces worse. To keep original functionality in place +#'ActionController::Base.send :include, ExceptionNotification::ConsiderLocal' or just include in your controller +module ExceptionNotification::ConsiderLocal + def self.included(target) + require 'ipaddr' + target.extend(ClassMethods) + end + + module ClassMethods + def consider_local(*args) + local_addresses.concat(args.flatten.map { |a| IPAddr.new(a) }) + end + + def local_addresses + addresses = read_inheritable_attribute(:local_addresses) + unless addresses + addresses = [IPAddr.new("127.0.0.1")] + write_inheritable_attribute(:local_addresses, addresses) + end + addresses + end + end + +private + + def local_request? + remote = IPAddr.new(request.remote_ip) + !self.class.local_addresses.detect { |addr| addr.include?(remote) }.nil? + end + +end diff --git a/vendor/plugins/exception_notification/lib/exception_notification/notifiable.rb b/vendor/plugins/exception_notification/lib/exception_notification/notifiable.rb new file mode 100644 index 000000000..19895e8db --- /dev/null +++ b/vendor/plugins/exception_notification/lib/exception_notification/notifiable.rb @@ -0,0 +1,66 @@ +# Copyright (c) 2005 Jamis Buck +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +module ExceptionNotification::Notifiable + def self.included(target) + target.extend(ClassMethods) + target.skip_exception_notifications false + end + + module ClassMethods + def exception_data(deliverer=self) + if deliverer == self + read_inheritable_attribute(:exception_data) + else + write_inheritable_attribute(:exception_data, deliverer) + end + end + + def skip_exception_notifications(boolean=true) + write_inheritable_attribute(:skip_exception_notifications, boolean) + end + + def skip_exception_notifications? + read_inheritable_attribute(:skip_exception_notifications) + end + end + +private + + def rescue_action_in_public(exception) + super + notify_about_exception(exception) if deliver_exception_notification? + end + + def deliver_exception_notification? + !self.class.skip_exception_notifications? && ![404, "404 Not Found"].include?(response.status.to_s) + end + + def notify_about_exception(exception) + deliverer = self.class.exception_data + data = case deliverer + when nil then {} + when Symbol then send(deliverer) + when Proc then deliverer.call(self) + end + + ExceptionNotification::Notifier.deliver_exception_notification(exception, self, request, data) + end +end diff --git a/vendor/plugins/exception_notification/lib/exception_notification/notifier.rb b/vendor/plugins/exception_notification/lib/exception_notification/notifier.rb new file mode 100644 index 000000000..2cab3f963 --- /dev/null +++ b/vendor/plugins/exception_notification/lib/exception_notification/notifier.rb @@ -0,0 +1,80 @@ +require 'pathname' + +# Copyright (c) 2005 Jamis Buck +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +class ExceptionNotification::Notifier < ActionMailer::Base + self.mailer_name = 'exception_notifier' + self.view_paths << "#{File.dirname(__FILE__)}/../../views" + + # next line is a hack to fix + # undefined method `find_template' for #<Array:0x000001009cd230> + # after Rails 2.3.8 -> 2.3.11 upgrade + self.view_paths = ActionView::PathSet.new(self.view_paths) unless self.view_paths.respond_to?(:find_template) + + @@sender_address = %("Exception Notifier" <exception.notifier@default.com>) + cattr_accessor :sender_address + + @@exception_recipients = [] + cattr_accessor :exception_recipients + + @@email_prefix = "[ERROR] " + cattr_accessor :email_prefix + + @@sections = %w(request session environment backtrace) + cattr_accessor :sections + + def self.reloadable?() false end + + def exception_notification(exception, controller, request, data={}) + source = self.class.exception_source(controller) + content_type "text/plain" + + subject "#{email_prefix}#{source} (#{exception.class}) #{exception.message.inspect}" + + recipients exception_recipients + from sender_address + + body data.merge({ :controller => controller, :request => request, + :exception => exception, :exception_source => source, :host => (request.env["HTTP_X_FORWARDED_HOST"] || request.env["HTTP_HOST"]), + :backtrace => sanitize_backtrace(exception.backtrace), + :rails_root => rails_root, :data => data, + :sections => sections }) + end + + def self.exception_source(controller) + if controller.respond_to?(:controller_name) + "in #{controller.controller_name}##{controller.action_name}" + else + "outside of a controller" + end + end + +private + + def sanitize_backtrace(trace) + re = Regexp.new(/^#{Regexp.escape(rails_root)}/) + trace.map { |line| Pathname.new(line.gsub(re, "[RAILS_ROOT]")).cleanpath.to_s } + end + + def rails_root + @rails_root ||= Pathname.new(RAILS_ROOT).cleanpath.to_s + end +end diff --git a/vendor/plugins/exception_notification/lib/exception_notification/notifier_helper.rb b/vendor/plugins/exception_notification/lib/exception_notification/notifier_helper.rb new file mode 100644 index 000000000..942e1c527 --- /dev/null +++ b/vendor/plugins/exception_notification/lib/exception_notification/notifier_helper.rb @@ -0,0 +1,67 @@ +require 'pp' + +# Copyright (c) 2005 Jamis Buck +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +module ExceptionNotification::NotifierHelper + PARAM_FILTER_REPLACEMENT = "[FILTERED]" + + def render_section(section) + RAILS_DEFAULT_LOGGER.info("rendering section #{section.inspect}") + summary = render("exception_notifier/#{section}").strip + unless summary.blank? + title = render("exception_notifier/title", :locals => { :title => section }).strip + "#{title}\n\n#{summary.gsub(/^/, " ")}\n\n" + end + end + + def inspect_model_object(model, locals={}) + render('exception_notifier/inspect_model', + :locals => { :inspect_model => model, + :show_instance_variables => true, + :show_attributes => true }.merge(locals)) + end + + def inspect_value(value) + len = 512 + result = object_to_yaml(value).gsub(/\n/, "\n ").strip + result = result[0,len] + "... (#{result.length-len} bytes more)" if result.length > len+20 + result + end + + def object_to_yaml(object) + object.to_yaml.sub(/^---\s*/m, "") + end + + def exclude_raw_post_parameters? + @controller && @controller.respond_to?(:filter_parameters) + end + + def filter_sensitive_post_data_parameters(parameters) + exclude_raw_post_parameters? ? @controller.__send__(:filter_parameters, parameters) : parameters + end + + def filter_sensitive_post_data_from_env(env_key, env_value) + return env_value unless exclude_raw_post_parameters? + return PARAM_FILTER_REPLACEMENT if (env_key =~ /RAW_POST_DATA/i) + return @controller.__send__(:filter_parameters, {env_key => env_value}).values[0] + end + +end diff --git a/vendor/plugins/exception_notification/test/exception_notifier_helper_test.rb b/vendor/plugins/exception_notification/test/exception_notifier_helper_test.rb new file mode 100644 index 000000000..e077f405b --- /dev/null +++ b/vendor/plugins/exception_notification/test/exception_notifier_helper_test.rb @@ -0,0 +1,62 @@ +require 'test_helper' +require 'exception_notification/notifier_helper' + +class ExceptionNotifierHelperTest < Test::Unit::TestCase + + class ExceptionNotifierHelperIncludeTarget + include ExceptionNotification::NotifierHelper + end + + def setup + @helper = ExceptionNotifierHelperIncludeTarget.new + end + + # No controller + + def test_should_not_exclude_raw_post_parameters_if_no_controller + assert !@helper.exclude_raw_post_parameters? + end + + # Controller, no filtering + + class ControllerWithoutFilterParameters; end + + def test_should_not_filter_env_values_for_raw_post_data_keys_if_controller_can_not_filter_parameters + stub_controller(ControllerWithoutFilterParameters.new) + assert @helper.filter_sensitive_post_data_from_env("RAW_POST_DATA", "secret").include?("secret") + end + def test_should_not_exclude_raw_post_parameters_if_controller_can_not_filter_parameters + stub_controller(ControllerWithoutFilterParameters.new) + assert !@helper.exclude_raw_post_parameters? + end + def test_should_return_params_if_controller_can_not_filter_parameters + stub_controller(ControllerWithoutFilterParameters.new) + assert_equal :params, @helper.filter_sensitive_post_data_parameters(:params) + end + + # Controller with filtering + + class ControllerWithFilterParameters + def filter_parameters(params) + { "PARAM" => ExceptionNotification::NotifierHelper::PARAM_FILTER_REPLACEMENT } + end + end + + def test_should_filter_env_values_for_raw_post_data_keys_if_controller_can_filter_parameters + stub_controller(ControllerWithFilterParameters.new) + assert !@helper.filter_sensitive_post_data_from_env("RAW_POST_DATA", "secret").include?("secret") + end + def test_should_exclude_raw_post_parameters_if_controller_can_filter_parameters + stub_controller(ControllerWithFilterParameters.new) + assert @helper.exclude_raw_post_parameters? + end + def test_should_delegate_param_filtering_to_controller_if_controller_can_filter_parameters + stub_controller(ControllerWithFilterParameters.new) + assert_equal({"PARAM" => "[FILTERED]" }, @helper.filter_sensitive_post_data_parameters({"PARAM" => 'secret'})) + end + + private + def stub_controller(controller) + @helper.instance_variable_set(:@controller, controller) + end +end
\ No newline at end of file diff --git a/vendor/plugins/exception_notification/test/test_helper.rb b/vendor/plugins/exception_notification/test/test_helper.rb new file mode 100644 index 000000000..5831a1784 --- /dev/null +++ b/vendor/plugins/exception_notification/test/test_helper.rb @@ -0,0 +1,8 @@ +require 'test/unit' +require 'rubygems' +require 'active_support' + +RAILS_ROOT = '.' unless defined?(RAILS_ROOT) + +$:.unshift File.join(File.dirname(__FILE__), '../lib') +require 'exception_notification'
\ No newline at end of file diff --git a/vendor/plugins/exception_notification/views/exception_notifier/_backtrace.rhtml b/vendor/plugins/exception_notification/views/exception_notifier/_backtrace.rhtml new file mode 100644 index 000000000..7d13ba007 --- /dev/null +++ b/vendor/plugins/exception_notification/views/exception_notifier/_backtrace.rhtml @@ -0,0 +1 @@ +<%= @backtrace.join "\n" %> diff --git a/vendor/plugins/exception_notification/views/exception_notifier/_environment.rhtml b/vendor/plugins/exception_notification/views/exception_notifier/_environment.rhtml new file mode 100644 index 000000000..42dd803f1 --- /dev/null +++ b/vendor/plugins/exception_notification/views/exception_notifier/_environment.rhtml @@ -0,0 +1,7 @@ +<% max = @request.env.keys.max { |a,b| a.length <=> b.length } -%> +<% @request.env.keys.sort.each do |key| -%> +* <%= "%-*s: %s" % [max.length, key, filter_sensitive_post_data_from_env(key, @request.env[key].to_s.strip)] %> +<% end -%> + +* Process: <%= $$ %> +* Server : <%= `hostname -s`.chomp %> diff --git a/vendor/plugins/exception_notification/views/exception_notifier/_inspect_model.rhtml b/vendor/plugins/exception_notification/views/exception_notifier/_inspect_model.rhtml new file mode 100644 index 000000000..e817847e4 --- /dev/null +++ b/vendor/plugins/exception_notification/views/exception_notifier/_inspect_model.rhtml @@ -0,0 +1,16 @@ +<% if show_attributes -%> +[attributes] +<% attrs = inspect_model.attributes -%> +<% max = attrs.keys.max { |a,b| a.length <=> b.length } -%> +<% attrs.keys.sort.each do |attr| -%> +* <%= "%*-s: %s" % [max.length, attr, object_to_yaml(attrs[attr]).gsub(/\n/, "\n ").strip] %> +<% end -%> +<% end -%> + +<% if show_instance_variables -%> +[instance variables] +<% inspect_model.instance_variables.sort.each do |variable| -%> +<%- next if variable == "@attributes" -%> +* <%= variable %>: <%= inspect_value(inspect_model.instance_variable_get(variable)) %> +<% end -%> +<% end -%> diff --git a/vendor/plugins/exception_notification/views/exception_notifier/_request.rhtml b/vendor/plugins/exception_notification/views/exception_notifier/_request.rhtml new file mode 100644 index 000000000..25423093f --- /dev/null +++ b/vendor/plugins/exception_notification/views/exception_notifier/_request.rhtml @@ -0,0 +1,4 @@ +* URL : <%= @request.protocol %><%= @host %><%= @request.request_uri %> +* IP address: <%= @request.env["HTTP_X_FORWARDED_FOR"] || @request.env["REMOTE_ADDR"] %> +* Parameters: <%= filter_sensitive_post_data_parameters(@request.parameters).inspect %> +* Rails root: <%= @rails_root %> diff --git a/vendor/plugins/exception_notification/views/exception_notifier/_session.rhtml b/vendor/plugins/exception_notification/views/exception_notifier/_session.rhtml new file mode 100644 index 000000000..308684885 --- /dev/null +++ b/vendor/plugins/exception_notification/views/exception_notifier/_session.rhtml @@ -0,0 +1,2 @@ +* session id: <%= @request.session_options[:id] %> +* data: <%= @request.session.inspect %>
\ No newline at end of file diff --git a/vendor/plugins/exception_notification/views/exception_notifier/_title.rhtml b/vendor/plugins/exception_notification/views/exception_notifier/_title.rhtml new file mode 100644 index 000000000..1ed5a3f2b --- /dev/null +++ b/vendor/plugins/exception_notification/views/exception_notifier/_title.rhtml @@ -0,0 +1,3 @@ +------------------------------- +<%= title.to_s.humanize %>: +------------------------------- diff --git a/vendor/plugins/exception_notification/views/exception_notifier/exception_notification.rhtml b/vendor/plugins/exception_notification/views/exception_notifier/exception_notification.rhtml new file mode 100644 index 000000000..715c105bf --- /dev/null +++ b/vendor/plugins/exception_notification/views/exception_notifier/exception_notification.rhtml @@ -0,0 +1,6 @@ +A <%= @exception.class %> occurred <%= @exception_source %>: + + <%= @exception.message %> + <%= @backtrace.first %> + +<%= @sections.map { |section| render_section(section) }.join %> |