aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore3
-rw-r--r--.gitmodules9
-rw-r--r--.rspec1
-rw-r--r--.rvmrc10
-rw-r--r--.travis.yml1
-rw-r--r--Gemfile38
-rw-r--r--Gemfile.lock262
-rw-r--r--LICENSE.txt12
-rw-r--r--README-rails.txt188
-rw-r--r--README.md3
-rw-r--r--Rakefile15
-rw-r--r--app/controllers/admin_censor_rule_controller.rb2
-rw-r--r--app/controllers/admin_controller.rb10
-rw-r--r--app/controllers/admin_general_controller.rb2
-rw-r--r--app/controllers/admin_public_body_controller.rb8
-rw-r--r--app/controllers/admin_request_controller.rb22
-rw-r--r--app/controllers/admin_track_controller.rb12
-rw-r--r--app/controllers/admin_user_controller.rb12
-rw-r--r--app/controllers/api_controller.rb13
-rw-r--r--app/controllers/application_controller.rb95
-rw-r--r--app/controllers/comment_controller.rb2
-rw-r--r--app/controllers/general_controller.rb23
-rw-r--r--app/controllers/help_controller.rb8
-rw-r--r--app/controllers/holiday_controller.rb4
-rw-r--r--app/controllers/public_body_controller.rb8
-rw-r--r--app/controllers/request_controller.rb103
-rw-r--r--app/controllers/request_game_controller.rb2
-rw-r--r--app/controllers/services_controller.rb6
-rw-r--r--app/controllers/track_controller.rb11
-rw-r--r--app/controllers/user_controller.rb32
-rw-r--r--app/helpers/application_helper.rb2
-rw-r--r--app/helpers/config_helper.rb4
-rwxr-xr-xapp/helpers/link_to_helper.rb15
-rw-r--r--app/helpers/mailer_helper.rb2
-rw-r--r--app/mailers/application_mailer.rb30
-rw-r--r--app/mailers/contact_mailer.rb45
-rw-r--r--app/mailers/outgoing_mailer.rb (renamed from app/models/outgoing_mailer.rb)32
-rw-r--r--app/mailers/request_mailer.rb (renamed from app/models/request_mailer.rb)228
-rw-r--r--app/mailers/track_mailer.rb (renamed from app/models/track_mailer.rb)21
-rw-r--r--app/mailers/user_mailer.rb44
-rw-r--r--app/models/about_me_validator.rb22
-rw-r--r--app/models/application_mailer.rb164
-rw-r--r--app/models/censor_rule.rb12
-rw-r--r--app/models/change_email_validator.rb38
-rw-r--r--app/models/comment.rb2
-rw-r--r--app/models/contact_mailer.rb56
-rw-r--r--app/models/contact_validator.rb34
-rw-r--r--app/models/foi_attachment.rb29
-rw-r--r--app/models/holiday.rb2
-rw-r--r--app/models/incoming_message.rb103
-rw-r--r--app/models/info_request.rb79
-rw-r--r--app/models/info_request_event.rb4
-rw-r--r--app/models/mail_server_log.rb12
-rw-r--r--app/models/mail_server_log_done.rb2
-rw-r--r--app/models/outgoing_message.rb23
-rw-r--r--app/models/post_redirect.rb28
-rw-r--r--app/models/profile_photo.rb39
-rw-r--r--app/models/public_body.rb12
-rw-r--r--app/models/purge_request.rb2
-rw-r--r--app/models/raw_email.rb6
-rw-r--r--app/models/track_thing.rb4
-rw-r--r--app/models/track_things_sent_email.rb2
-rw-r--r--app/models/user.rb41
-rw-r--r--app/models/user_info_request_sent_alert.rb2
-rw-r--r--app/models/user_mailer.rb48
-rw-r--r--app/views/admin_censor_rule/_form.html.erb (renamed from app/views/admin_censor_rule/_form.rhtml)0
-rw-r--r--app/views/admin_censor_rule/_show.html.erb (renamed from app/views/admin_censor_rule/_show.rhtml)0
-rw-r--r--app/views/admin_censor_rule/edit.html.erb (renamed from app/views/admin_censor_rule/edit.rhtml)4
-rw-r--r--app/views/admin_censor_rule/new.html.erb (renamed from app/views/admin_censor_rule/new.rhtml)2
-rw-r--r--app/views/admin_general/_admin_navbar.html.erb (renamed from app/views/admin_general/_admin_navbar.rhtml)0
-rw-r--r--app/views/admin_general/debug.html.erb (renamed from app/views/admin_general/debug.rhtml)7
-rw-r--r--app/views/admin_general/index.html.erb (renamed from app/views/admin_general/index.rhtml)0
-rw-r--r--app/views/admin_general/stats.html.erb (renamed from app/views/admin_general/stats.rhtml)0
-rw-r--r--app/views/admin_general/timeline.html.erb (renamed from app/views/admin_general/timeline.rhtml)0
-rw-r--r--app/views/admin_public_body/_form.html.erb (renamed from app/views/admin_public_body/_form.rhtml)5
-rw-r--r--app/views/admin_public_body/_one_list.html.erb (renamed from app/views/admin_public_body/_one_list.rhtml)2
-rw-r--r--app/views/admin_public_body/_tag_help.html.erb (renamed from app/views/admin_public_body/_tag_help.rhtml)0
-rw-r--r--app/views/admin_public_body/_tags.html.erb (renamed from app/views/admin_public_body/_tags.rhtml)0
-rw-r--r--app/views/admin_public_body/edit.html.erb (renamed from app/views/admin_public_body/edit.rhtml)4
-rw-r--r--app/views/admin_public_body/import_csv.html.erb (renamed from app/views/admin_public_body/import_csv.rhtml)2
-rw-r--r--app/views/admin_public_body/list.html.erb (renamed from app/views/admin_public_body/list.rhtml)3
-rw-r--r--app/views/admin_public_body/missing_scheme.html.erb (renamed from app/views/admin_public_body/missing_scheme.rhtml)0
-rw-r--r--app/views/admin_public_body/new.html.erb (renamed from app/views/admin_public_body/new.rhtml)2
-rw-r--r--app/views/admin_public_body/show.html.erb (renamed from app/views/admin_public_body/show.rhtml)0
-rw-r--r--app/views/admin_request/_incoming_message_actions.html.erb (renamed from app/views/admin_request/_incoming_message_actions.rhtml)4
-rw-r--r--app/views/admin_request/_some_requests.html.erb (renamed from app/views/admin_request/_some_requests.rhtml)0
-rw-r--r--app/views/admin_request/_tags.html.erb (renamed from app/views/admin_request/_tags.rhtml)0
-rw-r--r--app/views/admin_request/edit.html.erb (renamed from app/views/admin_request/edit.rhtml)4
-rw-r--r--app/views/admin_request/edit_comment.html.erb (renamed from app/views/admin_request/edit_comment.rhtml)2
-rw-r--r--app/views/admin_request/edit_outgoing.html.erb (renamed from app/views/admin_request/edit_outgoing.rhtml)4
-rw-r--r--app/views/admin_request/hidden_user_explanation.html.erb10
-rw-r--r--app/views/admin_request/hidden_user_explanation.rhtml10
-rw-r--r--app/views/admin_request/list.html.erb (renamed from app/views/admin_request/list.rhtml)2
-rw-r--r--app/views/admin_request/show.html.erb (renamed from app/views/admin_request/show.rhtml)16
-rw-r--r--app/views/admin_request/show_raw_email.html.erb (renamed from app/views/admin_request/show_raw_email.rhtml)0
-rw-r--r--app/views/admin_track/_some_tracks.html.erb (renamed from app/views/admin_track/_some_tracks.rhtml)4
-rw-r--r--app/views/admin_track/list.html.erb (renamed from app/views/admin_track/list.rhtml)2
-rw-r--r--app/views/admin_user/_form.html.erb (renamed from app/views/admin_user/_form.rhtml)0
-rw-r--r--app/views/admin_user/_user_table.html.erb (renamed from app/views/admin_user/_user_table.rhtml)0
-rw-r--r--app/views/admin_user/edit.html.erb (renamed from app/views/admin_user/edit.rhtml)2
-rw-r--r--app/views/admin_user/list.html.erb (renamed from app/views/admin_user/list.rhtml)2
-rw-r--r--app/views/admin_user/list_banned.html.erb (renamed from app/views/admin_user/list_banned.rhtml)0
-rw-r--r--app/views/admin_user/show.html.erb (renamed from app/views/admin_user/show.rhtml)4
-rw-r--r--app/views/admin_user/show_bounce_message.html.erb (renamed from app/views/admin_user/show_bounce_message.rhtml)0
-rw-r--r--app/views/comment/_comment_form.html.erb (renamed from app/views/comment/_comment_form.rhtml)2
-rw-r--r--app/views/comment/_single_comment.html.erb (renamed from app/views/comment/_single_comment.rhtml)0
-rw-r--r--app/views/comment/new.html.erb (renamed from app/views/comment/new.rhtml)0
-rw-r--r--app/views/comment/preview.html.erb (renamed from app/views/comment/preview.rhtml)2
-rw-r--r--app/views/contact_mailer/from_admin_message.text.erb (renamed from app/views/contact_mailer/from_admin_message.rhtml)0
-rw-r--r--app/views/contact_mailer/to_admin_message.text.erb (renamed from app/views/contact_mailer/to_admin_message.rhtml)0
-rw-r--r--app/views/contact_mailer/user_message.text.erb (renamed from app/views/contact_mailer/user_message.rhtml)0
-rw-r--r--app/views/general/_advanced_search_tips.html.erb (renamed from app/views/general/_advanced_search_tips.rhtml)0
-rw-r--r--app/views/general/_before_body_end.html.erb (renamed from app/views/general/_before_body_end.rhtml)0
-rw-r--r--app/views/general/_before_head_end.html.erb (renamed from app/views/general/_before_head_end.rhtml)0
-rw-r--r--app/views/general/_credits.html.erb (renamed from app/views/general/_credits.rhtml)0
-rw-r--r--app/views/general/_custom_state_descriptions.html.erb (renamed from app/views/general/_custom_state_descriptions.rhtml)0
-rw-r--r--app/views/general/_custom_state_transitions_complete.html.erb (renamed from app/views/general/_custom_state_transitions_complete.rhtml)0
-rw-r--r--app/views/general/_custom_state_transitions_pending.html.erb (renamed from app/views/general/_custom_state_transitions_pending.rhtml)0
-rw-r--r--app/views/general/_footer.html.erb (renamed from app/views/general/_footer.rhtml)2
-rw-r--r--app/views/general/_frontpage_bodies_list.html.erb (renamed from app/views/general/_frontpage_bodies_list.rhtml)0
-rw-r--r--app/views/general/_frontpage_intro_sentence.html.erb (renamed from app/views/general/_frontpage_intro_sentence.rhtml)0
-rw-r--r--app/views/general/_frontpage_new_request.html.erb (renamed from app/views/general/_frontpage_new_request.rhtml)0
-rw-r--r--app/views/general/_frontpage_requests_list.html.erb (renamed from app/views/general/_frontpage_requests_list.rhtml)0
-rw-r--r--app/views/general/_frontpage_search_box.html.erb (renamed from app/views/general/_frontpage_search_box.rhtml)0
-rw-r--r--app/views/general/_locale_switcher.html.erb (renamed from app/views/general/_locale_switcher.rhtml)0
-rw-r--r--app/views/general/_localised_datepicker.html.erb (renamed from app/views/general/_localised_datepicker.rhtml)0
-rw-r--r--app/views/general/_orglink.html.erb (renamed from app/views/general/_orglink.rhtml)0
-rw-r--r--app/views/general/_popup_banner.html.erb (renamed from app/views/general/_popup_banner.rhtml)0
-rw-r--r--app/views/general/_stylesheet_includes.html.erb (renamed from app/views/general/_stylesheet_includes.rhtml)2
-rw-r--r--app/views/general/_topnav.html.erb (renamed from app/views/general/_topnav.rhtml)0
-rw-r--r--app/views/general/blog.html.erb (renamed from app/views/general/blog.rhtml)14
-rw-r--r--app/views/general/custom_css.html.erb (renamed from app/views/general/custom_css.rhtml)0
-rw-r--r--app/views/general/exception_caught.html.erb (renamed from app/views/general/exception_caught.rhtml)2
-rw-r--r--app/views/general/frontpage.html.erb (renamed from app/views/general/frontpage.rhtml)2
-rw-r--r--app/views/general/search.html.erb (renamed from app/views/general/search.rhtml)4
-rw-r--r--app/views/help/_sidebar.html.erb (renamed from app/views/help/_sidebar.rhtml)0
-rw-r--r--app/views/help/_why_they_should_reply_by_email.html.erb (renamed from app/views/help/_why_they_should_reply_by_email.rhtml)0
-rw-r--r--app/views/help/about.html.erb (renamed from app/views/help/about.rhtml)0
-rw-r--r--app/views/help/alaveteli.html.erb (renamed from app/views/help/alaveteli.rhtml)0
-rw-r--r--app/views/help/api.html.erb (renamed from app/views/help/api.rhtml)0
-rw-r--r--app/views/help/contact.html.erb (renamed from app/views/help/contact.rhtml)4
-rw-r--r--app/views/help/credits.html.erb (renamed from app/views/help/credits.rhtml)0
-rw-r--r--app/views/help/officers.html.erb (renamed from app/views/help/officers.rhtml)0
-rw-r--r--app/views/help/privacy.html.erb (renamed from app/views/help/privacy.rhtml)0
-rw-r--r--app/views/help/requesting.html.erb (renamed from app/views/help/requesting.rhtml)0
-rw-r--r--app/views/help/unhappy.html.erb (renamed from app/views/help/unhappy.rhtml)0
-rw-r--r--app/views/holiday/due_date.html.erb (renamed from app/views/holiday/due_date.rhtml)0
-rw-r--r--app/views/layouts/admin.html.erb (renamed from app/views/layouts/admin.rhtml)0
-rw-r--r--app/views/layouts/contact_mailer.html.erb (renamed from app/views/layouts/contact_mailer.rhtml)0
-rw-r--r--app/views/layouts/default.html.erb (renamed from app/views/layouts/default.rhtml)10
-rw-r--r--app/views/layouts/no_chrome.html.erb (renamed from app/views/layouts/no_chrome.rhtml)0
-rw-r--r--app/views/layouts/outgoing_mailer.html.erb (renamed from app/views/layouts/outgoing_mailer.rhtml)0
-rw-r--r--app/views/layouts/request_mailer.html.erb (renamed from app/views/layouts/request_mailer.rhtml)0
-rw-r--r--app/views/layouts/user_mailer.html.erb (renamed from app/views/layouts/user_mailer.rhtml)0
-rw-r--r--app/views/outgoing_mailer/_followup_footer.text.erb (renamed from app/views/outgoing_mailer/_followup_footer.rhtml)0
-rw-r--r--app/views/outgoing_mailer/followup.text.erb (renamed from app/views/outgoing_mailer/followup.rhtml)0
-rw-r--r--app/views/outgoing_mailer/initial_request.text.erb (renamed from app/views/outgoing_mailer/initial_request.rhtml)0
-rw-r--r--app/views/public_body/_alphabet.html.erb (renamed from app/views/public_body/_alphabet.rhtml)2
-rw-r--r--app/views/public_body/_body_listing.html.erb (renamed from app/views/public_body/_body_listing.rhtml)0
-rw-r--r--app/views/public_body/_body_listing_single.html.erb (renamed from app/views/public_body/_body_listing_single.rhtml)0
-rw-r--r--app/views/public_body/_list_sidebar_extra.html.erb (renamed from app/views/public_body/_list_sidebar_extra.rhtml)0
-rw-r--r--app/views/public_body/_search_ahead.html.erb (renamed from app/views/public_body/_search_ahead.rhtml)2
-rw-r--r--app/views/public_body/list.html.erb (renamed from app/views/public_body/list.rhtml)2
-rw-r--r--app/views/public_body/show.html.erb (renamed from app/views/public_body/show.rhtml)0
-rw-r--r--app/views/public_body/view_email.html.erb (renamed from app/views/public_body/view_email.rhtml)0
-rw-r--r--app/views/public_body/view_email_captcha.html.erb (renamed from app/views/public_body/view_email_captcha.rhtml)2
-rw-r--r--app/views/request/_after_actions.html.erb (renamed from app/views/request/_after_actions.rhtml)0
-rw-r--r--app/views/request/_bubble.html.erb (renamed from app/views/request/_bubble.rhtml)0
-rw-r--r--app/views/request/_correspondence.html.erb (renamed from app/views/request/_correspondence.rhtml)0
-rw-r--r--app/views/request/_describe_state.html.erb (renamed from app/views/request/_describe_state.rhtml)6
-rw-r--r--app/views/request/_followup.html.erb (renamed from app/views/request/_followup.rhtml)2
-rw-r--r--app/views/request/_hidden_correspondence.html.erb (renamed from app/views/request/_hidden_correspondence.rhtml)10
-rw-r--r--app/views/request/_next_actions.html.erb (renamed from app/views/request/_next_actions.rhtml)0
-rw-r--r--app/views/request/_other_describe_state.html.erb (renamed from app/views/request/_other_describe_state.rhtml)2
-rw-r--r--app/views/request/_request_filter_form.html.erb (renamed from app/views/request/_request_filter_form.rhtml)2
-rw-r--r--app/views/request/_request_listing.html.erb (renamed from app/views/request/_request_listing.rhtml)0
-rw-r--r--app/views/request/_request_listing_short_via_event.html.erb (renamed from app/views/request/_request_listing_short_via_event.rhtml)0
-rw-r--r--app/views/request/_request_listing_single.html.erb (renamed from app/views/request/_request_listing_single.rhtml)0
-rw-r--r--app/views/request/_request_listing_via_event.html.erb (renamed from app/views/request/_request_listing_via_event.rhtml)0
-rw-r--r--app/views/request/_search_ahead.html.erb (renamed from app/views/request/_search_ahead.rhtml)0
-rw-r--r--app/views/request/_sidebar.html.erb (renamed from app/views/request/_sidebar.rhtml)19
-rw-r--r--app/views/request/_sidebar_request_listing.html.erb (renamed from app/views/request/_sidebar_request_listing.rhtml)0
-rw-r--r--app/views/request/_summary_suggestion.html.erb (renamed from app/views/request/_summary_suggestion.rhtml)0
-rw-r--r--app/views/request/_view_html_prefix.html.erb (renamed from app/views/request/_view_html_prefix.rhtml)0
-rw-r--r--app/views/request/_view_html_stylesheet.html.erb (renamed from app/views/request/_view_html_stylesheet.rhtml)0
-rw-r--r--app/views/request/_wall_listing.html.erb (renamed from app/views/request/_wall_listing.rhtml)0
-rw-r--r--app/views/request/describe_state_message.html.erb (renamed from app/views/request/describe_state_message.rhtml)2
-rw-r--r--app/views/request/details.html.erb (renamed from app/views/request/details.rhtml)0
-rw-r--r--app/views/request/followup_bad.html.erb (renamed from app/views/request/followup_bad.rhtml)0
-rw-r--r--app/views/request/followup_preview.html.erb (renamed from app/views/request/followup_preview.rhtml)4
-rw-r--r--app/views/request/hidden.html.erb (renamed from app/views/request/hidden.rhtml)2
-rw-r--r--app/views/request/list.html.erb (renamed from app/views/request/list.rhtml)0
-rw-r--r--app/views/request/new.html.erb (renamed from app/views/request/new.rhtml)4
-rw-r--r--app/views/request/new_bad_contact.html.erb (renamed from app/views/request/new_bad_contact.rhtml)0
-rw-r--r--app/views/request/new_please_describe.html.erb (renamed from app/views/request/new_please_describe.rhtml)2
-rw-r--r--app/views/request/preview.html.erb (renamed from app/views/request/preview.rhtml)6
-rw-r--r--app/views/request/select_authority.html.erb (renamed from app/views/request/select_authority.rhtml)2
-rw-r--r--app/views/request/show.html.erb (renamed from app/views/request/show.rhtml)2
-rw-r--r--app/views/request/show_response.html.erb (renamed from app/views/request/show_response.rhtml)0
-rw-r--r--app/views/request/similar.html.erb (renamed from app/views/request/similar.rhtml)0
-rw-r--r--app/views/request/simple_correspondence.html.erb (renamed from app/views/request/simple_correspondence.rhtml)2
-rw-r--r--app/views/request/upload_response.html.erb (renamed from app/views/request/upload_response.rhtml)2
-rw-r--r--app/views/request_game/play.html.erb (renamed from app/views/request_game/play.rhtml)0
-rw-r--r--app/views/request_mailer/comment_on_alert.text.erb (renamed from app/views/request_mailer/comment_on_alert.rhtml)0
-rw-r--r--app/views/request_mailer/comment_on_alert_plural.text.erb (renamed from app/views/request_mailer/comment_on_alert_plural.rhtml)0
-rw-r--r--app/views/request_mailer/external_response.rhtml1
-rw-r--r--app/views/request_mailer/external_response.text.erb1
-rw-r--r--app/views/request_mailer/fake_response.rhtml1
-rw-r--r--app/views/request_mailer/fake_response.text.erb1
-rw-r--r--app/views/request_mailer/new_response.text.erb (renamed from app/views/request_mailer/new_response.rhtml)0
-rw-r--r--app/views/request_mailer/new_response_reminder_alert.text.erb (renamed from app/views/request_mailer/new_response_reminder_alert.rhtml)0
-rw-r--r--app/views/request_mailer/not_clarified_alert.text.erb (renamed from app/views/request_mailer/not_clarified_alert.rhtml)0
-rw-r--r--app/views/request_mailer/old_unclassified_updated.text.erb (renamed from app/views/request_mailer/old_unclassified_updated.rhtml)0
-rw-r--r--app/views/request_mailer/overdue_alert.text.erb (renamed from app/views/request_mailer/overdue_alert.rhtml)0
-rw-r--r--app/views/request_mailer/requires_admin.text.erb (renamed from app/views/request_mailer/requires_admin.rhtml)0
-rw-r--r--app/views/request_mailer/stopped_responses.text.erb (renamed from app/views/request_mailer/stopped_responses.rhtml)0
-rw-r--r--app/views/request_mailer/very_overdue_alert.text.erb (renamed from app/views/request_mailer/very_overdue_alert.rhtml)0
-rw-r--r--app/views/track/_tracking_links.html.erb (renamed from app/views/track/_tracking_links.rhtml)2
-rw-r--r--app/views/track/atom_feed.atom.erb2
-rw-r--r--app/views/track_mailer/event_digest.text.erb (renamed from app/views/track_mailer/event_digest.rhtml)0
-rw-r--r--app/views/user/_change_receive_email.html.erb (renamed from app/views/user/_change_receive_email.rhtml)2
-rw-r--r--app/views/user/_show_user_info.html.erb (renamed from app/views/user/_show_user_info.rhtml)0
-rw-r--r--app/views/user/_signin.html.erb (renamed from app/views/user/_signin.rhtml)2
-rw-r--r--app/views/user/_signup.html.erb (renamed from app/views/user/_signup.rhtml)2
-rw-r--r--app/views/user/_user_listing_single.html.erb (renamed from app/views/user/_user_listing_single.rhtml)0
-rw-r--r--app/views/user/bad_token.html.erb (renamed from app/views/user/bad_token.rhtml)0
-rw-r--r--app/views/user/banned.html.erb (renamed from app/views/user/banned.rhtml)0
-rw-r--r--app/views/user/confirm.html.erb (renamed from app/views/user/confirm.rhtml)0
-rw-r--r--app/views/user/contact.html.erb (renamed from app/views/user/contact.rhtml)2
-rw-r--r--app/views/user/no_cookies.html.erb (renamed from app/views/user/no_cookies.rhtml)0
-rw-r--r--app/views/user/rate_limited.html.erb (renamed from app/views/user/rate_limited.rhtml)2
-rw-r--r--app/views/user/river.html.erb (renamed from app/views/user/river.rhtml)0
-rw-r--r--app/views/user/set_crop_profile_photo.html.erb (renamed from app/views/user/set_crop_profile_photo.rhtml)4
-rw-r--r--app/views/user/set_draft_profile_photo.html.erb (renamed from app/views/user/set_draft_profile_photo.rhtml)4
-rw-r--r--app/views/user/set_profile_about_me.html.erb (renamed from app/views/user/set_profile_about_me.rhtml)4
-rw-r--r--app/views/user/show.html.erb (renamed from app/views/user/show.rhtml)16
-rw-r--r--app/views/user/sign.html.erb (renamed from app/views/user/sign.rhtml)2
-rw-r--r--app/views/user/signchangeemail.html.erb (renamed from app/views/user/signchangeemail.rhtml)2
-rw-r--r--app/views/user/signchangeemail_confirm.html.erb (renamed from app/views/user/signchangeemail_confirm.rhtml)0
-rw-r--r--app/views/user/signchangepassword.html.erb (renamed from app/views/user/signchangepassword.rhtml)2
-rw-r--r--app/views/user/signchangepassword_confirm.html.erb (renamed from app/views/user/signchangepassword_confirm.rhtml)0
-rw-r--r--app/views/user/signchangepassword_send_confirm.html.erb (renamed from app/views/user/signchangepassword_send_confirm.rhtml)2
-rw-r--r--app/views/user/signin_successful.html.erb (renamed from app/views/user/signin_successful.rhtml)0
-rw-r--r--app/views/user/wall.html.erb (renamed from app/views/user/wall.rhtml)0
-rw-r--r--app/views/user/wrong_user.html.erb (renamed from app/views/user/wrong_user.rhtml)0
-rw-r--r--app/views/user/wrong_user_unknown_email.html.erb (renamed from app/views/user/wrong_user_unknown_email.rhtml)0
-rw-r--r--app/views/user_mailer/already_registered.text.erb (renamed from app/views/user_mailer/already_registered.rhtml)0
-rw-r--r--app/views/user_mailer/changeemail_already_used.text.erb (renamed from app/views/user_mailer/changeemail_already_used.rhtml)0
-rw-r--r--app/views/user_mailer/changeemail_confirm.text.erb (renamed from app/views/user_mailer/changeemail_confirm.rhtml)0
-rw-r--r--app/views/user_mailer/confirm_login.text.erb (renamed from app/views/user_mailer/confirm_login.rhtml)0
m---------commonlib0
-rw-r--r--config.ru6
-rw-r--r--config/application.rb75
-rw-r--r--config/boot.rb136
-rw-r--r--config/crontab.ugly2
-rw-r--r--config/database.yml-example2
-rw-r--r--config/deploy.yml.example4
-rw-r--r--config/environment.rb157
-rw-r--r--config/environments/development.rb47
-rw-r--r--config/environments/production.rb46
-rw-r--r--config/environments/staging.rb30
-rw-r--r--config/environments/test.rb40
-rw-r--r--config/httpd.conf-example (renamed from config/httpd.conf)9
-rw-r--r--config/initializers/alaveteli.rb64
-rw-r--r--config/initializers/backtrace_silencers.rb7
-rw-r--r--config/initializers/fast_gettext.rb2
-rw-r--r--config/initializers/gettext_i18n_rails.rb3
-rw-r--r--config/initializers/inflections.rb10
-rw-r--r--config/initializers/mime_types.rb5
-rw-r--r--config/initializers/secret_token.rb12
-rw-r--r--config/initializers/session_store.rb17
-rw-r--r--config/initializers/single_quote_escape_workaround.rb31
-rw-r--r--config/initializers/strip_nil_parameters_patch.rb51
-rw-r--r--config/initializers/theme_loader.rb23
l---------config/locales1
-rw-r--r--config/packages3
-rw-r--r--config/routes.rb473
-rw-r--r--config/test.yml2
-rw-r--r--db/development_structure.sql48
-rw-r--r--db/migrate/006_version_public_body.rb2
-rw-r--r--db/migrate/101_add_hash_to_info_request.rb6
-rw-r--r--db/seeds.rb7
-rw-r--r--doc/CHANGES.md10
-rw-r--r--doc/INSTALL-exim4.md11
-rw-r--r--doc/INSTALL.md38
-rw-r--r--doc/THEMES-UPGRADE.md101
-rw-r--r--doc/THEMES.md18
-rw-r--r--lib/activesupport_cache_extensions.rb2
-rw-r--r--lib/alaveteli_external_command.rb4
-rw-r--r--lib/configuration.rb125
-rw-r--r--lib/cookie_store_with_line_break_fix.rb19
-rw-r--r--lib/google_translate.rb18
-rw-r--r--lib/mail_handler/backends/mail_backend.rb82
-rw-r--r--lib/mail_handler/backends/mail_extensions.rb66
-rw-r--r--lib/mail_handler/backends/tmail_backend.rb288
-rw-r--r--lib/mail_handler/backends/tmail_extensions.rb138
-rw-r--r--lib/mail_handler/mail_handler.rb22
-rw-r--r--lib/no_constraint_disabling.rb110
-rw-r--r--lib/normalize_string.rb86
-rw-r--r--lib/old_rubygems_patch.rb46
-rw-r--r--lib/patches/fixtures_constraint_disabling.rb21
-rw-r--r--lib/public_body_categories.rb2
-rw-r--r--lib/rack_quote_monkeypatch.rb65
-rw-r--r--lib/sendmail_return_path.rb21
-rw-r--r--lib/tasks/.gitkeep (renamed from spec/fixtures/track_things_sent_emails.yml)0
-rw-r--r--lib/tasks/gettext.rake4
-rw-r--r--lib/tasks/rspec.rake148
-rw-r--r--lib/tasks/temp.rake150
-rw-r--r--lib/tasks/themes.rake10
-rw-r--r--lib/tasks/translation.rake46
-rw-r--r--lib/timezone_fixes.rb26
-rw-r--r--lib/willpaginate_extension.rb59
-rw-r--r--locale/aln/app.po82
-rw-r--r--locale/app.pot77
-rw-r--r--locale/ar/app.po2025
-rw-r--r--locale/bs/app.po81
-rw-r--r--locale/ca/app.po81
-rw-r--r--locale/cs/app.po207
-rw-r--r--locale/cy/app.po81
-rw-r--r--locale/de/app.po81
-rw-r--r--locale/en/app.po77
-rw-r--r--locale/en_IE/app.po81
-rw-r--r--locale/es/app.po91
-rw-r--r--locale/eu/app.po81
-rw-r--r--locale/fr/app.po1678
-rw-r--r--locale/gl/app.po81
-rw-r--r--locale/he_IL/app.po191
-rw-r--r--locale/hu_HU/app.po398
-rw-r--r--locale/id/app.po81
-rw-r--r--locale/it/app.po81
-rw-r--r--locale/model_attributes.rb17
-rw-r--r--locale/nb_NO/app.po87
-rw-r--r--locale/pt_BR/app.po83
-rw-r--r--locale/ro_RO/app.po81
-rw-r--r--locale/sl/app.po81
-rw-r--r--locale/sq/app.po81
-rw-r--r--locale/sr@latin/app.po81
-rw-r--r--locale/tr/app.po81
-rw-r--r--locale/uk/app.po94
-rw-r--r--public/404.html34
-rw-r--r--public/422.html26
-rw-r--r--public/500.html36
-rwxr-xr-xpublic/dispatch.cgi10
-rwxr-xr-xpublic/dispatch.fcgi24
-rwxr-xr-xpublic/dispatch.rb10
-rw-r--r--public/javascripts/controls.js148
-rw-r--r--public/javascripts/dragdrop.js340
-rw-r--r--public/javascripts/effects.js357
-rw-r--r--public/javascripts/prototype.js5198
-rw-r--r--public/javascripts/rails.js202
-rwxr-xr-xscript/about3
-rwxr-xr-xscript/alert-comment-on-request9
-rwxr-xr-xscript/alert-new-response-reminders9
-rwxr-xr-xscript/alert-not-clarified-request9
-rwxr-xr-xscript/alert-overdue-requests7
-rwxr-xr-xscript/alert-tracks10
-rwxr-xr-xscript/annotate-models2
-rwxr-xr-xscript/autospec6
-rwxr-xr-xscript/breakpointer3
-rwxr-xr-x[-rw-r--r--]script/cache-incoming-emails4
-rwxr-xr-xscript/check-recent-requests-sent10
-rwxr-xr-xscript/clear-caches14
-rwxr-xr-xscript/console3
-rwxr-xr-xscript/dbconsole3
-rwxr-xr-xscript/delete-old-things9
-rwxr-xr-xscript/destroy3
-rwxr-xr-xscript/direct-rspec8
-rwxr-xr-xscript/generate3
-rwxr-xr-xscript/handle-mail-replies.rb6
-rwxr-xr-xscript/load-mail-server-logs4
-rwxr-xr-xscript/load-sample-data26
-rwxr-xr-xscript/mailin2
-rwxr-xr-xscript/performance/benchmarker3
-rwxr-xr-xscript/performance/profiler3
-rwxr-xr-xscript/performance/request3
-rwxr-xr-xscript/plugin3
-rwxr-xr-xscript/process/inspector3
-rwxr-xr-xscript/process/reaper3
-rwxr-xr-xscript/process/spawner3
-rwxr-xr-xscript/purge-varnish7
-rwxr-xr-xscript/rails6
-rwxr-xr-xscript/rails-post-deploy21
-rwxr-xr-xscript/request-creation-graph2
-rwxr-xr-xscript/runner6
-rwxr-xr-xscript/server3
-rwxr-xr-xscript/spec10
-rwxr-xr-xscript/spec-all-pairs81
-rwxr-xr-xscript/spec_server116
-rwxr-xr-xscript/stop-new-responses-on-old-requests9
-rwxr-xr-xscript/test-run5
-rwxr-xr-xscript/user-use-graph2
-rwxr-xr-xscript/wraptest43
-rw-r--r--spec/controllers/admin_censor_rule_controller_spec.rb14
-rw-r--r--spec/controllers/admin_general_controller_spec.rb5
-rw-r--r--spec/controllers/admin_public_body_controller_spec.rb41
-rw-r--r--spec/controllers/admin_request_controller_spec.rb26
-rw-r--r--spec/controllers/admin_track_controller_spec.rb2
-rw-r--r--spec/controllers/admin_user_controller_spec.rb2
-rw-r--r--spec/controllers/api_controller_spec.rb22
-rw-r--r--spec/controllers/comment_controller_spec.rb2
-rw-r--r--spec/controllers/general_controller_spec.rb67
-rw-r--r--spec/controllers/help_controller_spec.rb2
-rw-r--r--spec/controllers/public_body_controller_spec.rb35
-rw-r--r--spec/controllers/request_controller_spec.rb351
-rw-r--r--spec/controllers/services_controller_spec.rb10
-rw-r--r--spec/controllers/track_controller_spec.rb18
-rw-r--r--spec/controllers/user_controller_spec.rb81
-rw-r--r--spec/fixtures/files/blog_feed.atom39
-rw-r--r--spec/fixtures/files/incoming-request-two-same-name.email4
-rw-r--r--spec/fixtures/files/inline-uuencode.email27
-rw-r--r--spec/fixtures/files/malformed-to-and-cc.email11
-rw-r--r--spec/fixtures/files/mislabelled-as-iso-8859-1.email20
-rw-r--r--spec/fixtures/files/multipart-no-final-boundary.email21
-rw-r--r--spec/fixtures/files/nested-attachments-premature-end.email110
-rw-r--r--spec/fixtures/files/no-part-charset-random-data.email30
-rw-r--r--spec/fixtures/files/part-without-charset-in-content-type.email38
-rw-r--r--spec/fixtures/files/subject-bad-utf-8-trailing-base64.email5
-rw-r--r--spec/fixtures/files/subject-bad-utf-8-trailing-quoted-printable.email5
-rw-r--r--spec/fixtures/files/tnef-attachment-empty.email196
-rw-r--r--spec/fixtures/files/tnef-attachment-truncated.email34
-rw-r--r--spec/fixtures/foi_attachments.yml1
-rw-r--r--spec/fixtures/theme_views/core/application_mailer/core_only.html.erb (renamed from spec/fixtures/theme_views/core/application_mailer/core_only.rhtml)0
-rw-r--r--spec/fixtures/theme_views/core/application_mailer/multipart_core_only.html.erb (renamed from spec/fixtures/theme_views/core/application_mailer/multipart_core_only.rhtml)0
-rw-r--r--spec/fixtures/theme_views/core/application_mailer/simple.html.erb (renamed from spec/fixtures/theme_views/core/application_mailer/simple.rhtml)0
-rw-r--r--spec/fixtures/theme_views/theme_one/application_mailer/multipart_theme_only.html.erb (renamed from spec/fixtures/theme_views/theme_one/application_mailer/multipart_theme_only.rhtml)0
-rw-r--r--spec/fixtures/theme_views/theme_one/application_mailer/simple.html.erb (renamed from spec/fixtures/theme_views/theme_one/application_mailer/simple.rhtml)0
-rw-r--r--spec/fixtures/theme_views/theme_one/application_mailer/theme_only.html.erb (renamed from spec/fixtures/theme_views/theme_one/application_mailer/theme_only.rhtml)0
-rw-r--r--spec/helpers/link_to_helper_spec.rb5
-rw-r--r--spec/integration/admin_spec.rb2
-rw-r--r--spec/integration/errors_spec.rb159
-rw-r--r--spec/integration/search_request_spec.rb6
-rw-r--r--spec/lib/basic_encoding_tests.rb157
-rw-r--r--spec/lib/mail_handler/mail_handler_spec.rb103
-rw-r--r--spec/lib/sendmail_return_path_spec.rb15
-rw-r--r--spec/lib/timezone_fixes_spec.rb5
-rw-r--r--spec/mailers/application_mailer_spec.rb (renamed from spec/models/application_mailer_spec.rb)46
-rw-r--r--spec/mailers/outgoing_mailer_spec.rb (renamed from spec/models/outgoing_mailer_spec.rb)0
-rw-r--r--spec/mailers/request_mailer_spec.rb (renamed from spec/models/request_mailer_spec.rb)28
-rw-r--r--spec/mailers/track_mailer_spec.rb (renamed from spec/models/track_mailer_spec.rb)26
-rw-r--r--spec/models/censor_rule_spec.rb22
-rw-r--r--spec/models/contact_mailer_spec.rb22
-rw-r--r--spec/models/foi_attachment_spec.rb2
-rw-r--r--spec/models/incoming_message_spec.rb70
-rw-r--r--spec/models/info_request_event_spec.rb10
-rw-r--r--spec/models/info_request_spec.rb16
-rw-r--r--spec/models/mail_server_log_spec.rb10
-rw-r--r--spec/models/public_body_spec.rb8
-rw-r--r--spec/models/user_mailer_spec.rb8
-rw-r--r--spec/models/user_spec.rb8
-rw-r--r--spec/script/mailin_spec.rb2
-rw-r--r--spec/spec.opts3
-rw-r--r--spec/spec_helper.rb349
-rw-r--r--spec/support/email_helpers.rb23
-rw-r--r--spec/support/load_file_fixtures.rb8
-rw-r--r--spec/support/xapian_index.rb42
-rw-r--r--spec/views/public_body/show.html.erb_spec.rb (renamed from spec/views/public_body/show.rhtml_spec.rb)62
-rw-r--r--spec/views/request/_after_actions.html.erb_spec.rb (renamed from spec/views/request/_after_actions.rhtml_spec.rb)71
-rw-r--r--spec/views/request/_describe_state.html.erb_spec.rb (renamed from spec/views/request/_describe_state.rhtml_spec.rb)28
-rw-r--r--spec/views/request/list.html.erb_spec.rb (renamed from spec/views/request/list.rhtml_spec.rb)32
-rw-r--r--spec/views/request/show.html.erb_spec.rb (renamed from spec/views/request/show.rhtml_spec.rb)54
-rw-r--r--spec/views/request_game/play.html.erb_spec.rb (renamed from spec/views/request_game/play.rhtml_spec.rb)14
-rw-r--r--vendor/plugins/active_record_base_without_table/CHANGELOG3
-rw-r--r--vendor/plugins/active_record_base_without_table/MIT-LICENSE20
-rw-r--r--vendor/plugins/active_record_base_without_table/README29
-rw-r--r--vendor/plugins/active_record_base_without_table/Rakefile22
-rw-r--r--vendor/plugins/active_record_base_without_table/lib/active_record/base_without_table.rb26
-rw-r--r--vendor/plugins/active_record_base_without_table/test/abstract_unit.rb15
-rw-r--r--vendor/plugins/active_record_base_without_table/test/active_record_base_without_table_test.rb41
-rw-r--r--vendor/plugins/active_record_base_without_table/test/database.yml6
-rw-r--r--vendor/plugins/acts_as_versioned/CHANGELOG82
-rw-r--r--vendor/plugins/acts_as_versioned/MIT-LICENSE20
-rw-r--r--vendor/plugins/acts_as_versioned/README28
-rw-r--r--vendor/plugins/acts_as_versioned/RUNNING_UNIT_TESTS41
-rw-r--r--vendor/plugins/acts_as_versioned/Rakefile182
-rw-r--r--vendor/plugins/acts_as_versioned/init.rb1
-rw-r--r--vendor/plugins/acts_as_versioned/lib/acts_as_versioned.rb490
-rw-r--r--vendor/plugins/acts_as_versioned/test/abstract_unit.rb48
-rw-r--r--vendor/plugins/acts_as_versioned/test/database.yml18
-rw-r--r--vendor/plugins/acts_as_versioned/test/fixtures/authors.yml6
-rw-r--r--vendor/plugins/acts_as_versioned/test/fixtures/landmark.rb3
-rw-r--r--vendor/plugins/acts_as_versioned/test/fixtures/landmark_versions.yml7
-rw-r--r--vendor/plugins/acts_as_versioned/test/fixtures/landmarks.yml7
-rw-r--r--vendor/plugins/acts_as_versioned/test/fixtures/locked_pages.yml10
-rw-r--r--vendor/plugins/acts_as_versioned/test/fixtures/locked_pages_revisions.yml27
-rw-r--r--vendor/plugins/acts_as_versioned/test/fixtures/migrations/1_add_versioned_tables.rb15
-rw-r--r--vendor/plugins/acts_as_versioned/test/fixtures/page.rb43
-rw-r--r--vendor/plugins/acts_as_versioned/test/fixtures/page_versions.yml16
-rw-r--r--vendor/plugins/acts_as_versioned/test/fixtures/pages.yml8
-rw-r--r--vendor/plugins/acts_as_versioned/test/fixtures/widget.rb6
-rw-r--r--vendor/plugins/acts_as_versioned/test/migration_test.rb46
-rw-r--r--vendor/plugins/acts_as_versioned/test/schema.rb80
-rw-r--r--vendor/plugins/acts_as_versioned/test/versioned_test.rb352
-rw-r--r--vendor/plugins/acts_as_xapian/README.txt40
-rw-r--r--vendor/plugins/acts_as_xapian/init.rb2
-rw-r--r--vendor/plugins/acts_as_xapian/lib/acts_as_xapian.rb16
-rw-r--r--vendor/plugins/exception_notification/README144
-rw-r--r--vendor/plugins/exception_notification/exception_notification.gemspec11
-rw-r--r--vendor/plugins/exception_notification/init.rb1
-rw-r--r--vendor/plugins/exception_notification/lib/exception_notification.rb7
-rw-r--r--vendor/plugins/exception_notification/lib/exception_notification/consider_local.rb31
-rw-r--r--vendor/plugins/exception_notification/lib/exception_notification/notifiable.rb66
-rw-r--r--vendor/plugins/exception_notification/lib/exception_notification/notifier.rb80
-rw-r--r--vendor/plugins/exception_notification/lib/exception_notification/notifier_helper.rb67
-rw-r--r--vendor/plugins/exception_notification/test/exception_notifier_helper_test.rb62
-rw-r--r--vendor/plugins/exception_notification/test/test_helper.rb8
-rw-r--r--vendor/plugins/exception_notification/views/exception_notifier/_backtrace.rhtml1
-rw-r--r--vendor/plugins/exception_notification/views/exception_notifier/_environment.rhtml7
-rw-r--r--vendor/plugins/exception_notification/views/exception_notifier/_inspect_model.rhtml16
-rw-r--r--vendor/plugins/exception_notification/views/exception_notifier/_request.rhtml4
-rw-r--r--vendor/plugins/exception_notification/views/exception_notifier/_session.rhtml2
-rw-r--r--vendor/plugins/exception_notification/views/exception_notifier/_title.rhtml3
-rw-r--r--vendor/plugins/exception_notification/views/exception_notifier/exception_notification.rhtml6
-rw-r--r--vendor/plugins/globalize2/LICENSE21
-rw-r--r--vendor/plugins/globalize2/README.textile86
-rw-r--r--vendor/plugins/globalize2/Rakefile39
-rw-r--r--vendor/plugins/globalize2/VERSION1
-rw-r--r--vendor/plugins/globalize2/generators/db_backend.rb0
-rw-r--r--vendor/plugins/globalize2/generators/templates/db_backend_migration.rb25
-rw-r--r--vendor/plugins/globalize2/globalize2.gemspec81
-rw-r--r--vendor/plugins/globalize2/init.rb1
-rw-r--r--vendor/plugins/globalize2/lib/globalize.rb15
-rw-r--r--vendor/plugins/globalize2/lib/globalize/active_record.rb238
-rw-r--r--vendor/plugins/globalize2/lib/globalize/active_record/adapter.rb80
-rw-r--r--vendor/plugins/globalize2/lib/globalize/active_record/attributes.rb25
-rw-r--r--vendor/plugins/globalize2/lib/globalize/active_record/migration.rb44
-rw-r--r--vendor/plugins/globalize2/lib/i18n/missing_translations_log_handler.rb41
-rw-r--r--vendor/plugins/globalize2/lib/i18n/missing_translations_raise_handler.rb25
-rw-r--r--vendor/plugins/globalize2/test/active_record/fallbacks_test.rb102
-rw-r--r--vendor/plugins/globalize2/test/active_record/migration_test.rb118
-rw-r--r--vendor/plugins/globalize2/test/active_record/sti_translated_test.rb49
-rw-r--r--vendor/plugins/globalize2/test/active_record/translates_test.rb96
-rw-r--r--vendor/plugins/globalize2/test/active_record/translation_class_test.rb30
-rw-r--r--vendor/plugins/globalize2/test/active_record/validation_tests.rb75
-rw-r--r--vendor/plugins/globalize2/test/active_record_test.rb467
-rw-r--r--vendor/plugins/globalize2/test/all.rb2
-rw-r--r--vendor/plugins/globalize2/test/data/models.rb56
-rw-r--r--vendor/plugins/globalize2/test/data/no_globalize_schema.rb11
-rw-r--r--vendor/plugins/globalize2/test/data/schema.rb55
-rw-r--r--vendor/plugins/globalize2/test/i18n/missing_translations_test.rb36
-rw-r--r--vendor/plugins/globalize2/test/test_helper.rb76
-rw-r--r--vendor/plugins/has_tag_string/lib/has_tag_string.rb2
-rw-r--r--vendor/plugins/rails_xss/MIT-LICENSE20
-rw-r--r--vendor/plugins/rails_xss/README.markdown91
-rw-r--r--vendor/plugins/rails_xss/Rakefile23
-rw-r--r--vendor/plugins/rails_xss/init.rb9
-rw-r--r--vendor/plugins/rails_xss/lib/rails_xss.rb3
-rw-r--r--vendor/plugins/rails_xss/lib/rails_xss/action_view.rb111
-rw-r--r--vendor/plugins/rails_xss/lib/rails_xss/erubis.rb41
-rw-r--r--vendor/plugins/rails_xss/lib/rails_xss/string_ext.rb65
-rw-r--r--vendor/plugins/rails_xss/lib/tasks/rails_xss_tasks.rake4
-rw-r--r--vendor/plugins/rails_xss/test/active_record_helper_test.rb74
-rw-r--r--vendor/plugins/rails_xss/test/asset_tag_helper_test.rb49
-rw-r--r--vendor/plugins/rails_xss/test/caching_test.rb54
-rw-r--r--vendor/plugins/rails_xss/test/content_for_test.rb39
-rw-r--r--vendor/plugins/rails_xss/test/date_helper_test.rb29
-rw-r--r--vendor/plugins/rails_xss/test/deprecated_output_safety_test.rb112
-rw-r--r--vendor/plugins/rails_xss/test/erb_util_test.rb36
-rw-r--r--vendor/plugins/rails_xss/test/form_helper_test.rb1447
-rw-r--r--vendor/plugins/rails_xss/test/form_tag_helper_test.rb354
-rw-r--r--vendor/plugins/rails_xss/test/javascript_helper_test.rb10
-rw-r--r--vendor/plugins/rails_xss/test/output_escaping_test.rb19
-rw-r--r--vendor/plugins/rails_xss/test/output_safety_test.rb115
-rw-r--r--vendor/plugins/rails_xss/test/rails_xss_test.rb23
-rw-r--r--vendor/plugins/rails_xss/test/raw_output_helper_test.rb18
-rw-r--r--vendor/plugins/rails_xss/test/safe_buffer_test.rb51
-rw-r--r--vendor/plugins/rails_xss/test/tag_helper_test.rb21
-rw-r--r--vendor/plugins/rails_xss/test/test_helper.rb6
-rw-r--r--vendor/plugins/rails_xss/test/text_helper_test.rb30
-rw-r--r--vendor/plugins/rails_xss/test/url_for_test.rb39
-rw-r--r--vendor/plugins/strip_attributes/lib/strip_attributes.rb16
-rw-r--r--vendor/plugins/strip_attributes/test/strip_attributes_test.rb6
m---------vendor/rails-locales0
572 files changed, 11776 insertions, 16489 deletions
diff --git a/.gitignore b/.gitignore
index efba35668..75c348ff9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -21,5 +21,8 @@ TAGS
.bundle
bin/
config/aliases
+config/httpd.conf
.sass-cache
alaveteli.sublime*
+webrat.log
+/.rbenv-version
diff --git a/.gitmodules b/.gitmodules
index 42d5db56b..0668c855f 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,8 +1,3 @@
[submodule "commonlib"]
- path = commonlib
- url = git://git.mysociety.org/commonlib
-# config/locales is a symbolic link to vendor/rails-locales/rails/locale
-# In Rails 3, this should be removed and the gem rails-i18n installed instead
-[submodule "vendor/rails-locales"]
- path = vendor/rails-locales
- url = git://github.com/svenfuchs/rails-i18n.git
+ path = commonlib
+ url = git://git.mysociety.org/commonlib
diff --git a/.rspec b/.rspec
new file mode 100644
index 000000000..7488cbe77
--- /dev/null
+++ b/.rspec
@@ -0,0 +1 @@
+--color --drb
diff --git a/.rvmrc b/.rvmrc
index 1f2700fc2..339f08013 100644
--- a/.rvmrc
+++ b/.rvmrc
@@ -5,10 +5,8 @@
# First we specify our desired <ruby>[@<gemset>], the @gemset name is optional,
# Only full ruby name is supported here, for short names use:
-# echo "rvm use 1.8.7" > .rvmrc
-environment_id="ruby-1.8.7-p370"
-
-rubygems_version="1.6.2"
+# echo "rvm use 1.9.3" > .rvmrc
+environment_id="1.9.3-p392"
# Uncomment the following lines if you want to verify rvm version per project
# rvmrc_rvm_version="1.14.10 (stable)" # 1.10.1 seams as a safe start
@@ -38,10 +36,6 @@ else
}
fi
-if [[ "$(gem --version)" != "${rubygems_version}" ]] ; then
- rvm rubygems ${rubygems_version}
-fi
-
# If you use bundler, this might be useful to you:
# if [[ -s Gemfile ]] && {
# ! builtin command -v bundle >/dev/null ||
diff --git a/.travis.yml b/.travis.yml
index a8ca00c6b..4fd2a59f7 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -21,6 +21,7 @@ before_install:
- sudo apt-get -y install exim4-daemon-light
- sudo apt-get -y install `cut -d " " -f 1 config/packages | egrep -v "(^#|wkhtml|bundler|^ruby$|^ruby1.8$|^rubygems$|^rake)"`
- RAILS_ENV=test ./script/rails-post-deploy
+ - RAILS_ENV=test ./script/update-xapian-index
before_script:
notifications:
irc: "irc.freenode.org#alaveteli"
diff --git a/Gemfile b/Gemfile
index 9abe5973a..18c2aec0d 100644
--- a/Gemfile
+++ b/Gemfile
@@ -7,20 +7,17 @@ if File.exist? "/etc/debian_version" and File.open("/etc/debian_version").read.s
end
source 'https://rubygems.org'
-# A fork of rails that is kept up to date with security patches
-git "git://github.com/mysociety/rails.git", :tag => "v2.3.18.1" do
- gem 'rails'
-end
+gem 'rails', '3.1.12'
gem 'pg'
+gem 'charlock_holmes'
gem 'fastercsv', '>=1.5.5'
gem 'json'
gem 'mahoro'
-gem 'mail', '~>2.4.4', :platforms => :ruby_19
-gem 'memcache-client', :require => 'memcache'
gem 'net-http-local'
gem 'net-purge'
-gem 'rack', '~> 1.1.0'
+gem 'rack'
+gem 'rails-i18n'
gem 'rdoc'
gem 'recaptcha', '~> 0.3.1', :require => 'recaptcha/rails'
# :require avoids "already initialized constant" warnings
@@ -28,18 +25,20 @@ gem 'rmagick', :require => 'RMagick'
gem 'rake', '0.9.2.2'
gem 'ruby-msg', '~> 1.5.0'
gem 'vpim'
-gem 'will_paginate', '~> 2.3.11'
+gem 'will_paginate'
# when 1.2.9 is released by the maintainer, we can stop using this fork:
gem 'xapian-full-alaveteli', '~> 1.2.9.5'
-gem 'xml-simple'
+gem 'xml-simple', :require => 'xmlsimple'
gem 'zip'
gem 'capistrano'
gem 'syslog_protocol'
gem 'newrelic_rpm'
-# erubis is required by rails_xss. Both erubis and rails_xss can be removed after upgrading to Rails 3.
-gem 'erubis'
-# rack-ssl won't be needed on upgrade to Rails 3.1 as something like it is baked in
-gem 'rack-ssl'
+# Use until this PR is merged: https://github.com/svenfuchs/globalize3/pull/191
+gem 'globalize3', :git => 'git://github.com/henare/globalize3.git', :branch => 'not-null-empty-attributes'
+# New gem releases aren't being done. master is newer and supports Rails > 3.0
+gem 'acts_as_versioned', :git => 'git://github.com/technoweenie/acts_as_versioned.git'
+gem 'dynamic_form'
+gem 'exception_notification'
# Gems related to internationalisation
# Also in vendor/plugins there is globalize2
@@ -51,12 +50,8 @@ gem 'routing-filter'
group :test do
gem 'fakeweb'
- gem 'rspec-rails', '~> 1.3.4'
- gem 'test-unit', '~> 1.2.3', :platforms => :ruby_19
gem 'coveralls', :require => false
- # Using webrat because the preferred (capybara) doesn't work out of the box with rspec 1
- gem 'webrat', :git => 'https://github.com/brynary/webrat', :ref => 'bea5b313783eaaf17e38a05a4eaa8c45c1eedd2a'
- gem 'launchy'
+ gem 'webrat'
end
group :development do
@@ -65,8 +60,13 @@ end
group :develop do
gem 'ruby-debug', :platforms => :ruby_18
- gem 'ruby-debug19', :platforms => :ruby_19
+ gem 'debugger', :platforms => :ruby_19
gem 'bootstrap-sass'
gem 'compass'
gem 'annotate'
end
+
+group :test, :development do
+ gem 'rspec-rails'
+ gem 'spork-rails'
+end
diff --git a/Gemfile.lock b/Gemfile.lock
index 9996118bc..24e4dd5e3 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -1,130 +1,171 @@
GIT
- remote: git://github.com/mysociety/rails.git
- revision: c0d325a13e133b14d2faa01053226cd77c1378a7
- tag: v2.3.18.1
+ remote: git://github.com/henare/globalize3.git
+ revision: 2931f559cbed8843ab7d16278d70ce99a0239132
+ branch: not-null-empty-attributes
specs:
- actionmailer (2.3.18)
- actionpack (= 2.3.18)
- actionpack (2.3.18)
- activesupport (= 2.3.18)
- rack (~> 1.1.0)
- activerecord (2.3.18)
- activesupport (= 2.3.18)
- activeresource (2.3.18)
- activesupport (= 2.3.18)
- activesupport (2.3.18)
- rails (2.3.18)
- actionmailer (= 2.3.18)
- actionpack (= 2.3.18)
- activerecord (= 2.3.18)
- activeresource (= 2.3.18)
- activesupport (= 2.3.18)
- rake (>= 0.8.3)
+ globalize3 (0.3.0)
+ activemodel (>= 3.0.0)
+ activerecord (>= 3.0.0)
+ paper_trail (~> 2)
GIT
- remote: https://github.com/brynary/webrat
- revision: bea5b313783eaaf17e38a05a4eaa8c45c1eedd2a
- ref: bea5b313783eaaf17e38a05a4eaa8c45c1eedd2a
+ remote: git://github.com/technoweenie/acts_as_versioned.git
+ revision: 63b1fc8529d028fae632fe80ec0cb25df56cd76b
specs:
- webrat (0.7.3)
- nokogiri (>= 1.2.0)
- rack (>= 1.0)
- rack-test (>= 0.5.3)
+ acts_as_versioned (0.6.0)
+ activerecord (>= 3.0.9)
GEM
remote: https://rubygems.org/
specs:
- addressable (2.3.3)
+ actionmailer (3.1.12)
+ actionpack (= 3.1.12)
+ mail (~> 2.4.4)
+ actionpack (3.1.12)
+ activemodel (= 3.1.12)
+ activesupport (= 3.1.12)
+ builder (~> 3.0.0)
+ erubis (~> 2.7.0)
+ i18n (~> 0.6)
+ rack (~> 1.3.6)
+ rack-cache (~> 1.2)
+ rack-mount (~> 0.8.2)
+ rack-test (~> 0.6.1)
+ sprockets (~> 2.0.4)
+ activemodel (3.1.12)
+ activesupport (= 3.1.12)
+ builder (~> 3.0.0)
+ i18n (~> 0.6)
+ activerecord (3.1.12)
+ activemodel (= 3.1.12)
+ activesupport (= 3.1.12)
+ arel (~> 2.2.3)
+ tzinfo (~> 0.3.29)
+ activeresource (3.1.12)
+ activemodel (= 3.1.12)
+ activesupport (= 3.1.12)
+ activesupport (3.1.12)
+ multi_json (~> 1.0)
annotate (2.5.0)
rake
- archive-tar-minitar (0.5.2)
- bootstrap-sass (2.3.0.1)
+ arel (2.2.3)
+ bootstrap-sass (2.3.1.2)
sass (~> 3.2)
- capistrano (2.14.2)
+ builder (3.0.4)
+ capistrano (2.15.4)
highline
net-scp (>= 1.0.0)
net-sftp (>= 2.0.0)
net-ssh (>= 2.0.14)
net-ssh-gateway (>= 1.1.0)
- chunky_png (1.2.7)
+ charlock_holmes (0.6.9.4)
+ chunky_png (1.2.8)
colorize (0.5.8)
columnize (0.3.6)
compass (0.12.2)
chunky_png (~> 1.2)
fssm (>= 0.2.7)
sass (~> 3.1)
- coveralls (0.6.2)
+ coveralls (0.6.7)
colorize
multi_json (~> 1.3)
rest-client
simplecov (>= 0.7)
thor
daemons (1.1.9)
+ debugger (1.6.0)
+ columnize (>= 0.3.1)
+ debugger-linecache (~> 1.2.0)
+ debugger-ruby_core_source (~> 1.2.1)
+ debugger-linecache (1.2.0)
+ debugger-ruby_core_source (1.2.2)
+ diff-lcs (1.2.4)
+ dynamic_form (1.1.4)
erubis (2.7.0)
eventmachine (1.0.3)
+ exception_notification (3.0.1)
+ actionmailer (>= 3.0.4)
fakeweb (1.3.0)
fast_gettext (0.7.0)
fastercsv (1.5.5)
fssm (0.2.10)
- gettext (2.3.7)
- levenshtein
+ gettext (2.3.9)
locale
- gettext_i18n_rails (0.9.2)
+ text
+ gettext_i18n_rails (0.9.4)
fast_gettext (>= 0.4.8)
- haml (4.0.0)
+ haml (4.0.3)
tilt
- highline (1.6.15)
- hoe (3.5.1)
- rake (>= 0.8, < 11.0)
+ highline (1.6.19)
+ hike (1.2.2)
i18n (0.6.4)
- json (1.7.7)
- launchy (2.2.0)
- addressable (~> 2.3)
- levenshtein (0.2.2)
+ json (1.8.0)
linecache (0.46)
rbx-require-relative (> 0.0.4)
- linecache19 (0.5.12)
- ruby_core_source (>= 0.1.4)
locale (2.0.8)
- mahoro (0.3)
+ mahoro (0.4)
mail (2.4.4)
i18n (>= 0.4.0)
mime-types (~> 1.16)
treetop (~> 1.4.8)
- mailcatcher (0.2.4)
- eventmachine
- haml
- i18n
- json
- mail
- sinatra
- skinny (>= 0.1.2)
- sqlite3-ruby
- thin
- memcache-client (1.8.5)
- mime-types (1.21)
- multi_json (1.6.1)
+ mailcatcher (0.5.11)
+ activesupport (~> 3.0)
+ eventmachine (~> 1.0.0)
+ haml (>= 3.1, < 5)
+ mail (~> 2.3)
+ sinatra (~> 1.2)
+ skinny (~> 0.2.3)
+ sqlite3 (~> 1.3)
+ thin (~> 1.5.0)
+ mime-types (1.23)
+ multi_json (1.7.4)
net-http-local (0.1.2)
net-purge (0.1.0)
- net-scp (1.1.0)
+ net-scp (1.1.1)
net-ssh (>= 2.6.5)
- net-sftp (2.1.1)
+ net-sftp (2.1.2)
net-ssh (>= 2.6.5)
- net-ssh (2.6.6)
+ net-ssh (2.6.7)
net-ssh-gateway (1.2.0)
net-ssh (>= 2.6.5)
- newrelic_rpm (3.5.8.72)
- nokogiri (1.5.6)
- pg (0.14.1)
+ newrelic_rpm (3.6.2.96)
+ nokogiri (1.5.9)
+ paper_trail (2.7.2)
+ activerecord (~> 3.0)
+ railties (~> 3.0)
+ pg (0.15.1)
polyglot (0.3.3)
- rack (1.1.6)
+ rack (1.3.10)
+ rack-cache (1.2)
+ rack (>= 0.4)
+ rack-mount (0.8.3)
+ rack (>= 1.0.0)
+ rack-protection (1.5.0)
+ rack
rack-ssl (1.3.3)
rack
rack-test (0.6.2)
rack (>= 1.0)
+ rails (3.1.12)
+ actionmailer (= 3.1.12)
+ actionpack (= 3.1.12)
+ activerecord (= 3.1.12)
+ activeresource (= 3.1.12)
+ activesupport (= 3.1.12)
+ bundler (~> 1.0)
+ railties (= 3.1.12)
+ rails-i18n (0.7.3)
+ i18n (~> 0.5)
+ railties (3.1.12)
+ actionpack (= 3.1.12)
+ activesupport (= 3.1.12)
+ rack-ssl (~> 1.3.2)
+ rake (>= 0.8.7)
+ rdoc (~> 3.4)
+ thor (~> 0.14.6)
rake (0.9.2.2)
rbx-require-relative (0.0.9)
- rdoc (4.0.0)
+ rdoc (3.12.2)
json (~> 1.4)
recaptcha (0.3.5)
rest-client (1.6.7)
@@ -132,57 +173,65 @@ GEM
rmagick (2.13.2)
routing-filter (0.3.1)
actionpack
- rspec (1.3.2)
- rspec-rails (1.3.4)
- rack (>= 1.0.0)
- rspec (~> 1.3.1)
+ rspec-core (2.13.1)
+ rspec-expectations (2.13.0)
+ diff-lcs (>= 1.1.3, < 2.0)
+ rspec-mocks (2.13.1)
+ rspec-rails (2.13.2)
+ actionpack (>= 3.0)
+ activesupport (>= 3.0)
+ railties (>= 3.0)
+ rspec-core (~> 2.13.0)
+ rspec-expectations (~> 2.13.0)
+ rspec-mocks (~> 2.13.0)
ruby-debug (0.10.4)
columnize (>= 0.1)
ruby-debug-base (~> 0.10.4.0)
ruby-debug-base (0.10.4)
linecache (>= 0.3)
- ruby-debug-base19 (0.11.25)
- columnize (>= 0.3.1)
- linecache19 (>= 0.5.11)
- ruby_core_source (>= 0.1.4)
- ruby-debug19 (0.11.6)
- columnize (>= 0.3.1)
- linecache19 (>= 0.5.11)
- ruby-debug-base19 (>= 0.11.19)
ruby-msg (1.5.1)
ruby-ole (>= 1.2.8)
vpim (>= 0.360)
ruby-ole (1.2.11.6)
- ruby_core_source (0.1.5)
- archive-tar-minitar (>= 0.5.2)
- sass (3.2.7)
+ sass (3.2.9)
simplecov (0.7.1)
multi_json (~> 1.0)
simplecov-html (~> 0.7.1)
simplecov-html (0.7.1)
- sinatra (1.2.8)
- rack (~> 1.1)
- tilt (>= 1.2.2, < 2.0)
+ sinatra (1.3.3)
+ rack (~> 1.3, >= 1.3.6)
+ rack-protection (~> 1.2)
+ tilt (~> 1.3, >= 1.3.3)
skinny (0.2.3)
eventmachine (~> 1.0.0)
thin (~> 1.5.0)
+ spork (1.0.0rc3)
+ spork-rails (3.2.1)
+ rails (>= 3.0.0, < 3.3.0)
+ spork (>= 1.0rc0)
+ sprockets (2.0.4)
+ hike (~> 1.2)
+ rack (~> 1.0)
+ tilt (~> 1.1, != 1.3.0)
sqlite3 (1.3.7)
- sqlite3-ruby (1.3.3)
- sqlite3 (>= 1.3.3)
syslog_protocol (0.9.2)
- test-unit (1.2.3)
- hoe (>= 1.5.1)
- thin (1.5.0)
+ text (1.2.1)
+ thin (1.5.1)
daemons (>= 1.0.9)
eventmachine (>= 0.12.6)
rack (>= 1.0.0)
- thor (0.17.0)
- tilt (1.3.5)
+ thor (0.14.6)
+ tilt (1.4.1)
treetop (1.4.12)
polyglot
polyglot (>= 0.3.1)
+ tzinfo (0.3.37)
vpim (0.695)
- will_paginate (2.3.16)
+ webrat (0.7.3)
+ nokogiri (>= 1.2.0)
+ rack (>= 1.0)
+ rack-test (>= 0.5.3)
+ will_paginate (3.0.4)
xapian-full-alaveteli (1.2.9.5)
xml-simple (1.1.2)
zip (2.0.2)
@@ -191,45 +240,46 @@ PLATFORMS
ruby
DEPENDENCIES
+ acts_as_versioned!
annotate
bootstrap-sass
capistrano
+ charlock_holmes
compass
coveralls
- erubis
+ debugger
+ dynamic_form
+ exception_notification
fakeweb
fast_gettext
fastercsv (>= 1.5.5)
gettext
gettext_i18n_rails
+ globalize3!
json
- launchy
locale
mahoro
- mail (~> 2.4.4)
mailcatcher
- memcache-client
net-http-local
net-purge
newrelic_rpm
pg
- rack (~> 1.1.0)
- rack-ssl
- rails!
+ rack
+ rails (= 3.1.12)
+ rails-i18n
rake (= 0.9.2.2)
rdoc
recaptcha (~> 0.3.1)
rmagick
routing-filter
- rspec-rails (~> 1.3.4)
+ rspec-rails
ruby-debug
- ruby-debug19
ruby-msg (~> 1.5.0)
+ spork-rails
syslog_protocol
- test-unit (~> 1.2.3)
vpim
- webrat!
- will_paginate (~> 2.3.11)
+ webrat
+ will_paginate
xapian-full-alaveteli (~> 1.2.9.5)
xml-simple
zip
diff --git a/LICENSE.txt b/LICENSE.txt
index f359b01d3..23976d86e 100644
--- a/LICENSE.txt
+++ b/LICENSE.txt
@@ -1,7 +1,7 @@
mySociety.org Software Licensing
-Most of the software in this directory is Copyright (c) 2004-2008 UK
-Citizens Online Democracy.
+Most of the software in this directory is Copyright (c) 2004-2013 UK
+Citizens Online Democracy.
Unless otherwise stated in particular files or directories, this
software is free software; you can redistribute it and/or modify it
@@ -9,7 +9,7 @@ under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
-Note in particular,
+Note in particular,
- acts_as_xapian in vendor/plugins/ is licensed with an MIT license.
Can you explain briefly what the GNU Affero GPL is? We offer the
@@ -28,13 +28,13 @@ WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Affero General Public License for more details.
-Information about the GNU Affero GPL:
+Information about the GNU Affero GPL:
http://www.fsf.org/licensing/licenses/agpl-3.0.html
-A copy of the GNU Affero General Public License follows.
+A copy of the GNU Affero General Public License follows.
-----------------------------------------------------------------------
-
+
GNU AFFERO GENERAL PUBLIC LICENSE
Version 3, 19 November 2007
diff --git a/README-rails.txt b/README-rails.txt
deleted file mode 100644
index 025ee5e84..000000000
--- a/README-rails.txt
+++ /dev/null
@@ -1,188 +0,0 @@
-== Welcome to Rails
-
-Rails is a web-application and persistence framework that includes everything
-needed to create database-backed web-applications according to the
-Model-View-Control pattern of separation. This pattern splits the view (also
-called the presentation) into "dumb" templates that are primarily responsible
-for inserting pre-built data in between HTML tags. The model contains the
-"smart" domain objects (such as Account, Product, Person, Post) that holds all
-the business logic and knows how to persist themselves to a database. The
-controller handles the incoming requests (such as Save New Account, Update
-Product, Show Post) by manipulating the model and directing data to the view.
-
-In Rails, the model is handled by what's called an object-relational mapping
-layer entitled Active Record. This layer allows you to present the data from
-database rows as objects and embellish these data objects with business logic
-methods. You can read more about Active Record in
-link:files/vendor/rails/activerecord/README.html.
-
-The controller and view are handled by the Action Pack, which handles both
-layers by its two parts: Action View and Action Controller. These two layers
-are bundled in a single package due to their heavy interdependence. This is
-unlike the relationship between the Active Record and Action Pack that is much
-more separate. Each of these packages can be used independently outside of
-Rails. You can read more about Action Pack in
-link:files/vendor/rails/actionpack/README.html.
-
-
-== Getting started
-
-1. At the command prompt, start a new rails application using the rails command
- and your application name. Ex: rails myapp
- (If you've downloaded rails in a complete tgz or zip, this step is already done)
-2. Change directory into myapp and start the web server: <tt>script/server</tt> (run with --help for options)
-3. Go to http://localhost:3000/ and get "Welcome aboard: You’re riding the Rails!"
-4. Follow the guidelines to start developing your application
-
-
-== Web Servers
-
-By default, Rails will try to use Mongrel and lighttpd if they are installed, otherwise
-Rails will use the WEBrick, the webserver that ships with Ruby. When you run script/server,
-Rails will check if Mongrel exists, then lighttpd and finally fall back to WEBrick. This ensures
-that you can always get up and running quickly.
-
-Mongrel is a Ruby-based webserver with a C-component (which requires compilation) that is
-suitable for development and deployment of Rails applications. If you have Ruby Gems installed,
-getting up and running with mongrel is as easy as: <tt>gem install mongrel</tt>.
-More info at: http://mongrel.rubyforge.org
-
-If Mongrel is not installed, Rails will look for lighttpd. It's considerably faster than
-Mongrel and WEBrick and also suited for production use, but requires additional
-installation and currently only works well on OS X/Unix (Windows users are encouraged
-to start with Mongrel). We recommend version 1.4.11 and higher. You can download it from
-http://www.lighttpd.net.
-
-And finally, if neither Mongrel or lighttpd are installed, Rails will use the built-in Ruby
-web server, WEBrick. WEBrick is a small Ruby web server suitable for development, but not
-for production.
-
-But of course its also possible to run Rails on any platform that supports FCGI.
-Apache, LiteSpeed, IIS are just a few. For more information on FCGI,
-please visit: http://wiki.rubyonrails.com/rails/pages/FastCGI
-
-
-== Debugging Rails
-
-Have "tail -f" commands running on the server.log and development.log. Rails will
-automatically display debugging and runtime information to these files. Debugging
-info will also be shown in the browser on requests from 127.0.0.1.
-
-
-== Breakpoints
-
-Breakpoint support is available through the script/breakpointer client. This
-means that you can break out of execution at any point in the code, investigate
-and change the model, AND then resume execution! Example:
-
- class WeblogController < ActionController::Base
- def index
- @posts = Post.find(:all)
- breakpoint "Breaking out from the list"
- end
- end
-
-So the controller will accept the action, run the first line, then present you
-with a IRB prompt in the breakpointer window. Here you can do things like:
-
-Executing breakpoint "Breaking out from the list" at .../webrick_server.rb:16 in 'breakpoint'
-
- >> @posts.inspect
- => "[#<Post:0x14a6be8 @attributes={\"title\"=>nil, \"body\"=>nil, \"id\"=>\"1\"}>,
- #<Post:0x14a6620 @attributes={\"title\"=>\"Rails you know!\", \"body\"=>\"Only ten..\", \"id\"=>\"2\"}>]"
- >> @posts.first.title = "hello from a breakpoint"
- => "hello from a breakpoint"
-
-...and even better is that you can examine how your runtime objects actually work:
-
- >> f = @posts.first
- => #<Post:0x13630c4 @attributes={"title"=>nil, "body"=>nil, "id"=>"1"}>
- >> f.
- Display all 152 possibilities? (y or n)
-
-Finally, when you're ready to resume execution, you press CTRL-D
-
-
-== Console
-
-You can interact with the domain model by starting the console through <tt>script/console</tt>.
-Here you'll have all parts of the application configured, just like it is when the
-application is running. You can inspect domain models, change values, and save to the
-database. Starting the script without arguments will launch it in the development environment.
-Passing an argument will specify a different environment, like <tt>script/console production</tt>.
-
-To reload your controllers and models after launching the console run <tt>reload!</tt>
-
-To reload your controllers and models after launching the console run <tt>reload!</tt>
-
-
-
-== Description of contents
-
-app
- Holds all the code that's specific to this particular application.
-
-app/controllers
- Holds controllers that should be named like weblogs_controller.rb for
- automated URL mapping. All controllers should descend from ApplicationController
- which itself descends from ActionController::Base.
-
-app/models
- Holds models that should be named like post.rb.
- Most models will descend from ActiveRecord::Base.
-
-app/views
- Holds the template files for the view that should be named like
- weblogs/index.rhtml for the WeblogsController#index action. All views use eRuby
- syntax.
-
-app/views/layouts
- Holds the template files for layouts to be used with views. This models the common
- header/footer method of wrapping views. In your views, define a layout using the
- <tt>layout :default</tt> and create a file named default.rhtml. Inside default.rhtml,
- call <% yield %> to render the view using this layout.
-
-app/helpers
- Holds view helpers that should be named like weblogs_helper.rb. These are generated
- for you automatically when using script/generate for controllers. Helpers can be used to
- wrap functionality for your views into methods.
-
-config
- Configuration files for the Rails environment, the routing map, the database, and other dependencies.
-
-components
- Self-contained mini-applications that can bundle together controllers, models, and views.
-
-db
- Contains the database schema in schema.rb. db/migrate contains all
- the sequence of Migrations for your schema.
-
-doc
- This directory is where your application documentation will be stored when generated
- using <tt>rake doc:app</tt>
-
-lib
- Application specific libraries. Basically, any kind of custom code that doesn't
- belong under controllers, models, or helpers. This directory is in the load path.
-
-public
- The directory available for the web server. Contains subdirectories for images, stylesheets,
- and javascripts. Also contains the dispatchers and the default HTML files. This should be
- set as the DOCUMENT_ROOT of your web server.
-
-script
- Helper scripts for automation and generation.
-
-spec
- Unit and functional specifications along with fixtures, using rspec. We use
- this instead of test.
-
-test
- DEPRECATED for this project, see 'spec' instead. Unit and functional tests
- along with fixtures. When using the script/generate scripts, template test
- files will be generated for you and placed in this directory.
-
-vendor
- External libraries that the application depends on. Also includes the plugins subdirectory.
- This directory is in the load path.
-
diff --git a/README.md b/README.md
index a7e4e0dc5..9cdb766bb 100644
--- a/README.md
+++ b/README.md
@@ -24,5 +24,6 @@ There's background information and a more documentation on
of useful information (including a blog) on
[the project website](http://alaveteli.org)
-Looking for the latest stable release? It's on the
+Looking for the latest stable release? It's on the
[master branch](https://github.com/mysociety/alaveteli/tree/master).
+
diff --git a/Rakefile b/Rakefile
index dc500c97c..5fa2a360d 100644
--- a/Rakefile
+++ b/Rakefile
@@ -1,14 +1,9 @@
# Add your own tasks in files placed in lib/tasks ending in .rake,
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
-require(File.join(File.dirname(__FILE__), 'config', 'boot'))
-
-
+require File.expand_path('../config/application', __FILE__)
require 'rake'
-require 'rake/testtask'
-require 'rdoc/task'
-
-require 'tasks/rails'
-
-
-Dir[File.join(File.dirname(__FILE__),'commonlib','rblib','tests','*.rake')].each { |file| load(file) }
+Alaveteli::Application.load_tasks
+if Rails.env == 'test'
+ Dir[File.join(File.dirname(__FILE__),'commonlib','rblib','tests','*.rake')].each { |file| load(file) }
+end
diff --git a/app/controllers/admin_censor_rule_controller.rb b/app/controllers/admin_censor_rule_controller.rb
index d3e9e47d2..6f79b5ba1 100644
--- a/app/controllers/admin_censor_rule_controller.rb
+++ b/app/controllers/admin_censor_rule_controller.rb
@@ -2,7 +2,7 @@
# For modifying requests.
#
# Copyright (c) 2008 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
class AdminCensorRuleController < AdminController
def new
diff --git a/app/controllers/admin_controller.rb b/app/controllers/admin_controller.rb
index e90f03187..0bccd3358 100644
--- a/app/controllers/admin_controller.rb
+++ b/app/controllers/admin_controller.rb
@@ -2,7 +2,7 @@
# All admin controllers are dervied from this.
#
# Copyright (c) 2009 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
require 'fileutils'
@@ -51,7 +51,7 @@ class AdminController < ApplicationController
# For administration interface, return display name of authenticated user
def admin_current_user
- if Configuration::skip_admin_auth
+ if AlaveteliConfiguration::skip_admin_auth
admin_http_auth_user
else
session[:admin_name]
@@ -74,12 +74,12 @@ class AdminController < ApplicationController
end
def authenticate
- if Configuration::skip_admin_auth
+ if AlaveteliConfiguration::skip_admin_auth
session[:using_admin] = 1
return
else
if session[:using_admin].nil? || session[:admin_name].nil?
- if params[:emergency].nil? || Configuration::disable_emergency_user
+ if params[:emergency].nil? || AlaveteliConfiguration::disable_emergency_user
if authenticated?(
:web => _("To log into the administrative interface"),
:email => _("Then you can log into the administrative interface"),
@@ -97,7 +97,7 @@ class AdminController < ApplicationController
end
else
authenticate_or_request_with_http_basic do |user_name, password|
- if user_name == Configuration::admin_username && password == Configuration::admin_password
+ if user_name == AlaveteliConfiguration::admin_username && password == AlaveteliConfiguration::admin_password
session[:using_admin] = 1
session[:admin_name] = user_name
else
diff --git a/app/controllers/admin_general_controller.rb b/app/controllers/admin_general_controller.rb
index 800678787..b64fcac3e 100644
--- a/app/controllers/admin_general_controller.rb
+++ b/app/controllers/admin_general_controller.rb
@@ -2,7 +2,7 @@
# Controller for main admin pages.
#
# Copyright (c) 2007 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
class AdminGeneralController < AdminController
skip_before_filter :authenticate, :only => :admin_js
diff --git a/app/controllers/admin_public_body_controller.rb b/app/controllers/admin_public_body_controller.rb
index 93715d364..52b56eda2 100644
--- a/app/controllers/admin_public_body_controller.rb
+++ b/app/controllers/admin_public_body_controller.rb
@@ -2,7 +2,7 @@
# Controller for editing public bodies from the admin interface.
#
# Copyright (c) 2007 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
require "public_body_categories"
@@ -23,12 +23,10 @@ class AdminPublicBodyController < AdminController
if @page == ""
@page = nil
end
- @public_bodies = PublicBody.paginate :order => "public_body_translations.name", :page => @page, :per_page => 100,
- :conditions => @query.nil? ? "public_body_translations.locale = '#{@locale}'" :
+ @public_bodies = PublicBody.joins(:translations).where(@query.nil? ? "public_body_translations.locale = '#{@locale}'" :
["(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
+ lower(public_body_translations.request_email) like lower('%'||?||'%' )) AND (public_body_translations.locale = '#{@locale}')", @query, @query, @query]).paginate :order => "public_body_translations.name", :page => @page, :per_page => 100
end
@public_bodies_by_tag = PublicBody.find_by_tag(@query)
end
diff --git a/app/controllers/admin_request_controller.rb b/app/controllers/admin_request_controller.rb
index 53055ae32..66989ea93 100644
--- a/app/controllers/admin_request_controller.rb
+++ b/app/controllers/admin_request_controller.rb
@@ -2,7 +2,7 @@
# Controller for viewing FOI requests from the admin interface.
#
# Copyright (c) 2007 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
require 'ostruct'
@@ -14,10 +14,14 @@ class AdminRequestController < AdminController
def list
@query = params[:query]
- @info_requests = InfoRequest.paginate :order => "created_at desc",
+ if @query
+ info_requests = InfoRequest.where(["lower(title) like lower('%'||?||'%')", @query])
+ else
+ info_requests = InfoRequest
+ end
+ @info_requests = info_requests.paginate :order => "created_at desc",
:page => params[:page],
- :per_page => 100,
- :conditions => @query.nil? ? nil : ["lower(title) like lower('%'||?||'%')", @query]
+ :per_page => 100
end
def show
@@ -25,11 +29,11 @@ class AdminRequestController < AdminController
# XXX is this *really* the only way to render a template to a
# variable, rather than to the response?
vars = OpenStruct.new(:name_to => @info_request.user_name,
- :name_from => Configuration::contact_name,
+ :name_from => AlaveteliConfiguration::contact_name,
:info_request => @info_request, :reason => params[:reason],
- :info_request_url => 'http://' + Configuration::domain + request_path(@info_request),
+ :info_request_url => 'http://' + AlaveteliConfiguration::domain + request_url(@info_request),
:site_name => site_name)
- template = File.read(File.join(File.dirname(__FILE__), "..", "views", "admin_request", "hidden_user_explanation.rhtml"))
+ template = File.read(File.join(File.dirname(__FILE__), "..", "views", "admin_request", "hidden_user_explanation.html.erb"))
@request_hidden_user_explanation = ERB.new(template).result(vars.instance_eval { binding })
end
@@ -361,11 +365,11 @@ class AdminRequestController < AdminController
info_request.save!
if ! info_request.is_external?
- ContactMailer.deliver_from_admin_message(
+ ContactMailer.from_admin_message(
info_request.user,
subject,
params[:explanation].strip.html_safe
- )
+ ).deliver
flash[:notice] = _("Your message to {{recipient_user_name}} has been sent",:recipient_user_name=>CGI.escapeHTML(info_request.user.name))
else
flash[:notice] = _("This external request has been hidden")
diff --git a/app/controllers/admin_track_controller.rb b/app/controllers/admin_track_controller.rb
index 525c96782..085c9c6cc 100644
--- a/app/controllers/admin_track_controller.rb
+++ b/app/controllers/admin_track_controller.rb
@@ -2,14 +2,18 @@
# Show email alerts / RSS feeds from admin interface.
#
# Copyright (c) 2008 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
class AdminTrackController < AdminController
def list
@query = params[:query]
- @admin_tracks = TrackThing.paginate :order => "created_at desc", :page => params[:page], :per_page => 100,
- :conditions => @query.nil? ? nil : ["lower(track_query) like lower('%'||?||'%')", @query ]
- @popular = ActiveRecord::Base.connection.select_all("select count(*) as count, title, info_request_id from track_things join info_requests on info_request_id = info_requests.id where info_request_id is not null group by info_request_id, title order by count desc limit 10;")
+ if @query
+ track_things = TrackThing.where(["lower(track_query) like lower('%'||?||'%')", @query])
+ else
+ track_things = TrackThing
+ end
+ @admin_tracks = track_things.paginate :order => "created_at desc", :page => params[:page], :per_page => 100
+ @popular = ActiveRecord::Base.connection.select_all("select count(*) as count, title, info_request_id from track_things join info_requests on info_request_id = info_requests.id where info_request_id is not null group by info_request_id, title order by count desc limit 10;")
end
private
diff --git a/app/controllers/admin_user_controller.rb b/app/controllers/admin_user_controller.rb
index feffa208e..929b93e0e 100644
--- a/app/controllers/admin_user_controller.rb
+++ b/app/controllers/admin_user_controller.rb
@@ -2,7 +2,7 @@
# Controller for viewing user accounts from the admin interface.
#
# Copyright (c) 2008 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
class AdminUserController < AdminController
def index
@@ -12,9 +12,13 @@ class AdminUserController < AdminController
def list
@query = params[:query]
- @admin_users = User.paginate :order => "name", :page => params[:page], :per_page => 100,
- :conditions => @query.nil? ? nil : ["lower(name) like lower('%'||?||'%') or
- lower(email) like lower('%'||?||'%')", @query, @query]
+ if @query
+ users = User.where(["lower(name) like lower('%'||?||'%') or
+ lower(email) like lower('%'||?||'%')", @query, @query])
+ else
+ users = User
+ end
+ @admin_users = users.paginate :order => "name", :page => params[:page], :per_page => 100
end
def list_banned
diff --git a/app/controllers/api_controller.rb b/app/controllers/api_controller.rb
index 5d8ceb888..49b226e4b 100644
--- a/app/controllers/api_controller.rb
+++ b/app/controllers/api_controller.rb
@@ -83,7 +83,7 @@ class ApiController < ApplicationController
direction = json["direction"]
body = json["body"]
- sent_at_str = json["sent_at"]
+ sent_at = json["sent_at"]
errors = []
@@ -107,12 +107,6 @@ class ApiController < ApplicationController
errors << "The 'body' is empty"
end
- begin
- sent_at = Time.iso8601(sent_at_str)
- rescue ArgumentError
- errors << "Failed to parse 'sent_at' field as ISO8601 time: #{sent_at_str}"
- end
-
if direction == "request" && !attachments.nil?
errors << "You cannot attach files to messages in the 'request' direction"
end
@@ -155,7 +149,8 @@ class ApiController < ApplicationController
)
end
- mail = RequestMailer.create_external_response(request, body, sent_at, attachment_hashes)
+ mail = RequestMailer.external_response(request, body, sent_at, attachment_hashes)
+
request.receive(mail, mail.encoded, true)
end
render :json => {
@@ -248,6 +243,6 @@ class ApiController < ApplicationController
private
def make_url(*args)
- "http://" + Configuration::domain + "/" + args.join("/")
+ "http://" + AlaveteliConfiguration::domain + "/" + args.join("/")
end
end
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index f3deeb64a..d1d702616 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -5,20 +5,22 @@
# 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/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
require 'open-uri'
class ApplicationController < ActionController::Base
class PermissionDenied < StandardError
end
+ class RouteNotFound < StandardError
+ end
+ # assign our own handler method for non-local exceptions
+ rescue_from Exception, :with => :render_exception
+
# 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
@@ -27,9 +29,6 @@ class ApplicationController < ActionController::Base
before_filter :set_vary_header
before_filter :set_popup_banner
- # scrub sensitive parameters from the logs
- filter_parameter_logging :password
-
def set_vary_header
response.headers['Vary'] = 'Cookie'
end
@@ -54,12 +53,12 @@ class ApplicationController < ActionController::Base
end
def set_gettext_locale
- if Configuration::include_default_locale_in_urls == false
+ if AlaveteliConfiguration::include_default_locale_in_urls == false
params_locale = params[:locale] ? params[:locale] : I18n.default_locale
else
params_locale = params[:locale]
end
- if Configuration::use_default_browser_language
+ if AlaveteliConfiguration::use_default_browser_language
requested_locale = params_locale || session[:locale] || cookies[:locale] || request.env['HTTP_ACCEPT_LANGUAGE'] || I18n.default_locale
else
requested_locale = params_locale || session[:locale] || cookies[:locale] || I18n.default_locale
@@ -74,9 +73,6 @@ class ApplicationController < ActionController::Base
end
end
- # scrub sensitive parameters from the logs
- filter_parameter_logging :password
-
helper_method :locale_from_params
# Help work out which request causes RAM spike.
@@ -92,7 +88,7 @@ class ApplicationController < ActionController::Base
# egrep "CONSUME MEMORY: [0-9]{7} KB" production.log
around_filter :record_memory
def record_memory
- record_memory = Configuration::debug_record_memory
+ record_memory = AlaveteliConfiguration::debug_record_memory
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+)/)
@@ -120,52 +116,36 @@ class ApplicationController < ActionController::Base
end
end
- # Override default error handler, for production sites.
- def rescue_action_in_public(exception)
- # Looks for before_filters called something like `set_view_paths_{themename}`. These
- # are set by the themes.
- # Normally, this is called by the theme itself in a
- # :before_filter, but when there's an error, this doesn't
- # happen. By calling it here, we can ensure error pages are
- # still styled according to the theme.
- ActionController::Base.before_filters.select{|f| f.to_s =~ /set_view_paths/}.each do |f|
- self.send(f)
- end
- # Make sure expiry time for session is set (before_filters are
- # otherwise missed by this override)
- session_remember_me
+ def render_exception(exception)
- # Make sure the locale is set correctly too
- set_gettext_locale
+ # In development, or the admin interface, or for a local request, let Rails handle the exception
+ # with its stack trace templates. Local requests in testing are a special case so that we can
+ # test this method - there we use consider_all_requests_local to control behaviour.
+ if Rails.application.config.consider_all_requests_local || local_request? ||
+ (request.local? && !Rails.env.test?)
+ raise exception
+ end
+ @exception_backtrace = exception.backtrace.join("\n")
+ @exception_class = exception.class.to_s
+ @exception_message = exception.message
case exception
- when ActiveRecord::RecordNotFound, ActionController::UnknownAction, ActionController::RoutingError
+ when ActiveRecord::RecordNotFound, RouteNotFound
@status = 404
when PermissionDenied
@status = 403
else
+ message = "\n#{@exception_class} (#{@exception_message}):\n"
+ backtrace = Rails.backtrace_cleaner.clean(exception.backtrace, :silent)
+ message << " " << backtrace.join("\n ")
+ Rails.logger.fatal("#{message}\n\n")
+ ExceptionNotifier::Notifier.exception_notification(request.env, exception).deliver
@status = 500
- notify_about_exception exception
end
- # Display user appropriate error message
- @exception_backtrace = exception.backtrace.join("\n")
- @exception_class = exception.class.to_s
- @exception_message = exception.message
- render :template => "general/exception_caught.rhtml", :status => @status
- end
-
- # For development sites.
- alias original_rescue_action_locally rescue_action_locally
- def rescue_action_locally(exception)
- # Make sure expiry time for session is set (before_filters are
- # otherwise missed by this override)
- session_remember_me
-
- # Make sure the locale is set correctly too
- set_gettext_locale
-
- # Display default, detailed error for developers
- original_rescue_action_locally(exception)
+ respond_to do |format|
+ format.html{ render :template => "general/exception_caught", :status => @status }
+ format.any{ render :nothing => true, :status => @status }
+ end
end
def local_request?
@@ -175,6 +155,7 @@ class ApplicationController < ActionController::Base
# Called from test code, is a mimic of UserController.confirm, for use in following email
# links when in controller tests (though we also have full integration tests that
# can work over multiple controllers)
+ # TODO: Move this to the tests. It shouldn't be here
def test_code_redirect_by_email_token(token, controller_example_group)
post_redirect = PostRedirect.find_by_email_token(token)
if post_redirect.nil?
@@ -182,7 +163,7 @@ class ApplicationController < ActionController::Base
end
session[:user_id] = post_redirect.user.id
session[:user_circumstance] = post_redirect.circumstance
- params = controller_example_group.params_from(:get, post_redirect.local_part_uri)
+ params = Rails.application.routes.recognize_path(post_redirect.local_part_uri)
params.merge(post_redirect.post_params)
controller_example_group.get params[:action], params
end
@@ -258,7 +239,7 @@ class ApplicationController < ActionController::Base
# Check the user is logged in
def authenticated?(reason_params)
unless session[:user_id]
- post_redirect = PostRedirect.new(:uri => request.request_uri, :post_params => params,
+ post_redirect = PostRedirect.new(:uri => request.fullpath, :post_params => params,
:reason_params => reason_params)
post_redirect.save!
# 'modal' controls whether the sign-in form will be displayed in the typical full-blown
@@ -346,10 +327,10 @@ class ApplicationController < ActionController::Base
#
def check_read_only
- if !Configuration::read_only.empty?
+ if !AlaveteliConfiguration::read_only.empty?
flash[:notice] = _("<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>",
:site_name => site_name,
- :read_only => Configuration::read_only)
+ :read_only => AlaveteliConfiguration::read_only)
redirect_to frontpage_url
end
@@ -552,10 +533,10 @@ class ApplicationController < ActionController::Base
def country_from_ip
country = ""
- if !Configuration::gaze_url.empty?
- country = quietly_try_to_open("#{Configuration::gaze_url}/gaze-rest?f=get_country_from_ip;ip=#{request.remote_ip}")
+ if !AlaveteliConfiguration::gaze_url.empty?
+ country = quietly_try_to_open("#{AlaveteliConfiguration::gaze_url}/gaze-rest?f=get_country_from_ip;ip=#{request.remote_ip}")
end
- country = Configuration::iso_country_code if country.empty?
+ country = AlaveteliConfiguration::iso_country_code if country.empty?
return country
end
diff --git a/app/controllers/comment_controller.rb b/app/controllers/comment_controller.rb
index ed249d6cc..d4b17e9d2 100644
--- a/app/controllers/comment_controller.rb
+++ b/app/controllers/comment_controller.rb
@@ -2,7 +2,7 @@
# Show annotations upon a request or other object.
#
# Copyright (c) 2008 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
class CommentController < ApplicationController
before_filter :check_read_only, :only => [ :new ]
diff --git a/app/controllers/general_controller.rb b/app/controllers/general_controller.rb
index 0783fc579..9d0f91dda 100644
--- a/app/controllers/general_controller.rb
+++ b/app/controllers/general_controller.rb
@@ -3,14 +3,7 @@
# particular model.
#
# Copyright (c) 2008 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
-
-begin
- require 'xmlsimple'
-rescue LoadError
- # Debian maintainers put their xmlsimple in a different location :(
- require 'lib/xmlsimple'
-end
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
require 'open-uri'
@@ -21,7 +14,7 @@ class GeneralController < ApplicationController
medium_cache
# get some example searches and public bodies to display
# either from config, or based on a (slow!) query if not set
- body_short_names = Configuration::frontpage_publicbody_examples.split(/\s*;\s*/).map{|s| "'%s'" % s.gsub(/'/, "''") }.join(", ")
+ body_short_names = AlaveteliConfiguration::frontpage_publicbody_examples.split(/\s*;\s*/).map{|s| "'%s'" % s.gsub(/'/, "''") }.join(", ")
@locale = self.locale_from_params()
locale_condition = 'public_body_translations.locale = ?'
conditions = [locale_condition, @locale]
@@ -71,7 +64,7 @@ class GeneralController < ApplicationController
def blog
medium_cache
@feed_autodetect = []
- @feed_url = Configuration::blog_feed
+ @feed_url = AlaveteliConfiguration::blog_feed
separator = @feed_url.include?('?') ? '&' : '?'
@feed_url = "#{@feed_url}#{separator}lang=#{self.locale_from_params()}"
@blog_items = []
@@ -84,7 +77,7 @@ class GeneralController < ApplicationController
@feed_autodetect = [{:url => @feed_url, :title => "#{site_name} blog"}]
end
end
- @twitter_user = Configuration::twitter_username
+ @twitter_user = AlaveteliConfiguration::twitter_username
end
# Just does a redirect from ?query= search to /query
@@ -109,7 +102,7 @@ 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.
- combined = params[:combined]
+ combined = params[:combined].split("/")
@sortby = nil
@bodies = @requests = @users = true
if combined.size > 0 && (['advanced'].include?(combined[-1]))
@@ -229,5 +222,11 @@ class GeneralController < ApplicationController
@locale = self.locale_from_params()
render(:layout => false, :content_type => 'text/css')
end
+
+ # Handle requests for non-existent URLs - will be handled by ApplicationController::render_exception
+ def not_found
+ raise RouteNotFound
+ end
+
end
diff --git a/app/controllers/help_controller.rb b/app/controllers/help_controller.rb
index 573abac63..9959df6d8 100644
--- a/app/controllers/help_controller.rb
+++ b/app/controllers/help_controller.rb
@@ -2,7 +2,7 @@
# Show information about one particular request.
#
# Copyright (c) 2008 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
class HelpController < ApplicationController
@@ -18,7 +18,7 @@ class HelpController < ApplicationController
end
def contact
- @contact_email = Configuration::contact_email
+ @contact_email = AlaveteliConfiguration::contact_email
# if they clicked remove for link to request/body, remove it
if params[:remove]
@@ -49,14 +49,14 @@ class HelpController < ApplicationController
end
@contact = ContactValidator.new(params[:contact])
if @contact.valid? && !params[:remove]
- ContactMailer.deliver_to_admin_message(
+ ContactMailer.to_admin_message(
params[:contact][:name],
params[:contact][:email],
params[:contact][:subject],
params[:contact][:message],
@user,
@last_request, @last_body
- )
+ ).deliver
flash[:notice] = _("Your message has been sent. Thank you for getting in touch! We'll get back to you soon.")
redirect_to frontpage_url
return
diff --git a/app/controllers/holiday_controller.rb b/app/controllers/holiday_controller.rb
index 3101c07e3..efc20701d 100644
--- a/app/controllers/holiday_controller.rb
+++ b/app/controllers/holiday_controller.rb
@@ -2,7 +2,7 @@
# Calculate dates
#
# Copyright (c) 2008 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
class HolidayController < ApplicationController
@@ -12,7 +12,7 @@ class HolidayController < ApplicationController
def due_date
if params[:holiday]
@request_date = Date.strptime(params[:holiday]) or raise "Invalid date"
- @due_date = Holiday.due_date_from(@request_date, Configuration::reply_late_after_days, Configuration::working_or_calendar_days)
+ @due_date = Holiday.due_date_from(@request_date, AlaveteliConfiguration::reply_late_after_days, AlaveteliConfiguration::working_or_calendar_days)
@skipped = Holiday.all(
:conditions => [ 'day >= ? AND day <= ?',
@request_date.strftime("%F"), @due_date.strftime("%F")
diff --git a/app/controllers/public_body_controller.rb b/app/controllers/public_body_controller.rb
index 1821e6725..74ea043bb 100644
--- a/app/controllers/public_body_controller.rb
+++ b/app/controllers/public_body_controller.rb
@@ -3,7 +3,7 @@
# Show information about a public body.
#
# Copyright (c) 2007 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
require 'fastercsv'
@@ -128,10 +128,8 @@ class PublicBodyController < ApplicationController
end
end
I18n.with_locale(@locale) do
- @public_bodies = PublicBody.paginate(
- :order => "public_body_translations.name", :page => params[:page], :per_page => 100,
- :conditions => conditions,
- :joins => :translations
+ @public_bodies = PublicBody.where(conditions).joins(:translations).order("public_body_translations.name").paginate(
+ :page => params[:page], :per_page => 100
)
render :template => "public_body/list"
end
diff --git a/app/controllers/request_controller.rb b/app/controllers/request_controller.rb
index e82871d7b..a455d1725 100644
--- a/app/controllers/request_controller.rb
+++ b/app/controllers/request_controller.rb
@@ -1,10 +1,10 @@
+# encoding: UTF-8
# app/controllers/request_controller.rb:
# Show information about one particular request.
#
# Copyright (c) 2007 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
-require 'alaveteli_file_types'
require 'zip/zip'
require 'open-uri'
@@ -17,7 +17,7 @@ class RequestController < ApplicationController
@@custom_states_loaded = false
begin
- if ENV["RAILS_ENV"] != "test"
+ if !Rails.env.test?
require 'customstates'
include RequestControllerCustomStates
@@custom_states_loaded = true
@@ -28,7 +28,7 @@ class RequestController < ApplicationController
def select_authority
# Check whether we force the user to sign in right at the start, or we allow her
# to start filling the request anonymously
- if Configuration::force_registration_on_new_request && !authenticated?(
+ if AlaveteliConfiguration::force_registration_on_new_request && !authenticated?(
:web => _("To send your FOI request"),
:email => _("Then you'll be allowed to send FOI requests."),
:email_subject => _("Confirm your email address")
@@ -44,7 +44,7 @@ class RequestController < ApplicationController
end
def show
- if !Configuration::varnish_host.blank?
+ if !AlaveteliConfiguration::varnish_host.blank?
# If varnish is set up to accept PURGEs, then cache for a
# long time
long_cache
@@ -67,8 +67,7 @@ class RequestController < ApplicationController
# Test for whole request being hidden
if !@info_request.user_can_view?(authenticated_user)
- render :template => 'request/hidden', :status => 410 # gone
- return
+ return render_hidden
end
# Other parameters
@@ -126,8 +125,7 @@ class RequestController < ApplicationController
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
+ return render_hidden
end
@columns = ['id', 'event_type', 'created_at', 'described_state', 'last_described_at', 'calculated_state' ]
end
@@ -146,8 +144,7 @@ class RequestController < ApplicationController
raise ActiveRecord::RecordNotFound.new("Request not found") if @info_request.nil?
if !@info_request.user_can_view?(authenticated_user)
- render :template => 'request/hidden', :status => 410 # gone
- return
+ return render_hidden
end
@xapian_object = ::ActsAsXapian::Similar.new([InfoRequestEvent], @info_request.info_request_events,
:offset => (@page - 1) * @per_page, :limit => @per_page, :collapse_by_prefix => 'request_collapse')
@@ -242,16 +239,19 @@ class RequestController < ApplicationController
# Read parameters in - first the public body (by URL name or id)
if params[:url_name]
if params[:url_name].match(/^[0-9]+$/)
- params[:info_request][:public_body_id] = params[:url_name]
+ params[:info_request][:public_body] = PublicBody.find(params[:url_name])
else
public_body = PublicBody.find_by_url_name_with_historic(params[:url_name])
raise ActiveRecord::RecordNotFound.new("None found") if public_body.nil? # XXX proper 404
- params[:info_request][:public_body_id] = public_body.id
+ params[:info_request][:public_body] = public_body
end
elsif params[:public_body_id]
- params[:info_request][:public_body_id] = params[:public_body_id]
+ params[:info_request][:public_body] = PublicBody.find(params[:public_body_id])
+ # Explicitly load the association as this isn't done automatically in newer Rails versions
+ elsif params[:info_request][:public_body_id]
+ params[:info_request][:public_body] = PublicBody.find(params[:info_request][:public_body_id])
end
- if !params[:info_request][:public_body_id]
+ if !params[:info_request][:public_body]
# compulsory to have a body by here, or go to front page which is start of process
redirect_to frontpage_url
return
@@ -344,7 +344,7 @@ class RequestController < ApplicationController
end
if !authenticated?(
- :web => _("To send your FOI request"),
+ :web => _("To send your FOI request").to_str,
:email => _("Then your FOI request to {{public_body_name}} will be sent.",:public_body_name=>@info_request.public_body.name),
:email_subject => _("Confirm your FOI request to ") + @info_request.public_body.name
)
@@ -368,8 +368,8 @@ class RequestController < ApplicationController
replied by then.</p>
<p>If you write about this request (for example in a forum or a blog) please link to this page, and add an
annotation below telling people about your writing.</p>",:law_used_full=>@info_request.law_used_full,
- :late_number_of_days => Configuration::reply_late_after_days)
- redirect_to show_new_request_url(:url_title => @info_request.url_title)
+ :late_number_of_days => AlaveteliConfiguration::reply_late_after_days)
+ redirect_to show_new_request_path(:url_title => @info_request.url_title)
end
# Submitted to the describing state of messages form
@@ -434,6 +434,7 @@ class RequestController < ApplicationController
return
end
+ calculated_status = info_request.calculate_status
# Display advice for requester on what to do next, as appropriate
flash[:notice] = case info_request.calculate_status
when 'waiting_response'
@@ -442,7 +443,7 @@ class RequestController < ApplicationController
when 'waiting_response_overdue'
_("<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>",:date_response_required_by=>simple_date(info_request.date_response_required_by))
when 'waiting_response_very_overdue'
- _("<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>", :very_late_number_of_days => Configuration::reply_very_late_after_days, :late_number_of_days => Configuration::reply_late_after_days)
+ _("<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>", :very_late_number_of_days => AlaveteliConfiguration::reply_very_late_after_days, :late_number_of_days => AlaveteliConfiguration::reply_late_after_days)
when 'not_held'
_("<p>Thank you! Here are some ideas on what to do next:</p>
<ul>
@@ -468,7 +469,7 @@ class RequestController < ApplicationController
when 'gone_postal'
nil
when 'internal_review'
- _("<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>",:late_number_of_days => Configuration.reply_late_after_days, :review_url => unhappy_url(info_request) + "#internal_review")
+ _("<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>",:late_number_of_days => AlaveteliConfiguration.reply_late_after_days, :review_url => unhappy_url(info_request) + "#internal_review")
when 'error_message', 'requires_admin'
_("Thank you! We'll look into what happened and try and fix it up.")
when 'user_withdrawn'
@@ -560,10 +561,7 @@ class RequestController < ApplicationController
end
- params_outgoing_message = params[:outgoing_message]
- if params_outgoing_message.nil?
- params_outgoing_message = {}
- end
+ params_outgoing_message = params[:outgoing_message] ? params[:outgoing_message].clone : {}
params_outgoing_message.merge!({
:status => 'ready',
:message_type => 'followup',
@@ -586,8 +584,7 @@ class RequestController < ApplicationController
# Test for hidden requests
if !authenticated_user.nil? && !@info_request.user_can_view?(authenticated_user)
- render :template => 'request/hidden', :status => 410 # gone
- return
+ return render_hidden
end
# Check address is good
@@ -670,7 +667,7 @@ class RequestController < ApplicationController
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
+ return render_hidden
end
# Is this a completely public request that we can cache attachments for
# to be served up without authentication?
@@ -708,16 +705,19 @@ class RequestController < ApplicationController
key_path = foi_fragment_cache_path(key)
if foi_fragment_cache_exists?(key_path)
logger.info("Reading cache for #{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)
+
+ if File.directory?(key_path)
+ render :text => "Directory listing not allowed", :status => 403
+ else
+ render :text => foi_fragment_cache_read(key_path),
+ :content_type => (AlaveteliFileTypes.filename_to_mimetype(params[:file_name]) || 'application/octet-stream')
+ end
return
end
yield
- if params[:skip_cache].nil?
+ if params[:skip_cache].nil? && response.status == 200
# write it to the fileystem ourselves, so is just a plain file. (The
# various fragment cache functions using Ruby Marshall to write the file
# which adds a header, so isnt compatible with images that have been
@@ -732,13 +732,14 @@ class RequestController < ApplicationController
def get_attachment
get_attachment_internal(false)
+ return unless @attachment
# Prevent spam to magic request address. Note that the binary
# subsitution method used depends on the content type
@incoming_message.binary_mask_stuff!(@attachment.body, @attachment.content_type)
# we don't use @attachment.content_type here, as we want same mime type when cached in cache_attachments above
- response.content_type = AlaveteliFileTypes.filename_to_mimetype(params[:file_name].join("/")) || 'application/octet-stream'
+ response.content_type = AlaveteliFileTypes.filename_to_mimetype(params[:file_name]) || 'application/octet-stream'
render :text => @attachment.body
end
@@ -751,6 +752,7 @@ class RequestController < ApplicationController
raise ActiveRecord::RecordNotFound.new("Attachment HTML not found.")
end
get_attachment_internal(true)
+ return unless @attachment
# images made during conversion (e.g. images in PDF files) are put in the cache directory, so
# the same cache code in cache_attachments above will display them.
@@ -788,7 +790,7 @@ class RequestController < ApplicationController
raise ActiveRecord::RecordNotFound.new(message)
end
@part_number = params[:part].to_i
- @filename = params[:file_name].join("/")
+ @filename = params[:file_name]
if html_conversion
@original_filename = @filename.gsub(/\.html$/, "")
else
@@ -797,8 +799,11 @@ class RequestController < ApplicationController
# check permissions
raise "internal error, pre-auth filter should have caught this" if !@info_request.user_can_view?(authenticated_user)
- @attachment = IncomingMessage.get_attachment_by_url_part_number(@incoming_message.get_attachments_for_display, @part_number)
- raise ActiveRecord::RecordNotFound.new("attachment not found part number " + @part_number.to_s + " incoming_message " + @incoming_message.id.to_s) if @attachment.nil?
+ @attachment = IncomingMessage.get_attachment_by_url_part_number_and_filename(@incoming_message.get_attachments_for_display, @part_number, @original_filename)
+ # If we can't find the right attachment, redirect to the incoming message:
+ unless @attachment
+ return redirect_to incoming_message_url(@incoming_message), :status => 303
+ end
# check filename in URL matches that in database (use a censor rule if you want to change a filename)
raise ActiveRecord::RecordNotFound.new("please use same filename as original file has, display: '" + @attachment.display_filename + "' old_display: '" + @attachment.old_display_filename + "' original: '" + @original_filename + "'") if @attachment.display_filename != @original_filename && @attachment.old_display_filename != @original_filename
@@ -849,7 +854,8 @@ class RequestController < ApplicationController
return
end
- mail = RequestMailer.create_fake_response(@info_request, @user, body, file_name, file_content)
+ mail = RequestMailer.fake_response(@info_request, @user, body, file_name, file_content)
+
@info_request.receive(mail, mail.encoded, true)
flash[:notice] = _("Thank you for responding to this FOI request! Your response has been published below, and a link to your response has been emailed to ") + CGI.escapeHTML(@info_request.user.name) + "."
redirect_to request_url(@info_request)
@@ -863,7 +869,7 @@ class RequestController < ApplicationController
# by making the last work a wildcard, which is quite the same
query = params[:q]
@xapian_requests = perform_search_typeahead(query, InfoRequestEvent)
- render :partial => "request/search_ahead.rhtml"
+ render :partial => "request/search_ahead"
end
def download_entire_request
@@ -872,8 +878,7 @@ class RequestController < ApplicationController
@info_request = InfoRequest.find_by_url_title!(params[:url_title])
# Test for whole request being hidden or requester-only
if !@info_request.all_can_view?
- render :template => 'request/hidden', :status => 410 # gone
- return
+ return render_hidden
end
if authenticated?(
:web => _("To download the zip file"),
@@ -891,10 +896,10 @@ class RequestController < ApplicationController
if !File.exists?(file_path)
FileUtils.mkdir_p(File.dirname(file_path))
Zip::ZipFile.open(file_path, Zip::ZipFile::CREATE) { |zipfile|
- convert_command = Configuration::html_to_pdf_command
+ convert_command = AlaveteliConfiguration::html_to_pdf_command
done = false
if !convert_command.blank? && File.exists?(convert_command)
- url = "http://#{Configuration::domain}#{request_path(@info_request)}?print_stylesheet=1"
+ url = "http://#{AlaveteliConfiguration::domain}#{request_path(@info_request)}?print_stylesheet=1"
tempfile = Tempfile.new('foihtml2pdf')
output = AlaveteliExternalCommand.run(convert_command, url, tempfile.path)
if !output.nil?
@@ -911,7 +916,7 @@ class RequestController < ApplicationController
end
if !done
@info_request_events = @info_request.info_request_events
- template = File.read(File.join(File.dirname(__FILE__), "..", "views", "request", "simple_correspondence.rhtml"))
+ template = File.read(File.join(File.dirname(__FILE__), "..", "views", "request", "simple_correspondence.html.erb"))
output = ERB.new(template).result(binding)
zipfile.get_output_stream("correspondence.txt") { |f|
f.puts(output)
@@ -933,5 +938,17 @@ class RequestController < ApplicationController
end
end
end
+
+ private
+
+ def render_hidden
+ respond_to do |format|
+ response_code = 410 # gone
+ format.html{ render :template => 'request/hidden', :status => response_code }
+ format.any{ render :nothing => true, :status => response_code }
+ end
+ false
+ end
+
end
diff --git a/app/controllers/request_game_controller.rb b/app/controllers/request_game_controller.rb
index 4b6f02970..6eac399ac 100644
--- a/app/controllers/request_game_controller.rb
+++ b/app/controllers/request_game_controller.rb
@@ -2,7 +2,7 @@
# The 'categorise old requests' game
#
# Copyright (c) 2009 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
class RequestGameController < ApplicationController
diff --git a/app/controllers/services_controller.rb b/app/controllers/services_controller.rb
index e75dac903..11ed4ac8f 100644
--- a/app/controllers/services_controller.rb
+++ b/app/controllers/services_controller.rb
@@ -6,7 +6,7 @@ class ServicesController < ApplicationController
def other_country_message
text = ""
- iso_country_code = Configuration::iso_country_code.downcase
+ iso_country_code = AlaveteliConfiguration::iso_country_code.downcase
if country_from_ip.downcase != iso_country_code
found_country = WorldFOIWebsites.by_code(country_from_ip)
@@ -36,9 +36,9 @@ class ServicesController < ApplicationController
:content_type => "text/plain",
:layout => false,
:locals => {:name_to => info_request.user_name,
- :name_from => Configuration::contact_name,
+ :name_from => AlaveteliConfiguration::contact_name,
:info_request => info_request, :reason => params[:reason],
- :info_request_url => 'http://' + Configuration::domain + request_path(info_request),
+ :info_request_url => 'http://' + AlaveteliConfiguration::domain + request_path(info_request),
:site_name => site_name}
end
diff --git a/app/controllers/track_controller.rb b/app/controllers/track_controller.rb
index 15da7f327..40e82e7a4 100644
--- a/app/controllers/track_controller.rb
+++ b/app/controllers/track_controller.rb
@@ -3,7 +3,7 @@
# social bookmarking.
#
# Copyright (c) 2008 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
class TrackController < ApplicationController
@@ -80,10 +80,7 @@ class TrackController < ApplicationController
# Track a search term
def track_search_query
- # XXX should be better thing in rails routes than having to do this
- # join just to get / and . to work in a query.
- query_array = params[:query_array]
- @query = query_array.join("/")
+ @query = params[:query_array]
# XXX more hackery to make alternate formats still work with query_array
if /^(.*)\.json$/.match(@query)
@@ -157,10 +154,10 @@ class TrackController < ApplicationController
def atom_feed_internal
@xapian_object = perform_search([InfoRequestEvent], @track_thing.track_query, @track_thing.params[:feed_sortby], nil, 25, 1)
respond_to do |format|
- format.atom { render :template => 'track/atom_feed', :content_type => "application/atom+xml" }
format.json { render :json => @xapian_object.results.map { |r| r[:model].json_for_api(true,
- lambda { |t| @template.highlight_and_excerpt(t, @xapian_object.words_to_highlight, 150) }
+ lambda { |t| view_context.highlight_and_excerpt(t, @xapian_object.words_to_highlight, 150) }
) } }
+ format.any { render :template => 'track/atom_feed.atom', :layout => false, :content_type => 'application/atom+xml' }
end
end
diff --git a/app/controllers/user_controller.rb b/app/controllers/user_controller.rb
index fc8b6e014..b7912b528 100644
--- a/app/controllers/user_controller.rb
+++ b/app/controllers/user_controller.rb
@@ -2,7 +2,7 @@
# Show information about a user.
#
# Copyright (c) 2007 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
require 'set'
@@ -136,7 +136,7 @@ class UserController < ApplicationController
# Login form
def signin
work_out_post_redirect
- @request_from_foreign_country = country_from_ip != Configuration::iso_country_code
+ @request_from_foreign_country = country_from_ip != AlaveteliConfiguration::iso_country_code
# make sure we have cookies
if session.instance_variable_get(:@dbman)
if not session.instance_variable_get(:@dbman).instance_variable_get(:@original)
@@ -190,7 +190,7 @@ class UserController < ApplicationController
# Create new account form
def signup
work_out_post_redirect
- @request_from_foreign_country = country_from_ip != Configuration::iso_country_code
+ @request_from_foreign_country = country_from_ip != AlaveteliConfiguration::iso_country_code
# Make the user and try to save it
@user_signup = User.new(params[:user_signup])
error = false
@@ -222,7 +222,7 @@ class UserController < ApplicationController
post_redirect = PostRedirect.find_by_email_token(params[:email_token])
if post_redirect.nil?
- render :template => 'user/bad_token.rhtml'
+ render :template => 'user/bad_token'
return
end
@@ -288,7 +288,7 @@ class UserController < ApplicationController
post_redirect.user = user_signchangepassword
post_redirect.save!
url = confirm_url(:email_token => post_redirect.email_token)
- UserMailer.deliver_confirm_login(user_signchangepassword, post_redirect.reason_params, url)
+ UserMailer.confirm_login(user_signchangepassword, post_redirect.reason_params, url).deliver
else
# User not found, but still show confirm page to not leak fact user exists
end
@@ -352,7 +352,7 @@ class UserController < ApplicationController
# if new email already in use, send email there saying what happened
user_alreadyexists = User.find_user_by_email(@signchangeemail.new_email)
if user_alreadyexists
- UserMailer.deliver_changeemail_already_used(@user.email, @signchangeemail.new_email)
+ UserMailer.changeemail_already_used(@user.email, @signchangeemail.new_email).deliver
# it is important this screen looks the same as the one below, so
# you can't change to someone's email in order to tell if they are
# registered with that email on the site
@@ -373,7 +373,7 @@ class UserController < ApplicationController
post_redirect.save!
url = confirm_url(:email_token => post_redirect.email_token)
- UserMailer.deliver_changeemail_confirm(@user, @signchangeemail.new_email, url)
+ UserMailer.changeemail_confirm(@user, @signchangeemail.new_email, url).deliver
# it is important this screen looks the same as the one above, so
# you can't change to someone's email in order to tell if they are
# registered with that email on the site
@@ -419,13 +419,13 @@ class UserController < ApplicationController
params[:contact][:email] = @user.email
@contact = ContactValidator.new(params[:contact])
if @contact.valid?
- ContactMailer.deliver_user_message(
+ ContactMailer.user_message(
@user,
@recipient_user,
user_url(@user),
params[:contact][:subject],
params[:contact][:message]
- )
+ ).deliver
flash[:notice] = _("Your message to {{recipient_user_name}} has been sent!",:recipient_user_name=>CGI.escapeHTML(@recipient_user.name))
redirect_to user_url(@recipient_user)
return
@@ -465,7 +465,7 @@ class UserController < ApplicationController
@draft_profile_photo = ProfilePhoto.new(:data => file_content, :draft => true)
if !@draft_profile_photo.valid?
# error page (uses @profile_photo's error fields in view to show errors)
- render :template => 'user/set_draft_profile_photo.rhtml'
+ render :template => 'user/set_draft_profile_photo'
return
end
@draft_profile_photo.save
@@ -480,7 +480,7 @@ class UserController < ApplicationController
return
end
- render :template => 'user/set_crop_profile_photo.rhtml'
+ render :template => 'user/set_crop_profile_photo'
return
elsif !params[:submitted_crop_profile_photo].nil?
# crop the draft photo according to jquery parameters and set it as the users photo
@@ -499,7 +499,7 @@ class UserController < ApplicationController
redirect_to set_profile_about_me_url()
end
else
- render :template => 'user/set_draft_profile_photo.rhtml'
+ render :template => 'user/set_draft_profile_photo'
end
end
@@ -527,7 +527,7 @@ class UserController < ApplicationController
def get_draft_profile_photo
profile_photo = ProfilePhoto.find(params[:id])
response.content_type = "image/png"
- render_for_text(profile_photo.data)
+ render :text => profile_photo.data
end
# actual profile photo of a user
@@ -542,7 +542,7 @@ class UserController < ApplicationController
end
response.content_type = "image/png"
- render_for_text(@display_user.profile_photo.data)
+ render :text => @display_user.profile_photo.data
end
# Change about me text on your profile page
@@ -631,7 +631,7 @@ class UserController < ApplicationController
post_redirect.save!
url = confirm_url(:email_token => post_redirect.email_token)
- UserMailer.deliver_confirm_login(user, post_redirect.reason_params, url)
+ UserMailer.confirm_login(user, post_redirect.reason_params, url).deliver
render :action => 'confirm'
end
@@ -642,7 +642,7 @@ class UserController < ApplicationController
post_redirect.save!
url = confirm_url(:email_token => post_redirect.email_token)
- UserMailer.deliver_already_registered(user, post_redirect.reason_params, url)
+ UserMailer.already_registered(user, post_redirect.reason_params, url).deliver
render :action => 'confirm' # must be same as for send_confirmation_mail above to avoid leak of presence of email in db
end
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index 42f9d30f1..e3b1e57ac 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -3,7 +3,7 @@
# in the application.
#
# Copyright (c) 2007 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
require 'languages'
diff --git a/app/helpers/config_helper.rb b/app/helpers/config_helper.rb
index 73e12172f..026600ff1 100644
--- a/app/helpers/config_helper.rb
+++ b/app/helpers/config_helper.rb
@@ -1,5 +1,5 @@
module ConfigHelper
def site_name
- Configuration::site_name
+ AlaveteliConfiguration::site_name
end
-end \ No newline at end of file
+end
diff --git a/app/helpers/link_to_helper.rb b/app/helpers/link_to_helper.rb
index 3f59c55ca..238a36ce4 100755
--- a/app/helpers/link_to_helper.rb
+++ b/app/helpers/link_to_helper.rb
@@ -3,7 +3,7 @@
# -
#
# Copyright (c) 2007 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
module LinkToHelper
@@ -218,6 +218,9 @@ module LinkToHelper
return url
end
+ def search_link(query, variety_postfix = nil, sort_postfix = nil, advanced = nil)
+ link_to h(query), search_url(query)
+ end
def search_path(query, options = {})
search_url(query, options.merge(:only_path => true))
@@ -238,7 +241,7 @@ module LinkToHelper
# TODO: Remove in next release
def main_url(relative_path, append = nil)
warn "[DEPRECATION] main_url is deprecated. Please remove it from your theme."
- url_prefix = "http://" + Configuration::domain
+ url_prefix = "http://" + AlaveteliConfiguration::domain
url = url_prefix + relative_path
if !append.nil?
begin
@@ -282,5 +285,13 @@ module LinkToHelper
def year_from_date(date)
return date.strftime("%Y").strip
end
+
+ #I18n locale switcher
+
+ def locale_switcher(locale, params)
+ params['locale'] = locale
+ return url_for(params)
+ end
+
end
diff --git a/app/helpers/mailer_helper.rb b/app/helpers/mailer_helper.rb
index be2ce47aa..3d4bbac71 100644
--- a/app/helpers/mailer_helper.rb
+++ b/app/helpers/mailer_helper.rb
@@ -1,5 +1,5 @@
module MailerHelper
def contact_from_name_and_email
- "#{Configuration::contact_name} <#{Configuration::contact_email}>"
+ "#{AlaveteliConfiguration::contact_name} <#{AlaveteliConfiguration::contact_email}>"
end
end
diff --git a/app/mailers/application_mailer.rb b/app/mailers/application_mailer.rb
new file mode 100644
index 000000000..d2230bb82
--- /dev/null
+++ b/app/mailers/application_mailer.rb
@@ -0,0 +1,30 @@
+# models/application_mailer.rb:
+# Shared code between different mailers.
+#
+# Copyright (c) 2008 UK Citizens Online Democracy. All rights reserved.
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
+
+require 'action_mailer/version'
+class ApplicationMailer < ActionMailer::Base
+ # Include all the functions views get, as emails call similar things.
+ helper :application
+ include MailerHelper
+
+ # This really should be the default - otherwise you lose any information
+ # about the errors, and have to do error checking on return codes.
+ self.raise_delivery_errors = true
+
+ def blackhole_email
+ AlaveteliConfiguration::blackhole_prefix+"@"+AlaveteliConfiguration::incoming_email_domain
+ 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.
+ include LinkToHelper
+
+ # Site-wide access to configuration settings
+ include ConfigHelper
+
+end
+
diff --git a/app/mailers/contact_mailer.rb b/app/mailers/contact_mailer.rb
new file mode 100644
index 000000000..4dc49bf8b
--- /dev/null
+++ b/app/mailers/contact_mailer.rb
@@ -0,0 +1,45 @@
+# models/contact_mailer.rb:
+# Sends contact form mails.
+#
+# Copyright (c) 2008 UK Citizens Online Democracy. All rights reserved.
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
+
+class ContactMailer < ApplicationMailer
+ # Send message to administrator
+ def to_admin_message(name, email, subject, message, logged_in_user, last_request, last_body)
+ @message, @logged_in_user, @last_request, @last_body = message, logged_in_user, last_request, last_body
+
+ mail(:from => "#{name} <#{email}>",
+ :to => contact_from_name_and_email,
+ :subject => subject)
+ end
+
+ # We always set Reply-To when we set Return-Path to be different from From,
+ # since some email clients seem to erroneously use the envelope from when
+ # they shouldn't, and this might help. (Have had mysterious cases of a
+ # reply coming in duplicate from a public body to both From and envelope
+ # from)
+
+ # Send message to another user
+ def user_message(from_user, recipient_user, from_user_url, subject, message)
+ @message, @from_user, @recipient_user, @from_user_url = message, from_user, recipient_user, from_user_url
+
+ # Do not set envelope from address to the from_user, so they can't get
+ # someone's email addresses from transitory bounce messages.
+ headers('Return-Path' => blackhole_email, 'Reply-To' => from_user.name_and_email)
+
+ mail(:from => from_user.name_and_email,
+ :to => recipient_user.name_and_email,
+ :subject => subject)
+ end
+
+ # Send message to a user from the administrator
+ def from_admin_message(recipient_user, subject, message)
+ @message, @from_user, @recipient_user = message, contact_from_name_and_email, recipient_user
+
+ mail(:from => contact_from_name_and_email,
+ :to => recipient_user.name_and_email,
+ :bcc => AlaveteliConfiguration::contact_email,
+ :subject => subject)
+ end
+end
diff --git a/app/models/outgoing_mailer.rb b/app/mailers/outgoing_mailer.rb
index 503166b8a..083c05a7c 100644
--- a/app/models/outgoing_mailer.rb
+++ b/app/mailers/outgoing_mailer.rb
@@ -2,7 +2,7 @@
# Emails which go to public bodies on behalf of users.
#
# Copyright (c) 2009 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
# Note: The layout for this wraps messages by lines rather than (blank line
# separated) paragraphs, as is the convention for all the other mailers. This
@@ -13,31 +13,29 @@
# throughout the application.
class OutgoingMailer < ApplicationMailer
-
# Email to public body requesting info
def initial_request(info_request, outgoing_message)
+ @info_request, @outgoing_message, @contact_email = info_request, outgoing_message, AlaveteliConfiguration::contact_email
@wrap_lines_as_paragraphs = true
- @from = info_request.incoming_name_and_email
- @recipients = info_request.recipient_name_and_email
- @subject = info_request.email_subject_request
- @headers["message-id"] = OutgoingMailer.id_for_message(outgoing_message)
- @body = {:info_request => info_request, :outgoing_message => outgoing_message,
- :contact_email => Configuration::contact_email }
+ headers["message-id"] = OutgoingMailer.id_for_message(outgoing_message)
+
+ mail(:from => info_request.incoming_name_and_email,
+ :to => info_request.recipient_name_and_email,
+ :subject => info_request.email_subject_request)
end
# Later message to public body regarding existing request
def followup(info_request, outgoing_message, incoming_message_followup)
+ @info_request, @outgoing_message, @incoming_message_followup, @contact_email = info_request, outgoing_message, incoming_message_followup, AlaveteliConfiguration::contact_email
@wrap_lines_as_paragraphs = true
- @from = info_request.incoming_name_and_email
- @recipients = OutgoingMailer.name_and_email_for_followup(info_request, incoming_message_followup)
- @subject = OutgoingMailer.subject_for_followup(info_request, outgoing_message)
- @headers["message-id"] = OutgoingMailer.id_for_message(outgoing_message)
- @body = {:info_request => info_request, :outgoing_message => outgoing_message,
- :incoming_message_followup => incoming_message_followup,
- :contact_email => Configuration::contact_email }
+ headers["message-id"] = OutgoingMailer.id_for_message(outgoing_message)
+
+ mail(:from => info_request.incoming_name_and_email,
+ :to => OutgoingMailer.name_and_email_for_followup(info_request, incoming_message_followup),
+ :subject => OutgoingMailer.subject_for_followup(info_request, outgoing_message))
end
- # XXX the condition checking valid_to_reply_to? also appears in views/request/_followup.rhtml,
+ # XXX the condition checking valid_to_reply_to? also appears in views/request/_followup.html.erb,
# it shouldn't really, should call something here.
# XXX also OutgoingMessage.get_salutation
# XXX these look like they should be members of IncomingMessage, but logically they
@@ -90,7 +88,7 @@ class OutgoingMailer < ApplicationMailer
message_id = "ogm-" + outgoing_message.id.to_s
t = Time.now
message_id += "+" + '%08x%05x-%04x' % [t.to_i, t.tv_usec, rand(0xffff)]
- message_id += "@" + Configuration::incoming_email_domain
+ message_id += "@" + AlaveteliConfiguration::incoming_email_domain
return "<" + message_id + ">"
end
diff --git a/app/models/request_mailer.rb b/app/mailers/request_mailer.rb
index 955f73ef4..4dbce6738 100644
--- a/app/models/request_mailer.rb
+++ b/app/mailers/request_mailer.rb
@@ -2,89 +2,87 @@
# Alerts relating to requests.
#
# Copyright (c) 2007 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
-require 'alaveteli_file_types'
-if Rails.env == 'test' && RUBY_VERSION.to_f >= 1.9
- # Avoid spec/script/mailin_spec.rb running script/runner as a test suite
- # http://stackoverflow.com/questions/1899009/why-are-tests-running-in-production-mode-and-causing-my-script-runners-to-fail
- Test::Unit.run = true
-end
class RequestMailer < ApplicationMailer
-
-
# Used when an FOI officer uploads a response from their web browser - this is
# the "fake" email used to store in the same format in the database as if they
# had emailed it.
- def fake_response(info_request, from_user, body, attachment_name, attachment_content)
- @from = from_user.name_and_email
- @recipients = info_request.incoming_name_and_email
- @body = {
- :body => body
- }
+ def fake_response(info_request, from_user, message_body, attachment_name, attachment_content)
+ @message_body = message_body
+
if !attachment_name.nil? && !attachment_content.nil?
content_type = AlaveteliFileTypes.filename_to_mimetype(attachment_name) || 'application/octet-stream'
- attachment :content_type => content_type,
- :body => attachment_content,
- :filename => attachment_name
+ attachments[attachment_name] = {:content => attachment_content,
+ :content_type => content_type}
end
+
+ mail(:from => from_user.name_and_email,
+ :to => info_request.incoming_name_and_email)
end
# Used when a response is uploaded using the API
- def external_response(info_request, body, sent_at, attachments)
- @from = blackhole_email
- @recipients = info_request.incoming_name_and_email
- @body = { :body => body }
-
- # ActionMailer only works properly when the time is in the local timezone:
- # see https://rails.lighthouseapp.com/projects/8994/tickets/3113-actionmailer-only-works-correctly-with-sent_on-times-that-are-in-the-local-time-zone
- @sent_on = sent_at.dup.localtime
+ def external_response(info_request, message_body, sent_at, attachment_hashes)
+ @message_body = message_body
- attachments.each do |attachment_hash|
- attachment attachment_hash
+ attachment_hashes.each do |attachment_hash|
+ attachments[attachment_hash[:filename]] = {:content => attachment_hash[:body],
+ :content_type => attachment_hash[:content_type]}
end
+
+ mail(:from => blackhole_email,
+ :to => info_request.incoming_name_and_email,
+ :date => sent_at)
end
# Incoming message arrived for a request, but new responses have been stopped.
def stopped_responses(info_request, email, raw_email_data)
- @from = contact_from_name_and_email
- headers 'Return-Path' => blackhole_email, 'Reply-To' => @from, # we don't care about bounces, likely from spammers
- 'Auto-Submitted' => 'auto-replied' # http://tools.ietf.org/html/rfc3834
- @recipients = email.from_addrs[0].to_s
- @subject = _("Your response to an FOI request was not delivered")
- attachment :content_type => 'message/rfc822', :body => raw_email_data,
- :filename => "original.eml", :transfer_encoding => '7bit', :content_disposition => 'inline'
- @body = {
- :info_request => info_request,
- :contact_email => Configuration::contact_email
- }
+ headers('Return-Path' => blackhole_email, # we don't care about bounces, likely from spammers
+ 'Auto-Submitted' => 'auto-replied') # http://tools.ietf.org/html/rfc3834
+
+ attachments.inline["original.eml"] = raw_email_data
+
+ @info_request = info_request
+ @contact_email = AlaveteliConfiguration::contact_email
+
+ mail(:to => email.from_addrs[0].to_s,
+ :from => contact_from_name_and_email,
+ :reply_to => contact_from_name_and_email,
+ :subject => _("Your response to an FOI request was not delivered"))
end
# An FOI response is outside the scope of the system, and needs admin attention
def requires_admin(info_request, set_by = nil, message = "")
user = set_by || info_request.user
- @from = user.name_and_email
- @recipients = contact_from_name_and_email
- @subject = _("FOI response requires admin ({{reason}}) - {{title}}", :reason => info_request.described_state, :title => info_request.title)
- url = request_url(info_request)
- admin_url = admin_request_show_url(info_request)
- @body = {:reported_by => user, :message => message, :info_request => info_request, :url => url, :admin_url => admin_url }
+ @reported_by = user
+ @url = request_url(info_request)
+ @admin_url = admin_request_show_url(info_request)
+ @info_request = info_request
+ @message = message
+
+ mail(:from => user.name_and_email,
+ :to => contact_from_name_and_email,
+ :subject => _("FOI response requires admin ({{reason}}) - {{title}}", :reason => info_request.described_state, :title => info_request.title))
end
# Tell the requester that a new response has arrived
def new_response(info_request, incoming_message)
# Don't use login link here, just send actual URL. This is
# because people tend to forward these emails amongst themselves.
- url = incoming_message_url(incoming_message)
+ @url = incoming_message_url(incoming_message)
+ @incoming_message, @info_request = incoming_message, info_request
- @from = contact_from_name_and_email
- headers 'Return-Path' => blackhole_email, 'Reply-To' => @from, # not much we can do if the user's email is broken
+ headers('Return-Path' => blackhole_email,
'Auto-Submitted' => 'auto-generated', # http://tools.ietf.org/html/rfc3834
- 'X-Auto-Response-Suppress' => 'OOF'
- @recipients = info_request.user.name_and_email
- @subject = (_("New response to your FOI request - ") + info_request.title).html_safe
- @body = { :incoming_message => incoming_message, :info_request => info_request, :url => url }
+ 'X-Auto-Response-Suppress' => 'OOF')
+
+ mail(:from => contact_from_name_and_email,
+ :to => info_request.user.name_and_email,
+ :subject => _("New response to your FOI request - ") + info_request.title,
+ :charset => "UTF-8",
+ # not much we can do if the user's email is broken
+ :reply_to => contact_from_name_and_email)
end
# Tell the requester that the public body is late in replying
@@ -92,18 +90,21 @@ class RequestMailer < ApplicationMailer
respond_url = respond_to_last_url(info_request) + "#followup"
post_redirect = PostRedirect.new(
- :uri => respond_url,
+ :uri => respond_to_last_url(info_request) + "#followup",
:user_id => user.id)
post_redirect.save!
url = confirm_url(:email_token => post_redirect.email_token)
- @from = contact_from_name_and_email
- headers 'Return-Path' => blackhole_email, 'Reply-To' => @from, # not much we can do if the user's email is broken
+ @url = confirm_url(:email_token => post_redirect.email_token)
+ @info_request = info_request
+
+ headers('Return-Path' => blackhole_email, 'Reply-To' => contact_from_name_and_email, # not much we can do if the user's email is broken
'Auto-Submitted' => 'auto-generated', # http://tools.ietf.org/html/rfc3834
- 'X-Auto-Response-Suppress' => 'OOF'
- @recipients = user.name_and_email
- @subject = (_("Delayed response to your FOI request - ") + info_request.title).html_safe
- @body = { :info_request => info_request, :url => url }
+ 'X-Auto-Response-Suppress' => 'OOF')
+
+ mail(:from => contact_from_name_and_email,
+ :to => user.name_and_email,
+ :subject => (_("Delayed response to your FOI request - ") + info_request.title).html_safe)
end
# Tell the requester that the public body is very late in replying
@@ -111,18 +112,19 @@ class RequestMailer < ApplicationMailer
respond_url = respond_to_last_url(info_request) + "#followup"
post_redirect = PostRedirect.new(
- :uri => respond_url,
+ :uri => respond_to_last_url(info_request) + "#followup",
:user_id => user.id)
post_redirect.save!
- url = confirm_url(:email_token => post_redirect.email_token)
+ @url = confirm_url(:email_token => post_redirect.email_token)
+ @info_request = info_request
- @from = contact_from_name_and_email
- headers 'Return-Path' => blackhole_email, 'Reply-To' => @from, # not much we can do if the user's email is broken
+ headers('Return-Path' => blackhole_email, 'Reply-To' => contact_from_name_and_email, # not much we can do if the user's email is broken
'Auto-Submitted' => 'auto-generated', # http://tools.ietf.org/html/rfc3834
- 'X-Auto-Response-Suppress' => 'OOF'
- @recipients = user.name_and_email
- @subject = (_("You're long overdue a response to your FOI request - ") + info_request.title).html_safe
- @body = { :info_request => info_request, :url => url }
+ 'X-Auto-Response-Suppress' => 'OOF')
+
+ mail(:from => contact_from_name_and_email,
+ :to => user.name_and_email,
+ :subject => (_("You're long overdue a response to your FOI request - ") + info_request.title).html_safe)
end
# Tell the requester that they need to say if the new response
@@ -134,27 +136,31 @@ class RequestMailer < ApplicationMailer
:uri => request_url(info_request) + "#describe_state_form_1",
:user_id => info_request.user.id)
post_redirect.save!
- url = confirm_url(:email_token => post_redirect.email_token)
+ @url = confirm_url(:email_token => post_redirect.email_token)
+ @incoming_message = incoming_message
+ @info_request = info_request
- @from = contact_from_name_and_email
- headers 'Return-Path' => blackhole_email, 'Reply-To' => @from, # not much we can do if the user's email is broken
+ headers('Return-Path' => blackhole_email, 'Reply-To' => contact_from_name_and_email, # not much we can do if the user's email is broken
'Auto-Submitted' => 'auto-generated', # http://tools.ietf.org/html/rfc3834
- 'X-Auto-Response-Suppress' => 'OOF'
- @recipients = info_request.user.name_and_email
- @subject = _("Was the response you got to your FOI request any good?")
- @body = { :incoming_message => incoming_message, :info_request => info_request, :url => url }
+ 'X-Auto-Response-Suppress' => 'OOF')
+
+ mail(:from => contact_from_name_and_email,
+ :to => info_request.user.name_and_email,
+ :subject => _("Was the response you got to your FOI request any good?"))
end
# Tell the requester that someone updated their old unclassified request
def old_unclassified_updated(info_request)
- @from = contact_from_name_and_email
- headers 'Return-Path' => blackhole_email, 'Reply-To' => @from, # not much we can do if the user's email is broken
+ @url = request_url(info_request)
+ @info_request = info_request
+
+ headers('Return-Path' => blackhole_email, 'Reply-To' => contact_from_name_and_email, # not much we can do if the user's email is broken
'Auto-Submitted' => 'auto-generated', # http://tools.ietf.org/html/rfc3834
- 'X-Auto-Response-Suppress' => 'OOF'
- @recipients = info_request.user.name_and_email
- @subject = _("Someone has updated the status of your request")
- url = request_url(info_request)
- @body = {:info_request => info_request, :url => url}
+ 'X-Auto-Response-Suppress' => 'OOF')
+
+ mail(:from => contact_from_name_and_email,
+ :to => info_request.user.name_and_email,
+ :subject => _("Someone has updated the status of your request"))
end
# Tell the requester that they need to clarify their request
@@ -166,35 +172,43 @@ class RequestMailer < ApplicationMailer
:uri => respond_url,
:user_id => info_request.user.id)
post_redirect.save!
- url = confirm_url(:email_token => post_redirect.email_token)
+ @url = confirm_url(:email_token => post_redirect.email_token)
+ @incoming_message = incoming_message
+ @info_request = info_request
- @from = contact_from_name_and_email
- headers 'Return-Path' => blackhole_email, 'Reply-To' => @from, # not much we can do if the user's email is broken
+ headers('Return-Path' => blackhole_email, 'Reply-To' => contact_from_name_and_email, # not much we can do if the user's email is broken
'Auto-Submitted' => 'auto-generated', # http://tools.ietf.org/html/rfc3834
- 'X-Auto-Response-Suppress' => 'OOF'
- @recipients = info_request.user.name_and_email
- @subject = (_("Clarify your FOI request - ") + info_request.title).html_safe
- @body = { :incoming_message => incoming_message, :info_request => info_request, :url => url }
+ 'X-Auto-Response-Suppress' => 'OOF')
+
+ mail(:from => contact_from_name_and_email,
+ :to => info_request.user.name_and_email,
+ :subject => _("Clarify your FOI request - ") + info_request.title)
end
# Tell requester that somebody add an annotation to their request
def comment_on_alert(info_request, comment)
- @from = contact_from_name_and_email
- headers 'Return-Path' => blackhole_email, 'Reply-To' => @from, # not much we can do if the user's email is broken
+ @comment, @info_request = comment, info_request
+ @url = comment_url(comment)
+
+ headers('Return-Path' => blackhole_email, 'Reply-To' => contact_from_name_and_email, # not much we can do if the user's email is broken
'Auto-Submitted' => 'auto-generated', # http://tools.ietf.org/html/rfc3834
- 'X-Auto-Response-Suppress' => 'OOF'
- @recipients = info_request.user.name_and_email
- @subject = (_("Somebody added a note to your FOI request - ") + info_request.title).html_safe
- @body = { :comment => comment, :info_request => info_request, :url => comment_url(comment) }
+ 'X-Auto-Response-Suppress' => 'OOF')
+
+ mail(:from => contact_from_name_and_email,
+ :to => info_request.user.name_and_email,
+ :subject => (_("Somebody added a note to your FOI request - ") + info_request.title).html_safe)
end
def comment_on_alert_plural(info_request, count, earliest_unalerted_comment)
- @from = contact_from_name_and_email
- headers 'Return-Path' => blackhole_email, 'Reply-To' => @from, # not much we can do if the user's email is broken
+ @count, @info_request = count, info_request
+ @url = comment_url(earliest_unalerted_comment)
+
+ headers('Return-Path' => blackhole_email, 'Reply-To' => contact_from_name_and_email, # not much we can do if the user's email is broken
'Auto-Submitted' => 'auto-generated', # http://tools.ietf.org/html/rfc3834
- 'X-Auto-Response-Suppress' => 'OOF'
- @recipients = info_request.user.name_and_email
- @subject = (_("Some notes have been added to your FOI request - ") + info_request.title).html_safe
- @body = { :count => count, :info_request => info_request, :url => comment_url(earliest_unalerted_comment) }
+ 'X-Auto-Response-Suppress' => 'OOF')
+
+ mail(:from => contact_from_name_and_email,
+ :to => info_request.user.name_and_email,
+ :subject => (_("Some notes have been added to your FOI request - ") + info_request.title).html_safe)
end
# Class function, called by script/mailin with all incoming responses.
@@ -307,9 +321,9 @@ class RequestMailer < ApplicationMailer
# (otherwise they are banned, and there is no point sending it)
if info_request.user.can_make_followup?
if calculated_status == 'waiting_response_overdue'
- RequestMailer.deliver_overdue_alert(info_request, info_request.user)
+ RequestMailer.overdue_alert(info_request, info_request.user).deliver
elsif calculated_status == 'waiting_response_very_overdue'
- RequestMailer.deliver_very_overdue_alert(info_request, info_request.user)
+ RequestMailer.very_overdue_alert(info_request, info_request.user).deliver
else
raise "unknown request status"
end
@@ -323,7 +337,7 @@ class RequestMailer < ApplicationMailer
# Send email alerts for new responses which haven't been classified. By default,
# it goes out 3 days after last update of event, then after 10, then after 24.
def self.alert_new_response_reminders
- Configuration::new_response_reminder_after_days.each_with_index do |days, i|
+ AlaveteliConfiguration::new_response_reminder_after_days.each_with_index do |days, i|
self.alert_new_response_reminders_internal(days, "new_response_reminder_#{i+1}")
end
end
@@ -348,7 +362,7 @@ class RequestMailer < ApplicationMailer
store_sent.alert_type = type_code
store_sent.info_request_event_id = alert_event_id
# XXX uses same template for reminder 1 and reminder 2 right now.
- RequestMailer.deliver_new_response_reminder_alert(info_request, last_response_message)
+ RequestMailer.new_response_reminder_alert(info_request, last_response_message).deliver
store_sent.save!
end
end
@@ -376,7 +390,7 @@ class RequestMailer < ApplicationMailer
# Only send the alert if the user can act on it by making a followup
# (otherwise they are banned, and there is no point sending it)
if info_request.user.can_make_followup?
- RequestMailer.deliver_not_clarified_alert(info_request, last_response_message)
+ RequestMailer.not_clarified_alert(info_request, last_response_message).deliver
end
store_sent.save!
end
@@ -440,9 +454,9 @@ class RequestMailer < ApplicationMailer
store_sent.alert_type = 'comment_1'
store_sent.info_request_event_id = last_comment_event.id
if count > 1
- RequestMailer.deliver_comment_on_alert_plural(info_request, count, earliest_unalerted_comment_event.comment)
+ RequestMailer.comment_on_alert_plural(info_request, count, earliest_unalerted_comment_event.comment).deliver
elsif count == 1
- RequestMailer.deliver_comment_on_alert(info_request, last_comment_event.comment)
+ RequestMailer.comment_on_alert(info_request, last_comment_event.comment).deliver
else
raise "internal error"
end
diff --git a/app/models/track_mailer.rb b/app/mailers/track_mailer.rb
index 7262c82f3..391143214 100644
--- a/app/models/track_mailer.rb
+++ b/app/mailers/track_mailer.rb
@@ -2,30 +2,31 @@
# Emails which go to users who are tracking things.
#
# Copyright (c) 2008 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
class TrackMailer < ApplicationMailer
def event_digest(user, email_about_things)
+ @user, @email_about_things = user, email_about_things
+
post_redirect = PostRedirect.new(
:uri => user_url(user) + "#email_subscriptions",
:user_id => user.id)
post_redirect.save!
- unsubscribe_url = confirm_url(:email_token => post_redirect.email_token)
+ @unsubscribe_url = confirm_url(:email_token => post_redirect.email_token)
- @from = contact_from_name_and_email
- headers 'Auto-Submitted' => 'auto-generated', # http://tools.ietf.org/html/rfc3834
- 'Precedence' => 'bulk' # http://www.vbulletin.com/forum/project.php?issueid=27687 (Exchange hack)
+ headers('Auto-Submitted' => 'auto-generated', # http://tools.ietf.org/html/rfc3834
+ 'Precedence' => 'bulk')# http://www.vbulletin.com/forum/project.php?issueid=27687 (Exchange hack)
# 'Return-Path' => blackhole_email, 'Reply-To' => @from # we don't care about bounces for tracks
# (We let it return bounces for now, so we can manually kill the tracks that bounce so Yahoo
# etc. don't decide we are spammers.)
- @recipients = user.name_and_email
- @subject = _("Your {{site_name}} email alert", :site_name => site_name)
- @body = { :user => user, :email_about_things => email_about_things, :unsubscribe_url => unsubscribe_url }
+ mail(:from => contact_from_name_and_email,
+ :to => user.name_and_email,
+ :subject => _("Your {{site_name}} email alert", :site_name => site_name))
end
def contact_from_name_and_email
- "#{Configuration::track_sender_name} <#{Configuration::track_sender_email}>"
+ "#{AlaveteliConfiguration::track_sender_name} <#{AlaveteliConfiguration::track_sender_email}>"
end
# Send email alerts for tracked things. Never more than one email
@@ -92,7 +93,7 @@ class TrackMailer < ApplicationMailer
# Send the email
I18n.with_locale(user.get_locale) do
- TrackMailer.deliver_event_digest(user, email_about_things)
+ TrackMailer.event_digest(user, email_about_things).deliver
end
end
diff --git a/app/mailers/user_mailer.rb b/app/mailers/user_mailer.rb
new file mode 100644
index 000000000..a351147f9
--- /dev/null
+++ b/app/mailers/user_mailer.rb
@@ -0,0 +1,44 @@
+# models/user_mailer.rb:
+# Emails relating to user accounts. e.g. Confirming a new account
+#
+# Copyright (c) 2007 UK Citizens Online Democracy. All rights reserved.
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
+
+class UserMailer < ApplicationMailer
+ def confirm_login(user, reasons, url)
+ @reasons, @name, @url = reasons, user.name, url
+ headers('Return-Path' => blackhole_email, 'Reply-To' => contact_from_name_and_email) # we don't care about bounces when people are fiddling with their account
+
+ mail(:from => contact_from_name_and_email,
+ :to => user.name_and_email,
+ :subject => reasons[:email_subject])
+ end
+
+ def already_registered(user, reasons, url)
+ @reasons, @name, @url = reasons, user.name, url
+ headers('Return-Path' => blackhole_email, 'Reply-To' => contact_from_name_and_email) # we don't care about bounces when people are fiddling with their account
+
+ mail(:from => contact_from_name_and_email,
+ :to => user.name_and_email,
+ :subject => reasons[:email_subject])
+ end
+
+ def changeemail_confirm(user, new_email, url)
+ @name, @url, @old_email, @new_email = user.name, url, user.email, new_email
+ headers('Return-Path' => blackhole_email, 'Reply-To' => contact_from_name_and_email) # we don't care about bounces when people are fiddling with their account
+
+ mail(:from => contact_from_name_and_email,
+ :to => new_email,
+ :subject => _("Confirm your new email address on {{site_name}}", :site_name => site_name))
+ end
+
+ def changeemail_already_used(old_email, new_email)
+ @old_email, @new_email = old_email, new_email
+ headers('Return-Path' => blackhole_email, 'Reply-To' => contact_from_name_and_email) # we don't care about bounces when people are fiddling with their account
+
+ mail(:from => contact_from_name_and_email,
+ :to => new_email,
+ :subject => _("Unable to change email address on {{site_name}}", :site_name=>site_name))
+ end
+end
+
diff --git a/app/models/about_me_validator.rb b/app/models/about_me_validator.rb
index 8ee505ac8..7df70fb61 100644
--- a/app/models/about_me_validator.rb
+++ b/app/models/about_me_validator.rb
@@ -1,25 +1,23 @@
-# == Schema Information
-# Schema version: 114
-#
-# Table name: about_me_validators
-#
-# about_me :text default("I..."), not null
-#
-
# models/about_me_validator.rb:
# Validates editing about me text on user profile pages.
#
# Copyright (c) 2010 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
-class AboutMeValidator < ActiveRecord::BaseWithoutTable
- strip_attributes!
+class AboutMeValidator
+ include ActiveModel::Validations
- column :about_me, :text, "I...", false
+ attr_accessor :about_me
# TODO: Switch to built in validations
validate :length_of_about_me
+ def initialize(attributes = {})
+ attributes.each do |name, value|
+ send("#{name}=", value)
+ end
+ end
+
private
def length_of_about_me
diff --git a/app/models/application_mailer.rb b/app/models/application_mailer.rb
deleted file mode 100644
index 1a97a4bf9..000000000
--- a/app/models/application_mailer.rb
+++ /dev/null
@@ -1,164 +0,0 @@
-# models/application_mailer.rb:
-# Shared code between different mailers.
-#
-# Copyright (c) 2008 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
-
-require 'action_mailer/version'
-class ApplicationMailer < ActionMailer::Base
- # Include all the functions views get, as emails call similar things.
- helper :application
- include MailerHelper
-
- # This really should be the default - otherwise you lose any information
- # about the errors, and have to do error checking on return codes.
- self.raise_delivery_errors = true
-
- def blackhole_email
- Configuration::blackhole_prefix+"@"+Configuration::incoming_email_domain
- 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.
- include LinkToHelper
-
- # Site-wide access to configuration settings
- include ConfigHelper
-
- # Instantiate a new mailer object. If +method_name+ is not +nil+, the mailer
- # will be initialized according to the named method. If not, the mailer will
- # remain uninitialized (useful when you only need to invoke the "receive"
- # method, for instance).
- def initialize(method_name=nil, *parameters) #:nodoc:
- create!(method_name, *parameters) if method_name
- end
-
- # For each multipart template (e.g. "the_template_file.text.html.erb") available,
- # add the one from the view path with the highest priority as a part to the mail
- def render_multipart_templates
- added_content_types = {}
- self.view_paths.each do |view_path|
- Dir.glob("#{view_path}/#{mailer_name}/#{@template}.*").each do |path|
- template = view_path["#{mailer_name}/#{File.basename(path)}"]
-
- # Skip unless template has a multipart format
- next unless template && template.multipart?
- next if added_content_types[template.content_type] == true
- @parts << Part.new(
- :content_type => template.content_type,
- :disposition => "inline",
- :charset => charset,
- :body => render_message(template, @body)
- )
- added_content_types[template.content_type] = true
- end
- end
- end
-
- # Look for the current template in each element of view_paths in order,
- # return the first
- def find_template
- self.view_paths.each do |view_path|
- if template = view_path["#{mailer_name}/#{@template}"]
- return template
- end
- end
- return nil
- end
-
- if ActionMailer::VERSION::MAJOR == 2
-
- # This method is a customised version of ActionMailer::Base.create!
- # modified to allow templates to be selected correctly for multipart
- # mails when themes have added to the view_paths. The problem from our
- # point of view with ActionMailer::Base is that it sets template_root to
- # the first element of the view_paths array and then uses only that (directly
- # and via template_path, which is created from it) in the create! method when
- # looking for templates. Our modified version looks for templates in the view_paths
- # in order.
-
- # It also has a line converting the mail subject to a string. This is because we
- # use translated strings in the subject lines, sometimes in conjunction with
- # user input, like request titles. The _() function used for translation
- # returns an instance of SafeBuffer, which doesn't handle gsub calls in the block form
- # with $ variables - https://github.com/rails/rails/issues/1555.
- # Unfortunately ActionMailer uses that form in quoted_printable(), which will be
- # called if any part of the subject requires quoting. So we convert the subject
- # back to a string via to_str() before passing in to create_mail. There is a test
- # for this in spec/models/request_mailer_spec.rb
-
- # Changed lines marked with ***
-
- # Initialize the mailer via the given +method_name+. The body will be
- # rendered and a new TMail::Mail object created.
- def create!(method_name, *parameters) #:nodoc:
- initialize_defaults(method_name)
- __send__(method_name, *parameters)
-
- # If an explicit, textual body has not been set, we check assumptions.
- unless String === @body
- # First, we look to see if there are any likely templates that match,
- # which include the content-type in their file name (i.e.,
- # "the_template_file.text.html.erb", etc.). Only do this if parts
- # have not already been specified manually.
- if @parts.empty?
- # *** render_multipart_templates replaces the following code
- # Dir.glob("#{template_path}/#{@template}.*").each do |path|
- # template = template_root["#{mailer_name}/#{File.basename(path)}"]
- #
- # # Skip unless template has a multipart format
- # next unless template && template.multipart?
- #
- # @parts << Part.new(
- # :content_type => template.content_type,
- # :disposition => "inline",
- # :charset => charset,
- # :body => render_message(template, @body)
- # )
- # end
- render_multipart_templates
-
- unless @parts.empty?
- @content_type = "multipart/alternative" if @content_type !~ /^multipart/
- @parts = sort_parts(@parts, @implicit_parts_order)
- end
- end
-
- # Then, if there were such templates, we check to see if we ought to
- # also render a "normal" template (without the content type). If a
- # normal template exists (or if there were no implicit parts) we render
- # it.
- template_exists = @parts.empty?
-
- # *** find_template replaces template_root call
- # template_exists ||= template_root["#{mailer_name}/#{@template}"]
- template_exists ||= find_template
-
- @body = render_message(@template, @body) if template_exists
-
- # Finally, if there are other message parts and a textual body exists,
- # we shift it onto the front of the parts and set the body to nil (so
- # that create_mail doesn't try to render it in addition to the parts).
- if !@parts.empty? && String === @body
- @parts.unshift ActionMailer::Part.new(:charset => charset, :body => @body)
- @body = nil
- end
- end
-
- # If this is a multipart e-mail add the mime_version if it is not
- # already set.
- @mime_version ||= "1.0" if !@parts.empty?
-
- # *** Convert into a string
- @subject = @subject.to_str if @subject
-
- # build the mail object itself
- @mail = create_mail
- end
- else
- raise "ApplicationMailer.create! is obsolete - find another way to ensure that themes can override mail templates for multipart mails"
- end
-
-end
-
diff --git a/app/models/censor_rule.rb b/app/models/censor_rule.rb
index f40ab6fbb..f0d06e088 100644
--- a/app/models/censor_rule.rb
+++ b/app/models/censor_rule.rb
@@ -20,7 +20,7 @@
# Stores alterations to remove specific data from requests.
#
# Copyright (c) 2008 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
class CensorRule < ActiveRecord::Base
belongs_to :info_request
@@ -33,13 +33,15 @@ class CensorRule < ActiveRecord::Base
validate :require_valid_regexp, :if => proc{ |rule| rule.regexp? == true }
validates_presence_of :text
- named_scope :global, {:conditions => {:info_request_id => nil,
- :user_id => nil,
- :public_body_id => nil}}
+ scope :global, {:conditions => {:info_request_id => nil,
+ :user_id => nil,
+ :public_body_id => nil}}
def require_user_request_or_public_body
if self.info_request.nil? && self.user.nil? && self.public_body.nil?
- errors.add("Censor must apply to an info request a user or a body; ")
+ [:info_request, :user, :public_body].each do |a|
+ errors.add(a, "Rule must apply to an info request, a user or a body")
+ end
end
end
diff --git a/app/models/change_email_validator.rb b/app/models/change_email_validator.rb
index 2ddebb177..5cc13d4c2 100644
--- a/app/models/change_email_validator.rb
+++ b/app/models/change_email_validator.rb
@@ -1,36 +1,27 @@
-# == Schema Information
-# Schema version: 114
-#
-# Table name: change_email_validators
-#
-# old_email :string
-# new_email :string
-# password :string
-# user_circumstance :string
-#
-
# models/changeemail_validator.rb:
# Validates email change form submissions.
#
# Copyright (c) 2010 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
-
-class ChangeEmailValidator < ActiveRecord::BaseWithoutTable
- strip_attributes!
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
- column :old_email, :string
- column :new_email, :string
- column :password, :string
- column :user_circumstance, :string
+class ChangeEmailValidator
+ include ActiveModel::Validations
- attr_accessor :logged_in_user
+ attr_accessor :old_email, :new_email, :password, :user_circumstance, :logged_in_user
validates_presence_of :old_email, :message => N_("Please enter your old email address")
validates_presence_of :new_email, :message => N_("Please enter your new email address")
validates_presence_of :password, :message => N_("Please enter your password"), :unless => :changing_email
validate :password_and_format_of_email
- def changing_email()
+ def initialize(attributes = {})
+ attributes.each do |name, value|
+ send("#{name}=", value)
+ end
+ end
+
+
+ def changing_email
self.user_circumstance == 'change_email'
end
@@ -41,11 +32,11 @@ class ChangeEmailValidator < ActiveRecord::BaseWithoutTable
errors.add(:old_email, _("Old email doesn't look like a valid address"))
end
- if !errors[:old_email]
+ if errors[:old_email].blank?
if self.old_email.downcase != self.logged_in_user.email.downcase
errors.add(:old_email, _("Old email address isn't the same as the address of the account you are logged in with"))
elsif (!self.changing_email) && (!self.logged_in_user.has_this_password?(self.password))
- if !errors[:password]
+ if errors[:password].blank?
errors.add(:password, _("Password is not correct"))
end
end
@@ -55,5 +46,4 @@ class ChangeEmailValidator < ActiveRecord::BaseWithoutTable
errors.add(:new_email, _("New email doesn't look like a valid address"))
end
end
-
end
diff --git a/app/models/comment.rb b/app/models/comment.rb
index 70f3ba00d..9527030a9 100644
--- a/app/models/comment.rb
+++ b/app/models/comment.rb
@@ -18,7 +18,7 @@
# A comment by a user upon something.
#
# Copyright (c) 2008 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
class Comment < ActiveRecord::Base
strip_attributes!
diff --git a/app/models/contact_mailer.rb b/app/models/contact_mailer.rb
deleted file mode 100644
index 318f54ea8..000000000
--- a/app/models/contact_mailer.rb
+++ /dev/null
@@ -1,56 +0,0 @@
-# models/contact_mailer.rb:
-# Sends contact form mails.
-#
-# Copyright (c) 2008 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
-
-class ContactMailer < ApplicationMailer
-
- # Send message to administrator
- def to_admin_message(name, email, subject, message, logged_in_user, last_request, last_body)
- @from = "#{name} <#{email}>"
- @recipients = contact_from_name_and_email
- @subject = subject
- @body = { :message => message,
- :logged_in_user => logged_in_user ,
- :last_request => last_request,
- :last_body => last_body
- }
- end
-
- # We always set Reply-To when we set Return-Path to be different from From,
- # since some email clients seem to erroneously use the envelope from when
- # they shouldn't, and this might help. (Have had mysterious cases of a
- # reply coming in duplicate from a public body to both From and envelope
- # from)
-
- # Send message to another user
- def user_message(from_user, recipient_user, from_user_url, subject, message)
- @from = from_user.name_and_email
- # Do not set envelope from address to the from_user, so they can't get
- # someone's email addresses from transitory bounce messages.
- headers 'Return-Path' => blackhole_email, 'Reply-To' => @from
- @recipients = recipient_user.name_and_email
- @subject = subject
- @body = {
- :message => message,
- :from_user => from_user,
- :recipient_user => recipient_user,
- :from_user_url => from_user_url
- }
- end
-
- # Send message to a user from the administrator
- def from_admin_message(recipient_user, subject, message)
- @from = contact_from_name_and_email
- @recipients = recipient_user.name_and_email
- @subject = subject
- @body = {
- :message => message,
- :from_user => @from,
- :recipient_user => recipient_user,
- }
- bcc Configuration::contact_email
- end
-
-end
diff --git a/app/models/contact_validator.rb b/app/models/contact_validator.rb
index d277161f9..65e539669 100644
--- a/app/models/contact_validator.rb
+++ b/app/models/contact_validator.rb
@@ -1,35 +1,29 @@
-# == Schema Information
-# Schema version: 114
-#
-# Table name: contact_validators
-#
-# name :string
-# email :string
-# subject :text
-# message :text
-#
-
# models/contact_validator.rb:
# Validates contact form submissions.
#
# Copyright (c) 2008 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
-class ContactValidator < ActiveRecord::BaseWithoutTable
- strip_attributes!
+class ContactValidator
+ include ActiveModel::Validations
- column :name, :string
- column :email, :string
- column :subject, :text
- column :message, :text
+ attr_accessor :name, :email, :subject, :message
validates_presence_of :name, :message => N_("Please enter your name")
validates_presence_of :email, :message => N_("Please enter your email address")
validates_presence_of :subject, :message => N_("Please enter a subject")
validates_presence_of :message, :message => N_("Please enter the message you want to send")
+ validate :email_format
- def validate
- errors.add(:email, _("Email doesn't look like a valid address")) unless MySociety::Validate.is_valid_email(self.email)
+ def initialize(attributes = {})
+ attributes.each do |name, value|
+ send("#{name}=", value)
+ end
end
+ private
+
+ def email_format
+ errors.add(:email, _("Email doesn't look like a valid address")) unless MySociety::Validate.is_valid_email(self.email)
+ end
end
diff --git a/app/models/foi_attachment.rb b/app/models/foi_attachment.rb
index bba0b6a8d..0340f2b83 100644
--- a/app/models/foi_attachment.rb
+++ b/app/models/foi_attachment.rb
@@ -20,7 +20,7 @@
# An attachment to an email (IncomingMessage)
#
# Copyright (c) 2007 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
# This is the type which is used to send data about attachments to the view
require 'digest'
@@ -38,11 +38,7 @@ class FoiAttachment < ActiveRecord::Base
BODY_MAX_DELAY = 5
def directory
- rails_env = Rails.env
- if rails_env.nil? || rails_env.empty?
- raise "$RAILS_ENV is not set"
- end
- base_dir = File.expand_path(File.join(File.dirname(__FILE__), "../../cache", "attachments_#{rails_env}"))
+ base_dir = File.expand_path(File.join(File.dirname(__FILE__), "../../cache", "attachments_#{Rails.env}"))
return File.join(base_dir, self.hexdigest[0..2])
end
@@ -67,28 +63,20 @@ class FoiAttachment < ActiveRecord::Base
file.write d
}
update_display_size!
- encode_cached_body!
@cached_body = d
end
- # If the original mail part had a charset, it's some kind of string, so assume that
- # it should be handled as a string in the stated charset, not a bytearray, and then
- # convert it our default encoding. For ruby 1.8 this is a noop.
- def encode_cached_body!
- if RUBY_VERSION.to_f >= 1.9
- if charset
- @cached_body.force_encoding(charset)
- @cached_body = @cached_body.encode(Encoding.default_internal, charset)
- end
- end
- end
-
def body
if @cached_body.nil?
tries = 0
delay = 1
begin
- @cached_body = File.open(self.filepath, "rb" ).read
+ binary_data = File.open(self.filepath, "rb" ).read
+ if self.content_type =~ /^text/
+ @cached_body = convert_string_to_utf8_or_binary(binary_data, 'UTF-8')
+ else
+ @cached_body = binary_data
+ end
rescue Errno::ENOENT
# we've lost our cached attachments for some reason. Reparse them.
if tries > BODY_MAX_TRIES
@@ -103,7 +91,6 @@ class FoiAttachment < ActiveRecord::Base
self.incoming_message.parse_raw_email!(force)
retry
end
- encode_cached_body!
end
return @cached_body
end
diff --git a/app/models/holiday.rb b/app/models/holiday.rb
index 13258396a..98f73e963 100644
--- a/app/models/holiday.rb
+++ b/app/models/holiday.rb
@@ -19,7 +19,7 @@
# -- Freedom of Information Act 2000 section 10
#
# Copyright (c) 2009 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
class Holiday < ActiveRecord::Base
diff --git a/app/models/incoming_message.rb b/app/models/incoming_message.rb
index 5c845ead3..f959a8799 100644
--- a/app/models/incoming_message.rb
+++ b/app/models/incoming_message.rb
@@ -25,19 +25,16 @@
# response from the public body.
#
# Copyright (c) 2007 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
# TODO
# Move some of the (e.g. quoting) functions here into rblib, as they feel
# general not specific to IncomingMessage.
-require 'alaveteli_file_types'
require 'htmlentities'
require 'rexml/document'
require 'zip/zip'
-require 'mapi/msg'
-require 'mapi/convert'
-
+require 'iconv' unless RUBY_VERSION >= '1.9'
class IncomingMessage < ActiveRecord::Base
belongs_to :info_request
@@ -132,6 +129,7 @@ class IncomingMessage < ActiveRecord::Base
end
self.valid_to_reply_to = self._calculate_valid_to_reply_to
self.last_parsed = Time.now
+ self.foi_attachments reload=true
self.save!
end
end
@@ -173,15 +171,29 @@ class IncomingMessage < ActiveRecord::Base
super
end
- # And look up by URL part number to get an attachment
+ # And look up by URL part number and display filename to get an attachment
# XXX relies on extract_attachments calling MailHandler.ensure_parts_counted
- def self.get_attachment_by_url_part_number(attachments, found_url_part_number)
- attachments.each do |a|
- if a.url_part_number == found_url_part_number
- return a
+ # The filename here is passed from the URL parameter, so it's the
+ # display_filename rather than the real filename.
+ def self.get_attachment_by_url_part_number_and_filename(attachments, found_url_part_number, display_filename)
+ attachment_by_part_number = attachments.detect { |a| a.url_part_number == found_url_part_number }
+ if attachment_by_part_number && attachment_by_part_number.display_filename == display_filename
+ # Then the filename matches, which is fine:
+ attachment_by_part_number
+ else
+ # Otherwise if the URL part number and filename don't
+ # match - this is probably due to a reparsing of the
+ # email. In that case, try to find a unique matching
+ # filename from any attachment.
+ attachments_by_filename = attachments.select { |a|
+ a.display_filename == display_filename
+ }
+ if attachments_by_filename.length == 1
+ attachments_by_filename[0]
+ else
+ nil
end
end
- return nil
end
# Converts email addresses we know about into textual descriptions of them
@@ -193,7 +205,7 @@ class IncomingMessage < ActiveRecord::Base
text.gsub!(self.info_request.public_body.request_email, _("[{{public_body}} request email]", :public_body => self.info_request.public_body.short_or_long_name))
end
text.gsub!(self.info_request.incoming_email, _('[FOI #{{request}} email]', :request => self.info_request.id.to_s) )
- text.gsub!(Configuration::contact_email, _("[{{site_name}} contact email]", :site_name => Configuration::site_name) )
+ text.gsub!(AlaveteliConfiguration::contact_email, _("[{{site_name}} contact email]", :site_name => AlaveteliConfiguration::site_name) )
end
# Replaces all email addresses in (possibly binary data) with equal length alternative ones.
@@ -219,7 +231,7 @@ class IncomingMessage < ActiveRecord::Base
if censored_uncompressed_text != uncompressed_text
# then use the altered file (recompressed)
recompressed_text = nil
- if Configuration::use_ghostscript_compression == true
+ if AlaveteliConfiguration::use_ghostscript_compression == true
command = ["gs", "-sDEVICE=pdfwrite", "-dCompatibilityLevel=1.4", "-dPDFSETTINGS=/screen", "-dNOPAUSE", "-dQUIET", "-dBATCH", "-sOutputFile=-", "-"]
else
command = ["pdftk", "-", "output", "-", "compress"]
@@ -258,11 +270,21 @@ class IncomingMessage < ActiveRecord::Base
# equivalents to the UCS-2
ascii_chars = text.gsub(/\0/, "")
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-2le', 'ascii', email[0]),
- Iconv.conv('ucs-2le', 'ascii', email[0].gsub(/[^@.]/, 'x'))
- ] }
+ if RUBY_VERSION >= '1.9'
+ emails.map! do |email|
+ # We want the ASCII representation of UCS-2
+ [email[0].encode('UTF-16LE').force_encoding('US-ASCII'),
+ email[0].gsub(/[^@.]/, 'x').encode('UTF-16LE').force_encoding('US-ASCII')]
+ end
+ else
+ emails.map! {|email| [
+ Iconv.conv('ucs-2le', 'ascii', email[0]),
+ Iconv.conv('ucs-2le', 'ascii', email[0].gsub(/[^@.]/, 'x'))
+ ] }
+ end
+
# Now search and replace the UCS-2 email with the UCS-2 mask
for email, mask in emails
text.gsub!(email, mask)
@@ -316,7 +338,7 @@ class IncomingMessage < ActiveRecord::Base
text.gsub!(/(Mobile|Mob)([\s\/]*(Fax|Tel))*\s*:?[\s\d]*\d/, "[mobile number]")
# Remove WhatDoTheyKnow signup links
- text.gsub!(/http:\/\/#{Configuration::domain}\/c\/[^\s]+/, "[WDTK login link]")
+ text.gsub!(/http:\/\/#{AlaveteliConfiguration::domain}\/c\/[^\s]+/, "[WDTK login link]")
# Remove things from censor rules
self.info_request.apply_censor_rules_to_text!(text)
@@ -534,7 +556,7 @@ class IncomingMessage < ActiveRecord::Base
source_charset = 'utf-8' if source_charset.nil?
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 => Configuration::site_name)
+ :site_name => AlaveteliConfiguration::site_name)
rescue Iconv::InvalidEncoding, Iconv::IllegalSequence, Iconv::InvalidCharacter
if source_charset != "utf-8"
source_charset = "utf-8"
@@ -546,9 +568,11 @@ class IncomingMessage < ActiveRecord::Base
text
end
- # Returns part which contains main body text, or nil if there isn't one
- def get_main_body_text_part
- leaves = self.foi_attachments
+ # Returns part which contains main body text, or nil if there isn't one,
+ # from a set of foi_attachments. If the leaves parameter is empty or not
+ # supplied, uses its own foi_attachments.
+ def get_main_body_text_part(leaves=[])
+ leaves = self.foi_attachments if leaves.empty?
# Find first part which is text/plain or text/html
# (We have to include HTML, as increasingly there are mail clients that
@@ -582,6 +606,7 @@ class IncomingMessage < ActiveRecord::Base
# nil in this case)
return p
end
+
# Returns attachments that are uuencoded in main body part
def _uudecode_and_save_attachments(text)
# Find any uudecoded things buried in it, yeuchly
@@ -605,7 +630,7 @@ class IncomingMessage < ActiveRecord::Base
content_type = 'application/octet-stream'
end
hexdigest = Digest::MD5.hexdigest(content)
- attachment = self.foi_attachments.find_or_create_by_hexdigest(:hexdigest => hexdigest)
+ attachment = self.foi_attachments.find_or_create_by_hexdigest(hexdigest)
attachment.update_attributes(:filename => filename,
:content_type => content_type,
:body => content,
@@ -632,15 +657,19 @@ class IncomingMessage < ActiveRecord::Base
attachment_attributes = MailHandler.get_attachment_attributes(self.mail(force))
attachments = []
attachment_attributes.each do |attrs|
- attachment = self.foi_attachments.find_or_create_by_hexdigest(:hexdigest => attrs[:hexdigest])
- body = attrs.delete(:body)
+ attachment = self.foi_attachments.find_or_create_by_hexdigest(attrs[:hexdigest])
attachment.update_attributes(attrs)
- # Set the body separately as its handling can depend on the value of charset
- attachment.body = body
attachment.save!
- attachments << attachment.id
+ attachments << attachment
end
- main_part = get_main_body_text_part
+
+ # Reload to refresh newly created foi_attachments
+ self.reload
+
+ # get the main body part from the set of attachments we just created,
+ # not from the self.foi_attachments association - some of the total set of
+ # self.foi_attachments may now be obsolete
+ main_part = get_main_body_text_part(attachments)
# we don't use get_main_body_text_internal, as we want to avoid charset
# conversions, since /usr/bin/uudecode needs to deal with those.
# e.g. for https://secure.mysociety.org/admin/foi/request/show_raw_email/24550
@@ -651,12 +680,14 @@ class IncomingMessage < ActiveRecord::Base
c += 1
uudecode_attachment.url_part_number = c
uudecode_attachment.save!
- attachments << uudecode_attachment.id
+ attachments << uudecode_attachment
end
end
+ attachment_ids = attachments.map{ |attachment| attachment.id }
# now get rid of any attachments we no longer have
- FoiAttachment.destroy_all("id NOT IN (#{attachments.join(',')}) AND incoming_message_id = #{self.id}")
+ FoiAttachment.destroy_all(["id NOT IN (?) AND incoming_message_id = ?",
+ attachment_ids, self.id])
end
# Returns body text as HTML with quotes flattened, and emails removed.
@@ -748,9 +779,15 @@ class IncomingMessage < ActiveRecord::Base
attachment.body,
attachment.charset)
end
+
# Remove any bad characters
- text = Iconv.conv('utf-8//IGNORE', 'utf-8', text)
- return text
+ if RUBY_VERSION >= '1.9'
+ text.encode("utf-8", :invalid => :replace,
+ :undef => :replace,
+ :replace => "")
+ else
+ Iconv.conv('utf-8//IGNORE', 'utf-8', text)
+ end
end
diff --git a/app/models/info_request.rb b/app/models/info_request.rb
index eaed25a61..cf1af0e87 100644
--- a/app/models/info_request.rb
+++ b/app/models/info_request.rb
@@ -26,8 +26,7 @@
require 'digest/sha1'
class InfoRequest < ActiveRecord::Base
- include ActionView::Helpers::UrlHelper
- include ActionController::UrlWriter
+ include Rails.application.routes.url_helpers
strip_attributes!
@@ -51,7 +50,7 @@ class InfoRequest < ActiveRecord::Base
has_tag_string
- named_scope :visible, :conditions => {:prominence => "normal"}
+ scope :visible, :conditions => {:prominence => "normal"}
# user described state (also update in info_request_event, admin_request/edit.rhtml)
validate :must_be_valid_state
@@ -81,6 +80,11 @@ class InfoRequest < ActiveRecord::Base
'blackhole' # just dump them
]
+ # only check on create, so existing models with mixed case are allowed
+ validate :title_formatting, :on => :create
+
+ after_initialize :set_defaults
+
def self.enumerate_states
states = [
'waiting_response',
@@ -148,7 +152,7 @@ class InfoRequest < ActiveRecord::Base
@@custom_states_loaded = false
begin
- if ENV["RAILS_ENV"] != "test"
+ if !Rails.env.test?
require 'customstates'
include InfoRequestCustomStates
@@custom_states_loaded = true
@@ -456,7 +460,7 @@ public
if !allow
if self.handle_rejected_responses == 'bounce'
- RequestMailer.deliver_stopped_responses(self, email, raw_email_data) if !is_external?
+ RequestMailer.stopped_responses(self, email, raw_email_data).deliver if !is_external?
elsif self.handle_rejected_responses == 'holding_pen'
InfoRequest.holding_pen_request.receive(email, raw_email_data, false, reason)
elsif self.handle_rejected_responses == 'blackhole'
@@ -495,13 +499,13 @@ public
self.awaiting_description = true
params = { :incoming_message_id => incoming_message.id }
if !rejected_reason.empty?
- params[:rejected_reason] = rejected_reason
+ params[:rejected_reason] = rejected_reason.to_str
end
self.log_event("response", params)
self.save!
end
self.info_request_events.each { |event| event.xapian_mark_needs_index } # for the "waiting_classification" index
- RequestMailer.deliver_new_response(self, incoming_message) if !is_external?
+ RequestMailer.new_response(self, incoming_message).deliver if !is_external?
end
@@ -554,6 +558,10 @@ public
# states which require administrator action (hence email administrators
# when they are entered, and offer state change dialog to them)
+ def InfoRequest.requires_admin_states
+ return ['requires_admin', 'error_message', 'attention_requested']
+ end
+
def requires_admin?
['requires_admin', 'error_message', 'attention_requested'].include?(described_state)
end
@@ -575,7 +583,7 @@ public
if self.requires_admin?
# Check there is someone to send the message "from"
if !set_by.nil? || !self.user.nil?
- RequestMailer.deliver_requires_admin(self, set_by, message)
+ RequestMailer.requires_admin(self, set_by, message).deliver
end
end
@@ -590,7 +598,7 @@ public
RequestClassification.create!(:user_id => set_by.id,
:info_request_event_id => event.id)
- RequestMailer.deliver_old_unclassified_updated(self) if !is_external?
+ RequestMailer.old_unclassified_updated(self).deliver if !is_external?
end
end
@@ -705,7 +713,7 @@ public
# last_event_forming_initial_request. There may be more obscure
# things, e.g. fees, not properly covered.
def date_response_required_by
- Holiday.due_date_from(self.date_initial_request_last_sent_at, Configuration::reply_late_after_days, Configuration::working_or_calendar_days)
+ Holiday.due_date_from(self.date_initial_request_last_sent_at, AlaveteliConfiguration::reply_late_after_days, AlaveteliConfiguration::working_or_calendar_days)
end
# This is a long stop - even with UK public interest test extensions, 40
# days is a very long time.
@@ -713,10 +721,10 @@ public
last_sent = last_event_forming_initial_request
if self.public_body.is_school?
# schools have 60 working days maximum (even over a long holiday)
- Holiday.due_date_from(self.date_initial_request_last_sent_at, Configuration::special_reply_very_late_after_days, Configuration::working_or_calendar_days)
+ Holiday.due_date_from(self.date_initial_request_last_sent_at, AlaveteliConfiguration::special_reply_very_late_after_days, AlaveteliConfiguration::working_or_calendar_days)
else
# public interest test ICO guidance gives 40 working maximum
- Holiday.due_date_from(self.date_initial_request_last_sent_at, Configuration::reply_very_late_after_days, Configuration::working_or_calendar_days)
+ Holiday.due_date_from(self.date_initial_request_last_sent_at, AlaveteliConfiguration::reply_very_late_after_days, AlaveteliConfiguration::working_or_calendar_days)
end
end
@@ -802,6 +810,16 @@ public
end
end
+ # Returns last event
+ def get_last_event
+ events = self.info_request_events
+ if events.size == 0
+ return nil
+ else
+ return events[-1]
+ end
+ end
+
# Get previous email sent to
def get_previous_email_sent_to(info_request_event)
last_email = nil
@@ -878,10 +896,10 @@ public
end
def InfoRequest.magic_email_for_id(prefix_part, id)
- magic_email = Configuration::incoming_email_prefix
+ magic_email = AlaveteliConfiguration::incoming_email_prefix
magic_email += prefix_part + id.to_s
magic_email += "-" + InfoRequest.hash_from_id(id)
- magic_email += "@" + Configuration::incoming_email_domain
+ magic_email += "@" + AlaveteliConfiguration::incoming_email_domain
return magic_email
end
@@ -892,7 +910,7 @@ public
end
def InfoRequest.hash_from_id(id)
- return Digest::SHA1.hexdigest(id.to_s + Configuration::incoming_email_secret)[0,8]
+ return Digest::SHA1.hexdigest(id.to_s + AlaveteliConfiguration::incoming_email_secret)[0,8]
end
# Called by find_by_incoming_email - and used to be called by separate
@@ -1115,7 +1133,7 @@ public
before_save :purge_in_cache
def purge_in_cache
- if !Configuration::varnish_host.blank? && !self.id.nil?
+ if !AlaveteliConfiguration::varnish_host.blank? && !self.id.nil?
# we only do this for existing info_requests (new ones have a nil id)
path = url_for(:controller => 'request', :action => 'show', :url_title => self.url_title, :only_path => true, :locale => :none)
req = PurgeRequest.find_by_url(path)
@@ -1133,5 +1151,34 @@ public
yield(column.human_name, self.send(column.name), column.type.to_s, column.name)
end
end
+
+ private
+
+ def set_defaults
+ begin
+ if self.described_state.nil?
+ self.described_state = 'waiting_response'
+ end
+ rescue ActiveModel::MissingAttributeError
+ # this should only happen on Model.exists?() call. It can be safely ignored.
+ # See http://www.tatvartha.com/2011/03/activerecordmissingattributeerror-missing-attribute-a-bug-or-a-features/
+ end
+ # FOI or EIR?
+ if !self.public_body.nil? && self.public_body.eir_only?
+ self.law_used = 'eir'
+ end
+ end
+
+ def title_formatting
+ if !self.title.nil? && !MySociety::Validate.uses_mixed_capitals(self.title, 10)
+ errors.add(:title, _('Please write the summary using a mixture of capital and lower case letters. This makes it easier for others to read.'))
+ end
+ if !self.title.nil? && title.size > 200
+ errors.add(:title, _('Please keep the summary short, like in the subject of an email. You can use a phrase, rather than a full sentence.'))
+ end
+ if !self.title.nil? && self.title =~ /^(FOI|Freedom of Information)\s*requests?$/i
+ errors.add(:title, _('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.'))
+ end
+ end
end
diff --git a/app/models/info_request_event.rb b/app/models/info_request_event.rb
index 871b81b1f..469aabc4a 100644
--- a/app/models/info_request_event.rb
+++ b/app/models/info_request_event.rb
@@ -20,7 +20,7 @@
# models/info_request_event.rb:
#
# Copyright (c) 2007 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
class InfoRequestEvent < ActiveRecord::Base
belongs_to :info_request
@@ -405,7 +405,7 @@ class InfoRequestEvent < ActiveRecord::Base
:comment_id => self.comment_id,
# XXX would be nice to add links here, but alas the
- # code to make them is in views only. See views/request/details.rhtml
+ # code to make them is in views only. See views/request/details.html.erb
# perhaps can call with @template somehow
}
diff --git a/app/models/mail_server_log.rb b/app/models/mail_server_log.rb
index 755584b90..7f61377ce 100644
--- a/app/models/mail_server_log.rb
+++ b/app/models/mail_server_log.rb
@@ -15,9 +15,7 @@
# We load log file lines for requests in here, for display in the admin interface.
#
# Copyright (c) 2009 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
-#
-# $Id: exim_log.rb,v 1.14 2009-09-17 21:10:05 francis Exp $
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
class MailServerLog < ActiveRecord::Base
belongs_to :info_request
@@ -53,7 +51,7 @@ class MailServerLog < ActiveRecord::Base
done.save!
f = is_gz ? Zlib::GzipReader.open(file_name) : File.open(file_name, 'r')
- case(Configuration::mta_log_type.to_sym)
+ case(AlaveteliConfiguration::mta_log_type.to_sym)
when :exim
load_exim_log_data(f, done)
when :postfix
@@ -123,13 +121,13 @@ class MailServerLog < ActiveRecord::Base
# We also check the email prefix so that we could, for instance, separately handle a staging and production
# instance running on the same server with different email prefixes.
def MailServerLog.email_addresses_on_line(line)
- prefix = Regexp::quote(Configuration::incoming_email_prefix)
- domain = Regexp::quote(Configuration::incoming_email_domain)
+ prefix = Regexp::quote(AlaveteliConfiguration::incoming_email_prefix)
+ domain = Regexp::quote(AlaveteliConfiguration::incoming_email_domain)
line.scan(/#{prefix}request-[^\s]+@#{domain}/).sort.uniq
end
def MailServerLog.request_sent?(ir)
- case(Configuration::mta_log_type.to_sym)
+ case(AlaveteliConfiguration::mta_log_type.to_sym)
when :exim
request_exim_sent?(ir)
when :postfix
diff --git a/app/models/mail_server_log_done.rb b/app/models/mail_server_log_done.rb
index 3fb20f0b3..0e7e9eec3 100644
--- a/app/models/mail_server_log_done.rb
+++ b/app/models/mail_server_log_done.rb
@@ -13,7 +13,7 @@
# Stores that a particular mail server log file has been loaded in, see mail_server_log.rb
#
# Copyright (c) 2009 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
class MailServerLogDone < ActiveRecord::Base
has_many :mail_server_logs
diff --git a/app/models/outgoing_message.rb b/app/models/outgoing_message.rb
index 248125808..dbe2cf1ca 100644
--- a/app/models/outgoing_message.rb
+++ b/app/models/outgoing_message.rb
@@ -20,7 +20,7 @@
# else. e.g. An initial request for information, or a complaint.
#
# Copyright (c) 2007 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
class OutgoingMessage < ActiveRecord::Base
strip_attributes!
@@ -51,6 +51,8 @@ class OutgoingMessage < ActiveRecord::Base
end
end
+ after_initialize :set_default_letter
+
# How the default letter starts and ends
def get_salutation
ret = ""
@@ -86,7 +88,7 @@ class OutgoingMessage < ActiveRecord::Base
"'" + self.info_request.title + "'." +
"\n\n\n\n [ " + self.get_internal_review_insert_here_note + " ] \n\n\n\n" +
"A full history of my FOI request and all correspondence is available on the Internet at this address:\n" +
- "http://" + Configuration::domain + "/request/" + self.info_request.url_title
+ "http://" + AlaveteliConfiguration::domain + "/request/" + self.info_request.url_title
else
""
end
@@ -130,13 +132,6 @@ class OutgoingMessage < ActiveRecord::Base
MySociety::Validate.contains_postcode?(self.body)
end
- # Set default letter
- def after_initialize
- if self.body.nil?
- self.body = get_default_message
- end
- end
-
# Deliver outgoing message
# Note: You can test this from script/console with, say:
# InfoRequest.find(1).outgoing_messages[0].send_message
@@ -147,7 +142,7 @@ class OutgoingMessage < ActiveRecord::Base
self.status = 'sent'
self.save!
- mail_message = OutgoingMailer.deliver_initial_request(self.info_request, self)
+ mail_message = OutgoingMailer.initial_request(self.info_request, self).deliver
self.info_request.log_event(log_event_type, {
:email => mail_message.to_addrs.join(", "),
:outgoing_message_id => self.id,
@@ -159,7 +154,7 @@ class OutgoingMessage < ActiveRecord::Base
self.status = 'sent'
self.save!
- mail_message = OutgoingMailer.deliver_followup(self.info_request, self, self.incoming_message_followup)
+ mail_message = OutgoingMailer.followup(self.info_request, self, self.incoming_message_followup).deliver
self.info_request.log_event('followup_' + log_event_type, {
:email => mail_message.to_addrs.join(", "),
:outgoing_message_id => self.id,
@@ -253,6 +248,12 @@ class OutgoingMessage < ActiveRecord::Base
private
+ def set_default_letter
+ if self.body.nil?
+ self.body = get_default_message
+ end
+ end
+
def format_of_body
if self.body.empty? || self.body =~ /\A#{get_salutation}\s+#{get_signoff}/ || self.body =~ /#{get_internal_review_insert_here_note}/
if self.message_type == 'followup'
diff --git a/app/models/post_redirect.rb b/app/models/post_redirect.rb
index 31f08c21a..409069cb6 100644
--- a/app/models/post_redirect.rb
+++ b/app/models/post_redirect.rb
@@ -24,7 +24,7 @@
# fakes the redirect to include POST parameters in request later.
#
# Copyright (c) 2007 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
require 'openssl' # for random bytes function
@@ -32,6 +32,8 @@ class PostRedirect < ActiveRecord::Base
# Optional, does a login confirm before redirect for use in email links.
belongs_to :user
+ after_initialize :generate_token
+
# We store YAML version of POST parameters in the database
def post_params=(params)
self.post_params_yaml = params.to_yaml
@@ -62,18 +64,6 @@ class PostRedirect < ActiveRecord::Base
MySociety::Util.generate_token
end
- # Make the token
- def after_initialize
- # The token is used to return you to what you are doing after the login form.
- if not self.token
- self.token = PostRedirect.generate_random_token
- end
- # There is a separate token to use in the URL if we send a confirmation email.
- if not self.email_token
- self.email_token = PostRedirect.generate_random_token
- end
- end
-
# Used by (rspec) test code only
def self.get_last_post_redirect
# XXX yeuch - no other easy way of getting the token so we can check
@@ -89,6 +79,18 @@ class PostRedirect < ActiveRecord::Base
PostRedirect.delete_all "updated_at < (now() - interval '2 months')"
end
+ private
+
+ def generate_token
+ # The token is used to return you to what you are doing after the login form.
+ if not self.token
+ self.token = PostRedirect.generate_random_token
+ end
+ # There is a separate token to use in the URL if we send a confirmation email.
+ if not self.email_token
+ self.email_token = PostRedirect.generate_random_token
+ end
+ end
end
diff --git a/app/models/profile_photo.rb b/app/models/profile_photo.rb
index f6aec6338..5d542daf1 100644
--- a/app/models/profile_photo.rb
+++ b/app/models/profile_photo.rb
@@ -13,7 +13,7 @@
# Image of user that goes on their profile.
#
# Copyright (c) 2009 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
class ProfilePhoto < ActiveRecord::Base
WIDTH = 96
@@ -29,25 +29,9 @@ class ProfilePhoto < ActiveRecord::Base
attr_accessor :x, :y, :w, :h
- # convert binary data blob into ImageMagick image when assigned
attr_accessor :image
- def after_initialize
- if data.nil?
- self.image = nil
- return
- end
-
- image_list = Magick::ImageList.new
- begin
- image_list.from_blob(data)
- rescue Magick::ImageMagickError
- self.image = nil
- return
- end
- self.image = image_list[0] # XXX perhaps take largest image or somesuch if there were multiple in the file?
- self.convert_image
- end
+ after_initialize :convert_data_to_image
# make image valid format and size
def convert_image
@@ -112,6 +96,25 @@ class ProfilePhoto < ActiveRecord::Base
raise "Internal error, real pictures must have a user"
end
end
+
+ # Convert binary data blob into ImageMagick image when assigned
+ def convert_data_to_image
+ if data.nil?
+ self.image = nil
+ return
+ end
+
+ image_list = Magick::ImageList.new
+ begin
+ image_list.from_blob(data)
+ rescue Magick::ImageMagickError
+ self.image = nil
+ return
+ end
+
+ self.image = image_list[0] # XXX perhaps take largest image or somesuch if there were multiple in the file?
+ self.convert_image
+ end
end
diff --git a/app/models/public_body.rb b/app/models/public_body.rb
index b4d36fe91..a76aeb189 100644
--- a/app/models/public_body.rb
+++ b/app/models/public_body.rb
@@ -45,7 +45,7 @@ class PublicBody < ActiveRecord::Base
before_save :set_api_key, :set_default_publication_scheme
# Every public body except for the internal admin one is visible
- named_scope :visible, lambda {
+ scope :visible, lambda {
{
:conditions => "public_bodies.id <> #{PublicBody.internal_admin_body.id}"
}
@@ -54,7 +54,7 @@ class PublicBody < ActiveRecord::Base
translates :name, :short_name, :request_email, :url_name, :notes, :first_letter, :publication_scheme
# Convenience methods for creating/editing translations via forms
- def translation(locale)
+ def find_translation_by_locale(locale)
self.translations.find_by_locale(locale)
end
@@ -79,7 +79,7 @@ class PublicBody < ActiveRecord::Base
if translation_attrs.respond_to? :each_value # Hash => updating
translation_attrs.each_value do |attrs|
next if skip?(attrs)
- t = translation(attrs[:locale]) || PublicBody::Translation.new
+ t = translation_for(attrs[:locale]) || PublicBody::Translation.new
t.attributes = attrs
calculate_cached_fields(t)
t.save!
@@ -332,7 +332,7 @@ class PublicBody < ActiveRecord::Base
pb = PublicBody.new(
:name => 'Internal admin authority',
:short_name => "",
- :request_email => Configuration::contact_email,
+ :request_email => AlaveteliConfiguration::contact_email,
:home_page => "",
:notes => "",
:publication_scheme => "",
@@ -548,7 +548,7 @@ class PublicBody < ActiveRecord::Base
# Returns nil if configuration variable not set
def override_request_email
- e = Configuration::override_all_public_body_request_emails
+ e = AlaveteliConfiguration::override_all_public_body_request_emails
e if e != ""
end
@@ -632,6 +632,8 @@ class PublicBody < ActiveRecord::Base
end
end
+ private
+
def request_email_if_requestable
# Request_email can be blank, meaning we don't have details
if self.is_requestable?
diff --git a/app/models/purge_request.rb b/app/models/purge_request.rb
index 48a16f9e6..e48f3cc6f 100644
--- a/app/models/purge_request.rb
+++ b/app/models/purge_request.rb
@@ -14,7 +14,7 @@
# A queue of URLs to purge
#
# Copyright (c) 2008 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
#
class PurgeRequest < ActiveRecord::Base
diff --git a/app/models/raw_email.rb b/app/models/raw_email.rb
index de7978b82..6bf01bc74 100644
--- a/app/models/raw_email.rb
+++ b/app/models/raw_email.rb
@@ -10,7 +10,7 @@
# The fat part of models/incoming_message.rb
#
# Copyright (c) 2008 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
class RawEmail < ActiveRecord::Base
# deliberately don't strip_attributes, so keeps raw email properly
@@ -23,10 +23,10 @@ class RawEmail < ActiveRecord::Base
raise "Failed to find the id number of the associated request: has it been saved?"
end
- if ENV["RAILS_ENV"] == "test"
+ if Rails.env.test?
return File.join(Rails.root, 'files/raw_email_test')
else
- return File.join(Configuration::raw_emails_location,
+ return File.join(AlaveteliConfiguration::raw_emails_location,
request_id[0..2], request_id)
end
end
diff --git a/app/models/track_thing.rb b/app/models/track_thing.rb
index a0c74bdb6..66b8a5c47 100644
--- a/app/models/track_thing.rb
+++ b/app/models/track_thing.rb
@@ -19,7 +19,7 @@
# When somebody is getting alerts for something.
#
# Copyright (c) 2008 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
require 'set'
@@ -260,7 +260,7 @@ class TrackThing < ActiveRecord::Base
:title_in_email => self.public_body.law_only_short + " requests to '" + self.public_body.name + "'",
:title_in_rss => self.public_body.law_only_short + " requests to '" + self.public_body.name + "'",
# Authentication
- :web => _("To follow requests made using {{site_name}} to the public authority '{{public_body_name}}'", :site_name=>Configuration::site_name, :public_body_name=>CGI.escapeHTML(self.public_body.name)),
+ :web => _("To follow requests made using {{site_name}} to the public authority '{{public_body_name}}'", :site_name=>AlaveteliConfiguration::site_name, :public_body_name=>CGI.escapeHTML(self.public_body.name)),
:email => _("Then you will be notified whenever someone requests something or gets a response from '{{public_body_name}}'.", :public_body_name=>CGI.escapeHTML(self.public_body.name)),
:email_subject => _("Confirm you want to follow requests to '{{public_body_name}}'", :public_body_name=>self.public_body.name),
# RSS sorting
diff --git a/app/models/track_things_sent_email.rb b/app/models/track_things_sent_email.rb
index a0a4c0f0c..a9ea2520e 100644
--- a/app/models/track_things_sent_email.rb
+++ b/app/models/track_things_sent_email.rb
@@ -16,7 +16,7 @@
# Record that alert has arrived.
#
# Copyright (c) 2008 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
class TrackThingsSentEmail < ActiveRecord::Base
belongs_to :info_request_event
diff --git a/app/models/user.rb b/app/models/user.rb
index 37edbe360..306d6ad4a 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -58,6 +58,9 @@ class User < ActiveRecord::Base
],
:terms => [ [ :variety, 'V', "variety" ] ],
:if => :indexed_by_search?
+
+ after_initialize :set_defaults
+
def created_at_numeric
# format it here as no datetime support in Xapian's value ranges
return self.created_at.strftime("%Y%m%d%H%M%S")
@@ -67,17 +70,6 @@ class User < ActiveRecord::Base
"user"
end
- def after_initialize
- if self.admin_level.nil?
- self.admin_level = 'none'
- end
- if self.new_record?
- # make alert emails go out at a random time for each new user, so
- # overall they are spread out throughout the day.
- self.last_daily_track_email = User.random_time_in_last_day
- end
- end
-
# requested_by: and commented_by: search queries also need updating after save
after_update :reindex_referencing_models
def reindex_referencing_models
@@ -138,14 +130,14 @@ class User < ActiveRecord::Base
if user
# There is user with email, check password
if !user.has_this_password?(params[:password])
- user.errors.add_to_base(auth_fail_message)
+ user.errors.add(:base, auth_fail_message)
end
else
# No user of same email, make one (that we don't save in the database)
# for the forms code to use.
user = User.new(params)
# deliberately same message as above so as not to leak whether registered
- user.errors.add_to_base(auth_fail_message)
+ user.errors.add(:base, auth_fail_message)
end
user
end
@@ -198,12 +190,12 @@ class User < ActiveRecord::Base
# The "internal admin" is a special user for internal use.
def User.internal_admin_user
- u = User.find_by_email(Configuration::contact_email)
+ u = User.find_by_email(AlaveteliConfiguration::contact_email)
if u.nil?
password = PostRedirect.generate_random_token
u = User.new(
:name => 'Internal admin user',
- :email => Configuration::contact_email,
+ :email => AlaveteliConfiguration::contact_email,
:password => password,
:password_confirmation => password
)
@@ -276,16 +268,16 @@ class User < ActiveRecord::Base
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?
- return false if Configuration::max_requests_per_user_per_day.blank?
+ return false if AlaveteliConfiguration::max_requests_per_user_per_day.blank?
recent_requests = InfoRequest.count(:conditions => ["user_id = ? and created_at > now() - '1 day'::interval", self.id])
- return (recent_requests >= Configuration::max_requests_per_user_per_day)
+ return (recent_requests >= AlaveteliConfiguration::max_requests_per_user_per_day)
end
def next_request_permitted_at
return nil if self.no_limit
- n_most_recent_requests = InfoRequest.all(:conditions => ["user_id = ? and created_at > now() - '1 day'::interval", self.id], :order => "created_at DESC", :limit => Configuration::max_requests_per_user_per_day)
- return nil if n_most_recent_requests.size < Configuration::max_requests_per_user_per_day
+ n_most_recent_requests = InfoRequest.all(:conditions => ["user_id = ? and created_at > now() - '1 day'::interval", self.id], :order => "created_at DESC", :limit => AlaveteliConfiguration::max_requests_per_user_per_day)
+ return nil if n_most_recent_requests.size < AlaveteliConfiguration::max_requests_per_user_per_day
nth_most_recent_request = n_most_recent_requests[-1]
return nth_most_recent_request.created_at + 1.day
@@ -404,6 +396,17 @@ class User < ActiveRecord::Base
self.salt = self.object_id.to_s + rand.to_s
end
+ def set_defaults
+ if self.admin_level.nil?
+ self.admin_level = 'none'
+ end
+ if self.new_record?
+ # make alert emails go out at a random time for each new user, so
+ # overall they are spread out throughout the day.
+ self.last_daily_track_email = User.random_time_in_last_day
+ end
+ end
+
def email_and_name_are_valid
if self.email != "" && !MySociety::Validate.is_valid_email(self.email)
errors.add(:email, _("Please enter a valid email address"))
diff --git a/app/models/user_info_request_sent_alert.rb b/app/models/user_info_request_sent_alert.rb
index cf20bcbf5..449a4c237 100644
--- a/app/models/user_info_request_sent_alert.rb
+++ b/app/models/user_info_request_sent_alert.rb
@@ -15,7 +15,7 @@
# given type of alert.
#
# Copyright (c) 2008 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
class UserInfoRequestSentAlert < ActiveRecord::Base
belongs_to :user
diff --git a/app/models/user_mailer.rb b/app/models/user_mailer.rb
deleted file mode 100644
index 1be4f8aa3..000000000
--- a/app/models/user_mailer.rb
+++ /dev/null
@@ -1,48 +0,0 @@
-# models/user_mailer.rb:
-# Emails relating to user accounts. e.g. Confirming a new account
-#
-# Copyright (c) 2007 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
-
-class UserMailer < ApplicationMailer
- def confirm_login(user, reasons, url)
- @from = contact_from_name_and_email
- headers 'Return-Path' => blackhole_email, 'Reply-To' => @from # we don't care about bounces when people are fiddling with their account
- @recipients = user.name_and_email
- @subject = reasons[:email_subject]
- @body[:reasons] = reasons
- @body[:name] = user.name
- @body[:url] = url
- end
-
- def already_registered(user, reasons, url)
- @from = contact_from_name_and_email
- headers 'Return-Path' => blackhole_email, 'Reply-To' => @from # we don't care about bounces when people are fiddling with their account
- @recipients = user.name_and_email
- @subject = reasons[:email_subject]
- @body[:reasons] = reasons
- @body[:name] = user.name
- @body[:url] = url
- end
-
- def changeemail_confirm(user, new_email, url)
- @from = contact_from_name_and_email
- headers 'Return-Path' => blackhole_email, 'Reply-To' => @from # we don't care about bounces when people are fiddling with their account
- @recipients = new_email
- @subject = _("Confirm your new email address on {{site_name}}", :site_name=>site_name)
- @body[:name] = user.name
- @body[:url] = url
- @body[:old_email] = user.email
- @body[:new_email] = new_email
- end
-
- def changeemail_already_used(old_email, new_email)
- @from = contact_from_name_and_email
- headers 'Return-Path' => blackhole_email, 'Reply-To' => @from # we don't care about bounces when people are fiddling with their account
- @recipients = new_email
- @subject = _("Unable to change email address on {{site_name}}", :site_name=>site_name)
- @body[:old_email] = old_email
- @body[:new_email] = new_email
- end
-end
-
diff --git a/app/views/admin_censor_rule/_form.rhtml b/app/views/admin_censor_rule/_form.html.erb
index 5035238d6..5035238d6 100644
--- a/app/views/admin_censor_rule/_form.rhtml
+++ b/app/views/admin_censor_rule/_form.html.erb
diff --git a/app/views/admin_censor_rule/_show.rhtml b/app/views/admin_censor_rule/_show.html.erb
index 0d4cece93..0d4cece93 100644
--- a/app/views/admin_censor_rule/_show.rhtml
+++ b/app/views/admin_censor_rule/_show.html.erb
diff --git a/app/views/admin_censor_rule/edit.rhtml b/app/views/admin_censor_rule/edit.html.erb
index 4eb99ce57..230446ed3 100644
--- a/app/views/admin_censor_rule/edit.rhtml
+++ b/app/views/admin_censor_rule/edit.html.erb
@@ -2,14 +2,14 @@
<h1><%=@title%></h1>
-<% form_tag admin_rule_update_path(@censor_rule), :class => "form form-horizontal" do %>
+<%= form_tag admin_rule_update_path(@censor_rule), :class => "form form-horizontal" do %>
<%= render :partial => 'form', :locals => { :info_request => @censor_rule.info_request, :user => @censor_rule.user } %>
<div class="form-actions">
<%= submit_tag 'Save', :accesskey => 's', :class => "btn btn-primary" %>
</div>
<% end %>
-<% form_tag admin_rule_destroy_path(@censor_rule), :class => "form form-horizontal" do %>
+<%= form_tag admin_rule_destroy_path(@censor_rule), :class => "form form-horizontal" do %>
<%= hidden_field_tag(:censor_rule_id, @censor_rule.id) %>
<div class="form-actions">
Permanent! --&gt; <%= submit_tag "Destroy rule", :class => "btn btn-primary" %>
diff --git a/app/views/admin_censor_rule/new.rhtml b/app/views/admin_censor_rule/new.html.erb
index f6978c07c..77d22990c 100644
--- a/app/views/admin_censor_rule/new.rhtml
+++ b/app/views/admin_censor_rule/new.html.erb
@@ -2,7 +2,7 @@
<h1><%=@title%></h1>
-<% form_tag admin_rule_create_path, :class => "form form-horizontal" do %>
+<%= form_tag admin_rule_create_path, :class => "form form-horizontal" do %>
<%= render :partial => 'form', :locals => { :info_request => @info_request, :user => @censor_user } %>
<div class="form-actions">
<%= submit_tag "Create", :class => "btn btn-primary" %>
diff --git a/app/views/admin_general/_admin_navbar.rhtml b/app/views/admin_general/_admin_navbar.html.erb
index 5cc740f70..5cc740f70 100644
--- a/app/views/admin_general/_admin_navbar.rhtml
+++ b/app/views/admin_general/_admin_navbar.html.erb
diff --git a/app/views/admin_general/debug.rhtml b/app/views/admin_general/debug.html.erb
index 7fd256025..bf984c2e1 100644
--- a/app/views/admin_general/debug.rhtml
+++ b/app/views/admin_general/debug.html.erb
@@ -21,16 +21,13 @@ RUBY_VERSION <%=h RUBY_VERSION %>
<br>
Rails::VERSION::STRING <%=h Rails::VERSION::STRING%>
<br>
-TMail::VERSION::STRING <%=h TMail::VERSION::STRING%>
-<br>
Xapian::version_string <%=h Xapian::version_string%>
</p>
<h2>Configuration</h2>
-<p>environment: <%=h Rails::configuration.environment %>
-<br>environment_path: <%=h Rails::configuration.environment_path %>
-<br>framework_paths: <%=h Rails::configuration.framework_paths.to_yaml %>
+<p>Rails env: <%=h Rails.env %>
+<br>Rails root: <%=h Rails.root %>
</p>
<h2>Environment variables</h2>
diff --git a/app/views/admin_general/index.rhtml b/app/views/admin_general/index.html.erb
index b239a2b3f..b239a2b3f 100644
--- a/app/views/admin_general/index.rhtml
+++ b/app/views/admin_general/index.html.erb
diff --git a/app/views/admin_general/stats.rhtml b/app/views/admin_general/stats.html.erb
index 27dc25ee0..27dc25ee0 100644
--- a/app/views/admin_general/stats.rhtml
+++ b/app/views/admin_general/stats.html.erb
diff --git a/app/views/admin_general/timeline.rhtml b/app/views/admin_general/timeline.html.erb
index 8fd8875b6..8fd8875b6 100644
--- a/app/views/admin_general/timeline.rhtml
+++ b/app/views/admin_general/timeline.html.erb
diff --git a/app/views/admin_public_body/_form.rhtml b/app/views/admin_public_body/_form.html.erb
index 3f346842c..c577d1e18 100644
--- a/app/views/admin_public_body/_form.rhtml
+++ b/app/views/admin_public_body/_form.html.erb
@@ -18,11 +18,10 @@
prefix = "public_body[translated_versions][]"
object = @public_body.new_record? ?
PublicBody::Translation.new :
- @public_body.translation(locale.to_s) || PublicBody::Translation.new
+ @public_body.find_translation_by_locale(locale.to_s) || PublicBody::Translation.new
end
-
- fields_for prefix, object do |t|
%>
+ <%= fields_for prefix, object do |t| %>
<div class="tab-pane" id="div-locale-<%=locale.to_s%>">
<div class="control-group">
<%= t.hidden_field :locale, :value => locale.to_s %>
diff --git a/app/views/admin_public_body/_one_list.rhtml b/app/views/admin_public_body/_one_list.html.erb
index d8746bae7..8f1d719ec 100644
--- a/app/views/admin_public_body/_one_list.rhtml
+++ b/app/views/admin_public_body/_one_list.html.erb
@@ -31,7 +31,7 @@
<% end %>
</div>
-<% form_tag(admin_body_mass_tag_add_url, :method => "post", :class => "form form-inline" ) do %>
+<%= form_tag(admin_body_mass_tag_add_url, :method => "post", :class => "form form-inline" ) do %>
<p>
<%= text_field_tag 'new_tag', params[:new_tag], { :size => 15, :id => "mass_add_tag_new_tag_" + table_name } %>
<%= hidden_field_tag(:query, params[:query], { :id => "mass_add_tag_query_" + table_name } ) %>
diff --git a/app/views/admin_public_body/_tag_help.rhtml b/app/views/admin_public_body/_tag_help.html.erb
index b64e65877..b64e65877 100644
--- a/app/views/admin_public_body/_tag_help.rhtml
+++ b/app/views/admin_public_body/_tag_help.html.erb
diff --git a/app/views/admin_public_body/_tags.rhtml b/app/views/admin_public_body/_tags.html.erb
index 26526f304..26526f304 100644
--- a/app/views/admin_public_body/_tags.rhtml
+++ b/app/views/admin_public_body/_tags.html.erb
diff --git a/app/views/admin_public_body/edit.rhtml b/app/views/admin_public_body/edit.html.erb
index eb0c45f19..11b7eec22 100644
--- a/app/views/admin_public_body/edit.rhtml
+++ b/app/views/admin_public_body/edit.html.erb
@@ -3,7 +3,7 @@
<div class="row">
<div class="span8">
<div id="public_body_form">
- <% form_for @public_body, :url => admin_body_update_path(@public_body), :html => { :class => "form form-horizontal" } do |f| %>
+ <%= form_for @public_body, :url => admin_body_update_path(@public_body), :html => { :class => "form form-horizontal" } do |f| %>
<%= render :partial => 'form', :locals => {:f => f} %>
<div class="form-actions">
<%= f.submit 'Save', :accesskey => 's', :class => "btn btn-success" %></p>
@@ -20,7 +20,7 @@
</div>
<% if @public_body.info_requests.empty? %>
- <% form_tag(admin_body_destroy_path(@public_body), :class => "form form-inline") do %>
+ <%= form_tag(admin_body_destroy_path(@public_body), :class => "form form-inline") do %>
<%= hidden_field_tag(:public_body_id, { :value => @public_body.id } ) %>
<%= submit_tag _("Destroy {{name}}", :name => @public_body.name), :class => "btn btn-danger" %> (this is permanent!)
<% end %>
diff --git a/app/views/admin_public_body/import_csv.rhtml b/app/views/admin_public_body/import_csv.html.erb
index bfe1b0c3b..afda5a468 100644
--- a/app/views/admin_public_body/import_csv.rhtml
+++ b/app/views/admin_public_body/import_csv.html.erb
@@ -9,7 +9,7 @@
<pre id="error"><%=@errors %></pre>
<% end %>
-<% form_tag 'import_csv', :multipart => true do %>
+<%= form_tag 'import_csv', :multipart => true do %>
<p>
<% if @original_csv_file && @temporary_csv_file %>
CSV file:
diff --git a/app/views/admin_public_body/list.rhtml b/app/views/admin_public_body/list.html.erb
index acc05f50d..3d7d9c4cd 100644
--- a/app/views/admin_public_body/list.rhtml
+++ b/app/views/admin_public_body/list.html.erb
@@ -15,7 +15,7 @@
</div>
</div>
-<% form_tag({}, :method => "get", :class => "form form-search") do %>
+<%= form_tag({}, :method => "get", :class => "form form-search") do %>
<%= text_field_tag 'query', params[:query], { :size => 30, :class => "input-large search-query" } %>
<%= submit_tag "Search", :class => "btn" %>
<% if !@query.nil? %>
@@ -35,7 +35,6 @@
<h2>All authorities</h2>
<% else %>
<h2>Substring search matches (<%= @public_bodies.total_entries %> total)</h2>
-
<% end %>
<%= render :partial => 'one_list', :locals => { :bodies => @public_bodies, :table_name => 'substring' } %>
<% end %>
diff --git a/app/views/admin_public_body/missing_scheme.rhtml b/app/views/admin_public_body/missing_scheme.html.erb
index 2ea55ae00..2ea55ae00 100644
--- a/app/views/admin_public_body/missing_scheme.rhtml
+++ b/app/views/admin_public_body/missing_scheme.html.erb
diff --git a/app/views/admin_public_body/new.rhtml b/app/views/admin_public_body/new.html.erb
index 6ead1810c..13e8238d6 100644
--- a/app/views/admin_public_body/new.rhtml
+++ b/app/views/admin_public_body/new.html.erb
@@ -4,7 +4,7 @@
<div class="row">
<div class="span8">
<div id="public_body_form">
- <% form_for :public_body, @public_body, :url => admin_body_create_path, :html => {:class => "form form-horizontal"} do |f| %>
+ <%= form_for @public_body, :as => :public_body, :url => admin_body_create_path, :html => {:class => "form form-horizontal"} do |f| %>
<%= render :partial => 'form', :locals => {:f => f} %>
<div class="form-actions">
<%= f.submit "Create", :class => "btn btn-primary" %>
diff --git a/app/views/admin_public_body/show.rhtml b/app/views/admin_public_body/show.html.erb
index cfb10b24e..cfb10b24e 100644
--- a/app/views/admin_public_body/show.rhtml
+++ b/app/views/admin_public_body/show.html.erb
diff --git a/app/views/admin_request/_incoming_message_actions.rhtml b/app/views/admin_request/_incoming_message_actions.html.erb
index 84c29dcc3..653e73337 100644
--- a/app/views/admin_request/_incoming_message_actions.rhtml
+++ b/app/views/admin_request/_incoming_message_actions.html.erb
@@ -1,6 +1,6 @@
<fieldset class="form-horizontal">
<legend>Actions</legend>
- <% form_tag admin_request_redeliver_incoming_path, :class => "form form-inline" do %>
+ <%= form_tag admin_request_redeliver_incoming_path, :class => "form form-inline" do %>
<div class="control-group">
<label class="control-label" for="url_title_<%= incoming_message.id %>">Redeliver message to one or more other requests</label>
<div class="controls">
@@ -22,7 +22,7 @@
</div>
</div>
- <% form_tag admin_request_destroy_incoming_path, :class => "form form-inline" do %>
+ <%= form_tag admin_request_destroy_incoming_path, :class => "form form-inline" do %>
<div class="control-group">
<label class="control-label" for="destroy_message_<%= incoming_message.id %>">Destroy message</label>
<div class="controls">
diff --git a/app/views/admin_request/_some_requests.rhtml b/app/views/admin_request/_some_requests.html.erb
index cff94956d..cff94956d 100644
--- a/app/views/admin_request/_some_requests.rhtml
+++ b/app/views/admin_request/_some_requests.html.erb
diff --git a/app/views/admin_request/_tags.rhtml b/app/views/admin_request/_tags.html.erb
index 22fbf13c8..22fbf13c8 100644
--- a/app/views/admin_request/_tags.rhtml
+++ b/app/views/admin_request/_tags.html.erb
diff --git a/app/views/admin_request/edit.rhtml b/app/views/admin_request/edit.html.erb
index 1cf5d4f12..0e9c68aea 100644
--- a/app/views/admin_request/edit.rhtml
+++ b/app/views/admin_request/edit.html.erb
@@ -2,7 +2,7 @@
<%= error_messages_for 'info_request' %>
-<% form_tag admin_request_update_path(@info_request) do %>
+<%= form_tag admin_request_update_path(@info_request) do %>
<p><label for="info_request_title"><strong>Title</strong></label> (warning: editing this will break URLs right now)<br/>
<%= text_field 'info_request', 'title', :size => 50 %></p>
@@ -49,7 +49,7 @@
<hr>
-<% form_tag admin_request_destroy_path(@info_request) do %>
+<%= form_tag admin_request_destroy_path(@info_request) do %>
<p>
<strong>This is permanent and irreversible!</strong> <%= submit_tag 'Destroy request entirely' %>
<br>Use it mainly if someone posts private information, e.g. made a Data Protection request. It
diff --git a/app/views/admin_request/edit_comment.rhtml b/app/views/admin_request/edit_comment.html.erb
index 07031f5f2..2cf49a4a8 100644
--- a/app/views/admin_request/edit_comment.rhtml
+++ b/app/views/admin_request/edit_comment.html.erb
@@ -2,7 +2,7 @@
<%= error_messages_for 'comment' %>
-<% form_tag admin_request_update_comment_path(@comment) do %>
+<%= form_tag admin_request_update_comment_path(@comment) do %>
<p><label for="comment_body">Body of annotation</label><br/>
<%= text_area 'comment', 'body', :rows => 10, :cols => 60 %></p>
diff --git a/app/views/admin_request/edit_outgoing.rhtml b/app/views/admin_request/edit_outgoing.html.erb
index ab209be0d..a0c60520a 100644
--- a/app/views/admin_request/edit_outgoing.rhtml
+++ b/app/views/admin_request/edit_outgoing.html.erb
@@ -2,7 +2,7 @@
<%= error_messages_for 'outgoing_message' %>
-<% form_tag admin_request_update_outgoing_path(@outgoing_message) do %>
+<%= form_tag admin_request_update_outgoing_path(@outgoing_message) do %>
<p><label for="outgoing_message_body">Body of message</label><br/>
<%= text_area 'outgoing_message', 'body', :rows => 10, :cols => 60 %></p>
@@ -22,7 +22,7 @@
<%= link_to 'List all', admin_request_list_path %>
</p>
-<% form_tag admin_request_destroy_outgoing_path do %>
+<%= form_tag admin_request_destroy_outgoing_path do %>
<div>
<%= hidden_field_tag 'outgoing_message_id', @outgoing_message.id %>
Warning, this is permanent! ---&gt;
diff --git a/app/views/admin_request/hidden_user_explanation.html.erb b/app/views/admin_request/hidden_user_explanation.html.erb
new file mode 100644
index 000000000..d0a5d727d
--- /dev/null
+++ b/app/views/admin_request/hidden_user_explanation.html.erb
@@ -0,0 +1,10 @@
+<%= _("Dear {{name}},", :name => name_to) %>
+
+<%= _("Your request '{{request}}' at {{url}} has been reviewed by moderators.", :request => info_request.title.html_safe, :url => info_request_url) %>
+
+<%= reason == 'not_foi' ? _("We consider it is not a valid FOI request, and have therefore hidden it from other users.") : _("We consider it to be vexatious, and have therefore hidden it from other users.") %> <%= _("You will still be able to view it while logged in to the site. Please reply to this email if you would like to discuss this decision further.") %>
+
+<%= _("Yours,") %>
+
+<%= _("The {{site_name}} team.", :site_name => site_name) %>
+
diff --git a/app/views/admin_request/hidden_user_explanation.rhtml b/app/views/admin_request/hidden_user_explanation.rhtml
deleted file mode 100644
index 7084e986f..000000000
--- a/app/views/admin_request/hidden_user_explanation.rhtml
+++ /dev/null
@@ -1,10 +0,0 @@
-Dear <%= name_to %>,
-
-Your request '<%= info_request.title.html_safe %>' at <%= info_request_url %> has been reviewed by moderators.
-
-We consider it <% if reason == 'not_foi' %>is not a valid FOI request<% else %>to be vexatious<% end%>, and have therefore hidden it from other users. You will still be able to view it while logged in to the site. Please reply to this email if you would like to discuss this decision further.
-
-Yours,
-
-The <%= site_name %> team.
-
diff --git a/app/views/admin_request/list.rhtml b/app/views/admin_request/list.html.erb
index 10b39d3a2..2bd3e3326 100644
--- a/app/views/admin_request/list.rhtml
+++ b/app/views/admin_request/list.html.erb
@@ -2,7 +2,7 @@
<h1><%=@title%></h1>
-<% form_tag({}, :method => "get", :class => "form form-search") do %>
+<%= form_tag({}, :method => "get", :class => "form form-search") do %>
<%= text_field_tag 'query', params[:query], { :size => 30, :class => "input-large search-query" } %>
<%= submit_tag "Search", :class => "btn" %> (substring search, titles only)
<% end %>
diff --git a/app/views/admin_request/show.rhtml b/app/views/admin_request/show.html.erb
index 2b37e8afb..e18e319be 100644
--- a/app/views/admin_request/show.rhtml
+++ b/app/views/admin_request/show.html.erb
@@ -2,7 +2,7 @@
<h1><%=@title%></h1>
-<% form_tag admin_request_move_request_path, { :class => "form form-horizontal" } do %>
+<%= form_tag admin_request_move_request_path, { :class => "form form-horizontal" } do %>
<%= hidden_field_tag 'info_request_id', @info_request.id %>
<div class="accordion" id="info_request">
<div class="accordion-group">
@@ -121,7 +121,7 @@
<p class="help-block">(see also option to general URLs for individual incoming messages below)</p>
</div>
</div>
- <% form_tag admin_request_hide_path(@info_request), :class => "form form-inline", :id => "hide_request_form", 'data-info-request-id' => @info_request.id.to_s do %>
+ <%= form_tag admin_request_hide_path(@info_request), :class => "form form-inline", :id => "hide_request_form", 'data-info-request-id' => @info_request.id.to_s do %>
<div class="control-group">
<% if @info_request.is_external? %>
<label class="control-label">Hide the request:</label>
@@ -149,7 +149,7 @@
<div class="control-group" id="request_hidden_user_subject">
<label for="request_hidden_user_subject_field" class="control-label">Subject of email:</label>
<div class="controls">
- <%= text_field_tag "subject", "Your request on WhatDoTheyKnow.com hidden", {:id => "request_hidden_user_subject_field", :cols => 100} %>
+ <%= text_field_tag "subject", _("Your request on {{site_name}} hidden", :site_name => site_name), {:id => "request_hidden_user_subject_field", :cols => 100} %>
</div>
</div>
@@ -191,7 +191,7 @@
<tr>
<td>
<% if info_request_event.described_state != 'waiting_clarification' and info_request_event.event_type == 'response' %>
- <% form_tag admin_request_clarification_path, :class => "form form-inline admin-table-form admin-inline-form" do %>
+ <%= form_tag admin_request_clarification_path, :class => "form form-inline admin-table-form admin-inline-form" do %>
<%= hidden_field_tag 'info_request_event_id', info_request_event.id, :id => nil %>
<%= submit_tag "Was clarification request", :class => "btn btn-mini btn-primary" %>
<% end %>
@@ -233,7 +233,7 @@
<div class="accordion-group">
<div class="accordion-heading">
<a href="#outgoing_<%=outgoing_message.id%>" data-toggle="collapse" data-parent="#outgoing_messages"><%= chevron_right %></a>
- <% link_to admin_request_edit_outgoing_path(outgoing_message) do %>
+ <%= link_to admin_request_edit_outgoing_path(outgoing_message) do %>
#<%= outgoing_message.id %> -- <%= outgoing_message.status.humanize %> <%= outgoing_message.message_type.humanize %>
<% end %>
<blockquote>
@@ -245,7 +245,7 @@
<tbody>
<tr>
<td colspan="2">
- <% form_tag admin_request_resend_path, :class => "admin-table-form" do %>
+ <%= form_tag admin_request_resend_path, :class => "admin-table-form" do %>
<%= hidden_field_tag 'outgoing_message_id', outgoing_message.id %>
<%= submit_tag "Resend", :class => "btn" %>
<% end %>
@@ -306,7 +306,7 @@
<%= simple_format( truncate(h(value), :length => 400, :omission => link_to("...", "#", :class => "toggle-hidden")).html_safe) %>
<div style="display:none;"><%= simple_format(value) %></div>
<% else %>
- <%= simple_format(value) %>
+ <%= simple_format(value.to_s) %>
<% end %>
</td>
</tr>
@@ -326,7 +326,7 @@
<div class="accordion-group">
<div class="accordion-heading">
<a href="#comment_<%=comment.id%>" data-toggle="collapse" data-parent="#comments"><%= chevron_right %></a>
- <% link_to admin_request_edit_comment_path(comment) do %>
+ <%= link_to admin_request_edit_comment_path(comment) do %>
#<%=comment.id%>
--
<%=h(comment.user.name)%>
diff --git a/app/views/admin_request/show_raw_email.rhtml b/app/views/admin_request/show_raw_email.html.erb
index 72c782ad6..72c782ad6 100644
--- a/app/views/admin_request/show_raw_email.rhtml
+++ b/app/views/admin_request/show_raw_email.html.erb
diff --git a/app/views/admin_track/_some_tracks.rhtml b/app/views/admin_track/_some_tracks.html.erb
index 95101cb55..e9facfb5d 100644
--- a/app/views/admin_track/_some_tracks.rhtml
+++ b/app/views/admin_track/_some_tracks.html.erb
@@ -32,7 +32,7 @@
<% if include_destroy %>
<tr>
<td colspan="2">
- <% form_tag admin_user_destroy_track_path, :class => "form form-inline admin-table-form" do %>
+ <%= form_tag admin_user_destroy_track_path, :class => "form form-inline admin-table-form" do %>
<div>
<%= hidden_field_tag 'track_id', track_thing.id %>
<%= submit_tag "Destroy track", :class => "btn btn-warning" %>
@@ -70,3 +70,5 @@
<% end %>
</div>
<% end %>
+</table>
+
diff --git a/app/views/admin_track/list.rhtml b/app/views/admin_track/list.html.erb
index 9cff5635b..5e967a926 100644
--- a/app/views/admin_track/list.rhtml
+++ b/app/views/admin_track/list.html.erb
@@ -2,7 +2,7 @@
<h1><%=@title%></h1>
-<% form_tag({}, :method => "get", :class => "form form-search") do %>
+<%= form_tag({}, :method => "get", :class => "form form-search") do %>
<%= text_field_tag 'query', params[:query], { :size => 30, :class => "input-large search-query" } %>
<%= submit_tag "Search", :class => "btn" %> (substring search the query – so use url_names_for_a_particular_request_or_authority_or_person)
<% end %>
diff --git a/app/views/admin_user/_form.rhtml b/app/views/admin_user/_form.html.erb
index e7175d09c..e7175d09c 100644
--- a/app/views/admin_user/_form.rhtml
+++ b/app/views/admin_user/_form.html.erb
diff --git a/app/views/admin_user/_user_table.rhtml b/app/views/admin_user/_user_table.html.erb
index 57066bf3f..57066bf3f 100644
--- a/app/views/admin_user/_user_table.rhtml
+++ b/app/views/admin_user/_user_table.html.erb
diff --git a/app/views/admin_user/edit.rhtml b/app/views/admin_user/edit.html.erb
index 3333a1e48..e641a13d6 100644
--- a/app/views/admin_user/edit.rhtml
+++ b/app/views/admin_user/edit.html.erb
@@ -1,6 +1,6 @@
<h1><%=@title%></h1>
-<% form_tag admin_user_update_path(@admin_user), :class => "form form-horizontal" do %>
+<%= form_tag admin_user_update_path(@admin_user), :class => "form form-horizontal" do %>
<%= render :partial => 'form' %>
<div class="form-actions">
<%= submit_tag 'Save', :accesskey => 's', :class => "btn btn-primary" %>
diff --git a/app/views/admin_user/list.rhtml b/app/views/admin_user/list.html.erb
index 23f75c159..b1238f87a 100644
--- a/app/views/admin_user/list.rhtml
+++ b/app/views/admin_user/list.html.erb
@@ -2,7 +2,7 @@
<h1><%=@title%></h1>
-<% form_tag({}, :method => "get", :class => "form form-search") do %>
+<%= form_tag({}, :method => "get", :class => "form form-search") do %>
<%= text_field_tag 'query', params[:query], { :size => 30, :class => "input-large search-query"} %>
<%= submit_tag "Search", :class => "btn" %> (substring search, names and emails)
<%= link_to 'Banned users', admin_user_list_banned_path, :class => "btn btn-info" %>
diff --git a/app/views/admin_user/list_banned.rhtml b/app/views/admin_user/list_banned.html.erb
index e535415e6..e535415e6 100644
--- a/app/views/admin_user/list_banned.rhtml
+++ b/app/views/admin_user/list_banned.html.erb
diff --git a/app/views/admin_user/show.rhtml b/app/views/admin_user/show.html.erb
index e23bcf58a..c93c08e50 100644
--- a/app/views/admin_user/show.rhtml
+++ b/app/views/admin_user/show.html.erb
@@ -4,7 +4,7 @@
<% if @admin_user.profile_photo %>
<div class="user_photo_on_admin">
- <% form_tag admin_clear_profile_photo_path(@admin_user), :multipart => true, :class => "form" do %>
+ <%= form_tag admin_clear_profile_photo_path(@admin_user), :multipart => true, :class => "form" do %>
<img src="<%= get_profile_photo_url(:url_name => @admin_user.url_name) %>">
<br>
<%= submit_tag "Clear photo", :class => "btn btn-info" %>
@@ -38,7 +38,7 @@
<%=h admin_value(value)%>
<% end %>
<% if column_name == 'email_bounced_at' && !@admin_user.email_bounced_at.nil? %>
- <% form_tag admin_user_clear_bounce_path(@admin_user), :class => "form form-inline" do %>
+ <%= form_tag admin_user_clear_bounce_path(@admin_user), :class => "form form-inline" do %>
<input type="submit" name="action" value="Clear bounce" class="btn btn-info">
<% end %>
<% end %>
diff --git a/app/views/admin_user/show_bounce_message.rhtml b/app/views/admin_user/show_bounce_message.html.erb
index ad643a13e..ad643a13e 100644
--- a/app/views/admin_user/show_bounce_message.rhtml
+++ b/app/views/admin_user/show_bounce_message.html.erb
diff --git a/app/views/comment/_comment_form.rhtml b/app/views/comment/_comment_form.html.erb
index d834b5b90..b78532768 100644
--- a/app/views/comment/_comment_form.rhtml
+++ b/app/views/comment/_comment_form.html.erb
@@ -1,4 +1,4 @@
-<% form_for(:comment, @comment, :url => { :controller => "comment", :action => "new", :type => "request" }, :html => { :id => 'comment_form' } ) do |f| %>
+<%= form_for(@comment, :as => :comment, :url => { :controller => "comment", :action => "new", :type => "request" }, :html => { :id => 'comment_form' } ) do |f| %>
<p>
<%= f.text_area :body, :rows => 10, :cols => 55 %>
</p>
diff --git a/app/views/comment/_single_comment.rhtml b/app/views/comment/_single_comment.html.erb
index 421a9d4ba..421a9d4ba 100644
--- a/app/views/comment/_single_comment.rhtml
+++ b/app/views/comment/_single_comment.html.erb
diff --git a/app/views/comment/new.rhtml b/app/views/comment/new.html.erb
index 578732cdb..578732cdb 100644
--- a/app/views/comment/new.rhtml
+++ b/app/views/comment/new.html.erb
diff --git a/app/views/comment/preview.rhtml b/app/views/comment/preview.html.erb
index 702bd9a9b..cd966e6a5 100644
--- a/app/views/comment/preview.rhtml
+++ b/app/views/comment/preview.html.erb
@@ -1,6 +1,6 @@
<% @title = _("Preview new annotation on '{{info_request_title}}'",:info_request_title=>h(@info_request.title)) %>
-<% form_for(:comment, @comment, :html => { :id => 'preview_form' }, :url => { :controller => "comment", :action => "new", :type => "request" } ) do |f| %>
+<%= form_for(@comment, :html => { :id => 'preview_form' }, :url => { :controller => "comment", :action => "new", :type => "request" } ) do |f| %>
<h1><%= _('Now preview your annotation') %></h1>
diff --git a/app/views/contact_mailer/from_admin_message.rhtml b/app/views/contact_mailer/from_admin_message.text.erb
index 4169d8d3a..4169d8d3a 100644
--- a/app/views/contact_mailer/from_admin_message.rhtml
+++ b/app/views/contact_mailer/from_admin_message.text.erb
diff --git a/app/views/contact_mailer/to_admin_message.rhtml b/app/views/contact_mailer/to_admin_message.text.erb
index dc9b1090b..dc9b1090b 100644
--- a/app/views/contact_mailer/to_admin_message.rhtml
+++ b/app/views/contact_mailer/to_admin_message.text.erb
diff --git a/app/views/contact_mailer/user_message.rhtml b/app/views/contact_mailer/user_message.text.erb
index afa1494db..afa1494db 100644
--- a/app/views/contact_mailer/user_message.rhtml
+++ b/app/views/contact_mailer/user_message.text.erb
diff --git a/app/views/general/_advanced_search_tips.rhtml b/app/views/general/_advanced_search_tips.html.erb
index 08ce04439..08ce04439 100644
--- a/app/views/general/_advanced_search_tips.rhtml
+++ b/app/views/general/_advanced_search_tips.html.erb
diff --git a/app/views/general/_before_body_end.rhtml b/app/views/general/_before_body_end.html.erb
index 25fdf4684..25fdf4684 100644
--- a/app/views/general/_before_body_end.rhtml
+++ b/app/views/general/_before_body_end.html.erb
diff --git a/app/views/general/_before_head_end.rhtml b/app/views/general/_before_head_end.html.erb
index 8886745ab..8886745ab 100644
--- a/app/views/general/_before_head_end.rhtml
+++ b/app/views/general/_before_head_end.html.erb
diff --git a/app/views/general/_credits.rhtml b/app/views/general/_credits.html.erb
index b1a9ce05e..b1a9ce05e 100644
--- a/app/views/general/_credits.rhtml
+++ b/app/views/general/_credits.html.erb
diff --git a/app/views/general/_custom_state_descriptions.rhtml b/app/views/general/_custom_state_descriptions.html.erb
index 913a6d50a..913a6d50a 100644
--- a/app/views/general/_custom_state_descriptions.rhtml
+++ b/app/views/general/_custom_state_descriptions.html.erb
diff --git a/app/views/general/_custom_state_transitions_complete.rhtml b/app/views/general/_custom_state_transitions_complete.html.erb
index e69de29bb..e69de29bb 100644
--- a/app/views/general/_custom_state_transitions_complete.rhtml
+++ b/app/views/general/_custom_state_transitions_complete.html.erb
diff --git a/app/views/general/_custom_state_transitions_pending.rhtml b/app/views/general/_custom_state_transitions_pending.html.erb
index e69de29bb..e69de29bb 100644
--- a/app/views/general/_custom_state_transitions_pending.rhtml
+++ b/app/views/general/_custom_state_transitions_pending.html.erb
diff --git a/app/views/general/_footer.rhtml b/app/views/general/_footer.html.erb
index 36f3919f0..990093694 100644
--- a/app/views/general/_footer.rhtml
+++ b/app/views/general/_footer.html.erb
@@ -1,6 +1,6 @@
<div id="footer">
<%= link_to _("Contact {{site_name}}", :site_name => site_name), help_contact_path %>
-| <img src="/images/twitter-16.png" alt="twitter icon" class="twitter-icon"> <a href="https://twitter.com/<%= Configuration::twitter_username %>"><%= _("Follow us on twitter") %></a>
+| <img src="/images/twitter-16.png" alt="twitter icon" class="twitter-icon"> <a href="https://twitter.com/<%= AlaveteliConfiguration::twitter_username %>"><%= _("Follow us on twitter") %></a>
<%= render :partial => 'general/credits' %>
</div>
<div class="after-footer">&nbsp;</div>
diff --git a/app/views/general/_frontpage_bodies_list.rhtml b/app/views/general/_frontpage_bodies_list.html.erb
index 75daea41d..75daea41d 100644
--- a/app/views/general/_frontpage_bodies_list.rhtml
+++ b/app/views/general/_frontpage_bodies_list.html.erb
diff --git a/app/views/general/_frontpage_intro_sentence.rhtml b/app/views/general/_frontpage_intro_sentence.html.erb
index 74b849fc9..74b849fc9 100644
--- a/app/views/general/_frontpage_intro_sentence.rhtml
+++ b/app/views/general/_frontpage_intro_sentence.html.erb
diff --git a/app/views/general/_frontpage_new_request.rhtml b/app/views/general/_frontpage_new_request.html.erb
index 499b60eb5..499b60eb5 100644
--- a/app/views/general/_frontpage_new_request.rhtml
+++ b/app/views/general/_frontpage_new_request.html.erb
diff --git a/app/views/general/_frontpage_requests_list.rhtml b/app/views/general/_frontpage_requests_list.html.erb
index fa498dfa7..fa498dfa7 100644
--- a/app/views/general/_frontpage_requests_list.rhtml
+++ b/app/views/general/_frontpage_requests_list.html.erb
diff --git a/app/views/general/_frontpage_search_box.rhtml b/app/views/general/_frontpage_search_box.html.erb
index 890602416..890602416 100644
--- a/app/views/general/_frontpage_search_box.rhtml
+++ b/app/views/general/_frontpage_search_box.html.erb
diff --git a/app/views/general/_locale_switcher.rhtml b/app/views/general/_locale_switcher.html.erb
index d0040bb0d..d0040bb0d 100644
--- a/app/views/general/_locale_switcher.rhtml
+++ b/app/views/general/_locale_switcher.html.erb
diff --git a/app/views/general/_localised_datepicker.rhtml b/app/views/general/_localised_datepicker.html.erb
index ec6593ea0..ec6593ea0 100644
--- a/app/views/general/_localised_datepicker.rhtml
+++ b/app/views/general/_localised_datepicker.html.erb
diff --git a/app/views/general/_orglink.rhtml b/app/views/general/_orglink.html.erb
index 66002c021..66002c021 100644
--- a/app/views/general/_orglink.rhtml
+++ b/app/views/general/_orglink.html.erb
diff --git a/app/views/general/_popup_banner.rhtml b/app/views/general/_popup_banner.html.erb
index 8b1378917..8b1378917 100644
--- a/app/views/general/_popup_banner.rhtml
+++ b/app/views/general/_popup_banner.html.erb
diff --git a/app/views/general/_stylesheet_includes.rhtml b/app/views/general/_stylesheet_includes.html.erb
index 7a03680f8..5b6e12258 100644
--- a/app/views/general/_stylesheet_includes.rhtml
+++ b/app/views/general/_stylesheet_includes.html.erb
@@ -16,6 +16,6 @@
<![endif]-->
<!-- the following method for customising CSS is deprecated; see `doc/THEMES.md` for detail -->
<%= stylesheet_link_tag 'custom', :title => "Main", :rel => "stylesheet" %>
- <% if Configuration::force_registration_on_new_request %>
+ <% if AlaveteliConfiguration::force_registration_on_new_request %>
<%= stylesheet_link_tag 'jquery.fancybox-1.3.4', :rel => "stylesheet" %>
<% end %>
diff --git a/app/views/general/_topnav.rhtml b/app/views/general/_topnav.html.erb
index c7f2cedea..c7f2cedea 100644
--- a/app/views/general/_topnav.rhtml
+++ b/app/views/general/_topnav.html.erb
diff --git a/app/views/general/blog.rhtml b/app/views/general/blog.html.erb
index d42b32282..7146aab5d 100644
--- a/app/views/general/blog.rhtml
+++ b/app/views/general/blog.html.erb
@@ -7,9 +7,9 @@
<img src="/images/twitter-16.png" alt="twitter icon" class="twitter-icon"> <a href="https://twitter.com/<%= @twitter_user %>"><%= _("Follow us on twitter") %></a><br/><br/>
<img src="/images/feed-16.png" alt="RSS icon"> <a href="<%= @feed_url %>"><%= _("Subscribe to blog") %></a>
</div>
- <% if Configuration::twitter_widget_id %>
+ <% if AlaveteliConfiguration::twitter_widget_id %>
<div id="twitter">
- <a class="twitter-timeline" data-dnt=true href="https://twitter.com/<%= Configuration::twitter_username %>" data-widget-id="<%= Configuration::twitter_widget_id %>">Tweets by @<%= Configuration::twitter_username %></a>
+ <a class="twitter-timeline" data-dnt=true href="https://twitter.com/<%= AlaveteliConfiguration::twitter_username %>" data-widget-id="<%= AlaveteliConfiguration::twitter_widget_id %>">Tweets by @<%= AlaveteliConfiguration::twitter_username %></a>
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");</script>
</div>
<% end %>
@@ -20,15 +20,15 @@
<h1><%=@title %></h1>
<div id="blog">
- <% for item in @blog_items: %>
+ <% @blog_items.each do |item| %>
<div class="blog_post">
- <h2 id="<%= Time.parse(item['pubDate'][0]).to_i %>"><a href="<%=item['link']%>"><%=h item['title'] %></a></h2>
- <p class="subtitle"><%= _("Posted on {{date}} by {{author}}", :date=>simple_date(Time.parse(item['pubDate'][0])), :author=>item['creator']) %></p>
+ <h2 id="<%= Time.parse(item['pubDate'][0]).to_i %>"><a href="<%=item['link'][0]%>"><%=h item['title'][0] %></a></h2>
+ <p class="subtitle"><%= _("Posted on {{date}} by {{author}}", :date=>simple_date(Time.parse(item['pubDate'][0])), :author=>item['creator'][0]) %></p>
<div>
<% if item['encoded'] %>
- <%= raw item['encoded'] %>
+ <%= raw item['encoded'][0] %>
<% elsif item['description'] %>
- <%= raw item['description'] %>
+ <%= raw item['description'][0] %>
<% end %>
</div>
<p><em>
diff --git a/app/views/general/custom_css.rhtml b/app/views/general/custom_css.html.erb
index 0def82ed0..0def82ed0 100644
--- a/app/views/general/custom_css.rhtml
+++ b/app/views/general/custom_css.html.erb
diff --git a/app/views/general/exception_caught.rhtml b/app/views/general/exception_caught.html.erb
index f8fe4343b..8d78e2e92 100644
--- a/app/views/general/exception_caught.rhtml
+++ b/app/views/general/exception_caught.html.erb
@@ -7,7 +7,7 @@
<ul>
<li><%= _("Check for mistakes if you typed or copied the address.")%></li>
<li><%= _("Search the site to find what you were looking for.")%>
- <% form_tag({:controller => "general", :action => "search_redirect"}, {:id => "search_form" }) do %>
+ <%= form_tag({:controller => "general", :action => "search_redirect"}, {:id => "search_form" }) do %>
<%= text_field_tag 'query', params[:query], { :size => 30, :title => "type your search term here" } %>
<%= submit_tag _("Search") %>
<% end %>
diff --git a/app/views/general/frontpage.rhtml b/app/views/general/frontpage.html.erb
index 6eceb3b28..bf5261d15 100644
--- a/app/views/general/frontpage.rhtml
+++ b/app/views/general/frontpage.html.erb
@@ -1,4 +1,4 @@
-<%# TODO: Cache for 5 minutes %>
+<% # TODO: Cache for 5 minutes %>
<div id="frontpage_splash">
<div id="left_column">
<%= render :partial => "frontpage_new_request" %>
diff --git a/app/views/general/search.rhtml b/app/views/general/search.html.erb
index df114782f..6234687f2 100644
--- a/app/views/general/search.rhtml
+++ b/app/views/general/search.html.erb
@@ -22,7 +22,7 @@
<% if @advanced %>
<div id="advanced-search">
<p><%= _('To use the advanced search, combine phrases and labels as described in the search tips below.') %></p>
- <% form_tag(advanced_search_url, :method => "get") do %>
+ <%= form_tag(advanced_search_url, :method => "get") do %>
<p>
<%= text_field_tag :query, @query, { :size => 60 } %>
<%= hidden_field_tag 'sortby', @inputted_sortby %>
@@ -35,7 +35,7 @@
<% end %>
</div>
<% else %>
- <% form_tag(request.url, {:method => "get", :id => "search_form"}) do %>
+ <%= form_tag(request.url, {:method => "get", :id => "search_form"}) do %>
<p>
<%= text_field_tag 'query', params[:query], { :size => 40, :title => "type your search term here" } %>
<%= hidden_field_tag 'sortby', @inputted_sortby %>
diff --git a/app/views/help/_sidebar.rhtml b/app/views/help/_sidebar.html.erb
index 2b7ed5647..2b7ed5647 100644
--- a/app/views/help/_sidebar.rhtml
+++ b/app/views/help/_sidebar.html.erb
diff --git a/app/views/help/_why_they_should_reply_by_email.rhtml b/app/views/help/_why_they_should_reply_by_email.html.erb
index faaa2b2e2..faaa2b2e2 100644
--- a/app/views/help/_why_they_should_reply_by_email.rhtml
+++ b/app/views/help/_why_they_should_reply_by_email.html.erb
diff --git a/app/views/help/about.rhtml b/app/views/help/about.html.erb
index 477f0e750..477f0e750 100644
--- a/app/views/help/about.rhtml
+++ b/app/views/help/about.html.erb
diff --git a/app/views/help/alaveteli.rhtml b/app/views/help/alaveteli.html.erb
index 6210f9f24..6210f9f24 100644
--- a/app/views/help/alaveteli.rhtml
+++ b/app/views/help/alaveteli.html.erb
diff --git a/app/views/help/api.rhtml b/app/views/help/api.html.erb
index 57390d65a..57390d65a 100644
--- a/app/views/help/api.rhtml
+++ b/app/views/help/api.html.erb
diff --git a/app/views/help/contact.rhtml b/app/views/help/contact.html.erb
index b1b5d4f24..ad89db9ec 100644
--- a/app/views/help/contact.rhtml
+++ b/app/views/help/contact.html.erb
@@ -40,13 +40,13 @@
<% end %>
</div>
-<% form_for :contact do |f| %>
+<%= form_for :contact do |f| %>
<% if not @user %>
<p>
<label class="form_label" for="contact_name">Your name:</label>
<%= f.text_field :name, :size => 20 %>
- (or <%= link_to "sign in", signin_path(:r => request.request_uri) %>)
+ (or <%= link_to "sign in", signin_path(:r => request.fullpath) %>)
</p>
<p>
diff --git a/app/views/help/credits.rhtml b/app/views/help/credits.html.erb
index 02f1e40e8..02f1e40e8 100644
--- a/app/views/help/credits.rhtml
+++ b/app/views/help/credits.html.erb
diff --git a/app/views/help/officers.rhtml b/app/views/help/officers.html.erb
index 6db706f78..6db706f78 100644
--- a/app/views/help/officers.rhtml
+++ b/app/views/help/officers.html.erb
diff --git a/app/views/help/privacy.rhtml b/app/views/help/privacy.html.erb
index 8e5293892..8e5293892 100644
--- a/app/views/help/privacy.rhtml
+++ b/app/views/help/privacy.html.erb
diff --git a/app/views/help/requesting.rhtml b/app/views/help/requesting.html.erb
index e7cfdd199..e7cfdd199 100644
--- a/app/views/help/requesting.rhtml
+++ b/app/views/help/requesting.html.erb
diff --git a/app/views/help/unhappy.rhtml b/app/views/help/unhappy.html.erb
index 79e3f8273..79e3f8273 100644
--- a/app/views/help/unhappy.rhtml
+++ b/app/views/help/unhappy.html.erb
diff --git a/app/views/holiday/due_date.rhtml b/app/views/holiday/due_date.html.erb
index 6f8c2e51a..6f8c2e51a 100644
--- a/app/views/holiday/due_date.rhtml
+++ b/app/views/holiday/due_date.html.erb
diff --git a/app/views/layouts/admin.rhtml b/app/views/layouts/admin.html.erb
index a58913892..a58913892 100644
--- a/app/views/layouts/admin.rhtml
+++ b/app/views/layouts/admin.html.erb
diff --git a/app/views/layouts/contact_mailer.rhtml b/app/views/layouts/contact_mailer.html.erb
index 3cdc75009..3cdc75009 100644
--- a/app/views/layouts/contact_mailer.rhtml
+++ b/app/views/layouts/contact_mailer.html.erb
diff --git a/app/views/layouts/default.rhtml b/app/views/layouts/default.html.erb
index a66b85e02..023a93138 100644
--- a/app/views/layouts/default.rhtml
+++ b/app/views/layouts/default.html.erb
@@ -43,7 +43,7 @@
<%= render :partial => 'general/before_head_end' %>
</head>
<body class="<%= 'front' if params[:action] == 'frontpage' %>">
- <% if Configuration::force_registration_on_new_request && !@user %>
+ <% if AlaveteliConfiguration::force_registration_on_new_request && !@user %>
<%= javascript_include_tag 'jquery.fancybox-1.3.4.pack' %>
<script type="text/javascript">
$(document).ready(function() {
@@ -93,9 +93,9 @@
<% end %>
- <%= link_to _("Sign out"), signout_path(:r => request.request_uri) %>
+ <%= link_to _("Sign out"), signout_path(:r => request.fullpath) %>
<% else %>
- <%= link_to _("Sign in or sign up"), signin_path(:r => request.request_uri) %>
+ <%= link_to _("Sign in or sign up"), signin_path(:r => request.fullpath) %>
<% end %>
</div>
<% end %>
@@ -140,13 +140,13 @@
<input type="text">
</div>
<%
- unless Configuration::ga_code.empty? || (@user && @user.super?) %>
+ unless AlaveteliConfiguration::ga_code.empty? || (@user && @user.super?) %>
<script type="text/javascript">
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
</script>
<script type="text/javascript">
- var pageTracker = _gat._getTracker("<%= Configuration::ga_code %>");
+ var pageTracker = _gat._getTracker("<%= AlaveteliConfiguration::ga_code %>");
pageTracker._trackPageview();
</script>
diff --git a/app/views/layouts/no_chrome.rhtml b/app/views/layouts/no_chrome.html.erb
index 120ba6f28..120ba6f28 100644
--- a/app/views/layouts/no_chrome.rhtml
+++ b/app/views/layouts/no_chrome.html.erb
diff --git a/app/views/layouts/outgoing_mailer.rhtml b/app/views/layouts/outgoing_mailer.html.erb
index 8bf8ef216..8bf8ef216 100644
--- a/app/views/layouts/outgoing_mailer.rhtml
+++ b/app/views/layouts/outgoing_mailer.html.erb
diff --git a/app/views/layouts/request_mailer.rhtml b/app/views/layouts/request_mailer.html.erb
index 3cdc75009..3cdc75009 100644
--- a/app/views/layouts/request_mailer.rhtml
+++ b/app/views/layouts/request_mailer.html.erb
diff --git a/app/views/layouts/user_mailer.rhtml b/app/views/layouts/user_mailer.html.erb
index 3cdc75009..3cdc75009 100644
--- a/app/views/layouts/user_mailer.rhtml
+++ b/app/views/layouts/user_mailer.html.erb
diff --git a/app/views/outgoing_mailer/_followup_footer.rhtml b/app/views/outgoing_mailer/_followup_footer.text.erb
index d7bc7c5aa..d7bc7c5aa 100644
--- a/app/views/outgoing_mailer/_followup_footer.rhtml
+++ b/app/views/outgoing_mailer/_followup_footer.text.erb
diff --git a/app/views/outgoing_mailer/followup.rhtml b/app/views/outgoing_mailer/followup.text.erb
index 049ebc881..049ebc881 100644
--- a/app/views/outgoing_mailer/followup.rhtml
+++ b/app/views/outgoing_mailer/followup.text.erb
diff --git a/app/views/outgoing_mailer/initial_request.rhtml b/app/views/outgoing_mailer/initial_request.text.erb
index 5c418ecc7..5c418ecc7 100644
--- a/app/views/outgoing_mailer/initial_request.rhtml
+++ b/app/views/outgoing_mailer/initial_request.text.erb
diff --git a/app/views/public_body/_alphabet.rhtml b/app/views/public_body/_alphabet.html.erb
index 46b345c2a..111da5b3b 100644
--- a/app/views/public_body/_alphabet.rhtml
+++ b/app/views/public_body/_alphabet.html.erb
@@ -1,3 +1,3 @@
-<% "A".upto("Z") do |l| -%>
+<%= "A".upto("Z") do |l| -%>
<%= link_to_unless (@tag == l), l, list_public_bodies_path(:tag => l.downcase) %>
<% end %>
diff --git a/app/views/public_body/_body_listing.rhtml b/app/views/public_body/_body_listing.html.erb
index 864ab8c9b..864ab8c9b 100644
--- a/app/views/public_body/_body_listing.rhtml
+++ b/app/views/public_body/_body_listing.html.erb
diff --git a/app/views/public_body/_body_listing_single.rhtml b/app/views/public_body/_body_listing_single.html.erb
index 8e0a64df7..8e0a64df7 100644
--- a/app/views/public_body/_body_listing_single.rhtml
+++ b/app/views/public_body/_body_listing_single.html.erb
diff --git a/app/views/public_body/_list_sidebar_extra.rhtml b/app/views/public_body/_list_sidebar_extra.html.erb
index 290593d6a..290593d6a 100644
--- a/app/views/public_body/_list_sidebar_extra.rhtml
+++ b/app/views/public_body/_list_sidebar_extra.html.erb
diff --git a/app/views/public_body/_search_ahead.rhtml b/app/views/public_body/_search_ahead.html.erb
index 7ade89b8e..b1af2464d 100644
--- a/app/views/public_body/_search_ahead.rhtml
+++ b/app/views/public_body/_search_ahead.html.erb
@@ -13,7 +13,7 @@
<%= render :partial => 'body_listing_single', :locals => { :public_body => result[:model] } %>
<% end %>
</div>
- <%= will_paginate WillPaginate::Collection.new(@page, @per_page, @xapian_requests.matches_estimated) %>
+ <%= will_paginate WillPaginate::Collection.new(@page, @per_page, @xapian_requests.matches_estimated), :params => {:controller=>"request", :action => "select_authority"} %>
<% end %>
</div>
diff --git a/app/views/public_body/list.rhtml b/app/views/public_body/list.html.erb
index 34b34d550..ce24daaf9 100644
--- a/app/views/public_body/list.rhtml
+++ b/app/views/public_body/list.html.erb
@@ -32,7 +32,7 @@
<div id="left_column_flip">
<h1><%= _('Public authorities') %></h1>
-<% form_tag(list_public_bodies_default_url, :method => "get", :id=>"search_form") do %>
+<%= form_tag(list_public_bodies_default_url, :method => "get", :id=>"search_form") do %>
<div>
<%= text_field_tag(:public_body_query, params[:public_body_query], { :title => "type your search term here" } ) %>
<%= submit_tag(_("Search")) %>
diff --git a/app/views/public_body/show.rhtml b/app/views/public_body/show.html.erb
index fa6243b47..fa6243b47 100644
--- a/app/views/public_body/show.rhtml
+++ b/app/views/public_body/show.html.erb
diff --git a/app/views/public_body/view_email.rhtml b/app/views/public_body/view_email.html.erb
index 3f0a558c7..3f0a558c7 100644
--- a/app/views/public_body/view_email.rhtml
+++ b/app/views/public_body/view_email.html.erb
diff --git a/app/views/public_body/view_email_captcha.rhtml b/app/views/public_body/view_email_captcha.html.erb
index 6f301e055..4f6db5b67 100644
--- a/app/views/public_body/view_email_captcha.rhtml
+++ b/app/views/public_body/view_email_captcha.html.erb
@@ -4,7 +4,7 @@
<p><%= _('To view the email address that we use to send FOI requests to {{public_body_name}}, please enter these words.', :public_body_name => h(@public_body.name))%></p>
-<% form_for :contact do |f| %>
+<%= form_for :contact do |f| %>
<%= recaptcha_tags %>
<%= hidden_field_tag(:submitted_view_email, { :value => 1 } ) %>
diff --git a/app/views/request/_after_actions.rhtml b/app/views/request/_after_actions.html.erb
index b54a8f5fb..b54a8f5fb 100644
--- a/app/views/request/_after_actions.rhtml
+++ b/app/views/request/_after_actions.html.erb
diff --git a/app/views/request/_bubble.rhtml b/app/views/request/_bubble.html.erb
index 94498612a..94498612a 100644
--- a/app/views/request/_bubble.rhtml
+++ b/app/views/request/_bubble.html.erb
diff --git a/app/views/request/_correspondence.rhtml b/app/views/request/_correspondence.html.erb
index 68711b259..68711b259 100644
--- a/app/views/request/_correspondence.rhtml
+++ b/app/views/request/_correspondence.html.erb
diff --git a/app/views/request/_describe_state.rhtml b/app/views/request/_describe_state.html.erb
index 0b65024fd..05cce013e 100644
--- a/app/views/request/_describe_state.rhtml
+++ b/app/views/request/_describe_state.html.erb
@@ -1,6 +1,6 @@
<% if @is_owning_user %>
- <% form_for(:incoming_message, @info_request, :url => describe_state_url(:id => @info_request.id)) do |f| %>
+ <%= form_for(@info_request, :as => :incoming_message, :url => describe_state_url(:id => @info_request.id), :html => {:id => "describe_form_#{id_suffix}"}) do |f| %>
<h2><%= _('What best describes the status of this request now?') %></h2>
<hr>
@@ -101,13 +101,13 @@
</p>
<% end %>
<% elsif @old_unclassified %>
- <%= render :partial => 'other_describe_state', :locals => {:id_suffix => id_suffix } %>
+ <%= render :partial => 'request/other_describe_state', :locals => {:id_suffix => id_suffix } %>
<% else %>
<% if !@info_request.is_external? %>
<%= _('We don\'t know whether the most recent response to this request contains
information or not
&ndash;
- if you are {{user_link}} please <a href="{{url}}">sign in</a> and let everyone know.',:user_link=>user_link(@info_request.user), :url=>signin_url(:r => request.request_uri)) %>
+ if you are {{user_link}} please <a href="{{url}}">sign in</a> and let everyone know.',:user_link=>user_link(@info_request.user), :url=>signin_url(:r => request.fullpath)) %>
<% end %>
<% end %>
diff --git a/app/views/request/_followup.rhtml b/app/views/request/_followup.html.erb
index 3776980a0..bb099ff15 100644
--- a/app/views/request/_followup.rhtml
+++ b/app/views/request/_followup.html.erb
@@ -78,7 +78,7 @@
</p>
<% end %>
- <% form_for(:outgoing_message, @outgoing_message, :html => { :id => 'followup_form' }, :url => incoming_message.nil? ? show_response_no_followup_url(:id => @info_request.id) : show_response_url(:id => @info_request.id, :incoming_message_id => incoming_message.id)) do |o| %>
+ <%= form_for(@outgoing_message, :html => { :id => 'followup_form' }, :url => incoming_message.nil? ? show_response_no_followup_url(:id => @info_request.id) : show_response_url(:id => @info_request.id, :incoming_message_id => incoming_message.id)) do |o| %>
<p>
<%= o.text_area :body, :rows => 15, :cols => 55 %>
</p>
diff --git a/app/views/request/_hidden_correspondence.rhtml b/app/views/request/_hidden_correspondence.html.erb
index a08c1badf..4c06f1f48 100644
--- a/app/views/request/_hidden_correspondence.rhtml
+++ b/app/views/request/_hidden_correspondence.html.erb
@@ -7,21 +7,21 @@
%>
<div class="correspondence" id="incoming-<%=incoming_message.id.to_s%>">
<p>
- <%= _('This response has been hidden. See annotations to find out why.
- If you are the requester, then you may <a href="{{url}}">sign in</a> to view the response.', :url => signin_url(:r => request.request_uri).html_safe) %>
+ <%= _('This response has been hidden. See annotations to find out why.
+ If you are the requester, then you may <a href="{{url}}">sign in</a> to view the response.', :url => signin_url(:r => request.fullpath).html_safe) %>
</p>
</div>
<% elsif [ 'sent', 'followup_sent', 'resent', 'followup_resent' ].include?(info_request_event.event_type) %>
<div class="correspondence" id="outgoing-<%=outgoing_message.id.to_s%>">
<p>
- <%= _('This outgoing message has been hidden. See annotations to
- find out why. If you are the requester, then you may <a href="{{url}}">sign in</a> to view the response.', :url => signin_url(:r => request.request_uri).html_safe) %>
+ <%= _('This outgoing message has been hidden. See annotations to
+ find out why. If you are the requester, then you may <a href="{{url}}">sign in</a> to view the response.', :url => signin_url(:r => request.fullpath).html_safe) %>
</p>
</div>
<% elsif info_request_event.event_type == 'comment' %>
<div class="comment_in_request" id="comment-<%=comment.id.to_s%>">
<p><%= _('This comment has been hidden. See annotations to
- find out why. If you are the requester, then you may <a href="{{url}}">sign in</a> to view the response.', :url => signin_url(:r => request.request_uri).html_safe) %>
+ find out why. If you are the requester, then you may <a href="{{url}}">sign in</a> to view the response.', :url => signin_url(:r => request.fullpath).html_safe) %>
</p>
</div>
<% end %>
diff --git a/app/views/request/_next_actions.rhtml b/app/views/request/_next_actions.html.erb
index f318df6e4..f318df6e4 100644
--- a/app/views/request/_next_actions.rhtml
+++ b/app/views/request/_next_actions.html.erb
diff --git a/app/views/request/_other_describe_state.rhtml b/app/views/request/_other_describe_state.html.erb
index 3a80823c6..e49f9ecb3 100644
--- a/app/views/request/_other_describe_state.rhtml
+++ b/app/views/request/_other_describe_state.html.erb
@@ -1,6 +1,6 @@
-<% form_for(:incoming_message, @info_request, :url => describe_state_url(:id => @info_request.id)) do |f| %>
+<%= form_for(@info_request, :as => :incoming_message, :url => describe_state_url(:id => @info_request.id), :html => {:id => "describe_form_#{id_suffix}"}) do |f| %>
<h2><%= _('Hi! We need your help. The person who made the following request
hasn\'t told us whether or not it was successful. Would you mind taking
a moment to read it and help us keep the place tidy for everyone?
diff --git a/app/views/request/_request_filter_form.rhtml b/app/views/request/_request_filter_form.html.erb
index 0c215a9b6..090db01df 100644
--- a/app/views/request/_request_filter_form.rhtml
+++ b/app/views/request/_request_filter_form.html.erb
@@ -1,7 +1,7 @@
<%= render :partial => 'general/localised_datepicker' %>
<div id="list-filter">
- <% form_tag(request.path, :method => "get", :id=>"filter_requests_form") do %>
+ <%= form_tag(request.path, :method => "get", :id=>"filter_requests_form") do %>
<div class="list-filter-item">
<%= label_tag(:query, _("Keywords"), :class=>"form_label title") %>
<%= text_field_tag(:query, params[:query]) %>
diff --git a/app/views/request/_request_listing.rhtml b/app/views/request/_request_listing.html.erb
index 492f874f3..492f874f3 100644
--- a/app/views/request/_request_listing.rhtml
+++ b/app/views/request/_request_listing.html.erb
diff --git a/app/views/request/_request_listing_short_via_event.rhtml b/app/views/request/_request_listing_short_via_event.html.erb
index c2f6474a1..c2f6474a1 100644
--- a/app/views/request/_request_listing_short_via_event.rhtml
+++ b/app/views/request/_request_listing_short_via_event.html.erb
diff --git a/app/views/request/_request_listing_single.rhtml b/app/views/request/_request_listing_single.html.erb
index 56737fd3e..56737fd3e 100644
--- a/app/views/request/_request_listing_single.rhtml
+++ b/app/views/request/_request_listing_single.html.erb
diff --git a/app/views/request/_request_listing_via_event.rhtml b/app/views/request/_request_listing_via_event.html.erb
index cc8bae8a9..cc8bae8a9 100644
--- a/app/views/request/_request_listing_via_event.rhtml
+++ b/app/views/request/_request_listing_via_event.html.erb
diff --git a/app/views/request/_search_ahead.rhtml b/app/views/request/_search_ahead.html.erb
index 1e65a5458..1e65a5458 100644
--- a/app/views/request/_search_ahead.rhtml
+++ b/app/views/request/_search_ahead.html.erb
diff --git a/app/views/request/_sidebar.rhtml b/app/views/request/_sidebar.html.erb
index c7d21d867..4bc8826fd 100644
--- a/app/views/request/_sidebar.rhtml
+++ b/app/views/request/_sidebar.html.erb
@@ -16,12 +16,12 @@
<% if @info_request.attention_requested %>
<% if @info_request.prominence == 'hidden' %>
<%# The eccentric formatting of the following string is in order that it be identical
- to the corresponding string in request/show.rhtml %>
+ to the corresponding string in request/show.html.erb %>
<p><%= _('This request has prominence \'hidden\'. You can only see it because you are logged
in as a super user.') %></p>
<% elsif @info_request.prominence == 'requester_only' %>
<%# The eccentric formatting of the following string is in order that it be identical
- to the corresponding string in request/show.rhtml %>
+ to the corresponding string in request/show.html.erb %>
<p><%= _('This request is hidden, so that only you the requester can see it. Please
<a href="{{url}}">contact us</a> if you are not sure why.', :url => help_requesting_path.html_safe) %></p>
<% else %>
@@ -30,26 +30,23 @@
<% else %>
<p><%= _('Requests for personal information and vexatious requests are not considered valid for FOI purposes (<a href="/help/about">read more</a>).') %></p>
<p><%= _('If you believe this request is not suitable, you can report it for attention by the site administrators') %></p>
- <%= button_to _("Report this request"), report_path, :class => "link_button_green" %>
+ <%= button_to _("Report this request"), report_path(:url_title => @info_request.url_title), :class => "link_button_green" %>
<% end %>
<% end %>
<h2><%= _("Act on what you've learnt") %></h2>
<div class="act_link">
- <%
- # Cast "related" to normal string because html safe string (from rails_xss gem) and CGI::escape
- # interact badly with ':' character. Go figure! Might go away in rails 3
- %>
- <% link_to "https://twitter.com/share?" + {:url => request.url, :via => Configuration::twitter_username, :text => @info_request.title, :related => _('alaveteli_foi:The software that runs {{site_name}}', :site_name => site_name).to_str}.to_query do %>
+ <% tweet_link = "https://twitter.com/share?" + {:url => request.url, :via => AlaveteliConfiguration::twitter_username, :text => "'#{@info_request.title}'", :related => _('alaveteli_foi:The software that runs {{site_name}}', :site_name => site_name)}.to_query %>
+ <% link_to tweet_link do %>
<%= image_tag "twitter-16.png", :alt => "twitter icon" %>
- <%= _("Tweet this request") %>
<% end %>
+ <%= link_to _("Tweet this request"), tweet_link %>
</div>
<div class="act_link">
- <% link_to "http://wordpress.com/" do %>
+ <%= link_to "http://wordpress.com/" do %>
<%= image_tag "wordpress.png", :class => "rss" %>
- <%= _("Start your own blog") %>
<% end %>
+ <%= link_to _("Start your own blog"), "http://wordpress.com/"%>
</div>
<%= render :partial => 'request/next_actions' %>
diff --git a/app/views/request/_sidebar_request_listing.rhtml b/app/views/request/_sidebar_request_listing.html.erb
index ec5a5813d..ec5a5813d 100644
--- a/app/views/request/_sidebar_request_listing.rhtml
+++ b/app/views/request/_sidebar_request_listing.html.erb
diff --git a/app/views/request/_summary_suggestion.rhtml b/app/views/request/_summary_suggestion.html.erb
index a5da09cda..a5da09cda 100644
--- a/app/views/request/_summary_suggestion.rhtml
+++ b/app/views/request/_summary_suggestion.html.erb
diff --git a/app/views/request/_view_html_prefix.rhtml b/app/views/request/_view_html_prefix.html.erb
index 3a9946745..3a9946745 100644
--- a/app/views/request/_view_html_prefix.rhtml
+++ b/app/views/request/_view_html_prefix.html.erb
diff --git a/app/views/request/_view_html_stylesheet.rhtml b/app/views/request/_view_html_stylesheet.html.erb
index d6cb932a8..d6cb932a8 100644
--- a/app/views/request/_view_html_stylesheet.rhtml
+++ b/app/views/request/_view_html_stylesheet.html.erb
diff --git a/app/views/request/_wall_listing.rhtml b/app/views/request/_wall_listing.html.erb
index b6b4b38b1..b6b4b38b1 100644
--- a/app/views/request/_wall_listing.rhtml
+++ b/app/views/request/_wall_listing.html.erb
diff --git a/app/views/request/describe_state_message.rhtml b/app/views/request/describe_state_message.html.erb
index 1427fea22..73237759f 100644
--- a/app/views/request/describe_state_message.rhtml
+++ b/app/views/request/describe_state_message.html.erb
@@ -9,7 +9,7 @@
<% end %>
</p>
-<% form_for :incoming_message, :url => describe_state_url(:id => @info_request.id) do |f| %>
+<%= form_for :incoming_message, :url => describe_state_url(:id => @info_request.id) do |f| %>
<p>
<label class="form_label" for="incoming_message_message">Please tell us more:</label>
diff --git a/app/views/request/details.rhtml b/app/views/request/details.html.erb
index 3cb2f5afe..3cb2f5afe 100644
--- a/app/views/request/details.rhtml
+++ b/app/views/request/details.html.erb
diff --git a/app/views/request/followup_bad.rhtml b/app/views/request/followup_bad.html.erb
index ea2400c5d..ea2400c5d 100644
--- a/app/views/request/followup_bad.rhtml
+++ b/app/views/request/followup_bad.html.erb
diff --git a/app/views/request/followup_preview.rhtml b/app/views/request/followup_preview.html.erb
index 50c64138f..55afc0245 100644
--- a/app/views/request/followup_preview.rhtml
+++ b/app/views/request/followup_preview.html.erb
@@ -2,7 +2,7 @@
<div id="followup">
-<% form_for(:outgoing_message, @outgoing_message, :html => { :id => 'preview_form' }, :url => (@incoming_message.nil? ? show_response_no_followup_url(:id => @info_request.id) : show_response_url(:id => @info_request.id, :incoming_message_id => @incoming_message.id)) + "#followup" ) do |o| %>
+<%= form_for(@outgoing_message, :html => { :id => 'preview_form' }, :url => (@incoming_message.nil? ? show_response_no_followup_url(:id => @info_request.id) : show_response_url(:id => @info_request.id, :incoming_message_id => @incoming_message.id)) + "#followup" ) do |o| %>
<% if @internal_review %>
<h1><%= _('Now preview your message asking for an internal review') %></h1>
@@ -15,7 +15,7 @@
<li><%= _('Your message will appear in <strong>search engines</strong>') %></li>
</ul>
- <% fields_for :outgoing_message do |o| %>
+ <%= fields_for :outgoing_message do |o| %>
<div class="correspondence" id="outgoing-0">
<p class="preview_subject">
diff --git a/app/views/request/hidden.rhtml b/app/views/request/hidden.html.erb
index 4190fb47c..f2f76a817 100644
--- a/app/views/request/hidden.rhtml
+++ b/app/views/request/hidden.html.erb
@@ -12,7 +12,7 @@ various reasons why we might have done this, sorry we can\'t be more specific he
</p>
<% if @info_request.prominence == 'requester_only' %>
<p>
- <%= _('If you are the requester, then you may <a href="{{url}}">sign in</a> to view the request.', :url => signin_url(:r => request.request_uri).html_safe) %>
+ <%= _('If you are the requester, then you may <a href="{{url}}">sign in</a> to view the request.', :url => signin_url(:r => request.fullpath).html_safe) %>
</p>
<% end %>
diff --git a/app/views/request/list.rhtml b/app/views/request/list.html.erb
index 062b77c3e..062b77c3e 100644
--- a/app/views/request/list.rhtml
+++ b/app/views/request/list.html.erb
diff --git a/app/views/request/new.rhtml b/app/views/request/new.html.erb
index 0790bd0ac..8b7d38ac0 100644
--- a/app/views/request/new.rhtml
+++ b/app/views/request/new.html.erb
@@ -33,7 +33,7 @@
<%= foi_error_messages_for :info_request, :outgoing_message %>
- <% form_for(:info_request, @info_request, :html => { :id => 'write_form' } ) do |f| %>
+ <%= form_for(@info_request, :url => new_request_path, :html => { :id => 'write_form' } ) do |f| %>
<div id="request_header">
<div id="request_header_body">
@@ -103,7 +103,7 @@
</div>
<div id="request_form">
- <% fields_for :outgoing_message do |o| %>
+ <%= fields_for :outgoing_message do |o| %>
<p>
<label class="form_label" for="outgoing_message_body"><%= _('Your request:') %></label>
<%= o.text_area :body, :rows => 20, :cols => 60 %>
diff --git a/app/views/request/new_bad_contact.rhtml b/app/views/request/new_bad_contact.html.erb
index 56f3f4168..56f3f4168 100644
--- a/app/views/request/new_bad_contact.rhtml
+++ b/app/views/request/new_bad_contact.html.erb
diff --git a/app/views/request/new_please_describe.rhtml b/app/views/request/new_please_describe.html.erb
index 808fbb206..5a67d01f9 100644
--- a/app/views/request/new_please_describe.rhtml
+++ b/app/views/request/new_please_describe.html.erb
@@ -13,7 +13,7 @@ if they are successful yet or not.') %>
</ul>
<p>
- <%= _('When you\'re done, <strong>come back here</strong>, <a href="{{url}}">reload this page</a> and file your new request.', :url => request.request_uri.html_safe) %>
+ <%= _('When you\'re done, <strong>come back here</strong>, <a href="{{url}}">reload this page</a> and file your new request.', :url => request.fullpath.html_safe) %>
</p>
<p>
diff --git a/app/views/request/preview.rhtml b/app/views/request/preview.html.erb
index 424277b50..243dc90a9 100644
--- a/app/views/request/preview.rhtml
+++ b/app/views/request/preview.html.erb
@@ -1,6 +1,6 @@
<% @title = "Preview new " + h(@info_request.law_used_short) + " request to '" + h(@info_request.public_body.name) + "'" %>
-<% form_for(:info_request, @info_request, :html => { :id => 'preview_form' } ) do |f| %>
+<%= form_for(@info_request, :url => new_request_path, :html => { :id => 'preview_form' } ) do |f| %>
<h1><%= _('3. Now check your request') %></h1>
<ul>
@@ -10,7 +10,7 @@
</li>
</ul>
- <% fields_for :outgoing_message do |o| %>
+ <%= fields_for :outgoing_message do |o| %>
<div class="correspondence" id="outgoing-0">
<p class="preview_subject">
@@ -45,4 +45,4 @@
<p><strong><%= _('Tags:') %></strong> <%=h @info_request.tag_string %></p>
<% end %>
-<% end %> \ No newline at end of file
+<% end %>
diff --git a/app/views/request/select_authority.rhtml b/app/views/request/select_authority.html.erb
index 737541872..c01e2776f 100644
--- a/app/views/request/select_authority.rhtml
+++ b/app/views/request/select_authority.html.erb
@@ -30,7 +30,7 @@
<h1 style="clear: left"><%= _('1. Select an authority') %></h1>
<div id="authority_selection">
- <% form_tag({:controller => "request", :action => "select_authority"}, {:id => "search_form", :method => "get"}) do %>
+ <%= form_tag({:controller => "request", :action => "select_authority"}, {:id => "search_form", :method => "get"}) do %>
<div>
<p>
<%= _('First, type in the <strong>name of the UK public authority</strong> you\'d
diff --git a/app/views/request/show.rhtml b/app/views/request/show.html.erb
index a33bc7037..4b0663f76 100644
--- a/app/views/request/show.rhtml
+++ b/app/views/request/show.html.erb
@@ -106,7 +106,7 @@
<%= _('The request is <strong>waiting for clarification</strong>.') %>
<% if !@info_request.is_external? %>
<%= _('If you are {{user_link}}, please',:user_link=>user_link_for_request(@info_request)) %>
- <%= link_to _("sign in"), signin_path(:r => request.request_uri) %> <%= _('to send a follow up message.') %>
+ <%= link_to _("sign in"), signin_path(:r => request.fullpath) %> <%= _('to send a follow up message.') %>
<% end %>
<% end %>
<% elsif @status == 'gone_postal' %>
diff --git a/app/views/request/show_response.rhtml b/app/views/request/show_response.html.erb
index a61359679..a61359679 100644
--- a/app/views/request/show_response.rhtml
+++ b/app/views/request/show_response.html.erb
diff --git a/app/views/request/similar.rhtml b/app/views/request/similar.html.erb
index 0d53f6919..0d53f6919 100644
--- a/app/views/request/similar.rhtml
+++ b/app/views/request/similar.html.erb
diff --git a/app/views/request/simple_correspondence.rhtml b/app/views/request/simple_correspondence.html.erb
index 0da9ef172..461fa3912 100644
--- a/app/views/request/simple_correspondence.rhtml
+++ b/app/views/request/simple_correspondence.html.erb
@@ -1,4 +1,4 @@
-<%= _('This is a plain-text version of the Freedom of Information request "{{request_title}}". The latest, full version is available online at {{full_url}}', :request_title => @info_request.title, :full_url => "http://#{Configuration::domain}#{show_request_path(:url_title=>@info_request.url_title)}") %>.
+<%= _('This is a plain-text version of the Freedom of Information request "{{request_title}}". The latest, full version is available online at {{full_url}}', :request_title => @info_request.title, :full_url => "http://#{AlaveteliConfiguration::domain}#{show_request_path(:url_title=>@info_request.url_title)}") %>.
<% for info_request_event in @info_request_events %>
<%
diff --git a/app/views/request/upload_response.rhtml b/app/views/request/upload_response.html.erb
index f9f818e86..f5fd6f000 100644
--- a/app/views/request/upload_response.rhtml
+++ b/app/views/request/upload_response.html.erb
@@ -30,7 +30,7 @@
<p><%= raw(_('Enter your response below. You may attach one file (use email, or
<a href="{{url}}">contact us</a> if you need more).', :url => help_contact_path.html_safe)) %></p>
- <% form_tag '', :id => 'upload_response_form', :multipart => true do %>
+ <%= form_tag '', :id => 'upload_response_form', :multipart => true do %>
<p>
<label class="form_label" for="body"><% _('Response:')%></label>
<%= text_area_tag :body, "", :rows => 10, :cols => 55 %>
diff --git a/app/views/request_game/play.rhtml b/app/views/request_game/play.html.erb
index d5aa0d00e..d5aa0d00e 100644
--- a/app/views/request_game/play.rhtml
+++ b/app/views/request_game/play.html.erb
diff --git a/app/views/request_mailer/comment_on_alert.rhtml b/app/views/request_mailer/comment_on_alert.text.erb
index 691e6f9bb..691e6f9bb 100644
--- a/app/views/request_mailer/comment_on_alert.rhtml
+++ b/app/views/request_mailer/comment_on_alert.text.erb
diff --git a/app/views/request_mailer/comment_on_alert_plural.rhtml b/app/views/request_mailer/comment_on_alert_plural.text.erb
index a495b8e08..a495b8e08 100644
--- a/app/views/request_mailer/comment_on_alert_plural.rhtml
+++ b/app/views/request_mailer/comment_on_alert_plural.text.erb
diff --git a/app/views/request_mailer/external_response.rhtml b/app/views/request_mailer/external_response.rhtml
deleted file mode 100644
index 896054a43..000000000
--- a/app/views/request_mailer/external_response.rhtml
+++ /dev/null
@@ -1 +0,0 @@
-<%= raw @body %>
diff --git a/app/views/request_mailer/external_response.text.erb b/app/views/request_mailer/external_response.text.erb
new file mode 100644
index 000000000..fab256adf
--- /dev/null
+++ b/app/views/request_mailer/external_response.text.erb
@@ -0,0 +1 @@
+<%= @message_body %>
diff --git a/app/views/request_mailer/fake_response.rhtml b/app/views/request_mailer/fake_response.rhtml
deleted file mode 100644
index 896054a43..000000000
--- a/app/views/request_mailer/fake_response.rhtml
+++ /dev/null
@@ -1 +0,0 @@
-<%= raw @body %>
diff --git a/app/views/request_mailer/fake_response.text.erb b/app/views/request_mailer/fake_response.text.erb
new file mode 100644
index 000000000..fab256adf
--- /dev/null
+++ b/app/views/request_mailer/fake_response.text.erb
@@ -0,0 +1 @@
+<%= @message_body %>
diff --git a/app/views/request_mailer/new_response.rhtml b/app/views/request_mailer/new_response.text.erb
index 672212f20..672212f20 100644
--- a/app/views/request_mailer/new_response.rhtml
+++ b/app/views/request_mailer/new_response.text.erb
diff --git a/app/views/request_mailer/new_response_reminder_alert.rhtml b/app/views/request_mailer/new_response_reminder_alert.text.erb
index c196dafe6..c196dafe6 100644
--- a/app/views/request_mailer/new_response_reminder_alert.rhtml
+++ b/app/views/request_mailer/new_response_reminder_alert.text.erb
diff --git a/app/views/request_mailer/not_clarified_alert.rhtml b/app/views/request_mailer/not_clarified_alert.text.erb
index 2408452b3..2408452b3 100644
--- a/app/views/request_mailer/not_clarified_alert.rhtml
+++ b/app/views/request_mailer/not_clarified_alert.text.erb
diff --git a/app/views/request_mailer/old_unclassified_updated.rhtml b/app/views/request_mailer/old_unclassified_updated.text.erb
index 5b8534832..5b8534832 100644
--- a/app/views/request_mailer/old_unclassified_updated.rhtml
+++ b/app/views/request_mailer/old_unclassified_updated.text.erb
diff --git a/app/views/request_mailer/overdue_alert.rhtml b/app/views/request_mailer/overdue_alert.text.erb
index 249bf6bb8..249bf6bb8 100644
--- a/app/views/request_mailer/overdue_alert.rhtml
+++ b/app/views/request_mailer/overdue_alert.text.erb
diff --git a/app/views/request_mailer/requires_admin.rhtml b/app/views/request_mailer/requires_admin.text.erb
index b2e58295e..b2e58295e 100644
--- a/app/views/request_mailer/requires_admin.rhtml
+++ b/app/views/request_mailer/requires_admin.text.erb
diff --git a/app/views/request_mailer/stopped_responses.rhtml b/app/views/request_mailer/stopped_responses.text.erb
index 9cd156860..9cd156860 100644
--- a/app/views/request_mailer/stopped_responses.rhtml
+++ b/app/views/request_mailer/stopped_responses.text.erb
diff --git a/app/views/request_mailer/very_overdue_alert.rhtml b/app/views/request_mailer/very_overdue_alert.text.erb
index 80597473c..80597473c 100644
--- a/app/views/request_mailer/very_overdue_alert.rhtml
+++ b/app/views/request_mailer/very_overdue_alert.text.erb
diff --git a/app/views/track/_tracking_links.rhtml b/app/views/track/_tracking_links.html.erb
index d89c0e4a9..a16dbc78f 100644
--- a/app/views/track/_tracking_links.rhtml
+++ b/app/views/track/_tracking_links.html.erb
@@ -9,7 +9,7 @@
<% elsif existing_track %>
<p><%= track_thing.params[:verb_on_page_already] %></p>
<div class="feed_link feed_link_<%=location%>">
- <%= link_to _("Unsubscribe"), {:controller => 'track', :action => 'update', :track_id => existing_track.id, :track_medium => "delete", :r => request.request_uri}, :class => "link_button_green" %>
+ <%= link_to _("Unsubscribe"), {:controller => 'track', :action => 'update', :track_id => existing_track.id, :track_medium => "delete", :r => request.fullpath}, :class => "link_button_green" %>
</div>
<% elsif track_thing %>
<div class="feed_link feed_link_<%=location%>">
diff --git a/app/views/track/atom_feed.atom.erb b/app/views/track/atom_feed.atom.erb
index 23c932308..a12b9eff0 100644
--- a/app/views/track/atom_feed.atom.erb
+++ b/app/views/track/atom_feed.atom.erb
@@ -9,7 +9,7 @@
# Get the HTML content from the same partial template as website search does
content = ''
if result[:model].class.to_s == 'InfoRequestEvent'
- content += render :partial => 'request/request_listing_via_event', :locals => { :event => result[:model], :info_request => result[:model].info_request }
+ content += render :partial => 'request/request_listing_via_event.html', :locals => { :event => result[:model], :info_request => result[:model].info_request }
else
content = "<p><strong>Unknown search result type " + result[:model].class.to_s + "</strong></p>"
end
diff --git a/app/views/track_mailer/event_digest.rhtml b/app/views/track_mailer/event_digest.text.erb
index 8dbc7fe06..8dbc7fe06 100644
--- a/app/views/track_mailer/event_digest.rhtml
+++ b/app/views/track_mailer/event_digest.text.erb
diff --git a/app/views/user/_change_receive_email.rhtml b/app/views/user/_change_receive_email.html.erb
index 83e5d8601..12824f711 100644
--- a/app/views/user/_change_receive_email.rhtml
+++ b/app/views/user/_change_receive_email.html.erb
@@ -1,4 +1,4 @@
-<% form_tag(:controller=>"user", :action=>"set_receive_email_alerts") do %>
+<%= form_tag(:controller=>"user", :action=>"set_receive_email_alerts") do %>
<div>
<% if @user.receive_email_alerts %>
<%= _('You are currently receiving notification of new activity on your wall by email.', :wall_url => show_user_wall_path) %><br><br>
diff --git a/app/views/user/_show_user_info.rhtml b/app/views/user/_show_user_info.html.erb
index 305300236..305300236 100644
--- a/app/views/user/_show_user_info.rhtml
+++ b/app/views/user/_show_user_info.html.erb
diff --git a/app/views/user/_signin.rhtml b/app/views/user/_signin.html.erb
index 7db07e4b4..afc55d249 100644
--- a/app/views/user/_signin.rhtml
+++ b/app/views/user/_signin.html.erb
@@ -1,6 +1,6 @@
<div id="signin">
-<% form_tag({:action => "signin"}, {:id => "signin_form"}) do %>
+<%= form_tag({:action => "signin"}, {:id => "signin_form"}) do %>
<%= foi_error_messages_for :user_signin %>
<!--<% if not sign_in_as_existing_user %>
diff --git a/app/views/user/_signup.rhtml b/app/views/user/_signup.html.erb
index eba3b8522..ec6541881 100644
--- a/app/views/user/_signup.rhtml
+++ b/app/views/user/_signup.html.erb
@@ -1,6 +1,6 @@
<div id="signup">
-<% form_tag({:action => "signup"}, {:id => "signup_form"}) do %>
+<%= form_tag({:action => "signup"}, {:id => "signup_form"}) do %>
<%= foi_error_messages_for :user_signup %>
<!--<h2><%= _('If you\'re new to {{site_name}}', :site_name=>site_name)%></h2>-->
diff --git a/app/views/user/_user_listing_single.rhtml b/app/views/user/_user_listing_single.html.erb
index ed1b95718..ed1b95718 100644
--- a/app/views/user/_user_listing_single.rhtml
+++ b/app/views/user/_user_listing_single.html.erb
diff --git a/app/views/user/bad_token.rhtml b/app/views/user/bad_token.html.erb
index 538bc5606..538bc5606 100644
--- a/app/views/user/bad_token.rhtml
+++ b/app/views/user/bad_token.html.erb
diff --git a/app/views/user/banned.rhtml b/app/views/user/banned.html.erb
index 475c10977..475c10977 100644
--- a/app/views/user/banned.rhtml
+++ b/app/views/user/banned.html.erb
diff --git a/app/views/user/confirm.rhtml b/app/views/user/confirm.html.erb
index bc70a1f36..bc70a1f36 100644
--- a/app/views/user/confirm.rhtml
+++ b/app/views/user/confirm.html.erb
diff --git a/app/views/user/contact.rhtml b/app/views/user/contact.html.erb
index 333b72334..6d23dd1ed 100644
--- a/app/views/user/contact.rhtml
+++ b/app/views/user/contact.html.erb
@@ -6,7 +6,7 @@
<%= foi_error_messages_for :contact %>
-<% form_for :contact do |f| %>
+<%= form_for :contact do |f| %>
<div class="form_note">
<h1><%= _("Contact {{recipient}}", :recipient => h(@recipient_user.name)) %></h1>
diff --git a/app/views/user/no_cookies.rhtml b/app/views/user/no_cookies.html.erb
index 0a4a39b1b..0a4a39b1b 100644
--- a/app/views/user/no_cookies.rhtml
+++ b/app/views/user/no_cookies.html.erb
diff --git a/app/views/user/rate_limited.rhtml b/app/views/user/rate_limited.html.erb
index d52deebab..54a4e0461 100644
--- a/app/views/user/rate_limited.rhtml
+++ b/app/views/user/rate_limited.html.erb
@@ -2,7 +2,7 @@
<h1><%=@title%></h1>
-<p><%= _("You have hit the rate limit on new requests. Users are ordinarily limited to {{max_requests_per_user_per_day}} requests in any rolling 24-hour period. You will be able to make another request in {{can_make_another_request}}.", :max_requests_per_user_per_day => Configuration::max_requests_per_user_per_day, :can_make_another_request => distance_of_time_in_words(Time.now, @next_request_permitted_at))%></p>
+<p><%= _("You have hit the rate limit on new requests. Users are ordinarily limited to {{max_requests_per_user_per_day}} requests in any rolling 24-hour period. You will be able to make another request in {{can_make_another_request}}.", :max_requests_per_user_per_day => AlaveteliConfiguration::max_requests_per_user_per_day, :can_make_another_request => distance_of_time_in_words(Time.now, @next_request_permitted_at))%></p>
<p><%= _("There is a limit on the number of requests you can make in a day, because we don’t want public authorities to be bombarded with large numbers of inappropriate requests. If you feel you have a good reason to ask for the limit to be lifted in your case, please <a href='{{help_contact_path}}'>get in touch</a>.", :help_contact_path => help_contact_path) %></p>
diff --git a/app/views/user/river.rhtml b/app/views/user/river.html.erb
index 9618e0aa8..9618e0aa8 100644
--- a/app/views/user/river.rhtml
+++ b/app/views/user/river.html.erb
diff --git a/app/views/user/set_crop_profile_photo.rhtml b/app/views/user/set_crop_profile_photo.html.erb
index eed0304d2..0a22d36dc 100644
--- a/app/views/user/set_crop_profile_photo.rhtml
+++ b/app/views/user/set_crop_profile_photo.html.erb
@@ -9,7 +9,7 @@
<div id="set_crop_profile_photo">
-<% form_tag 'set_photo', :id => 'set_crop_profile_photo_form', :multipart => true do %>
+<%= form_tag 'set_photo', :id => 'set_crop_profile_photo_form', :multipart => true do %>
<table>
<tr>
@@ -37,7 +37,7 @@
<p>
<%= hidden_field_tag 'submitted_crop_profile_photo', 1 %>
- <%= submit_tag _("Done") + " &gt;&gt;" %>
+ <%= submit_tag _("Done &gt;&gt;") %>
</p>
<% end %>
diff --git a/app/views/user/set_draft_profile_photo.rhtml b/app/views/user/set_draft_profile_photo.html.erb
index 757498249..b4bdd80f3 100644
--- a/app/views/user/set_draft_profile_photo.rhtml
+++ b/app/views/user/set_draft_profile_photo.html.erb
@@ -8,7 +8,7 @@
<div id="set_draft_profile_photo">
-<% form_tag 'set_photo', :id => 'set_draft_profile_photo_form', :multipart => true do %>
+<%= form_tag 'set_photo', :id => 'set_draft_profile_photo_form', :multipart => true do %>
<p>
<label class="form_label" for="file_1"><%= _('Photo of you:')%></label>
<%= file_field_tag :file, :size => 35, :id => 'file_1' %>
@@ -45,7 +45,7 @@
<h2><%= _('OR remove the existing photo')%></h2>
- <% form_tag 'clear_photo', :id => 'clear_profile_photo_form', :multipart => true do %>
+ <%= form_tag 'clear_photo', :id => 'clear_profile_photo_form', :multipart => true do %>
<%= submit_tag _("Clear photo") %>
<% end %>
diff --git a/app/views/user/set_profile_about_me.rhtml b/app/views/user/set_profile_about_me.html.erb
index 4fe1047da..fb7de7e97 100644
--- a/app/views/user/set_profile_about_me.rhtml
+++ b/app/views/user/set_profile_about_me.html.erb
@@ -4,7 +4,7 @@
<%= foi_error_messages_for :about_me %>
-<% form_for :about_me do |f| %>
+<%= form_for :about_me do |f| %>
<div class="form_note">
<h1><%= _('Edit text about you')%></h1>
<p>
@@ -26,7 +26,7 @@
<%= _(' Include relevant links, such as to a campaign page, your blog or a
twitter account. They will be made clickable.
e.g.')%>
- <a href="https://twitter.com/<%= Configuration::twitter_username %>">https://twitter.com/<%= Configuration::twitter_username %></a>
+ <a href="https://twitter.com/<%= AlaveteliConfiguration::twitter_username %>">https://twitter.com/<%= AlaveteliConfiguration::twitter_username %></a>
</p>
</div>
diff --git a/app/views/user/show.rhtml b/app/views/user/show.html.erb
index c538426ce..c9862effe 100644
--- a/app/views/user/show.rhtml
+++ b/app/views/user/show.html.erb
@@ -97,7 +97,7 @@
<% if not @is_you %>
<p id="user_not_logged_in">
- <%= _('<a href="{{url}}">Sign in</a> to change password, subscriptions and more ({{user_name}} only)',:user_name=>h(@display_user.name), :url => signin_url(:r => request.request_uri).html_safe) %>
+ <%= _('<a href="{{url}}">Sign in</a> to change password, subscriptions and more ({{user_name}} only)',:user_name=>h(@display_user.name), :url => signin_url(:r => request.fullpath).html_safe) %>
</p>
<% end %>
</div>
@@ -107,7 +107,7 @@
<% if @show_requests %>
<div id="user_profile_search">
- <% form_tag(show_user_url, :method => "get", :id=>"search_form") do %>
+ <%= form_tag(show_user_url, :method => "get", :id=>"search_form") do %>
<div>
<%= text_field_tag(:user_query, params[:user_query], {:title => "type your search term here" }) %>
<% if @is_you %>
@@ -181,12 +181,12 @@
<p><%= _("You're not following anything.")%></p>
<% else %>
<% if @track_things_grouped.size == 1 %>
- <% form_tag({:controller => 'track', :action => 'delete_all_type'}, :class => "feed_form") do %>
+ <%= 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 %>
+ <%= hidden_field_tag 'r', request.fullpath %>
<% if @track_things.size > 1 %>
<%= submit_tag _('unsubscribe all') %>
<% end %>
@@ -195,12 +195,12 @@
<% 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 %>
+ <%= 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 %>
+ <%= hidden_field_tag 'r', request.fullpath %>
<% if track_things.size > 1 %>
<%= submit_tag _('unsubscribe all')%>
<% end %>
@@ -211,11 +211,11 @@
<ul>
<% for track_thing in track_things %>
<li>
- <% form_tag({:controller => 'track', :action => 'update', :track_id => track_thing.id}, :class => "feed_form") do %>
+ <%= 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 } %>
+ <%= hidden_field_tag 'r', request.fullpath, { :id => 'r_' + track_thing.id.to_s } %>
<%= submit_tag _('unsubscribe') %>
</div>
<% end %>
diff --git a/app/views/user/sign.rhtml b/app/views/user/sign.html.erb
index 5e8cced91..8291cdace 100644
--- a/app/views/user/sign.rhtml
+++ b/app/views/user/sign.html.erb
@@ -12,7 +12,7 @@
<% end %>
</p>
<% if @post_redirect.post_params["controller"] == "admin_general" %>
- <% unless Configuration::disable_emergency_user %>
+ <% unless AlaveteliConfiguration::disable_emergency_user %>
<p id="superuser_message">Don't have a superuser account yet? <%= link_to "Sign in as the emergency user", @post_redirect.uri + "?emergency=1" %></p>
<% end %>
<% end %>
diff --git a/app/views/user/signchangeemail.rhtml b/app/views/user/signchangeemail.html.erb
index 0f8b76bc5..7308179f4 100644
--- a/app/views/user/signchangeemail.rhtml
+++ b/app/views/user/signchangeemail.html.erb
@@ -4,7 +4,7 @@
<div id="change_email">
-<% form_tag({:action => "signchangeemail"}, {:id => "signchangeemail_form"}) do %>
+<%= form_tag({:action => "signchangeemail"}, {:id => "signchangeemail_form"}) do %>
<%= foi_error_messages_for :signchangeemail %>
<div class="form_note">
diff --git a/app/views/user/signchangeemail_confirm.rhtml b/app/views/user/signchangeemail_confirm.html.erb
index bfedbac2d..bfedbac2d 100644
--- a/app/views/user/signchangeemail_confirm.rhtml
+++ b/app/views/user/signchangeemail_confirm.html.erb
diff --git a/app/views/user/signchangepassword.rhtml b/app/views/user/signchangepassword.html.erb
index edb980b9f..51bcb466d 100644
--- a/app/views/user/signchangepassword.rhtml
+++ b/app/views/user/signchangepassword.html.erb
@@ -4,7 +4,7 @@
<div id="change_password">
-<% form_tag({:action => "signchangepassword"}, {:id => "signchangepassword_form"}) do %>
+<%= form_tag({:action => "signchangepassword"}, {:id => "signchangepassword_form"}) do %>
<%= foi_error_messages_for :user %>
<div class="form_note">
diff --git a/app/views/user/signchangepassword_confirm.rhtml b/app/views/user/signchangepassword_confirm.html.erb
index 63b6515cd..63b6515cd 100644
--- a/app/views/user/signchangepassword_confirm.rhtml
+++ b/app/views/user/signchangepassword_confirm.html.erb
diff --git a/app/views/user/signchangepassword_send_confirm.rhtml b/app/views/user/signchangepassword_send_confirm.html.erb
index 84ee28f07..850237c34 100644
--- a/app/views/user/signchangepassword_send_confirm.rhtml
+++ b/app/views/user/signchangepassword_send_confirm.html.erb
@@ -2,7 +2,7 @@
<div id="change_password">
-<% form_tag({:action => "signchangepassword"}, {:id => "signchangepassword_form"}) do %>
+<%= form_tag({:action => "signchangepassword"}, {:id => "signchangepassword_form"}) do %>
<%= foi_error_messages_for :signchangepassword %>
<div class="form_note">
diff --git a/app/views/user/signin_successful.rhtml b/app/views/user/signin_successful.html.erb
index 675701d74..675701d74 100644
--- a/app/views/user/signin_successful.rhtml
+++ b/app/views/user/signin_successful.html.erb
diff --git a/app/views/user/wall.rhtml b/app/views/user/wall.html.erb
index 190cc0a6d..190cc0a6d 100644
--- a/app/views/user/wall.rhtml
+++ b/app/views/user/wall.html.erb
diff --git a/app/views/user/wrong_user.rhtml b/app/views/user/wrong_user.html.erb
index 30256a639..30256a639 100644
--- a/app/views/user/wrong_user.rhtml
+++ b/app/views/user/wrong_user.html.erb
diff --git a/app/views/user/wrong_user_unknown_email.rhtml b/app/views/user/wrong_user_unknown_email.html.erb
index c1967fc1f..c1967fc1f 100644
--- a/app/views/user/wrong_user_unknown_email.rhtml
+++ b/app/views/user/wrong_user_unknown_email.html.erb
diff --git a/app/views/user_mailer/already_registered.rhtml b/app/views/user_mailer/already_registered.text.erb
index 32c2c7e63..32c2c7e63 100644
--- a/app/views/user_mailer/already_registered.rhtml
+++ b/app/views/user_mailer/already_registered.text.erb
diff --git a/app/views/user_mailer/changeemail_already_used.rhtml b/app/views/user_mailer/changeemail_already_used.text.erb
index 1d74dda35..1d74dda35 100644
--- a/app/views/user_mailer/changeemail_already_used.rhtml
+++ b/app/views/user_mailer/changeemail_already_used.text.erb
diff --git a/app/views/user_mailer/changeemail_confirm.rhtml b/app/views/user_mailer/changeemail_confirm.text.erb
index c73e9486b..c73e9486b 100644
--- a/app/views/user_mailer/changeemail_confirm.rhtml
+++ b/app/views/user_mailer/changeemail_confirm.text.erb
diff --git a/app/views/user_mailer/confirm_login.rhtml b/app/views/user_mailer/confirm_login.text.erb
index fa86dc2b1..fa86dc2b1 100644
--- a/app/views/user_mailer/confirm_login.rhtml
+++ b/app/views/user_mailer/confirm_login.text.erb
diff --git a/commonlib b/commonlib
-Subproject f4b4adfc6dea2434e52633c4923ef6e2aee3f86
+Subproject 3f57d96fe765242c3a7082d386b5763b2e1ca73
diff --git a/config.ru b/config.ru
index 30b00bfa1..74748fd45 100644
--- a/config.ru
+++ b/config.ru
@@ -1,2 +1,4 @@
-require File.dirname(__FILE__) + '/config/environment'
-run ActionController::Dispatcher.new
+# This file is used by Rack-based servers to start the application.
+
+require ::File.expand_path('../config/environment', __FILE__)
+run Alaveteli::Application
diff --git a/config/application.rb b/config/application.rb
new file mode 100644
index 000000000..92fd30685
--- /dev/null
+++ b/config/application.rb
@@ -0,0 +1,75 @@
+require File.expand_path('../boot', __FILE__)
+
+require 'rails/all'
+
+require File.dirname(__FILE__) + '/../lib/configuration'
+
+# If you have a Gemfile, require the gems listed there, including any gems
+# you've limited to :test, :development, or :production.
+Bundler.require(:default, Rails.env) if defined?(Bundler)
+
+module Alaveteli
+ class Application < Rails::Application
+ # Settings in config/environments/* take precedence over those specified here.
+ # Application configuration should go into files in config/initializers
+ # -- all .rb files in that directory are automatically loaded.
+
+ # Custom directories with classes and modules you want to be autoloadable.
+ # config.autoload_paths += %W(#{config.root}/extras)
+
+ # Only load the plugins named here, in the order given (default is alphabetical).
+ # :all can be used as a placeholder for all plugins not explicitly named.
+ # config.plugins = [ :exception_notification, :ssl_requirement, :all ]
+
+ # Activate observers that should always be running.
+ # config.active_record.observers = :cacher, :garbage_collector, :forum_observer
+
+ # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
+ # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
+ # config.time_zone = 'Central Time (US & Canada)'
+
+ # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
+ # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
+ # config.i18n.default_locale = :de
+
+ # JavaScript files you want as :defaults (application.js is always included).
+ # config.action_view.javascript_expansions[:defaults] = %w(jquery rails)
+
+ # Configure the default encoding used in templates for Ruby 1.9.
+ config.encoding = "utf-8"
+
+ # Configure sensitive parameters which will be filtered from the log file.
+ config.filter_parameters += [:password]
+
+ # Use SQL instead of Active Record's schema dumper when creating the test database.
+ # This is necessary if your schema can't be completely dumped by the schema dumper,
+ # like if you have constraints or database-specific column types
+ config.active_record.schema_format = :sql
+
+ # Make Active Record use UTC-base instead of local time
+ config.active_record.default_timezone = :utc
+
+ # This is the timezone that times and dates are displayed in
+ # Note that having set a zone, the Active Record
+ # time_zone_aware_attributes flag is on, so times from models
+ # will be in this time zone
+ config.time_zone = ::AlaveteliConfiguration::time_zone
+
+ config.after_initialize do |app|
+ require 'routing_filters.rb'
+ # Add a catch-all route to force routing errors to be handled by the application,
+ # rather than by middleware.
+ app.routes.append{ match '*path', :to => 'general#not_found' }
+ end
+
+ config.autoload_paths << "#{Rails.root.to_s}/lib/mail_handler"
+
+ # See Rails::Configuration for more options
+ ENV['RECAPTCHA_PUBLIC_KEY'] = ::AlaveteliConfiguration::recaptcha_public_key
+ ENV['RECAPTCHA_PRIVATE_KEY'] = ::AlaveteliConfiguration::recaptcha_private_key
+
+ # Insert a bit of middleware code to prevent uneeded cookie setting.
+ require "#{Rails.root}/lib/whatdotheyknow/strip_empty_sessions"
+ config.middleware.insert_before ActionDispatch::Session::CookieStore, WhatDoTheyKnow::StripEmptySessions, :key => '_wdtk_cookie_session', :path => "/", :httponly => true
+ end
+end
diff --git a/config/boot.rb b/config/boot.rb
index 906a2bace..a810be358 100644
--- a/config/boot.rb
+++ b/config/boot.rb
@@ -1,135 +1,15 @@
-# Don't change this file!
-# Configure your app in config/environment.rb and config/environments/*.rb
+require 'rubygems'
-# Hmmm, that's a bit daft - 'production' needs setting not only in the web
-# server, it also needs setting in all the scripts, so a central place seems
-# better. Look for a config/rails_env file, and read stuff from there if
+# Set up gems listed in the Gemfile.
+ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
+
+require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE'])
+
+# TODO: Remove this. This is a hacky system for having a default environment.
+# It looks for a config/rails_env.rb file, and reads stuff from there if
# it exists. Put just a line like this in there:
# ENV['RAILS_ENV'] = 'production'
rails_env_file = File.expand_path(File.join(File.dirname(__FILE__), 'rails_env.rb'))
if File.exists?(rails_env_file)
require rails_env_file
end
-
-RAILS_ROOT = "#{File.dirname(__FILE__)}/.." unless defined?(RAILS_ROOT)
-
-module Rails
- class << self
- def boot!
- unless booted?
- preinitialize
- pick_boot.run
- end
- end
-
- def booted?
- defined? Rails::Initializer
- end
-
- def pick_boot
- (vendor_rails? ? VendorBoot : GemBoot).new
- end
-
- def vendor_rails?
- File.exist?("#{RAILS_ROOT}/vendor/rails/Rakefile")
- end
-
- def preinitialize
- load(preinitializer_path) if File.exist?(preinitializer_path)
- end
-
- def preinitializer_path
- "#{RAILS_ROOT}/config/preinitializer.rb"
- end
- end
-
- class Boot
- def run
- load_initializer
-
- Rails::Initializer.class_eval do
- def load_gems
- @bundler_loaded ||= Bundler.require :default, Rails.env
- end
- end
-
- Rails::Initializer.run(:set_load_path)
- end
- end
-
- class VendorBoot < Boot
- def load_initializer
- require "#{RAILS_ROOT}/vendor/rails/railties/lib/initializer"
- Rails::Initializer.run(:install_gem_spec_stubs)
- Rails::GemDependency.add_frozen_gem_path
- end
- end
-
- class GemBoot < Boot
- def load_initializer
- self.class.load_rubygems
- load_rails_gem
- require 'initializer'
- end
-
- def load_rails_gem
- if version = self.class.gem_version
- gem 'rails', version
- else
- gem 'rails'
- end
- rescue Gem::LoadError => load_error
- if load_error.message =~ /Could not find RubyGem rails/
- STDERR.puts %(Missing the Rails #{version} gem. Please `gem install -v=#{version} rails`, update your RAILS_GEM_VERSION setting in config/environment.rb for the Rails version you do have installed, or comment out RAILS_GEM_VERSION to use the latest version installed.)
- exit 1
- else
- raise
- end
- end
-
- class << self
- def rubygems_version
- Gem::RubyGemsVersion rescue nil
- end
-
- def gem_version
- if defined? RAILS_GEM_VERSION
- RAILS_GEM_VERSION
- elsif ENV.include?('RAILS_GEM_VERSION')
- ENV['RAILS_GEM_VERSION']
- else
- parse_gem_version(read_environment_rb)
- end
- end
-
- def load_rubygems
- min_version = '1.3.2'
- require 'rubygems'
-
- unless rubygems_version >= min_version
- $stderr.puts %Q(Rails requires RubyGems >= #{min_version} (you have #{rubygems_version}). Please `gem update --system` and try again.)
- exit 1
- end
-
- rescue LoadError
- $stderr.puts %Q(Rails requires RubyGems >= #{min_version}. Please install RubyGems and try again: http://rubygems.rubyforge.org)
- exit 1
- end
-
- def parse_gem_version(text)
- $1 if text =~ /^[^#]*RAILS_GEM_VERSION\s*=\s*["']([!~<>=]*\s*[\d.]+)["']/
- end
-
- private
- def read_environment_rb
- File.read("#{RAILS_ROOT}/config/environment.rb")
- end
- end
- end
-end
-
-
-
-# All that for this:
-Rails.boot!
-
diff --git a/config/crontab.ugly b/config/crontab.ugly
index ef3455113..d33450df4 100644
--- a/config/crontab.ugly
+++ b/config/crontab.ugly
@@ -2,7 +2,7 @@
# Timed tasks for FOI site. Template file.
#
# Copyright (c) 2008 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org. WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org. WWW: http://www.mysociety.org/
PATH=/usr/local/bin:/usr/bin:/bin
MAILTO=cron-!!(*= $site *)!!@mysociety.org
diff --git a/config/database.yml-example b/config/database.yml-example
index b1597e6fe..e48577f23 100644
--- a/config/database.yml-example
+++ b/config/database.yml-example
@@ -19,6 +19,8 @@ test:
password: <password>
host: localhost
port: 5432
+# Uncomment the following if the user is not a postgres superuser
+# constraint_disabling: false
production:
adapter: postgresql
diff --git a/config/deploy.yml.example b/config/deploy.yml.example
index aea045dff..61931e50e 100644
--- a/config/deploy.yml.example
+++ b/config/deploy.yml.example
@@ -1,12 +1,12 @@
# Site-specific deployment configuration lives in this file
production:
- repository: git://github.com:mysociety/alaveteli.git
+ repository: git://github.com/mysociety/alaveteli.git
branch: master
server: www.example.com
user: deploy
deploy_to: /srv/www/alaveteli_production
staging:
- repository: git://github.com:mysociety/alaveteli.git
+ repository: git://github.com/mysociety/alaveteli.git
branch: develop
server: test.example.com
user: deploy
diff --git a/config/environment.rb b/config/environment.rb
index da4bd984a..196680b23 100644
--- a/config/environment.rb
+++ b/config/environment.rb
@@ -1,154 +1,5 @@
-# Be sure to restart your web server when you modify this file.
-if RUBY_VERSION.to_f >= 1.9
- # the default encoding for IO is utf-8, and we use utf-8 internally
- Encoding.default_external = Encoding.default_internal = Encoding::UTF_8
- # Suppress warning messages and require inflector to avoid iconv deprecation message
- # "iconv will be deprecated in the future, use String#encode instead." when loading
- # it as part of rails
- original_verbose, $VERBOSE = $VERBOSE, nil
- require 'active_support/inflector'
- # Activate warning messages again.
- $VERBOSE = original_verbose
- require 'yaml'
- YAML::ENGINE.yamler = "syck"
-end
+# Load the rails application
+require File.expand_path('../application', __FILE__)
-# Uncomment below to force Rails into production mode when
-# you don't control web/app server and can't set it the proper way
-# ENV['RAILS_ENV'] ||= 'production'
-
-# Specifies gem version of Rails to use when vendor/rails is not present
-RAILS_GEM_VERSION = '2.3.18' unless defined? RAILS_GEM_VERSION
-
-# Bootstrap the Rails environment, frameworks, and default configuration
-require File.join(File.dirname(__FILE__), 'boot')
-
-# MySociety specific helper functions
-$:.push(File.join(File.dirname(__FILE__), '../commonlib/rblib'))
-# ... if these fail to include, you need the commonlib submodule from git
-# (type "git submodule update --init" in the whatdotheyknow directory)
-
-$:.unshift(File.join(File.dirname(__FILE__), '../vendor/plugins/globalize2/lib'))
-
-load "validate.rb"
-load "config.rb"
-load "format.rb"
-load "debug_helpers.rb"
-load "util.rb"
-# Patch Rails::GemDependency to cope with older versions of rubygems, e.g. in Debian Lenny
-# Restores override removed in https://github.com/rails/rails/commit/c20a4d18e36a13b5eea3155beba36bb582c0cc87
-# without effecting method behaviour
-# and adds fallback gem call removed in https://github.com/rails/rails/commit/4c3725723f15fab0a424cb1318b82b460714b72f
-require File.join(File.dirname(__FILE__), '../lib/old_rubygems_patch')
-require 'configuration'
-
-# Application version
-ALAVETELI_VERSION = '0.9'
-
-Rails::Initializer.run do |config|
- # Load intial mySociety config
- if ENV["RAILS_ENV"] == "test"
- MySociety::Config.set_file(File.join(config.root_path, 'config', 'test'), true)
- else
- MySociety::Config.set_file(File.join(config.root_path, 'config', 'general'), true)
- end
- MySociety::Config.load_default
-
- # Settings in config/environments/* take precedence over those specified here
-
- # Skip frameworks you're not going to use (only works if using vendor/rails)
- # config.frameworks -= [ :action_web_service, :action_mailer ]
-
- # Only load the plugins named here, by default all plugins in vendor/plugins are loaded
- # config.plugins = %W( exception_notification ssl_requirement )
-
- # Add additional load paths for your own custom dirs
- # config.load_paths += %W( #{Rails.root}/extras )
-
- # Force all environments to use the same logger level
- # (by default production uses :info, the others :debug)
- # TEMP: uncomment this to turn on logging in production environments
- # config.log_level = :debug
- #
- # Specify gems that this application depends on and have them installed with rake gems:install
- #GettextI18nRails.translations_are_html_safe = true
-
- # Use SQL instead of Active Record's schema dumper when creating the test database.
- # This is necessary if your schema can't be completely dumped by the schema dumper,
- # like if you have constraints or database-specific column types
- config.active_record.schema_format = :sql
-
- # Activate observers that should always be running
- # config.active_record.observers = :cacher, :garbage_collector
-
- # Make Active Record use UTC-base instead of local time
- config.active_record.default_timezone = :utc
-
- # This is the timezone that times and dates are displayed in
- # Note that having set a zone, the Active Record
- # time_zone_aware_attributes flag is on, so times from models
- # will be in this time zone
- config.time_zone = Configuration::time_zone
-
- config.after_initialize do
- require 'routing_filters.rb'
- end
-
- config.autoload_paths << "#{RAILS_ROOT}/lib/mail_handler"
-
- # See Rails::Configuration for more options
- ENV['RECAPTCHA_PUBLIC_KEY'] = Configuration::recaptcha_public_key
- ENV['RECAPTCHA_PRIVATE_KEY'] = Configuration::recaptcha_private_key
-end
-
-# Add new inflection rules using the following format
-# (all these examples are active by default):
-# Inflector.inflections do |inflect|
-# inflect.plural /^(ox)$/i, '\1en'
-# inflect.singular /^(ox)en/i, '\1'
-# inflect.irregular 'person', 'people'
-# inflect.uncountable %w( fish sheep )
-# end
-
-# Add new mime types for use in respond_to blocks:
-# Mime::Type.register "text/richtext", :rtf
-# Mime::Type.register "application/x-mobile", :mobile
-
-# Domain for URLs (so can work for scripts, not just web pages)
-ActionMailer::Base.default_url_options[:host] = Configuration::domain
-if Configuration::force_ssl
- ActionMailer::Base.default_url_options[:protocol] = "https"
-end
-
-# fallback locale and available locales
-available_locales = Configuration::available_locales.split(/ /)
-default_locale = Configuration::default_locale
-
-FastGettext.default_available_locales = available_locales
-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 'activesupport_cache_extensions.rb'
-require 'timezone_fixes.rb'
-require 'use_spans_for_errors.rb'
-require 'activerecord_errors_extensions.rb'
-require 'willpaginate_extension.rb'
-require 'sendmail_return_path.rb'
-require 'i18n_fixes.rb'
-require 'rack_quote_monkeypatch.rb'
-require 'world_foi_websites.rb'
-require 'alaveteli_external_command.rb'
-require 'quiet_opener.rb'
-require 'mail_handler'
-require "cookie_store_with_line_break_fix"
-
-if !Configuration.exception_notifications_from.blank? && !Configuration.exception_notifications_to.blank?
- ExceptionNotification::Notifier.sender_address = Configuration::exception_notifications_from
- ExceptionNotification::Notifier.exception_recipients = Configuration::exception_notifications_to
-end
+# Initialize the rails application
+Alaveteli::Application.initialize!
diff --git a/config/environments/development.rb b/config/environments/development.rb
index c43cdb049..54ab2977f 100644
--- a/config/environments/development.rb
+++ b/config/environments/development.rb
@@ -1,29 +1,30 @@
-# Settings specified here will take precedence over those in config/environment.rb
+Alaveteli::Application.configure do
+ # Settings specified here will take precedence over those in config/environment.rb
-config.log_level = :info
+ # In the development environment your application's code is reloaded on
+ # every request. This slows down response time but is perfect for development
+ # since you don't have to restart the webserver when you make code changes.
+ config.cache_classes = false
-# In the development environment your application's code is reloaded on
-# every request. This slows down response time but is perfect for development
-# since you don't have to restart the webserver when you make code changes.
-config.cache_classes = false
+ # Log error messages when you accidentally call methods on nil.
+ config.whiny_nils = true
-# Log error messages when you accidentally call methods on nil.
-config.whiny_nils = true
+ # Show full error reports and disable caching
+ config.consider_all_requests_local = true
+ config.action_controller.perform_caching = false
-# Show full error reports and disable caching
-config.action_controller.consider_all_requests_local = true
-config.action_controller.perform_caching = false
-config.action_view.debug_rjs = true
+ # Don't care if the mailer can't send
+ config.action_mailer.raise_delivery_errors = false
+ config.action_mailer.perform_deliveries = true
+ # Use mailcatcher in development
+ config.action_mailer.delivery_method = :smtp # so is queued, rather than giving immediate errors
+ config.action_mailer.smtp_settings = { :address => "localhost", :port => 1025 }
-# Don't care if the mailer can't send
-config.action_mailer.raise_delivery_errors = false
-config.action_mailer.perform_deliveries = true
-# Use mailcatcher in development
-config.action_mailer.delivery_method = :smtp # so is queued, rather than giving immediate errors
-config.action_mailer.smtp_settings = { :address => "localhost", :port => 1025 }
+ # Writes useful log files to debug memory leaks, of the sort where have
+ # unintentionally kept references to objects, especially strings.
+ # require 'memory_profiler'
+ # MemoryProfiler.start :string_debug => true, :delay => 10
-
-# Writes useful log files to debug memory leaks, of the sort where have
-# unintentionally kept references to objects, especially strings.
-# require 'memory_profiler'
-# MemoryProfiler.start :string_debug => true, :delay => 10
+ # Print deprecation notices to the Rails logger
+ config.active_support.deprecation = :log
+end
diff --git a/config/environments/production.rb b/config/environments/production.rb
index 097944196..0c1929366 100644
--- a/config/environments/production.rb
+++ b/config/environments/production.rb
@@ -1,26 +1,34 @@
-# Settings specified here will take precedence over those in config/environment.rb
+Alaveteli::Application.configure do
+ # Settings specified here will take precedence over those in config/environment.rb
-# The production environment is meant for finished, "live" apps.
-# Code is not reloaded between requests
-config.cache_classes = true
+ # The production environment is meant for finished, "live" apps.
+ # Code is not reloaded between requests
+ config.cache_classes = true
-# Use a different logger for distributed setups
-# config.logger = SyslogLogger.new
+ # Use a different logger for distributed setups
+ # config.logger = SyslogLogger.new
-# Full error reports are disabled and caching is turned on
-config.action_controller.consider_all_requests_local = false
-config.action_controller.perform_caching = true
+ # Full error reports are disabled and caching is turned on
+ config.consider_all_requests_local = false
+ config.action_controller.perform_caching = true
-# Enable serving of images, stylesheets, and javascripts from an asset server
-# config.action_controller.asset_host = "http://assets.example.com"
+ # Enable serving of images, stylesheets, and javascripts from an asset server
+ # config.action_controller.asset_host = "http://assets.example.com"
-# Disable delivery errors, bad email addresses will be ignored
-# config.action_mailer.raise_delivery_errors = false
-config.action_mailer.delivery_method = :sendmail # so is queued, rather than giving immediate errors
+ # Disable delivery errors, bad email addresses will be ignored
+ # config.action_mailer.raise_delivery_errors = false
+ config.action_mailer.delivery_method = :sendmail # so is queued, rather than giving immediate errors
-require 'rack/ssl'
-if ::Configuration::force_ssl
- config.middleware.insert_after ActionController::Failsafe, ::Rack::SSL
- # For Rails 3.x this will need to change to
- #config.middleware.insert_before ActionDispatch::Cookies, ::Rack::SSL
+ config.active_support.deprecation = :notify
+
+ if !AlaveteliConfiguration.exception_notifications_from.blank? && !AlaveteliConfiguration.exception_notifications_to.blank?
+ middleware.use ExceptionNotifier,
+ :sender_address => AlaveteliConfiguration::exception_notifications_from,
+ :exception_recipients => AlaveteliConfiguration::exception_notifications_to
+ end
+
+ require 'rack/ssl'
+ if AlaveteliConfiguration::force_ssl
+ config.middleware.insert_before ActionDispatch::Cookies, ::Rack::SSL
+ end
end
diff --git a/config/environments/staging.rb b/config/environments/staging.rb
index 84a8f5965..0bb0db71a 100644
--- a/config/environments/staging.rb
+++ b/config/environments/staging.rb
@@ -1,19 +1,21 @@
-# Settings specified here will take precedence over those in config/environment.rb
+Alaveteli::Application.configure do
+ # Settings specified here will take precedence over those in config/environment.rb
-# The production environment is meant for finished, "live" apps.
-# Code is not reloaded between requests
-config.cache_classes = true
+ # The production environment is meant for finished, "live" apps.
+ # Code is not reloaded between requests
+ config.cache_classes = true
-# Use a different logger for distributed setups
-# config.logger = SyslogLogger.new
+ # Use a different logger for distributed setups
+ # config.logger = SyslogLogger.new
-# Full error reports are disabled and caching is turned on
-config.action_controller.consider_all_requests_local = false
-config.action_controller.perform_caching = true
+ # Full error reports are disabled and caching is turned on
+ config.action_controller.consider_all_requests_local = false
+ config.action_controller.perform_caching = true
-# Enable serving of images, stylesheets, and javascripts from an asset server
-# config.action_controller.asset_host = "http://assets.example.com"
+ # Enable serving of images, stylesheets, and javascripts from an asset server
+ # config.action_controller.asset_host = "http://assets.example.com"
-# Disable delivery errors, bad email addresses will be ignored
-# config.action_mailer.raise_delivery_errors = false
-config.action_mailer.delivery_method = :sendmail # so is queued, rather than giving immediate errors
+ # Disable delivery errors, bad email addresses will be ignored
+ # config.action_mailer.raise_delivery_errors = false
+ config.action_mailer.delivery_method = :sendmail # so is queued, rather than giving immediate errors
+end
diff --git a/config/environments/test.rb b/config/environments/test.rb
index 784ea18d3..df39e8873 100644
--- a/config/environments/test.rb
+++ b/config/environments/test.rb
@@ -1,25 +1,27 @@
-# Settings specified here will take precedence over those in config/environment.rb
+Alaveteli::Application.configure do
+ # Settings specified here will take precedence over those in config/environment.rb
-require '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
+ # and recreated between test runs. Don't rely on the data there!
+ config.cache_classes = true
-# 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
-# and recreated between test runs. Don't rely on the data there!
-config.cache_classes = true
+ # Log error messages when you accidentally call methods on nil.
+ config.whiny_nils = true
-# Log error messages when you accidentally call methods on nil.
-config.whiny_nils = true
+ # Show full error reports and disable caching
+ config.consider_all_requests_local = true
+ config.action_controller.perform_caching = false
-# Show full error reports and disable caching
-config.action_controller.consider_all_requests_local = true
-config.action_controller.perform_caching = false
+ # Tell ActionMailer not to deliver emails to the real world.
+ # The :test delivery method accumulates sent emails in the
+ # ActionMailer::Base.deliveries array.
+ config.action_mailer.delivery_method = :test
-# Tell ActionMailer not to deliver emails to the real world.
-# The :test delivery method accumulates sent emails in the
-# ActionMailer::Base.deliveries array.
-config.action_mailer.delivery_method = :test
-
-# Disable request forgery protection in test environment
-config.action_controller.allow_forgery_protection = false
+ # Disable request forgery protection in test environment
+ config.action_controller.allow_forgery_protection = false
+ # Print deprecation notices to the stderr
+ config.active_support.deprecation = :stderr
+end
diff --git a/config/httpd.conf b/config/httpd.conf-example
index acf37d97c..1326252f5 100644
--- a/config/httpd.conf
+++ b/config/httpd.conf-example
@@ -1,10 +1,10 @@
-# Apache configuracreated_attion for FOI site.
+# Apache configuration for FOI site.
#
# For development ignore this, you can just run ./scripts/server as for any
# Ruby on Rails application.
#
# Copyright (c) 2007 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org
# This is needed for the PHP spell checker
<Location /fcgi>
@@ -50,7 +50,12 @@ RewriteRule ^/request/((\d{1,3})\d*)/(response/\d+/attach/(html/)?\d+/.+) /views
PassengerResolveSymlinksInDocumentRoot on
# Recommend setting this to 3 or less on servers with 512MB RAM
PassengerMaxPoolSize 6
+ # The RackEnv variable applies to Rails 3 applications, while
+ # the RailsEnv variable applies to applications for earlier
+ # versions of Rails. There doesn't seem to be any harm in
+ # setting both, however.
RailsEnv production
+ RackEnv production
</IfModule>
# Gzip font resources
diff --git a/config/initializers/alaveteli.rb b/config/initializers/alaveteli.rb
new file mode 100644
index 000000000..22ea238b7
--- /dev/null
+++ b/config/initializers/alaveteli.rb
@@ -0,0 +1,64 @@
+# MySociety specific helper functions
+$:.push(File.join(File.dirname(__FILE__), '../../commonlib/rblib'))
+# ... if these fail to include, you need the commonlib submodule from git
+# (type "git submodule update --init" in the whatdotheyknow directory)
+
+load "validate.rb"
+load "config.rb"
+load "format.rb"
+load "debug_helpers.rb"
+load "util.rb"
+
+# Application version
+ALAVETELI_VERSION = '0.11'
+
+# Add new inflection rules using the following format
+# (all these examples are active by default):
+# Inflector.inflections do |inflect|
+# inflect.plural /^(ox)$/i, '\1en'
+# inflect.singular /^(ox)en/i, '\1'
+# inflect.irregular 'person', 'people'
+# inflect.uncountable %w( fish sheep )
+# end
+
+# Add new mime types for use in respond_to blocks:
+# Mime::Type.register "text/richtext", :rtf
+# Mime::Type.register "application/x-mobile", :mobile
+
+# The Rails cache is set up by the Interlock plugin to use memcached
+
+# Domain for URLs (so can work for scripts, not just web pages)
+ActionMailer::Base.default_url_options[:host] = AlaveteliConfiguration::domain
+# https links in emails if forcing SSL
+if AlaveteliConfiguration::force_ssl
+ ActionMailer::Base.default_url_options[:protocol] = "https"
+end
+
+# fallback locale and available locales
+available_locales = AlaveteliConfiguration::available_locales.split(/ /)
+default_locale = AlaveteliConfiguration::default_locale
+
+FastGettext.default_available_locales = available_locales
+I18n.locale = default_locale
+I18n.available_locales = available_locales.map {|locale_name| locale_name.to_sym}
+I18n.default_locale = default_locale
+
+# Load monkey patches and other things from lib/
+require 'ruby19.rb'
+require 'activesupport_cache_extensions.rb'
+require 'use_spans_for_errors.rb'
+require 'activerecord_errors_extensions.rb'
+require 'i18n_fixes.rb'
+require 'world_foi_websites.rb'
+require 'alaveteli_external_command.rb'
+require 'quiet_opener.rb'
+require 'mail_handler'
+require 'public_body_categories'
+require 'ability'
+require 'normalize_string'
+require 'alaveteli_file_types'
+
+# Allow tests to be run under a non-superuser database account if required
+if Rails.env == 'test' and ActiveRecord::Base.configurations['test']['constraint_disabling'] == false
+ require 'no_constraint_disabling'
+end
diff --git a/config/initializers/backtrace_silencers.rb b/config/initializers/backtrace_silencers.rb
new file mode 100644
index 000000000..59385cdf3
--- /dev/null
+++ b/config/initializers/backtrace_silencers.rb
@@ -0,0 +1,7 @@
+# Be sure to restart your server when you modify this file.
+
+# You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces.
+# Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ }
+
+# You can also remove all the silencers if you're trying to debug a problem that might stem from framework code.
+# Rails.backtrace_cleaner.remove_silencers!
diff --git a/config/initializers/fast_gettext.rb b/config/initializers/fast_gettext.rb
index 1cd6440e4..752448a41 100644
--- a/config/initializers/fast_gettext.rb
+++ b/config/initializers/fast_gettext.rb
@@ -3,4 +3,4 @@ FastGettext.default_text_domain = 'app'
I18n::Backend::Simple.send(:include, I18n::Backend::Fallbacks)
-RoutingFilter::Locale.include_default_locale = Configuration::include_default_locale_in_urls \ No newline at end of file
+RoutingFilter::Locale.include_default_locale = AlaveteliConfiguration::include_default_locale_in_urls
diff --git a/config/initializers/gettext_i18n_rails.rb b/config/initializers/gettext_i18n_rails.rb
new file mode 100644
index 000000000..ef306682b
--- /dev/null
+++ b/config/initializers/gettext_i18n_rails.rb
@@ -0,0 +1,3 @@
+# FIXME: Audit the translations for XSS opportunities. Ultimately it would be
+# good to get rid of this and explicitly mark strings as html_safe
+GettextI18nRails.translations_are_html_safe = true
diff --git a/config/initializers/inflections.rb b/config/initializers/inflections.rb
new file mode 100644
index 000000000..9e8b0131f
--- /dev/null
+++ b/config/initializers/inflections.rb
@@ -0,0 +1,10 @@
+# Be sure to restart your server when you modify this file.
+
+# Add new inflection rules using the following format
+# (all these examples are active by default):
+# ActiveSupport::Inflector.inflections do |inflect|
+# inflect.plural /^(ox)$/i, '\1en'
+# inflect.singular /^(ox)en/i, '\1'
+# inflect.irregular 'person', 'people'
+# inflect.uncountable %w( fish sheep )
+# end
diff --git a/config/initializers/mime_types.rb b/config/initializers/mime_types.rb
new file mode 100644
index 000000000..72aca7e44
--- /dev/null
+++ b/config/initializers/mime_types.rb
@@ -0,0 +1,5 @@
+# Be sure to restart your server when you modify this file.
+
+# Add new mime types for use in respond_to blocks:
+# Mime::Type.register "text/richtext", :rtf
+# Mime::Type.register_alias "text/html", :iphone
diff --git a/config/initializers/secret_token.rb b/config/initializers/secret_token.rb
new file mode 100644
index 000000000..d120b94ae
--- /dev/null
+++ b/config/initializers/secret_token.rb
@@ -0,0 +1,12 @@
+# Be sure to restart your server when you modify this file.
+
+# Your secret key for verifying the integrity of signed cookies.
+# If you change this key, all old signed cookies will become invalid!
+# Make sure the secret is at least 30 characters and all random,
+# no regular words or you'll be exposed to dictionary attacks.
+
+# Just plopping an extra character on the secret_token so that any sessions on upgrading from
+# Rails 2 to Rails 3 version of Alaveteli are invalidated.
+# See http://blog.carbonfive.com/2011/03/19/rails-3-upgrade-tip-invalidate-session-cookies/
+
+Alaveteli::Application.config.secret_token = "3" + AlaveteliConfiguration::cookie_store_session_secret
diff --git a/config/initializers/session_store.rb b/config/initializers/session_store.rb
index 8cfa333f2..ca283d4e0 100644
--- a/config/initializers/session_store.rb
+++ b/config/initializers/session_store.rb
@@ -1,17 +1,2 @@
# Be sure to restart your server when you modify this file.
-
-# Your secret key for verifying cookie session data integrity.
-# If you change this key, all old sessions will become invalid!
-# Make sure the secret is at least 30 characters and all random,
-# no regular words or you'll be exposed to dictionary attacks.
-
-ActionController::Base.session = {
- :key => '_wdtk_cookie_session',
- :secret => Configuration::cookie_store_session_secret
-}
-ActionController::Base.session_store = :cookie_store
-
-# Insert a bit of middleware code to prevent uneeded cookie setting.
-require "#{Rails.root}/lib/whatdotheyknow/strip_empty_sessions"
-ActionController::Dispatcher.middleware.insert_before ActionController::Base.session_store, WhatDoTheyKnow::StripEmptySessions, :key => '_wdtk_cookie_session', :path => "/", :httponly => true
-
+Rails.application.config.session_store :cookie_store, :key => '_wdtk_cookie_session'
diff --git a/config/initializers/single_quote_escape_workaround.rb b/config/initializers/single_quote_escape_workaround.rb
deleted file mode 100644
index 2e713b982..000000000
--- a/config/initializers/single_quote_escape_workaround.rb
+++ /dev/null
@@ -1,31 +0,0 @@
-class ERB
- module Util
-
- if "html_safe exists".respond_to?(:html_safe)
- def html_escape(s)
- s = s.to_s
- if s.html_safe?
- s
- else
- Rack::Utils.escape_html(s).html_safe
- end
- end
- else
- def html_escape(s)
- s = s.to_s
- Rack::Utils.escape_html(s).html_safe
- end
- end
-
- remove_method :h
- alias h html_escape
-
- class << self
- remove_method :html_escape
- remove_method :h
- end
-
- module_function :html_escape
- module_function :h
- end
-end
diff --git a/config/initializers/strip_nil_parameters_patch.rb b/config/initializers/strip_nil_parameters_patch.rb
deleted file mode 100644
index 35d0a28c5..000000000
--- a/config/initializers/strip_nil_parameters_patch.rb
+++ /dev/null
@@ -1,51 +0,0 @@
-# Stolen from https://raw.github.com/mysociety/fixmytransport/fa9b014eb2628c300693e055f129cb8959772082/config/initializers/strip_nil_parameters_patch.rb
-
-# Monkey patch for CVE-2012-2660 on Rails 2.3.14
-
-# Strip [nil] from parameters hash
-# based on a pull request from @sebbacon
-# https://github.com/rails/rails/pull/6580
-
-module ActionController
- class Request < Rack::Request
- protected
- def deep_munge(hash)
- hash.each_value do |v|
- case v
- when Array
- v.grep(Hash) { |x| deep_munge(x) }
- when Hash
- deep_munge(v)
- end
- end
-
- keys = hash.keys.find_all { |k| hash[k] == [nil] }
- keys.each { |k| hash[k] = nil }
- hash
- end
-
- private
-
- def normalize_parameters(value)
- case value
- when Hash
- if value.has_key?(:tempfile)
- upload = value[:tempfile]
- upload.extend(UploadedFile)
- upload.original_path = value[:filename]
- upload.content_type = value[:type]
- upload
- else
- h = {}
- value.each { |k, v| h[k] = normalize_parameters(v) }
- deep_munge(h.with_indifferent_access)
- end
- when Array
- value.map { |e| normalize_parameters(e) }
- else
- value
- end
- end
-
- end
-end
diff --git a/config/initializers/theme_loader.rb b/config/initializers/theme_loader.rb
index 877149e9d..1ad2d01f1 100644
--- a/config/initializers/theme_loader.rb
+++ b/config/initializers/theme_loader.rb
@@ -2,12 +2,23 @@
# It is used by our config/routes.rb to decide which route extension files to load.
$alaveteli_route_extensions = []
-if ENV["RAILS_ENV"] != "test" # Don't let the themes interfere with Alaveteli specs
- for url in Configuration::theme_urls.reverse
+def require_theme(theme_name)
+ theme_main_include = File.expand_path "../../../vendor/plugins/#{theme_name}/lib/alavetelitheme.rb", __FILE__
+ if File.exists? theme_main_include
+ require theme_main_include
+ end
+end
+
+if Rails.env == "test"
+ # By setting this ALAVETELI_TEST_THEME to a theme name, theme tests can run in the Rails
+ # context with the theme loaded. Otherwise the themes from the config aren't loaded in testing
+ # so they don't interfere with core Alaveteli tests
+ if defined? ALAVETELI_TEST_THEME
+ require_theme(ALAVETELI_TEST_THEME)
+ end
+else
+ for url in AlaveteliConfiguration::theme_urls.reverse
theme_name = url.sub(/.*\/(.*).git/, "\\1")
- theme_main_include = File.expand_path "../../../vendor/plugins/#{theme_name}/lib/alavetelitheme.rb", __FILE__
- if File.exists? theme_main_include
- require theme_main_include
- end
+ require_theme(theme_name)
end
end
diff --git a/config/locales b/config/locales
deleted file mode 120000
index 10a4f96c3..000000000
--- a/config/locales
+++ /dev/null
@@ -1 +0,0 @@
-../vendor/rails-locales/rails/locale \ No newline at end of file
diff --git a/config/packages b/config/packages
index db51e5bdd..fc67cda6b 100644
--- a/config/packages
+++ b/config/packages
@@ -36,4 +36,5 @@ rake (>= 0.9.2.2)
build-essential
bundler
sqlite3
-libsqlite3-dev \ No newline at end of file
+libsqlite3-dev
+libicu-dev
diff --git a/config/routes.rb b/config/routes.rb
index 15e62bc53..1895543d7 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -1,255 +1,246 @@
+# encoding: UTF-8
# config/routes.rb:
# Mapping URLs to controllers for FOIFA.
#
# Copyright (c) 2007 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
# Allow easy extension from themes. Note these will have the highest priority.
$alaveteli_route_extensions.each do |f|
load File.join('config', f)
end
-ActionController::Routing::Routes.draw do |map|
-
- # The priority is based upon order of creation: first created -> highest priority.
-
- # Sample of regular route:
- # map.connect 'products/:id', :controller => 'catalog', :action => 'view'
- # Keep in mind you can assign values other than :controller and :action
-
- map.with_options :controller => 'general' do |general|
- general.frontpage '/', :action => 'frontpage'
- general.blog '/blog', :action => 'blog'
- general.custom_css '/stylesheets/custom.css', :action => 'custom_css'
- general.search_redirect '/search', :action => 'search_redirect'
- general.search_redirect '/search/all', :action => 'search_redirect'
- # XXX combined is the search query, and then if sorted a "/newest" at the end.
- # 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/all', :action => 'search', :view => 'all'
- general.search_general '/search/*combined', :action => 'search'
- general.advanced_search '/advancedsearch', :action => 'search_redirect', :advanced => true
-
- general.random_request '/random', :action => 'random_request'
- end
-
- map.with_options :controller => 'request' do |request|
- request.request_list_recent '/list/recent', :action => 'list', :view => 'recent'
- request.request_list_all '/list/all', :action => 'list', :view => 'all'
- request.request_list_successful '/list/successful', :action => 'list', :view => 'successful'
- request.request_list_unsuccessful '/list/unsuccessful', :action => 'list', :view => 'unsuccessful'
- request.request_list_awaiting '/list/awaiting', :action => 'list', :view => 'awaiting'
- request.request_list '/list', :action => 'list'
-
- request.select_authority '/select_authority', :action => 'select_authority'
-
- request.new_request '/new', :action => 'new'
- request.new_request_to_body '/new/:url_name', :action => 'new'
-
- request.search_ahead '/request/search_ahead', :action => 'search_typeahead'
-
- request.show_request '/request/:url_title.:format', :action => 'show'
- request.show_new_request '/request/:url_title/new', :action => 'show'
- request.details_request '/details/request/:url_title', :action => 'details'
- request.similar_request '/similar/request/:url_title', :action => 'similar'
-
- request.describe_state '/request/:id/describe', :action => 'describe_state'
- request.describe_state_message '/request/:url_title/describe/:described_state', :action => 'describe_state_message'
- request.show_response_no_followup '/request/:id/response', :action => 'show_response'
- request.show_response '/request/:id/response/:incoming_message_id', :action => 'show_response'
- request.get_attachment_as_html '/request/:id/response/:incoming_message_id/attach/html/:part/*file_name', :action => 'get_attachment_as_html'
- request.get_attachment '/request/:id/response/:incoming_message_id/attach/:part/*file_name', :action => 'get_attachment'
-
- request.info_request_event '/request_event/:info_request_event_id', :action => 'show_request_event'
-
- request.upload_response "/upload/request/:url_title", :action => 'upload_response'
- request.download_entire_request '/request/:url_title/download', :action => 'download_entire_request'
-
- # It would be nice to add :conditions => { :method => :post } to this next one,
- # because it ought not really to be available as a GET request since it changes
- # the server state. Unfortunately this doesn’t play well with the PostRedirect
- # mechanism, which assumes all post-login actions are available via GET, so we
- # refrain.
- request.report '/request/:url_title/report', :action => 'report_request'
-
- end
-
+Alaveteli::Application.routes.draw do
+ #### General contoller
+ match '/' => 'general#frontpage', :as => :frontpage
+ match '/blog' => 'general#blog', :as => :blog
+ match '/stylesheets/custom.css' => 'general#custom_css', :as => :custom_css
+ match '/search' => 'general#search_redirect', :as => :search_redirect
+ match '/search/all' => 'general#search_redirect', :as => :search_redirect
+ # XXX combined is the search query, and then if sorted a "/newest" at the end.
+ # 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.
+ match '/search/*combined/all' => 'general#search', :as => :search_general, :view => 'all'
+ match '/search(/*combined)' => 'general#search', :as => :search_general
+ match '/advancedsearch' => 'general#search_redirect', :as => :advanced_search, :advanced => true
+
+ match '/random' => 'general#random_request', :as => :random_request
+ #####
+
+ ##### Request controller
+ match '/list/recent' => 'request#list', :as => :request_list_recent, :view => 'recent'
+ match '/list/all' => 'request#list', :as => :request_list_all, :view => 'all'
+ match '/list/successful' => 'request#list', :as => :request_list_successful, :view => 'successful'
+ match '/list/unsuccessful' => 'request#list', :as => :request_list_unsuccessful, :view => 'unsuccessful'
+ match '/list/awaiting' => 'request#list', :as => :request_list_awaiting, :view => 'awaiting'
+ match '/list' => 'request#list', :as => :request_list
+
+ match '/select_authority' => 'request#select_authority', :as => :select_authority
+
+ match '/new' => 'request#new', :as => :new_request
+ match '/new/:url_name' => 'request#new', :as => :new_request_to_body
+
+ match '/request/search_ahead' => 'request#search_typeahead', :as => :search_ahead
+
+ match '/request/:url_title' => 'request#show', :as => :show_request
+ match '/request/:url_title/new' => 'request#show', :as => :show_new_request
+ match '/details/request/:url_title' => 'request#details', :as => :details_request
+ match '/similar/request/:url_title' => 'request#similar', :as => :similar_request
+
+ match '/request/:id/describe' => 'request#describe_state', :as => :describe_state
+ match '/request/:url_title/describe/:described_state' => 'request#describe_state_message', :as => :describe_state_message
+ match '/request/:id/response' => 'request#show_response', :as => :show_response_no_followup
+ match '/request/:id/response/:incoming_message_id' => 'request#show_response', :as => :show_response
+ match '/request/:id/response/:incoming_message_id/attach/html/:part/*file_name' => 'request#get_attachment_as_html', :format => false, :as => :get_attachment_as_html
+ match '/request/:id/response/:incoming_message_id/attach/:part(/*file_name)' => 'request#get_attachment', :format => false, :as => :get_attachment
+
+ match '/request_event/:info_request_event_id' => 'request#show_request_event', :as => :info_request_event
+
+ match '/upload/request/:url_title' => 'request#upload_response', :as => :upload_response
+ match '/request/:url_title/download' => 'request#download_entire_request', :as => :download_entire_request
+
+ # It would be nice to add :conditions => { :method => :post } to this next one,
+ # because it ought not really to be available as a GET request since it changes
+ # the server state. Unfortunately this doesn’t play well with the PostRedirect
+ # mechanism, which assumes all post-login actions are available via GET, so we
+ # refrain.
+ match '/request/:url_title/report' => 'request#report_request', :as => :report
+ ####
+
+ #### User controller
# Use /profile for things to do with the currently signed in user.
# Use /user/XXXX for things that anyone can see about that user.
# Note that /profile isn't indexed by search (see robots.txt)
- map.with_options :controller => 'user' do |user|
- user.signin '/profile/sign_in', :action => 'signin'
- user.signup '/profile/sign_up', :action => 'signup'
- user.signout '/profile/sign_out', :action => 'signout'
-
- 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.show_user_wall '/user/:url_name/wall.:format', :action => 'wall'
- user.contact_user '/user/contact/:id', :action => 'contact'
-
- user.signchangepassword '/profile/change_password', :action => 'signchangepassword'
- user.signchangeemail '/profile/change_email', :action => 'signchangeemail'
-
- user.set_profile_photo '/profile/set_photo', :action => 'set_profile_photo'
- user.clear_profile_photo '/profile/clear_photo', :action => 'clear_profile_photo'
- user.get_profile_photo '/user/:url_name/photo.png', :action => 'get_profile_photo'
- user.get_draft_profile_photo '/profile/draft_photo/:id.png', :action => 'get_draft_profile_photo'
- user.set_profile_about_me '/profile/set_about_me', :action => 'set_profile_about_me'
- user.set_receive_email_alerts '/profile/set_receive_alerts', :action => 'set_receive_email_alerts'
- user.river '/profile/river', :action => 'river'
- end
-
- map.with_options :controller => 'public_body' do |body|
- body.search_ahead_bodies '/body/search_ahead', :action => 'search_typeahead'
- body.list_public_bodies "/body", :action => 'list'
- body.list_public_bodies_default "/body/list/all", :action => 'list'
- body.list_public_bodies "/body/list/:tag", :action => 'list'
- body.list_public_bodies_redirect "/local/:tag", :action => 'list_redirect'
- body.all_public_bodies_csv "/body/all-authorities.csv", :action => 'list_all_csv'
- body.show_public_body "/body/:url_name.:format", :action => 'show', :view => 'all'
- body.show_public_body_all "/body/:url_name/all", :action => 'show', :view => 'all'
- body.show_public_body_successful "/body/:url_name/successful", :action => 'show', :view => "successful"
- body.show_public_body_unsuccessful "/body/:url_name/unsuccessful", :action => 'show', :view => "unsuccessful"
- body.show_public_body_awaiting "/body/:url_name/awaiting", :action => 'show', :view => "awaiting"
- body.view_public_body_email "/body/:url_name/view_email", :action => 'view_email'
- body.show_public_body_tag "/body/:url_name/:tag", :action => 'show'
- body.show_public_body_tag_view "/body/:url_name/:tag/:view", :action => 'show'
- end
-
- map.with_options :controller => 'comment' do |comment|
- comment.new_comment "/annotate/request/:url_title", :action => 'new', :type => 'request'
- end
-
- map.with_options :controller => 'services' do |service|
- service.other_country_message "/country_message", :action => 'other_country_message'
- service.hidden_user_explanation "/hidden_user_explanation", :action => 'hidden_user_explanation'
- end
-
- map.with_options :controller => 'track' do |track|
- # /track/ is for setting up an email alert for the item
- # /feed/ is a direct RSS feed of the item
- track.track_request '/:feed/request/:url_title.:format', :action => 'track_request', :feed => /(track|feed)/
- track.track_list '/:feed/list/:view.:format', :action => 'track_list', :view => nil, :feed => /(track|feed)/
- track.track_public_body "/:feed/body/:url_name.:format", :action => 'track_public_body', :feed => /(track|feed)/
- track.track_user "/:feed/user/:url_name.:format", :action => 'track_user', :feed => /(track|feed)/
- # XXX must be better way of getting dots and slashes in search queries to work than this *query_array
- # Also, the :format doesn't work. See hacky code in the controller that makes up for this.
- track.track_search "/:feed/search/*query_array.:format", :action => 'track_search_query' , :feed => /(track|feed)/
-
- track.update '/track/update/:track_id', :action => 'update'
- track.delete_all_type '/track/delete_all_type', :action => 'delete_all_type'
- track.atom_feed '/track/feed/:track_id', :action => 'atom_feed'
- end
-
- map.with_options :controller => 'help' do |help|
- help.help_unhappy '/help/unhappy/:url_title', :action => 'unhappy'
- help.help_about '/help/about', :action => 'about'
- help.help_alaveteli '/help/alaveteli', :action => 'alaveteli'
- help.help_contact '/help/contact', :action => 'contact'
- help.help_officers '/help/officers', :action => 'officers'
- help.help_requesting '/help/requesting', :action => 'requesting'
- help.help_privacy '/help/privacy', :action => 'privacy'
- help.help_api '/help/api', :action => 'api'
- help.help_credits '/help/credits', :action => 'credits'
- help.help_general '/help/:action', :action => :action
- end
-
- map.with_options :controller => 'holiday' do |holiday|
- holiday.due_date "/due_date/:holiday", :action => 'due_date'
- end
-
- map.with_options :controller => 'request_game' do |game|
- game.categorise_play '/categorise/play', :action => 'play'
- game.categorise_request '/categorise/request/:url_title', :action => 'show'
- game.categorise_stop '/categorise/stop', :action => 'stop'
- end
-
- map.with_options :controller => 'admin_public_body' do |body|
- body.admin_body_missing '/admin/missing_scheme', :action => 'missing_scheme'
- body.admin_body_index '/admin/body', :action => 'index'
- body.admin_body_list '/admin/body/list', :action => 'list'
- body.admin_body_show '/admin/body/show/:id', :action => 'show'
- body.admin_body_new '/admin/body/new', :action => 'new'
- body.admin_body_edit '/admin/body/edit/:id', :action => 'edit'
- body.admin_body_update '/admin/body/update/:id', :action => 'update'
- body.admin_body_create '/admin/body/create', :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|
- admin.admin_general_index '/admin', :action => 'index'
- admin.admin_timeline '/admin/timeline', :action => 'timeline'
- admin.admin_debug '/admin/debug', :action => 'debug'
- admin.admin_stats '/admin/stats', :action => 'stats'
- admin.admin_js '/admin/javascripts/admin.js', :action => 'admin_js'
- end
-
- map.with_options :controller => 'admin_request' do |admin|
- admin.admin_request_index '/admin/request', :action => 'index'
- admin.admin_request_list '/admin/request/list', :action => 'list'
- admin.admin_request_show '/admin/request/show/:id', :action => 'show'
- admin.admin_request_resend '/admin/request/resend', :action => 'resend'
- admin.admin_request_edit '/admin/request/edit/:id', :action => 'edit'
- admin.admin_request_update '/admin/request/update/:id', :action => 'update'
- admin.admin_request_destroy '/admin/request/destroy/:id', :action => 'fully_destroy'
- admin.admin_request_edit_outgoing '/admin/request/edit_outgoing/:id', :action => 'edit_outgoing'
- admin.admin_request_destroy_outgoing '/admin/request/destroy_outgoing', :action => 'destroy_outgoing'
- admin.admin_request_update_outgoing '/admin/request/update_outgoing/:id', :action => 'update_outgoing'
- admin.admin_request_edit_comment '/admin/request/edit_comment/:id', :action => 'edit_comment'
- admin.admin_request_update_comment '/admin/request/update_comment/:id', :action => 'update_comment'
- admin.admin_request_destroy_incoming '/admin/request/destroy_incoming', :action => 'destroy_incoming'
- admin.admin_request_redeliver_incoming '/admin/request/redeliver_incoming', :action => 'redeliver_incoming'
- admin.admin_request_move_request '/admin/request/move_request', :action => 'move_request'
- admin.admin_request_generate_upload_url '/admin/request/generate_upload_url/:id', :action => 'generate_upload_url'
- admin.admin_request_show_raw_email '/admin/request/show_raw_email/:id', :action => 'show_raw_email'
- admin.admin_request_download_raw_email '/admin/request/download_raw_email/:id', :action => 'download_raw_email'
- admin.admin_request_clarification '/admin/request/mark_event_as_clarification', :action => 'mark_event_as_clarification'
- admin.admin_request_hide '/admin/request/hide/:id', :action => 'hide_request'
- end
-
- map.with_options :controller => 'admin_user' do |user|
- user.admin_user_index '/admin/user', :action => 'index'
- user.admin_user_list '/admin/user/list', :action => 'list'
- user.admin_user_list_banned '/admin/user/banned', :action => 'list_banned'
- user.admin_user_show '/admin/user/show/:id', :action => 'show'
- user.admin_user_edit '/admin/user/edit/:id', :action => 'edit'
- user.admin_user_show_bounce '/admin/user/show_bounce_message/:id', :action => 'show_bounce_message'
- user.admin_user_update '/admin/user/update/:id', :action => 'update'
- user.admin_user_clear_bounce '/admin/user/clear_bounce/:id', :action => 'clear_bounce'
- user.admin_user_destroy_track '/admin/user/destroy_track', :action => 'destroy_track'
- user.admin_user_login_as '/admin/user/login_as/:id', :action => 'login_as'
- user.admin_clear_profile_photo '/admin/user/clear_profile_photo/:id', :action => 'clear_profile_photo'
- end
-
- map.with_options :controller => 'admin_track' do |track|
- track.admin_track_list '/admin/track/list', :action => 'list'
- end
-
- map.with_options :controller => 'admin_censor_rule' do |rule|
- rule.admin_rule_new '/admin/censor/new', :action => 'new'
- rule.admin_rule_create '/admin/censor/create', :action => 'create'
- rule.admin_rule_edit '/admin/censor/edit/:id', :action => 'edit'
- rule.admin_rule_update '/admin/censor/update/:id', :action => 'update'
- rule.admin_rule_destroy '/admin/censor/destroy/:censor_rule_id', :action => 'destroy'
- end
-
- map.with_options :controller => 'api' do |api|
- api.api_create_request '/api/v2/request.json', :action => 'create_request', :conditions => { :method => :post }
-
- api.api_show_request '/api/v2/request/:id.json', :action => 'show_request', :conditions => { :method => :get }
- api.api_add_correspondence '/api/v2/request/:id.json', :action => 'add_correspondence', :conditions => { :method => :post }
-
- api.api_body_request_events '/api/v2/body/:id/request_events.:feed_type', :action => 'body_request_events', :feed_type => '^(json|atom)$'
- end
-
- map.filter('conditionallyprependlocale')
-
- # Allow downloading Web Service WSDL as a file with an extension
- # instead of a file named 'wsdl'
- # map.connect ':controller/service.wsdl', :action => 'wsdl'
+ match '/profile/sign_in' => 'user#signin', :as => :signin
+ match '/profile/sign_up' => 'user#signup', :as => :signup
+ match '/profile/sign_out' => 'user#signout', :as => :signout
+
+ match '/c/:email_token' => 'user#confirm', :as => :confirm
+ match '/user/:url_name' => 'user#show', :as => :show_user
+ match '/user/:url_name/profile' => 'user#show', :as => :show_user_profile, :view => 'profile'
+ match '/user/:url_name/requests' => 'user#show', :as => :show_user_requests, :view => 'requests'
+ match '/user/:url_name/wall' => 'user#wall', :as => :show_user_wall
+ match '/user/contact/:id' => 'user#contact', :as => :contact_user
+
+ match '/profile/change_password' => 'user#signchangepassword', :as => :signchangepassword
+ match '/profile/change_email' => 'user#signchangeemail', :as => :signchangeemail
+
+ match '/profile/set_photo' => 'user#set_profile_photo', :as => :set_profile_photo
+ match '/profile/clear_photo' => 'user#clear_profile_photo', :as => :clear_profile_photo
+ match '/user/:url_name/photo.png' => 'user#get_profile_photo', :as => :get_profile_photo
+ match '/profile/draft_photo/:id.png' => 'user#get_draft_profile_photo', :as => :get_draft_profile_photo
+ match '/profile/set_about_me' => 'user#set_profile_about_me', :as => :set_profile_about_me
+ match '/profile/set_receive_alerts' => 'user#set_receive_email_alerts', :as => :set_receive_email_alerts
+ match '/profile/river' => 'user#river', :as => :river
+ ####
+
+ #### PublicBody controller
+ match '/body/search_ahead' => 'public_body#search_typeahead', :as => :search_ahead_bodies
+ match '/body' => 'public_body#list', :as => :list_public_bodies
+ match '/body/list/all' => 'public_body#list', :as => :list_public_bodies_default
+ match '/body/list/:tag' => 'public_body#list', :as => :list_public_bodies
+ match '/local/:tag' => 'public_body#list_redirect', :as => :list_public_bodies_redirect
+ match '/body/all-authorities.csv' => 'public_body#list_all_csv', :as => :all_public_bodies_csv
+ match '/body/:url_name' => 'public_body#show', :as => :show_public_body, :view => 'all'
+ match '/body/:url_name/all' => 'public_body#show', :as => :show_public_body_all, :view => 'all'
+ match '/body/:url_name/successful' => 'public_body#show', :as => :show_public_body_successful, :view => 'successful'
+ match '/body/:url_name/unsuccessful' => 'public_body#show', :as => :show_public_body_unsuccessful, :view => 'unsuccessful'
+ match '/body/:url_name/awaiting' => 'public_body#show', :as => :show_public_body_awaiting, :view => 'awaiting'
+ match '/body/:url_name/view_email' => 'public_body#view_email', :as => :view_public_body_email
+ match '/body/:url_name/:tag' => 'public_body#show', :as => :show_public_body_tag
+ match '/body/:url_name/:tag/:view' => 'public_body#show', :as => :show_public_body_tag_view
+ ####
+
+ #### Comment controller
+ match '/annotate/request/:url_title' => 'comment#new', :as => :new_comment, :type => 'request'
+ ####
+
+ #### Services controller
+ match '/country_message' => 'services#other_country_message', :as => :other_country_message
+ match '/hidden_user_explanation' => 'services#hidden_user_explanation', :as => :hidden_user_explanation
+ ####
+
+ #### Track controller
+ # /track/ is for setting up an email alert for the item
+ # /feed/ is a direct RSS feed of the item
+ match '/:feed/request/:url_title' => 'track#track_request', :as => :track_request, :feed => /(track|feed)/
+ match '/:feed/list/:view' => 'track#track_list', :as => :track_list, :view => nil, :feed => /(track|feed)/
+ match '/:feed/body/:url_name' => 'track#track_public_body', :as => :track_public_body, :feed => /(track|feed)/
+ match '/:feed/user/:url_name' => 'track#track_user', :as => :track_user, :feed => /(track|feed)/
+ # XXX :format doesn't work. See hacky code in the controller that makes up for this.
+ match '/:feed/search/:query_array' => 'track#track_search_query',
+ :as => :track_search,
+ :feed => /(track|feed)/,
+ :constraints => { :query_array => /.*/ }
+
+ match '/track/update/:track_id' => 'track#update', :as => :update
+ match '/track/delete_all_type' => 'track#delete_all_type', :as => :delete_all_type
+ match '/track/feed/:track_id' => 'track#atom_feed', :as => :atom_feed
+ ####
+
+ #### Help controller
+ match '/help/unhappy/:url_title' => 'help#unhappy', :as => :help_unhappy
+ match '/help/about' => 'help#about', :as => :help_about
+ match '/help/alaveteli' => 'help#alaveteli', :as => :help_alaveteli
+ match '/help/contact' => 'help#contact', :as => :help_contact
+ match '/help/officers' => 'help#officers', :as => :help_officers
+ match '/help/requesting' => 'help#requesting', :as => :help_requesting
+ match '/help/privacy' => 'help#privacy', :as => :help_privacy
+ match '/help/api' => 'help#api', :as => :help_api
+ match '/help/credits' => 'help#credits', :as => :help_credits
+ match '/help/:action' => 'help#action', :as => :help_general
+ ####
+
+ #### Holiday controller
+ match '/due_date/:holiday' => 'holiday#due_date', :as => :due_date
+ ####
+
+ #### RequestGame controller
+ match '/categorise/play' => 'request_game#play', :as => :categorise_play
+ match '/categorise/request/:url_title' => 'request_game#show', :as => :categorise_request
+ match '/categorise/stop' => 'request_game#stop', :as => :categorise_stop
+ ####
+
+ #### AdminPublicBody controller
+ match '/admin/missing_scheme' => 'admin_public_body#missing_scheme', :as => :admin_body_missing
+ match '/admin/body' => 'admin_public_body#index', :as => :admin_body_index
+ match '/admin/body/list' => 'admin_public_body#list', :as => :admin_body_list
+ match '/admin/body/show/:id' => 'admin_public_body#show', :as => :admin_body_show
+ match '/admin/body/new' => 'admin_public_body#new', :as => :admin_body_new
+ match '/admin/body/edit/:id' => 'admin_public_body#edit', :as => :admin_body_edit
+ match '/admin/body/update/:id' => 'admin_public_body#update', :as => :admin_body_update
+ match '/admin/body/create' => 'admin_public_body#create', :as => :admin_body_create
+ match '/admin/body/destroy/:id' => 'admin_public_body#destroy', :as => :admin_body_destroy
+ match '/admin/body/import_csv' => 'admin_public_body#import_csv', :as => :admin_body_import_csv
+ match '/admin/body/mass_tag_add' => 'admin_public_body#mass_tag_add', :as => :admin_body_mass_tag_add
+ ####
+
+ #### AdminGeneral controller
+ match '/admin' => 'admin_general#index', :as => :admin_general_index
+ match '/admin/timeline' => 'admin_general#timeline', :as => :admin_timeline
+ match '/admin/debug' => 'admin_general#debug', :as => :admin_debug
+ match '/admin/stats' => 'admin_general#stats', :as => :admin_stats
+ match '/admin/javascripts/admin.js' => 'admin_general#admin_js', :as => :admin_js
+ ####
+
+ #### AdminRequest controller
+ match '/admin/request' => 'admin_request#index', :as => :admin_request_index
+ match '/admin/request/list' => 'admin_request#list', :as => :admin_request_list
+ match '/admin/request/show/:id' => 'admin_request#show', :as => :admin_request_show
+ match '/admin/request/resend' => 'admin_request#resend', :as => :admin_request_resend
+ match '/admin/request/edit/:id' => 'admin_request#edit', :as => :admin_request_edit
+ match '/admin/request/update/:id' => 'admin_request#update', :as => :admin_request_update
+ match '/admin/request/destroy/:id' => 'admin_request#fully_destroy', :as => :admin_request_destroy
+ match '/admin/request/edit_outgoing/:id' => 'admin_request#edit_outgoing', :as => :admin_request_edit_outgoing
+ match '/admin/request/destroy_outgoing/:id' => 'admin_request#destroy_outgoing', :as => :admin_request_destroy_outgoing
+ match '/admin/request/update_outgoing/:id' => 'admin_request#update_outgoing', :as => :admin_request_update_outgoing
+ match '/admin/request/edit_comment/:id' => 'admin_request#edit_comment', :as => :admin_request_edit_comment
+ match '/admin/request/update_comment/:id' => 'admin_request#update_comment', :as => :admin_request_update_comment
+ match '/admin/request/destroy_incoming' => 'admin_request#destroy_incoming', :as => :admin_request_destroy_incoming
+ match '/admin/request/redeliver_incoming' => 'admin_request#redeliver_incoming', :as => :admin_request_redeliver_incoming
+ match '/admin/request/move_request' => 'admin_request#move_request', :as => :admin_request_move_request
+ match '/admin/request/generate_upload_url/:id' => 'admin_request#generate_upload_url', :as => :admin_request_generate_upload_url
+ match '/admin/request/show_raw_email/:id' => 'admin_request#show_raw_email', :as => :admin_request_show_raw_email
+ match '/admin/request/download_raw_email/:id' => 'admin_request#download_raw_email', :as => :admin_request_download_raw_email
+ match '/admin/request/mark_event_as_clarification' => 'admin_request#mark_event_as_clarification', :as => :admin_request_clarification
+ match '/admin/request/hide/:id' => 'admin_request#hide_request', :as => :admin_request_hide
+ ####
+
+ #### AdminUser controller
+ match '/admin/user' => 'admin_user#index', :as => :admin_user_index
+ match '/admin/user/list' => 'admin_user#list', :as => :admin_user_list
+ match '/admin/user/banned' => 'admin_user#list_banned', :as => :admin_user_list_banned
+ match '/admin/user/show/:id' => 'admin_user#show', :as => :admin_user_show
+ match '/admin/user/edit/:id' => 'admin_user#edit', :as => :admin_user_edit
+ match '/admin/user/show_bounce_message/:id' => 'admin_user#show_bounce_message', :as => :admin_user_show_bounce
+ match '/admin/user/update/:id' => 'admin_user#update', :as => :admin_user_update
+ match '/admin/user/clear_bounce/:id' => 'admin_user#clear_bounce', :as => :admin_user_clear_bounce
+ match '/admin/user/destroy_track' => 'admin_user#destroy_track', :as => :admin_user_destroy_track
+ match '/admin/user/login_as/:id' => 'admin_user#login_as', :as => :admin_user_login_as
+ match '/admin/user/clear_profile_photo/:id' => 'admin_user#clear_profile_photo', :as => :admin_clear_profile_photo
+ ####
+
+ #### AdminTrack controller
+ match '/admin/track/list' => 'admin_track#list', :as => :admin_track_list
+ ####
+
+ #### AdminCensorRule controller
+ match '/admin/censor/new' => 'admin_censor_rule#new', :as => :admin_rule_new
+ match '/admin/censor/create' => 'admin_censor_rule#create', :as => :admin_rule_create
+ match '/admin/censor/edit/:id' => 'admin_censor_rule#edit', :as => :admin_rule_edit
+ match '/admin/censor/update/:id' => 'admin_censor_rule#update', :as => :admin_rule_update
+ match '/admin/censor/destroy/:censor_rule_id' => 'admin_censor_rule#destroy', :as => :admin_rule_destroy
+ ####
+
+ #### Api controller
+ match '/api/v2/request.json' => 'api#create_request', :as => :api_create_request, :via => :post
+
+ match '/api/v2/request/:id.json' => 'api#show_request', :as => :api_show_request, :via => :get
+ match '/api/v2/request/:id.json' => 'api#add_correspondence', :as => :api_add_correspondence, :via => :post
+
+ match '/api/v2/body/:id/request_events.:feed_type' => 'api#body_request_events', :as => :api_body_request_events, :feed_type => '^(json|atom)$'
+ ####
+
+ filter :conditionallyprependlocale
end
diff --git a/config/test.yml b/config/test.yml
index bc9ec099a..5c08e928b 100644
--- a/config/test.yml
+++ b/config/test.yml
@@ -1,7 +1,7 @@
# test.yml
# Test values for the "general" config file.
#
-# Configuration parameters, in YAML syntax.
+# AlaveteliConfiguration parameters, in YAML syntax.
#
# These may be values expected by the test suite; changing them may
# break tests.
diff --git a/db/development_structure.sql b/db/development_structure.sql
index bd4870948..47e33e373 100644
--- a/db/development_structure.sql
+++ b/db/development_structure.sql
@@ -908,168 +908,168 @@ ALTER SEQUENCE users_id_seq OWNED BY users.id;
-- Name: id; Type: DEFAULT; Schema: public; Owner: -
--
-ALTER TABLE ONLY acts_as_xapian_jobs ALTER COLUMN id SET DEFAULT nextval('acts_as_xapian_jobs_id_seq'::regclass);
+ALTER TABLE acts_as_xapian_jobs ALTER COLUMN id SET DEFAULT nextval('acts_as_xapian_jobs_id_seq'::regclass);
--
-- Name: id; Type: DEFAULT; Schema: public; Owner: -
--
-ALTER TABLE ONLY censor_rules ALTER COLUMN id SET DEFAULT nextval('censor_rules_id_seq'::regclass);
+ALTER TABLE censor_rules ALTER COLUMN id SET DEFAULT nextval('censor_rules_id_seq'::regclass);
--
-- Name: id; Type: DEFAULT; Schema: public; Owner: -
--
-ALTER TABLE ONLY comments ALTER COLUMN id SET DEFAULT nextval('comments_id_seq'::regclass);
+ALTER TABLE comments ALTER COLUMN id SET DEFAULT nextval('comments_id_seq'::regclass);
--
-- Name: id; Type: DEFAULT; Schema: public; Owner: -
--
-ALTER TABLE ONLY foi_attachments ALTER COLUMN id SET DEFAULT nextval('foi_attachments_id_seq'::regclass);
+ALTER TABLE foi_attachments ALTER COLUMN id SET DEFAULT nextval('foi_attachments_id_seq'::regclass);
--
-- Name: id; Type: DEFAULT; Schema: public; Owner: -
--
-ALTER TABLE ONLY has_tag_string_tags ALTER COLUMN id SET DEFAULT nextval('public_body_tags_id_seq'::regclass);
+ALTER TABLE has_tag_string_tags ALTER COLUMN id SET DEFAULT nextval('public_body_tags_id_seq'::regclass);
--
-- Name: id; Type: DEFAULT; Schema: public; Owner: -
--
-ALTER TABLE ONLY holidays ALTER COLUMN id SET DEFAULT nextval('holidays_id_seq'::regclass);
+ALTER TABLE holidays ALTER COLUMN id SET DEFAULT nextval('holidays_id_seq'::regclass);
--
-- Name: id; Type: DEFAULT; Schema: public; Owner: -
--
-ALTER TABLE ONLY incoming_messages ALTER COLUMN id SET DEFAULT nextval('incoming_messages_id_seq'::regclass);
+ALTER TABLE incoming_messages ALTER COLUMN id SET DEFAULT nextval('incoming_messages_id_seq'::regclass);
--
-- Name: id; Type: DEFAULT; Schema: public; Owner: -
--
-ALTER TABLE ONLY info_request_events ALTER COLUMN id SET DEFAULT nextval('info_request_events_id_seq'::regclass);
+ALTER TABLE info_request_events ALTER COLUMN id SET DEFAULT nextval('info_request_events_id_seq'::regclass);
--
-- Name: id; Type: DEFAULT; Schema: public; Owner: -
--
-ALTER TABLE ONLY info_requests ALTER COLUMN id SET DEFAULT nextval('info_requests_id_seq'::regclass);
+ALTER TABLE info_requests ALTER COLUMN id SET DEFAULT nextval('info_requests_id_seq'::regclass);
--
-- Name: id; Type: DEFAULT; Schema: public; Owner: -
--
-ALTER TABLE ONLY mail_server_log_dones ALTER COLUMN id SET DEFAULT nextval('exim_log_dones_id_seq'::regclass);
+ALTER TABLE mail_server_log_dones ALTER COLUMN id SET DEFAULT nextval('exim_log_dones_id_seq'::regclass);
--
-- Name: id; Type: DEFAULT; Schema: public; Owner: -
--
-ALTER TABLE ONLY mail_server_logs ALTER COLUMN id SET DEFAULT nextval('exim_logs_id_seq'::regclass);
+ALTER TABLE mail_server_logs ALTER COLUMN id SET DEFAULT nextval('exim_logs_id_seq'::regclass);
--
-- Name: id; Type: DEFAULT; Schema: public; Owner: -
--
-ALTER TABLE ONLY outgoing_messages ALTER COLUMN id SET DEFAULT nextval('outgoing_messages_id_seq'::regclass);
+ALTER TABLE outgoing_messages ALTER COLUMN id SET DEFAULT nextval('outgoing_messages_id_seq'::regclass);
--
-- Name: id; Type: DEFAULT; Schema: public; Owner: -
--
-ALTER TABLE ONLY post_redirects ALTER COLUMN id SET DEFAULT nextval('post_redirects_id_seq'::regclass);
+ALTER TABLE post_redirects ALTER COLUMN id SET DEFAULT nextval('post_redirects_id_seq'::regclass);
--
-- Name: id; Type: DEFAULT; Schema: public; Owner: -
--
-ALTER TABLE ONLY profile_photos ALTER COLUMN id SET DEFAULT nextval('profile_photos_id_seq'::regclass);
+ALTER TABLE profile_photos ALTER COLUMN id SET DEFAULT nextval('profile_photos_id_seq'::regclass);
--
-- Name: id; Type: DEFAULT; Schema: public; Owner: -
--
-ALTER TABLE ONLY public_bodies ALTER COLUMN id SET DEFAULT nextval('public_bodies_id_seq'::regclass);
+ALTER TABLE public_bodies ALTER COLUMN id SET DEFAULT nextval('public_bodies_id_seq'::regclass);
--
-- Name: id; Type: DEFAULT; Schema: public; Owner: -
--
-ALTER TABLE ONLY public_body_translations ALTER COLUMN id SET DEFAULT nextval('public_body_translations_id_seq'::regclass);
+ALTER TABLE public_body_translations ALTER COLUMN id SET DEFAULT nextval('public_body_translations_id_seq'::regclass);
--
-- Name: id; Type: DEFAULT; Schema: public; Owner: -
--
-ALTER TABLE ONLY public_body_versions ALTER COLUMN id SET DEFAULT nextval('public_body_versions_id_seq'::regclass);
+ALTER TABLE public_body_versions ALTER COLUMN id SET DEFAULT nextval('public_body_versions_id_seq'::regclass);
--
-- Name: id; Type: DEFAULT; Schema: public; Owner: -
--
-ALTER TABLE ONLY purge_requests ALTER COLUMN id SET DEFAULT nextval('purge_requests_id_seq'::regclass);
+ALTER TABLE purge_requests ALTER COLUMN id SET DEFAULT nextval('purge_requests_id_seq'::regclass);
--
-- Name: id; Type: DEFAULT; Schema: public; Owner: -
--
-ALTER TABLE ONLY raw_emails ALTER COLUMN id SET DEFAULT nextval('raw_emails_id_seq'::regclass);
+ALTER TABLE raw_emails ALTER COLUMN id SET DEFAULT nextval('raw_emails_id_seq'::regclass);
--
-- Name: id; Type: DEFAULT; Schema: public; Owner: -
--
-ALTER TABLE ONLY request_classifications ALTER COLUMN id SET DEFAULT nextval('request_classifications_id_seq'::regclass);
+ALTER TABLE request_classifications ALTER COLUMN id SET DEFAULT nextval('request_classifications_id_seq'::regclass);
--
-- Name: id; Type: DEFAULT; Schema: public; Owner: -
--
-ALTER TABLE ONLY track_things ALTER COLUMN id SET DEFAULT nextval('track_things_id_seq'::regclass);
+ALTER TABLE track_things ALTER COLUMN id SET DEFAULT nextval('track_things_id_seq'::regclass);
--
-- Name: id; Type: DEFAULT; Schema: public; Owner: -
--
-ALTER TABLE ONLY track_things_sent_emails ALTER COLUMN id SET DEFAULT nextval('track_things_sent_emails_id_seq'::regclass);
+ALTER TABLE track_things_sent_emails ALTER COLUMN id SET DEFAULT nextval('track_things_sent_emails_id_seq'::regclass);
--
-- Name: id; Type: DEFAULT; Schema: public; Owner: -
--
-ALTER TABLE ONLY user_info_request_sent_alerts ALTER COLUMN id SET DEFAULT nextval('user_info_request_sent_alerts_id_seq'::regclass);
+ALTER TABLE user_info_request_sent_alerts ALTER COLUMN id SET DEFAULT nextval('user_info_request_sent_alerts_id_seq'::regclass);
--
-- Name: id; Type: DEFAULT; Schema: public; Owner: -
--
-ALTER TABLE ONLY users ALTER COLUMN id SET DEFAULT nextval('users_id_seq'::regclass);
+ALTER TABLE users ALTER COLUMN id SET DEFAULT nextval('users_id_seq'::regclass);
--
diff --git a/db/migrate/006_version_public_body.rb b/db/migrate/006_version_public_body.rb
index 34586add2..0e4527133 100644
--- a/db/migrate/006_version_public_body.rb
+++ b/db/migrate/006_version_public_body.rb
@@ -1,6 +1,8 @@
class VersionPublicBody < ActiveRecord::Migration
def self.up
PublicBody.create_versioned_table
+
+ add_timestamps(:public_body_versions)
end
def self.down
diff --git a/db/migrate/101_add_hash_to_info_request.rb b/db/migrate/101_add_hash_to_info_request.rb
index e21bf0989..e38384cd6 100644
--- a/db/migrate/101_add_hash_to_info_request.rb
+++ b/db/migrate/101_add_hash_to_info_request.rb
@@ -5,13 +5,11 @@ class AddHashToInfoRequest < ActiveRecord::Migration
add_column :info_requests, :idhash, :string
# Create the missing events for requests already sent
- InfoRequest.find(:all).each do |info_request|
- info_request.idhash = Digest::SHA1.hexdigest(info_request.id.to_s + Configuration::incoming_email_secret)[0,8]
+ InfoRequest.all.each do |info_request|
+ info_request.idhash = Digest::SHA1.hexdigest(info_request.id.to_s + AlaveteliConfiguration::incoming_email_secret)[0,8]
info_request.save!
- puts info_request.idhash
end
change_column :info_requests, :idhash, :string, :null => false
- puts InfoRequest.find_by_idhash
end
def self.down
remove_column :info_requests, :idhash
diff --git a/db/seeds.rb b/db/seeds.rb
new file mode 100644
index 000000000..664d8c74c
--- /dev/null
+++ b/db/seeds.rb
@@ -0,0 +1,7 @@
+# This file should contain all the record creation needed to seed the database with its default values.
+# The data can then be loaded with the rake db:seed (or created alongside the db with db:setup).
+#
+# Examples:
+#
+# cities = City.create([{ :name => 'Chicago' }, { :name => 'Copenhagen' }])
+# Mayor.create(:name => 'Daley', :city => cities.first)
diff --git a/doc/CHANGES.md b/doc/CHANGES.md
index 9a027a3a8..e53dcfe0b 100644
--- a/doc/CHANGES.md
+++ b/doc/CHANGES.md
@@ -1,3 +1,13 @@
+# Version 0.11
+## Highlighted features
+* Upgrade of the Rails framework to version 3.1.12 (Henare Degan, Matthew Landauer, Mark Longair, Louise Crow)
+
+## Upgrade notes
+* Manually remove vendor/rails-locales
+* Themes created for 0.9 and below should be updated to work with Rails 3. See `THEMES-UPGRADE.md` for notes on upgrading your theme. You will need to manually remove your old theme directory before running `rails-post-deploy`.
+* The `config/httpd.conf` has moved to `config/httpd.conf`, as it may need customization before deploying. It also has a new line setting RackEnv to production - copy this to your config/httpd.conf file.
+* Alaveteli now uses the [mail gem](https://github.com/mikel/mail) rather than [tmail](https://github.com/mikel/tmail) to handle mail. If you're using Exim as your MTA, you'll need to use the setting `extract_addresses_remove_arguments = false` in your Exim conf (see INSTALL-exim4.md for details). This means it won't remove addresses specified with -t on command line from the mail recipient list.
+
# Version 0.9
## Highlighted features
* Consistent and more informative variable interpolation syntax in translated phrases. All of these phrases will now appear in the form "There are {{count}} people following this request", where some were previously in the form "There are %s people following this request". (Matthew Landauer)
diff --git a/doc/INSTALL-exim4.md b/doc/INSTALL-exim4.md
index e37da14ff..cdc33ab12 100644
--- a/doc/INSTALL-exim4.md
+++ b/doc/INSTALL-exim4.md
@@ -6,15 +6,16 @@ In `/etc/exim4/conf.d/main/04_alaveteli_options`:
ALAVETELI_HOME=/path/to/alaveteli/software
ALAVETELI_USER=www-data
log_file_path=/var/log/exim4/exim-%slog-%D
- MAIN_LOG_SELECTOR==+all -retry_defer
+ MAIN_LOG_SELECTOR==+all -retry_defer
+ extract_addresses_remove_arguments=false
(The user ALAVETELI_USER should have write permissions on ALAVETELI_HOME).
-Note that the name and location of the log files created by Exim must match
+Note that the name and location of the log files created by Exim must match
what the `load-mail-server-logs` script expects, hence the need for the extra
`log_file_path` setting. And the `check-recent-requests-sent` scripts expects
-the logs to contain the `from=<...>` envelope information, so we make the
-logs more verbose with `log_selector`.
+the logs to contain the `from=<...>` envelope information, so we make the
+logs more verbose with `log_selector`.
In `/etc/exim4/conf.d/router/04_alaveteli`:
@@ -33,7 +34,7 @@ In `/etc/exim4/conf.d/transport/04_alaveteli`:
home_directory = ALAVETELI_HOME
user = ALAVETELI_USER
group = ALAVETELI_USER
-
+
And, assuming you set `INCOMING_EMAIL_PREFIX` in your config at
`config/general` to "foi+", create `config/aliases` with the following
content:
diff --git a/doc/INSTALL.md b/doc/INSTALL.md
index 2156f4c4a..b6e8d2265 100644
--- a/doc/INSTALL.md
+++ b/doc/INSTALL.md
@@ -67,15 +67,7 @@ Some of the files also have a version number listed in config/packages
# Install Ruby dependencies
-Install rubygems 1.6.2 (we're not using the Debian package because we
-need an older version; see "Troubleshooting" below for an
-explanation):
-
- wget http://rubyforge.org/frs/download.php/74445/rubygems-1.6.2.tgz -O /tmp/rubygems-1.6.2.tgz
- tar zxvf /tmp/rubygems-1.6.2.tgz -C /tmp/
- sudo ruby1.8 /tmp/rubygems-1.6.2/setup.rb
-
-To install Alaveteli's Ruby dependencies, we also need to install
+To install Alaveteli's Ruby dependencies, we need to install
bundler. In Debian, this is provided as a package (installed as part
of the package install process above). You could also install it as a
gem:
@@ -138,7 +130,8 @@ username and password of your postgres database.
Make sure that the user specified in database.yml exists, and has full
permissions on these databases. As they need the ability to turn off
constraints whilst running the tests they also need to be a superuser.
-(See http://dev.rubyonrails.org/ticket/9981)
+If you don't want your database user to be a superuser, you can add a line
+`disable_constraints: false` to the test config in database.yml, as seen in database.yml-example
You can create a `foi` user from the command line, thus:
@@ -230,7 +223,7 @@ for instructions on switching on local and remote performance analysis.
In the 'alaveteli' directory, run:
- ./script/rails-post-deploy
+ script/rails-post-deploy
(This will need execute privs so `chmod 755` if necessary.) This sets
up directory structures, creates logs, installs/updates themes, runs
@@ -245,11 +238,11 @@ If you want some dummy data to play with, you can try loading the
fixtures that the test suite uses into your development database. You
can do this with:
- ./script/load-sample-data
+ script/load-sample-data
Next we need to create the index for the search engine (Xapian):
- ./script/rebuild-xapian-index
+ script/rebuild-xapian-index
If this fails, the site should still mostly run, but it's a core
component so you should really try to get this working.
@@ -281,7 +274,7 @@ tests to pass by setting `export LD_PRELOAD=/lib/libuuid.so.1`.
Run the following to get the server running:
- ./script/server --environment=development
+ script/server --environment=development
By default the server listens on all interfaces. You can restrict it to the
localhost interface by adding ` --binding=127.0.0.1`
@@ -367,8 +360,8 @@ It is not recommended to run the website using the default Rails web
server. There are various recommendations here:
http://rubyonrails.org/deploy
-We usually use Passenger / mod_rails. The file at `conf/httpd.conf`
-contains the WhatDoTheyKnow settings. At a minimum, you should
+We usually use Passenger / mod_rails. The file at `conf/httpd.conf-example`
+gives you an example config file for WhatDoTheyKnow. At a minimum, you should
include the following in an Apache configuration file:
PassengerResolveSymlinksInDocumentRoot on
@@ -509,19 +502,6 @@ various other things that can be automated for deployment.
[https://github.com/mysociety/alaveteli/issues/128#issuecomment-1814845](this issue followup)
for further discussion.
-* **I'm getting lots of `SourceIndex.new(hash) is deprecated` errors when running the tests**
-
- The latest versions of rubygems contain a large number of noisy
- deprecation warnings that you can't turn off individually. Rails
- 2.x isn't under active development so isn't going to get fixed (in
- the sense of using a non-deprecated API). So the only vaguely
- sensible way to avoid this noisy output is to downgrade rubygems.
-
- For example, you might do this by uninstalling your
- system-packaged rubygems, and then installing the latest rubygems
- from source, and finally executing `sudo gem update --system
- 1.6.2`.
-
* **I'm seeing `rake: command not found` when running the post install script
The script uses `rake`.
diff --git a/doc/THEMES-UPGRADE.md b/doc/THEMES-UPGRADE.md
new file mode 100644
index 000000000..457274d7a
--- /dev/null
+++ b/doc/THEMES-UPGRADE.md
@@ -0,0 +1,101 @@
+This file contains some notes on changing your Alaveteli theme for the
+upgrade to Rails 3, in version 0.11 of Alaveteli. These were written
+by Henare Degan, with some additions by Mark Longair.
+
+# Alaveteli Theme Upgrade Checks
+
+## RAILS_ROOT/RAILS_ENV
+
+[Example](https://github.com/henare/adminbootstraptheme/commit/857e33c9b0bc577024b476404aec4f9749f65a0b)
+
+Check your theme for instances of:
+
+* `RAILS_ROOT` and replace it with `Rails.root`
+* `RAILS_ENV` and replace it with `Rails.env`
+
+Note that `Rails.root` is a `Pathname`, so you can replace, for
+example:
+
+ File.join(RAILS_ROOT, 'public', 'alavetelitheme')
+
+... with:
+
+ Rails.root.join('public', 'alavetelitheme')
+
+## Dispatcher
+
+[Example](https://github.com/henare/adminbootstraptheme/commit/fba2d6b7dfdc26a25fdc1596bfe120270dd4cd0d)
+
+This...
+
+```ruby
+require 'dispatcher'
+Dispatcher.to_prepare do
+```
+
+should be replaced with this...
+
+```ruby
+Rails.configuration.to_prepare do
+````
+
+## Routes
+
+[Example](https://github.com/henare/adminbootstraptheme/commit/87f1991dafb09401f9b17f642a94382d5a47a713)
+
+You need to upgrade your custom routes to the new Rails syntax.
+
+## list_public_bodies_default removed
+
+[Example](https://github.com/openaustralia/alavetelitheme/commit/5927877af996a1afb1a23a950f0d012b52c36f83)
+
+The list_public_bodies_default helper has been removed from Alaveteli
+
+## Patching mailer templates has changed
+
+[Example](https://github.com/openaustralia/alavetelitheme/commit/ffb5242973a0b2acc4981c25659fcb752b92eb97)
+
+In `lib/patch_mailer_paths.rb` change `ActionMailer::Base.view_paths.unshift File.join(File.dirname(__FILE__), "views")` to `ActionMailer::Base.prepend_view_path File.join(File.dirname(__FILE__), "views")`
+
+There's also `ActionMailer::Base.append_view_path` for replacing `ActionMailer::Base.view_paths <<`.
+
+## Rename view templates
+
+[Example](https://github.com/henare/adminbootstraptheme/commit/b616b636c283ae6cf696a6af1fa481f371baf2b6)
+
+Rename view templates from `filename.rhtml` to `filename.html.erb`.
+
+Run this in the root of your theme directory:
+
+ for r in $(find lib/views -name '*.rhtml'); do echo git mv $r ${r%.rhtml}.html.erb; done
+
+[GOTCHA!](https://github.com/openaustralia/alavetelitheme/commit/65e775488822367d981bb15ab2cbcf1fce842cc2)
+One exception is mailer templates, these should be renamed to
+`filename.text.erb` as we only use text emails.
+
+## The Configuration class has been renamed
+
+[Example](https://github.com/openaustralia/alavetelitheme/commit/db6cca4650216c6f85acffaea380727344f0f740)
+
+Due to a naming conflict, `Configuration` has been renamed to `AlaveteliConfiguration`.
+
+You may have this in your theme for things like `Configuration::site_name`, just change it to `AlaveteliConfiguration::site_name`
+
+## request.request_uri is deprecated
+
+[Example](https://github.com/openaustralia/alavetelitheme/commit/d670eeebfb049e1dc83fdb36a628f7722d2ad419)
+
+Replace instances of `request.request_uri` with `request.fullpath`
+
+## content-inserting <% %> block helpers are deprecated
+
+[Example](https://github.com/openaustralia/alavetelitheme/commit/a4b13bbd76249b3a28e2a755cede20dd9db30140)
+
+The Rails 3 releases notes are [irritatingly
+imprecise](http://edgeguides.rubyonrails.org/3_0_release_notes.html#helpers-with-blocks)
+about which such helpers have changed. You can find some candidates
+with this `git grep` command:
+
+ git grep -E '<%[^=].*(_for|_tag|link_to)\b'
+
+(Ignore `content_for` in those results.)
diff --git a/doc/THEMES.md b/doc/THEMES.md
index c5e4a3eee..8c4b927da 100644
--- a/doc/THEMES.md
+++ b/doc/THEMES.md
@@ -42,8 +42,8 @@ explanation.
You can also install the sample theme by hand, by running:
- ./script/plugin install git://github.com/mysociety/alavetelitheme.git
-
+ bundle exec rails plugin install git://github.com/mysociety/alavetelitheme.git -r rails-3
+
The sample theme contains examples for nearly everything you might
want to customise. You should probably make a copy, rename it, and
use that as the basis for your own theme.
@@ -66,8 +66,8 @@ add custom help pages, as described below.
The core templates that comprise the layout and user interface of an
Alaveteli site live in `app/views/`. They are use Rails' ERB syntax.
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`.
+`app/views/general/frontpage.html.erb`, and the template for the "about
+us" page is at `app/views/help/about.html.erb`.
Obviously, you *could* edit those core files directly, but this would
be a Bad Idea, because you would find it increasingly hard to do
@@ -90,7 +90,7 @@ the main Rails app -- see `alavetelitheme/install.rb` to see how this
happens.
The partial at
-`alavetelitheme/lib/views/general/_before_head_end.rhtml` includes the
+`alavetelitheme/lib/views/general/_before_head_end.html.erb` includes the
custom CSS in your theme's stylesheet folder (by convention, in
`alavetelitheme/public/stylesheets/`), with:
@@ -137,20 +137,20 @@ The latter must have one method:
When you've added your extra states, you also need to create the following files in your theme:
-* `lib/views/general/_custom_state_descriptions.rhtml`: Descriptions
+* `lib/views/general/_custom_state_descriptions.html.erb`: Descriptions
of your new states, suitable for displaying to end users
-* `lib/views/general/_custom_state_transitions_complete.rhtml`:
+* `lib/views/general/_custom_state_transitions_complete.html.erb`:
Descriptions for any new states that you might characterise as
'completion' states, for displaying on the categorisation form that
we ask requestors to fill out
-* `lib/views/general/_custom_state_transitions_pending.rhtml`: As
+* `lib/views/general/_custom_state_transitions_pending.html.erb`: As
above, but for new states you might characterise as 'pending'
states.
You can see examples of these customisations in
[this commit](https://github.com/sebbacon/informatazyrtare-theme/commit/2b240491237bd72415990399904361ce9bfa431d)
for the Kosovan version of Alaveteli, Informata Zyrtare (ignore the
-file `lib/views/general/_custom_state_transitions.rhtml`, which is
+file `lib/views/general/_custom_state_transitions.html.erb`, which is
unused).
# Adding new pages in the navigation
diff --git a/lib/activesupport_cache_extensions.rb b/lib/activesupport_cache_extensions.rb
index f15d72894..2791d5996 100644
--- a/lib/activesupport_cache_extensions.rb
+++ b/lib/activesupport_cache_extensions.rb
@@ -2,7 +2,7 @@
# Extensions / fixes to ActiveSupport::Cache
#
# Copyright (c) 2009 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
# Monkeypatch! ./activesupport/lib/active_support/cache/file_store.rb
diff --git a/lib/alaveteli_external_command.rb b/lib/alaveteli_external_command.rb
index 5e9a7ee83..fbdee8a62 100644
--- a/lib/alaveteli_external_command.rb
+++ b/lib/alaveteli_external_command.rb
@@ -22,14 +22,14 @@ module AlaveteliExternalCommand
program_path = program_name
else
found = false
- Configuration::utility_search_path.each do |d|
+ AlaveteliConfiguration::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 #{Configuration::utility_search_path.join(', ')}" if !found
+ raise "Could not find #{program_name} in any of #{AlaveteliConfiguration::utility_search_path.join(', ')}" if !found
end
xc = ExternalCommand.new(program_path, *args)
diff --git a/lib/configuration.rb b/lib/configuration.rb
index 4a0e0339b..88890856b 100644
--- a/lib/configuration.rb
+++ b/lib/configuration.rb
@@ -1,64 +1,77 @@
+require File.dirname(__FILE__) + '/../commonlib/rblib/config'
+
+# Load intial mySociety config
+if ENV["RAILS_ENV"] == "test"
+ MySociety::Config.set_file(File.join(File.dirname(__FILE__), '..', 'config', 'test'), true)
+else
+ MySociety::Config.set_file(File.join(File.dirname(__FILE__), '..', 'config', 'general'), true)
+end
+MySociety::Config.load_default
+
# Configuration values with defaults
# TODO: Make this return different values depending on the current rails environment
-module Configuration
- DEFAULTS = {
- :ADMIN_PASSWORD => '',
- :ADMIN_USERNAME => '',
- :AVAILABLE_LOCALES => '',
- :BLACKHOLE_PREFIX => 'do-not-reply-to-this-address',
- :BLOG_FEED => '',
- :CONTACT_EMAIL => 'contact@localhost',
- :CONTACT_NAME => 'Alaveteli',
- :COOKIE_STORE_SESSION_SECRET => 'this default is insecure as code is open source, please override for live sites in config/general; this will do for local development',
- :DEBUG_RECORD_MEMORY => false,
- :DEFAULT_LOCALE => '',
- :DISABLE_EMERGENCY_USER => false,
- :DOMAIN => 'localhost:3000',
- :EXCEPTION_NOTIFICATIONS_FROM => '',
- :EXCEPTION_NOTIFICATIONS_TO => '',
- :FORCE_REGISTRATION_ON_NEW_REQUEST => false,
- :FORCE_SSL => true,
- :FORWARD_NONBOUNCE_RESPONSES_TO => 'user-support@localhost',
- :FRONTPAGE_PUBLICBODY_EXAMPLES => '',
- :GA_CODE => '',
- :GAZE_URL => '',
- :HTML_TO_PDF_COMMAND => '',
- :INCLUDE_DEFAULT_LOCALE_IN_URLS => true,
- :INCOMING_EMAIL_DOMAIN => 'localhost',
- :INCOMING_EMAIL_PREFIX => '',
- :INCOMING_EMAIL_SECRET => 'dummysecret',
- :ISO_COUNTRY_CODE => 'GB',
- :MAX_REQUESTS_PER_USER_PER_DAY => '',
- :MTA_LOG_TYPE => 'exim',
- :NEW_RESPONSE_REMINDER_AFTER_DAYS => [3, 10, 24],
- :OVERRIDE_ALL_PUBLIC_BODY_REQUEST_EMAILS => '',
- :RAW_EMAILS_LOCATION => 'files/raw_emails',
- :READ_ONLY => '',
- :RECAPTCHA_PRIVATE_KEY => 'x',
- :RECAPTCHA_PUBLIC_KEY => 'x',
- :REPLY_LATE_AFTER_DAYS => 20,
- :REPLY_VERY_LATE_AFTER_DAYS => 40,
- :SITE_NAME => 'Alaveteli',
- :SKIP_ADMIN_AUTH => false,
- :SPECIAL_REPLY_VERY_LATE_AFTER_DAYS => 60,
- :THEME_BRANCH => false,
- :THEME_URL => "",
- :THEME_URLS => [],
- :TIME_ZONE => "UTC",
- :TRACK_SENDER_EMAIL => 'contact@localhost',
- :TRACK_SENDER_NAME => 'Alaveteli',
- :TWITTER_USERNAME => '',
- :TWITTER_WIDGET_ID => false,
- :USE_DEFAULT_BROWSER_LANGUAGE => true,
- :USE_GHOSTSCRIPT_COMPRESSION => false,
- :UTILITY_SEARCH_PATH => ["/usr/bin", "/usr/local/bin"],
- :VARNISH_HOST => '',
- :WORKING_OR_CALENDAR_DAYS => 'working',
- }
+module AlaveteliConfiguration
+ if !const_defined?(:DEFAULTS)
+
+ DEFAULTS = {
+ :ADMIN_PASSWORD => '',
+ :ADMIN_USERNAME => '',
+ :AVAILABLE_LOCALES => '',
+ :BLACKHOLE_PREFIX => 'do-not-reply-to-this-address',
+ :BLOG_FEED => '',
+ :CONTACT_EMAIL => 'contact@localhost',
+ :CONTACT_NAME => 'Alaveteli',
+ :COOKIE_STORE_SESSION_SECRET => 'this default is insecure as code is open source, please override for live sites in config/general; this will do for local development',
+ :DEBUG_RECORD_MEMORY => false,
+ :DEFAULT_LOCALE => '',
+ :DISABLE_EMERGENCY_USER => false,
+ :DOMAIN => 'localhost:3000',
+ :EXCEPTION_NOTIFICATIONS_FROM => '',
+ :EXCEPTION_NOTIFICATIONS_TO => '',
+ :FORCE_REGISTRATION_ON_NEW_REQUEST => false,
+ :FORCE_SSL => true,
+ :FORWARD_NONBOUNCE_RESPONSES_TO => 'user-support@localhost',
+ :FRONTPAGE_PUBLICBODY_EXAMPLES => '',
+ :GA_CODE => '',
+ :GAZE_URL => '',
+ :HTML_TO_PDF_COMMAND => '',
+ :INCLUDE_DEFAULT_LOCALE_IN_URLS => true,
+ :INCOMING_EMAIL_DOMAIN => 'localhost',
+ :INCOMING_EMAIL_PREFIX => '',
+ :INCOMING_EMAIL_SECRET => 'dummysecret',
+ :ISO_COUNTRY_CODE => 'GB',
+ :MAX_REQUESTS_PER_USER_PER_DAY => '',
+ :MTA_LOG_TYPE => 'exim',
+ :NEW_RESPONSE_REMINDER_AFTER_DAYS => [3, 10, 24],
+ :OVERRIDE_ALL_PUBLIC_BODY_REQUEST_EMAILS => '',
+ :RAW_EMAILS_LOCATION => 'files/raw_emails',
+ :READ_ONLY => '',
+ :RECAPTCHA_PRIVATE_KEY => 'x',
+ :RECAPTCHA_PUBLIC_KEY => 'x',
+ :REPLY_LATE_AFTER_DAYS => 20,
+ :REPLY_VERY_LATE_AFTER_DAYS => 40,
+ :SITE_NAME => 'Alaveteli',
+ :SKIP_ADMIN_AUTH => false,
+ :SPECIAL_REPLY_VERY_LATE_AFTER_DAYS => 60,
+ :THEME_BRANCH => false,
+ :THEME_URL => "",
+ :THEME_URLS => [],
+ :TIME_ZONE => "UTC",
+ :TRACK_SENDER_EMAIL => 'contact@localhost',
+ :TRACK_SENDER_NAME => 'Alaveteli',
+ :TWITTER_USERNAME => '',
+ :TWITTER_WIDGET_ID => false,
+ :USE_DEFAULT_BROWSER_LANGUAGE => true,
+ :USE_GHOSTSCRIPT_COMPRESSION => false,
+ :UTILITY_SEARCH_PATH => ["/usr/bin", "/usr/local/bin"],
+ :VARNISH_HOST => '',
+ :WORKING_OR_CALENDAR_DAYS => 'working',
+ }
+ end
- def Configuration.method_missing(name)
+ def AlaveteliConfiguration.method_missing(name)
key = name.to_s.upcase
if DEFAULTS.has_key?(key.to_sym)
MySociety::Config.get(key, DEFAULTS[key.to_sym])
diff --git a/lib/cookie_store_with_line_break_fix.rb b/lib/cookie_store_with_line_break_fix.rb
deleted file mode 100644
index dc623fbd0..000000000
--- a/lib/cookie_store_with_line_break_fix.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-# See https://makandracards.com/makandra/9443-rails-2-s-cookiestore-produces-invalid-cookie-data-causing-tests-to-break
-
-# Should be able to remove this when we upgrade to Rails 3
-
-module ActionController
- module Session
- CookieStore.class_eval do
-
- def call_with_line_break_fix(*args)
- status, headers, body = call_without_line_break_fix(*args)
- headers['Set-Cookie'].gsub! "\n\n", "\n" if headers['Set-Cookie'].present?
- [ status, headers, body ]
- end
-
- alias_method_chain :call, :line_break_fix
-
- end
- end
-end \ No newline at end of file
diff --git a/lib/google_translate.rb b/lib/google_translate.rb
deleted file mode 100644
index 369e1de3b..000000000
--- a/lib/google_translate.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-require 'rubygems'
-require 'net/http'
-require 'open-uri'
-require 'cgi'
-require 'json'
-
-def detect_language(request, translate_string)
- google_api_key = ''
- user_ip = URI.encode(request.env['REMOTE_ADDR'])
- translate_string = URI.encode(translate_string)
- url = "http://ajax.googleapis.com/ajax/services/language/detect?v=1.0&q=#{translate_string}&userip=#{user_ip}"
- if google_api_key != ''
- url += "&key=#{google_api_key}"
- end
- response = Net::HTTP.get_response(URI.parse(url))
- result = JSON.parse(response.body)
- result['responseData']['language']
-end
diff --git a/lib/mail_handler/backends/mail_backend.rb b/lib/mail_handler/backends/mail_backend.rb
index 0a12ab3bb..561946980 100644
--- a/lib/mail_handler/backends/mail_backend.rb
+++ b/lib/mail_handler/backends/mail_backend.rb
@@ -1,4 +1,35 @@
require 'mail'
+require 'mapi/msg'
+require 'mapi/convert'
+
+module Mail
+ class Message
+
+ # The behaviour of the 'to' and 'cc' methods have changed
+ # between TMail and Mail; this monkey-patching restores the
+ # TMail behaviour. The key difference is that when there's an
+ # invalid address, e.g. '<foo@example.org', Mail returns the
+ # string as an ActiveSupport::Multibyte::Chars, whereas
+ # previously TMail would return nil.
+
+ alias_method :old_to, :to
+ alias_method :old_cc, :cc
+
+ def clean_addresses(old_method, val)
+ old_result = self.send(old_method, val)
+ old_result.class == Mail::AddressContainer ? old_result : nil
+ end
+
+ def to(val = nil)
+ self.clean_addresses :old_to, val
+ end
+
+ def cc(val = nil)
+ self.clean_addresses :old_cc, val
+ end
+
+ end
+end
module MailHandler
module Backends
@@ -38,7 +69,11 @@ module MailHandler
# Get the body of a mail part
def get_part_body(part)
- part.body.decoded
+ decoded = part.body.decoded
+ if part.content_type =~ /^text\//
+ decoded = convert_string_to_utf8_or_binary decoded, part.charset
+ end
+ decoded
end
# Return the first from field if any
@@ -60,7 +95,7 @@ module MailHandler
def get_from_address(mail)
first_from = first_from(mail)
if first_from
- if first_from.is_a?(String)
+ if first_from.is_a?(ActiveSupport::Multibyte::Chars)
return nil
else
return first_from.address
@@ -74,7 +109,7 @@ module MailHandler
def get_from_name(mail)
first_from = first_from(mail)
if first_from
- if first_from.is_a?(String)
+ if first_from.is_a?(ActiveSupport::Multibyte::Chars)
return nil
else
return first_from.display_name ? eval(%Q{"#{first_from.display_name}"}) : nil
@@ -85,7 +120,7 @@ module MailHandler
end
def get_all_addresses(mail)
- envelope_to = mail['envelope-to'] ? [mail['envelope-to'].value] : []
+ envelope_to = mail['envelope-to'] ? [mail['envelope-to'].value.to_s] : []
((mail.to || []) +
(mail.cc || []) +
(envelope_to || [])).uniq
@@ -141,9 +176,14 @@ module MailHandler
end
elsif get_content_type(part) == 'application/ms-tnef'
# A set of attachments in a TNEF file
- part.rfc822_attachment = mail_from_tnef(part.body.decoded)
- if part.rfc822_attachment.nil?
- # Attached mail didn't parse, so treat as binary
+ begin
+ part.rfc822_attachment = mail_from_tnef(part.body.decoded)
+ if part.rfc822_attachment.nil?
+ # Attached mail didn't parse, so treat as binary
+ part.content_type = 'application/octet-stream'
+ end
+ rescue TNEFParsingError
+ part.rfc822_attachment = nil
part.content_type = 'application/octet-stream'
end
end
@@ -160,8 +200,11 @@ module MailHandler
part.parts.each{ |sub_part| expand_and_normalize_parts(sub_part, parent_mail) }
else
part_filename = get_part_file_name(part)
- charset = part.charset # save this, because overwriting content_type also resets charset
-
+ if part.has_charset?
+ original_charset = part.charset # save this, because overwriting content_type also resets charset
+ else
+ original_charset = nil
+ end
# Don't allow nil content_types
if get_content_type(part).nil?
part.content_type = 'application/octet-stream'
@@ -180,7 +223,9 @@ module MailHandler
# Use standard content types for Word documents etc.
part.content_type = normalise_content_type(get_content_type(part))
decode_attached_part(part, parent_mail)
- part.charset = charset
+ if original_charset
+ part.charset = original_charset
+ end
end
end
@@ -228,8 +273,15 @@ module MailHandler
def _get_attachment_leaves_recursive(part, within_rfc822_attachment, parent_mail)
leaves_found = []
if part.multipart?
- raise "no parts on multipart mail" if part.parts.size == 0
- if part.sub_type == 'alternative'
+ if part.parts.size == 0
+ # This is typically caused by a missing final
+ # MIME boundary, in which case the text of the
+ # message (including the opening MIME
+ # boundary) is in part.body, so just add this
+ # part as a leaf and treat it as text/plain:
+ part.content_type = "text/plain"
+ leaves_found += [part]
+ elsif part.sub_type == 'alternative'
best_part = choose_best_alternative(part)
leaves_found += _get_attachment_leaves_recursive(best_part,
within_rfc822_attachment,
@@ -315,8 +367,10 @@ module MailHandler
end
def address_from_string(string)
- Mail::Address.new(string).address
+ mail = Mail.new
+ mail.from = string
+ mail.from[0]
end
end
end
-end \ No newline at end of file
+end
diff --git a/lib/mail_handler/backends/mail_extensions.rb b/lib/mail_handler/backends/mail_extensions.rb
index f756abd1a..322c49bb5 100644
--- a/lib/mail_handler/backends/mail_extensions.rb
+++ b/lib/mail_handler/backends/mail_extensions.rb
@@ -64,4 +64,68 @@ module Mail
end.join(";\r\n\s")
end
end
-end \ No newline at end of file
+
+ # HACK: Backport encoding fixes for Ruby 1.8 from Mail 2.5
+ # Can be removed when we no longer support Ruby 1.8
+ class Ruby18
+ def Ruby18.b_value_decode(str)
+ match = str.match(/\=\?(.+)?\?[Bb]\?(.+)?\?\=/m)
+ if match
+ encoding = match[1]
+ str = Ruby18.decode_base64(match[2])
+ # Adding and removing trailing spaces is a workaround
+ # for Iconv.conv throwing an exception if it finds an
+ # invalid character at the end of the string, even
+ # with UTF-8//IGNORE:
+ # http://po-ru.com/diary/fixing-invalid-utf-8-in-ruby-revisited/
+ str = Iconv.conv('UTF-8//IGNORE', fix_encoding(encoding), str + " ")[0...-4]
+ end
+ str
+ end
+
+ def Ruby18.q_value_decode(str)
+ match = str.match(/\=\?(.+)?\?[Qq]\?(.+)?\?\=/m)
+ if match
+ encoding = match[1]
+ string = match[2].gsub(/_/, '=20')
+ # Remove trailing = if it exists in a Q encoding
+ string = string.sub(/\=$/, '')
+ str = Encodings::QuotedPrintable.decode(string)
+ # Adding and removing trailing spaces is a workaround
+ # for Iconv.conv throwing an exception if it finds an
+ # invalid character at the end of the string, even
+ # with UTF-8//IGNORE:
+ # http://po-ru.com/diary/fixing-invalid-utf-8-in-ruby-revisited/
+ str = Iconv.conv('UTF-8//IGNORE', fix_encoding(encoding), str + " ")[0...-4]
+ end
+ str
+ end
+
+ private
+
+ def Ruby18.fix_encoding(encoding)
+ case encoding.upcase
+ when 'UTF8'
+ 'UTF-8'
+ else
+ encoding
+ end
+ end
+ end
+ class Ruby19
+
+ def Ruby19.q_value_decode(str)
+ match = str.match(/\=\?(.+)?\?[Qq]\?(.+)?\?\=/m)
+ if match
+ encoding = match[1]
+ str = Encodings::QuotedPrintable.decode(match[2].gsub(/_/, '=20'))
+ # Backport line from mail 2.5 to strip a trailing = character
+ # Remove trailing = if it exists in a Q encoding
+ str = str.sub(/\=$/, '')
+ str.force_encoding(fix_encoding(encoding))
+ end
+ decoded = str.encode("utf-8", :invalid => :replace, :replace => "")
+ decoded.valid_encoding? ? decoded : decoded.encode("utf-16le", :invalid => :replace, :replace => "").encode("utf-8")
+ end
+ end
+end
diff --git a/lib/mail_handler/backends/tmail_backend.rb b/lib/mail_handler/backends/tmail_backend.rb
deleted file mode 100644
index 1e241f261..000000000
--- a/lib/mail_handler/backends/tmail_backend.rb
+++ /dev/null
@@ -1,288 +0,0 @@
-module MailHandler
- module Backends
- module TmailBackend
-
- def backend()
- 'TMail'
- end
-
- # Turn raw data into a structured TMail::Mail object
- # Documentation at http://i.loveruby.net/en/projects/tmail/doc/
- def mail_from_raw_email(data)
- # Hack round bug in TMail's MIME decoding.
- # Report of TMail bug:
- # http://rubyforge.org/tracker/index.php?func=detail&aid=21810&group_id=4512&atid=17370
- copy_of_raw_data = data.gsub(/; boundary=\s+"/im,'; boundary="')
- TMail::Mail.parse(copy_of_raw_data)
- end
-
- # Extracts all attachments from the given TNEF file as a TMail::Mail object
- def mail_from_tnef(content)
- main = TMail::Mail.new
- main.set_content_type 'multipart', 'mixed', { 'boundary' => TMail.new_boundary }
- tnef_attachments(content).each do |attachment|
- tmail_attachment = TMail::Mail.new
- tmail_attachment['content-location'] = attachment[:filename]
- tmail_attachment.body = attachment[:content]
- main.parts << tmail_attachment
- end
- main
- end
-
- # Return a copy of the file name for the mail part
- def get_part_file_name(mail_part)
- part_file_name = TMail::Mail.get_part_file_name(mail_part)
- if part_file_name.nil?
- return nil
- end
- part_file_name = part_file_name.dup
- return part_file_name
- end
-
- # Get the body of a mail part
- def get_part_body(mail_part)
- mail_part.body
- end
-
- # Return the first from address if any
- def get_from_address(mail)
- if mail.from_addrs.nil? || mail.from_addrs.size == 0
- return nil
- end
- mail.from_addrs[0].spec
- end
-
- # Return the first from name if any
- def get_from_name(mail)
- mail.from_name_if_present
- end
-
- def get_all_addresses(mail)
- ((mail.to || []) +
- (mail.cc || []) +
- (mail.envelope_to || [])).uniq
- end
-
- def empty_return_path?(mail)
- return false if mail['return-path'].nil?
- return true if mail['return-path'].addr.to_s == '<>'
- return false
- end
-
- def get_auto_submitted(mail)
- mail['auto-submitted'] ? mail['auto-submitted'].body : nil
- end
-
- def get_content_type(part)
- part.content_type
- end
-
- def get_header_string(header, mail)
- mail.header_string(header)
- end
-
- # Number the attachments in depth first tree order, for use in URLs.
- # XXX This fills in part.rfc822_attachment and part.url_part_number within
- # all the parts of the email (see monkeypatches in lib/mail_handler/tmail_extensions and
- # lib/mail_handler/mail_extensions for how these attributes are added). ensure_parts_counted
- # must be called before using the attributes.
- def ensure_parts_counted(mail)
- mail.count_parts_count = 0
- _count_parts_recursive(mail, mail)
- # we carry on using these numeric ids for attachments uudecoded from within text parts
- mail.count_first_uudecode_count = mail.count_parts_count
- end
- def _count_parts_recursive(part, mail)
- if part.multipart?
- part.parts.each do |p|
- _count_parts_recursive(p, mail)
- end
- else
- part_filename = get_part_file_name(part)
- begin
- if part.content_type == 'message/rfc822'
- # An email attached as text
- # e.g. http://www.whatdotheyknow.com/request/64/response/102
- part.rfc822_attachment = mail_from_raw_email(part.body)
- elsif part.content_type == 'application/vnd.ms-outlook' || part_filename && AlaveteliFileTypes.filename_to_mimetype(part_filename) == 'application/vnd.ms-outlook'
- # An email attached as an Outlook file
- # e.g. http://www.whatdotheyknow.com/request/chinese_names_for_british_politi
- msg = Mapi::Msg.open(StringIO.new(part.body))
- part.rfc822_attachment = mail_from_raw_email(msg.to_mime.to_s)
- elsif part.content_type == 'application/ms-tnef'
- # A set of attachments in a TNEF file
- part.rfc822_attachment = mail_from_tnef(part.body)
- end
- rescue
- # If attached mail doesn't parse, treat it as text part
- part.rfc822_attachment = nil
- else
- unless part.rfc822_attachment.nil?
- _count_parts_recursive(part.rfc822_attachment, mail)
- end
- end
- if part.rfc822_attachment.nil?
- mail.count_parts_count += 1
- part.url_part_number = mail.count_parts_count
- end
- end
- end
-
- def get_attachment_attributes(mail)
- leaves = get_attachment_leaves(mail)
- # XXX we have to call ensure_parts_counted after get_attachment_leaves
- # which is really messy.
- ensure_parts_counted(mail)
- attachment_attributes = []
- for leaf in leaves
- body = get_part_body(leaf)
- # As leaf.body causes MIME decoding which uses lots of RAM, do garbage collection here
- # to prevent excess memory use. XXX not really sure if this helps reduce
- # peak RAM use overall. Anyway, maybe there is something better to do than this.
- GC.start
- if leaf.within_rfc822_attachment
- within_rfc822_subject = leaf.within_rfc822_attachment.subject
- # Test to see if we are in the first part of the attached
- # RFC822 message and it is text, if so add headers.
- # XXX should probably use hunting algorithm to find main text part, rather than
- # just expect it to be first. This will do for now though.
- if leaf.within_rfc822_attachment == leaf && leaf.content_type == 'text/plain'
- headers = ""
- for header in [ 'Date', 'Subject', 'From', 'To', 'Cc' ]
- if leaf.within_rfc822_attachment.header.include?(header.downcase)
- header_value = leaf.within_rfc822_attachment.header[header.downcase]
- if !header_value.blank?
- headers = headers + header + ": " + header_value.to_s + "\n"
- end
- end
- end
- # XXX call _convert_part_body_to_text here, but need to get charset somehow
- # e.g. http://www.whatdotheyknow.com/request/1593/response/3088/attach/4/Freedom%20of%20Information%20request%20-%20car%20oval%20sticker:%20Article%2020,%20Convention%20on%20Road%20Traffic%201949.txt
- body = headers + "\n" + body
-
- # This is quick way of getting all headers, but instead we only add some a) to
- # make it more usable, b) as at least one authority accidentally leaked security
- # information into a header.
- #attachment.body = leaf.within_rfc822_attachment.port.to_s
- end
- end
- attachment_attributes << {:url_part_number => leaf.url_part_number,
- :content_type => get_content_type(leaf),
- :filename => get_part_file_name(leaf),
- :charset => leaf.charset,
- :within_rfc822_subject => within_rfc822_subject,
- :body => body,
- :hexdigest => Digest::MD5.hexdigest(body) }
- end
- attachment_attributes
- end
-
- # (This risks losing info if the unchosen alternative is the only one to contain
- # useful info, but let's worry about that another time)
- def get_attachment_leaves(mail)
- return _get_attachment_leaves_recursive(mail, mail)
- end
- def _get_attachment_leaves_recursive(curr_mail, parent_mail, within_rfc822_attachment = nil)
- leaves_found = []
- if curr_mail.multipart?
- if curr_mail.parts.size == 0
- raise "no parts on multipart mail"
- end
-
- if curr_mail.sub_type == 'alternative'
- # Choose best part from alternatives
- best_part = nil
- # Take the last text/plain one, or else the first one
- curr_mail.parts.each do |m|
- if not best_part
- best_part = m
- elsif m.content_type == 'text/plain'
- best_part = m
- end
- end
- # Take an HTML one as even higher priority. (They tend
- # to render better than text/plain, e.g. don't wrap links here:
- # http://www.whatdotheyknow.com/request/amount_and_cost_of_freedom_of_in#incoming-72238 )
- curr_mail.parts.each do |m|
- if m.content_type == 'text/html'
- best_part = m
- end
- end
- leaves_found += _get_attachment_leaves_recursive(best_part, parent_mail, within_rfc822_attachment)
- else
- # Add all parts
- curr_mail.parts.each do |m|
- leaves_found += _get_attachment_leaves_recursive(m, parent_mail, within_rfc822_attachment)
- end
- end
- else
- # XXX Yuck. this section alters various content_types. That puts
- # 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'
- end
- # PDFs often come with this mime type, fix it up for view code
- if curr_mail.content_type == 'application/octet-stream'
- part_file_name = get_part_file_name(curr_mail)
- part_body = get_part_body(curr_mail)
- calc_mime = AlaveteliFileTypes.filename_and_content_to_mimetype(part_file_name, part_body)
- if calc_mime
- curr_mail.content_type = calc_mime
- end
- end
-
- # Use standard content types for Word documents etc.
- curr_mail.content_type = normalise_content_type(curr_mail.content_type)
- if curr_mail.content_type == 'message/rfc822'
- ensure_parts_counted(parent_mail) # fills in rfc822_attachment variable
- if curr_mail.rfc822_attachment.nil?
- # Attached mail didn't parse, so treat as text
- curr_mail.content_type = 'text/plain'
- end
- end
- if curr_mail.content_type == 'application/vnd.ms-outlook' || curr_mail.content_type == 'application/ms-tnef'
- ensure_parts_counted(parent_mail) # fills in rfc822_attachment variable
- if curr_mail.rfc822_attachment.nil?
- # Attached mail didn't parse, so treat as binary
- 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(parent_mail) # fills in rfc822_attachment variable
- leaves_found += _get_attachment_leaves_recursive(curr_mail.rfc822_attachment, parent_mail, curr_mail.rfc822_attachment)
- else
- # Store leaf
- 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
-
-
- def address_from_name_and_email(name, email)
- if !MySociety::Validate.is_valid_email(email)
- raise "invalid email " + email + " passed to address_from_name_and_email"
- end
- if name.nil?
- return TMail::Address.parse(email).to_s
- end
- # Botch an always quoted RFC address, then parse it
- name = name.gsub(/(["\\])/, "\\\\\\1")
- TMail::Address.parse('"' + name + '" <' + email + '>').to_s
- end
-
- def address_from_string(string)
- TMail::Address.parse(string).address
- end
-
- end
- end
-end \ No newline at end of file
diff --git a/lib/mail_handler/backends/tmail_extensions.rb b/lib/mail_handler/backends/tmail_extensions.rb
deleted file mode 100644
index 3576a8eca..000000000
--- a/lib/mail_handler/backends/tmail_extensions.rb
+++ /dev/null
@@ -1,138 +0,0 @@
-# lib/tmail_extensions.rb:
-# Extensions / fixes to TMail.
-#
-# Copyright (c) 2009 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
-
-require 'racc/parser'
-require 'tmail'
-require 'tmail/scanner'
-require 'tmail/utils'
-require 'tmail/interface'
-
-# Monkeypatch!
-
-# These mainly used in app/models/incoming_message.rb
-module TMail
- class Mail
- # Monkeypatch! Adding some extra members to store extra info in.
-
- attr_accessor :url_part_number
- attr_accessor :rfc822_attachment # when a whole email message is attached as text
- attr_accessor :within_rfc822_attachment # for parts within a message attached as text (for getting subject mainly)
- attr_accessor :count_parts_count
- attr_accessor :count_first_uudecode_count
-
- # Monkeypatch! (check to see if this becomes a standard function in
- # TMail::Mail, then use that, whatever it is called)
- def Mail.get_part_file_name(part)
- file_name = (part['content-location'] &&
- part['content-location'].body) ||
- part.sub_header("content-type", "name") ||
- part.sub_header("content-disposition", "filename")
- file_name = file_name.strip if file_name
- file_name
- end
-
- # 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 TMail::Unquoter.unquote_and_convert_to(self.from_addrs[0].name, "utf-8")
- else
- return nil
- end
- end
-
- # Monkeypatch! Generalisation of To:, Cc:
- def envelope_to(default = nil)
- # XXX assumes only one envelope-to, and no parsing needed
- val = self.header_string('envelope-to')
- return val ? [val,] : []
- end
-
- # Monkeypatch!
- # Bug fix to this function - is for message in humberside-police-odd-mime-type.email
- # Which was originally: https://secure.mysociety.org/admin/foi/request/show_raw_email/11209
- # See test in spec/lib/tmail_extensions.rb
- def set_content_type( str, sub = nil, param = nil )
- if sub
- main, sub = str, sub
- else
- main, sub = str.split(%r</>, 2)
- raise ArgumentError, "sub type missing: #{str.inspect}" unless sub
- end
- if h = @header['content-type']
- h.main_type = main
- h.sub_type = sub
- h.params.clear if !h.params.nil? # XXX this if statement is the fix # XXX disabled until works with test
- else
- store 'Content-Type', "#{main}/#{sub}"
- end
- @header['content-type'].params.replace param if param
- str
- end
- # Need to make sure this alias calls the Monkeypatch too
- alias content_type= set_content_type
-
- end
-
- module TextUtils
- # Monkeypatch! Much more aggressive list of characters to cause quoting
- # than in normal TMail. e.g. Have found real cases where @ needs quoting.
- # We list characters to allow, rather than characters not to allow.
- NEW_PHRASE_UNSAFE=/[^A-Za-z0-9!#\$%&'*+\-\/=?^_`{|}~ ]/n
- def quote_phrase( str )
- (NEW_PHRASE_UNSAFE === str) ? dquote(str) : str
- end
- end
-end
-
-# Monkeypatch! TMail 1.2.7.1 will parse only one address out of a list of addresses with
-# unquoted display parts https://github.com/mikel/tmail/issues#issue/9 - this monkeypatch
-# fixes this issue.
-module TMail
-
- class Parser < Racc::Parser
-
-module_eval <<'..end lib/tmail/parser.y modeval..id2dd1c7d21d', 'lib/tmail/parser.y', 340
-
- def self.special_quote_address(str) #:nodoc:
- # Takes a string which is an address and adds quotation marks to special
- # edge case methods that the RACC parser can not handle.
- #
- # Right now just handles two edge cases:
- #
- # Full stop as the last character of the display name:
- # Mikel L. <mikel@me.com>
- # Returns:
- # "Mikel L." <mikel@me.com>
- #
- # Unquoted @ symbol in the display name:
- # mikel@me.com <mikel@me.com>
- # Returns:
- # "mikel@me.com" <mikel@me.com>
- #
- # Any other address not matching these patterns just gets returned as is.
- case
- # This handles the missing "" in an older version of Apple Mail.app
- # around the display name when the display name contains a '@'
- # like 'mikel@me.com <mikel@me.com>'
- # Just quotes it to: '"mikel@me.com" <mikel@me.com>'
- when str =~ /\A([^"][^<]+@[^>]+[^"])\s(<.*?>)\Z/
- return "\"#{$1}\" #{$2}"
- # This handles cases where 'Mikel A. <mikel@me.com>' which is a trailing
- # full stop before the address section. Just quotes it to
- # '"Mikel A." <mikel@me.com>'
- when str =~ /\A(.*?\.)\s(<.*?>)\s*\Z/
- return "\"#{$1}\" #{$2}"
- else
- str
- end
- end
-
-..end lib/tmail/parser.y modeval..id2dd1c7d21d
- end # class Parser
-
-end # module TMail
-
-
diff --git a/lib/mail_handler/mail_handler.rb b/lib/mail_handler/mail_handler.rb
index cd5abfab7..9c955cccd 100644
--- a/lib/mail_handler/mail_handler.rb
+++ b/lib/mail_handler/mail_handler.rb
@@ -3,16 +3,12 @@ require 'tmpdir'
module MailHandler
- if RUBY_VERSION.to_f >= 1.9
- require 'mail'
- require 'backends/mail_extensions'
- require 'backends/mail_backend'
- include Backends::MailBackend
- else
- require 'action_mailer'
- require 'backends/tmail_extensions'
- require 'backends/tmail_backend'
- include Backends::TmailBackend
+ require 'mail'
+ require 'backends/mail_extensions'
+ require 'backends/mail_backend'
+ include Backends::MailBackend
+
+ class TNEFParsingError < StandardError
end
# Returns a set of attachments from the given TNEF contents
@@ -21,14 +17,14 @@ module MailHandler
def tnef_attachments(content)
attachments = []
Dir.mktmpdir do |dir|
- IO.popen("#{`which tnef`.chomp} -K -C #{dir}", "wb") do |f|
+ IO.popen("tnef -K -C #{dir} 2> /dev/null", "wb") do |f|
f.write(content)
f.close
if $?.signaled?
raise IOError, "tnef exited with signal #{$?.termsig}"
end
if $?.exited? && $?.exitstatus != 0
- raise IOError, "tnef exited with status #{$?.exitstatus}"
+ raise TNEFParsingError, "tnef exited with status #{$?.exitstatus}"
end
end
found = 0
@@ -41,7 +37,7 @@ module MailHandler
end
end
if found == 0
- raise IOError, "tnef produced no attachments"
+ raise TNEFParsingError, "tnef produced no attachments"
end
end
attachments
diff --git a/lib/no_constraint_disabling.rb b/lib/no_constraint_disabling.rb
new file mode 100644
index 000000000..d515a959a
--- /dev/null
+++ b/lib/no_constraint_disabling.rb
@@ -0,0 +1,110 @@
+# In order to work around the problem of the database use not having
+# the permission to disable referential integrity when loading fixtures,
+# we redefine disable_referential_integrity so that it doesn't try to
+# disable foreign key constraints, and redefine the
+# ActiveRecord::Fixtures.create_fixtures method to pay attention to the order
+# which fixture tables are passed so that foreign key constraints won't be
+# violated. The only lines that are changed from the initial definition
+# are those between the "***" comments
+require 'active_record/fixtures'
+require 'active_record/connection_adapters/postgresql_adapter'
+module ActiveRecord
+ module ConnectionAdapters
+ class PostgreSQLAdapter < AbstractAdapter
+ def disable_referential_integrity(&block)
+ transaction {
+ yield
+ }
+ end
+ end
+ end
+end
+
+module ActiveRecord
+ class Fixtures
+
+ def self.create_fixtures(fixtures_directory, table_names, class_names = {})
+ table_names = [table_names].flatten.map { |n| n.to_s }
+ table_names.each { |n|
+ class_names[n.tr('/', '_').to_sym] = n.classify if n.include?('/')
+ }
+
+ # FIXME: Apparently JK uses this.
+ connection = block_given? ? yield : ActiveRecord::Base.connection
+
+ files_to_read = table_names.reject { |table_name|
+ fixture_is_cached?(connection, table_name)
+ }
+
+ unless files_to_read.empty?
+ connection.disable_referential_integrity do
+ fixtures_map = {}
+
+ fixture_files = files_to_read.map do |path|
+ table_name = path.tr '/', '_'
+
+ fixtures_map[path] = ActiveRecord::Fixtures.new(
+ connection,
+ table_name,
+ class_names[table_name.to_sym] || table_name.classify,
+ File.join(fixtures_directory, path))
+ end
+
+ all_loaded_fixtures.update(fixtures_map)
+
+ connection.transaction(:requires_new => true) do
+ # Patch - replace this...
+ # ***
+ # fixture_files.each do |ff|
+ # conn = ff.model_class.respond_to?(:connection) ? ff.model_class.connection : connection
+ # table_rows = ff.table_rows
+ #
+ # table_rows.keys.each do |table|
+ # conn.delete "DELETE FROM #{conn.quote_table_name(table)}", 'Fixture Delete'
+ # end
+ #
+ # table_rows.each do |table_name,rows|
+ # rows.each do |row|
+ # conn.insert_fixture(row, table_name)
+ # end
+ # end
+ # end
+ # ***
+ # ... with this
+ fixture_files.reverse.each do |ff|
+ conn = ff.model_class.respond_to?(:connection) ? ff.model_class.connection : connection
+ table_rows = ff.table_rows
+
+ table_rows.keys.each do |table|
+ conn.delete "DELETE FROM #{conn.quote_table_name(table)}", 'Fixture Delete'
+ end
+ end
+
+ fixture_files.each do |ff|
+ conn = ff.model_class.respond_to?(:connection) ? ff.model_class.connection : connection
+ table_rows = ff.table_rows
+ table_rows.each do |table_name,rows|
+ rows.each do |row|
+ conn.insert_fixture(row, table_name)
+ end
+ end
+ end
+ # ***
+
+ # Cap primary key sequences to max(pk).
+ if connection.respond_to?(:reset_pk_sequence!)
+ table_names.each do |table_name|
+ connection.reset_pk_sequence!(table_name.tr('/', '_'))
+ end
+ end
+ end
+
+ cache_fixtures(connection, fixtures_map)
+ end
+ end
+ cached_fixtures(connection, table_names)
+ end
+
+ end
+
+end
diff --git a/lib/normalize_string.rb b/lib/normalize_string.rb
new file mode 100644
index 000000000..f02b18ee0
--- /dev/null
+++ b/lib/normalize_string.rb
@@ -0,0 +1,86 @@
+require 'iconv' unless RUBY_VERSION.to_f >= 1.9
+require 'charlock_holmes'
+
+class EncodingNormalizationError < StandardError
+end
+
+def normalize_string_to_utf8(s, suggested_character_encoding=nil)
+
+ # Make a list of encodings to try:
+ to_try = []
+
+ guessed_encoding = CharlockHolmes::EncodingDetector.detect(s)[:encoding]
+ guessed_encoding ||= ''
+
+ # It's reasonably common for windows-1252 text to be mislabelled
+ # as ISO-8859-1, so try that first if charlock_holmes guessed
+ # that. However, it can also easily misidentify UTF-8 strings as
+ # ISO-8859-1 so we don't want to go with the guess by default...
+ to_try.push guessed_encoding if guessed_encoding.downcase == 'windows-1252'
+
+ to_try.push suggested_character_encoding if suggested_character_encoding
+ to_try.push 'UTF-8'
+ to_try.push guessed_encoding
+
+ to_try.each do |from_encoding|
+ if RUBY_VERSION.to_f >= 1.9
+ begin
+ s.force_encoding from_encoding
+ return s.encode('UTF-8') if s.valid_encoding?
+ rescue ArgumentError
+ # We get this is there are invalid bytes when
+ # interpreted as from_encoding at the point of
+ # the encode('UTF-8'); move onto the next one...
+ end
+ else
+ to_encoding = 'UTF-8'
+ begin
+ converted = Iconv.conv 'UTF-8', from_encoding, s
+ return converted
+ rescue Iconv::Failure
+ # We get this is there are invalid bytes when
+ # interpreted as from_encoding at the point of
+ # the Iconv.iconv; move onto the next one...
+ end
+ end
+ end
+ raise EncodingNormalizationError, "Couldn't find a valid character encoding for the string"
+
+end
+
+def convert_string_to_utf8_or_binary(s, suggested_character_encoding=nil)
+ # This function exists to help to keep consistent with the
+ # behaviour of earlier versions of Alaveteli: in the code as it
+ # is, there are situations where it's expected that we generally
+ # have a UTF-8 encoded string, but if the source data was
+ # unintepretable under any character encoding, the string may be
+ # binary data (i.e. invalid UTF-8). Such a string would then be
+ # mangled into valid UTF-8 by _sanitize_text for the purposes of
+ # display.
+
+ # This seems unsatisfactory to me - two better alternatives would
+ # be either: (a) to mangle the data into valid UTF-8 in this
+ # method or (b) to treat the 'text/*' attachment as
+ # 'application/octet-stream' instead. However, for the purposes
+ # of the transition to Ruby 1.9 and/or Rails 3 we just want the
+ # behaviour to be as similar as possible.
+
+ begin
+ result = normalize_string_to_utf8 s, suggested_character_encoding
+ rescue EncodingNormalizationError
+ result = s
+ s.force_encoding 'ASCII-8BIT' if RUBY_VERSION.to_f >= 1.9
+ end
+ result
+end
+
+def log_text_details(message, text)
+ if RUBY_VERSION.to_f >= 1.9
+ STDERR.puts "#{message}, we have text: #{text}, of class #{text.class} and encoding #{text.encoding}"
+ else
+ STDERR.puts "#{message}, we have text: #{text}, of class #{text.class}"
+ end
+ filename = "/var/tmp/#{Digest::MD5.hexdigest(text)}.txt"
+ File.open(filename, "wb") { |f| f.write text }
+ STDERR.puts "#{message}, the filename is: #{filename}"
+end
diff --git a/lib/old_rubygems_patch.rb b/lib/old_rubygems_patch.rb
deleted file mode 100644
index 3001a7381..000000000
--- a/lib/old_rubygems_patch.rb
+++ /dev/null
@@ -1,46 +0,0 @@
-if File.exist? File.join(File.dirname(__FILE__),'..','vendor','rails','railties','lib','rails','gem_dependency.rb')
- require File.join(File.dirname(__FILE__),'..','vendor','rails','railties','lib','rails','gem_dependency.rb')
-else
- require 'rails/gem_dependency'
-end
-
-module Rails
- class GemDependency < Gem::Dependency
-
- # This definition of the requirement method is a patch
- if !method_defined?(:requirement)
- def requirement
- req = version_requirements
- end
- end
-
- def add_load_paths
- self.class.add_frozen_gem_path
- return if @loaded || @load_paths_added
- if framework_gem?
- @load_paths_added = @loaded = @frozen = true
- return
- end
-
- begin
- dep = Gem::Dependency.new(name, requirement)
- spec = Gem.source_index.find { |_,s| s.satisfies_requirement?(dep) }.last
- spec.activate # a way that exists
- rescue
- begin
- gem self.name, self.requirement # < 1.8 unhappy way
- # This second rescue is a patch - fall back to passing Rails::GemDependency to gem
- # for older rubygems
- rescue ArgumentError
- gem self
- end
- end
-
- @spec = Gem.loaded_specs[name]
- @frozen = @spec.loaded_from.include?(self.class.unpacked_path) if @spec
- @load_paths_added = true
- rescue Gem::LoadError
- end
- end
-
-end
diff --git a/lib/patches/fixtures_constraint_disabling.rb b/lib/patches/fixtures_constraint_disabling.rb
deleted file mode 100644
index 7d97e81f7..000000000
--- a/lib/patches/fixtures_constraint_disabling.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-# 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 c6f0a6690..7f548b130 100644
--- a/lib/public_body_categories.rb
+++ b/lib/public_body_categories.rb
@@ -2,7 +2,7 @@
# Categorisations of public bodies.
#
# Copyright (c) 2009 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
class PublicBodyCategories
diff --git a/lib/rack_quote_monkeypatch.rb b/lib/rack_quote_monkeypatch.rb
deleted file mode 100644
index b477ac0cb..000000000
--- a/lib/rack_quote_monkeypatch.rb
+++ /dev/null
@@ -1,65 +0,0 @@
-# There's a bug in Rack 1.1.x which is fixed in Rack 1.2, but our
-# current version of Rails won't use that. So for now, monkeypatch,
-# This can be dropped when we move to Rails 3.
-#
-# See https://github.com/mysociety/alaveteli/issues/38 for Alaveteli
-# bug report
-#
-# More info about the monkeypatch:
-# http://thewebfellas.com/blog/2010/7/15/rails-2-3-8-rack-1-1-and-the-curious-case-of-the-missing-quotes
-
-module Rack
- module Utils
- def parse_query(qs, d = nil)
- params = {}
-
- (qs || '').split(d ? /[#{d}] */n : DEFAULT_SEP).each do |p|
- k, v = p.split('=', 2).map { |x| unescape(x) }
- if cur = params[k]
- if cur.class == Array
- params[k] << v
- else
- params[k] = [cur, v]
- end
- else
- params[k] = v
- end
- end
-
- return params
- end
- module_function :parse_query
-
- def normalize_params(params, name, v = nil)
- name =~ %r(\A[\[\]]*([^\[\]]+)\]*)
- k = $1 || ''
- after = $' || ''
-
- return if k.empty?
-
- if after == ""
- params[k] = v
- elsif after == "[]"
- params[k] ||= []
- raise TypeError, "expected Array (got #{params[k].class.name}) for param `#{k}'" unless params[k].is_a?(Array)
- params[k] << v
- elsif after =~ %r(^\[\]\[([^\[\]]+)\]$) || after =~ %r(^\[\](.+)$)
- child_key = $1
- params[k] ||= []
- raise TypeError, "expected Array (got #{params[k].class.name}) for param `#{k}'" unless params[k].is_a?(Array)
- if params[k].last.is_a?(Hash) && !params[k].last.key?(child_key)
- normalize_params(params[k].last, child_key, v)
- else
- params[k] << normalize_params({}, child_key, v)
- end
- else
- params[k] ||= {}
- raise TypeError, "expected Hash (got #{params[k].class.name}) for param `#{k}'" unless params[k].is_a?(Hash)
- params[k] = normalize_params(params[k], after, v)
- end
-
- return params
- end
- module_function :normalize_params
- end
-end
diff --git a/lib/sendmail_return_path.rb b/lib/sendmail_return_path.rb
deleted file mode 100644
index 23c4d4376..000000000
--- a/lib/sendmail_return_path.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-# Monkeypatch!
-# Grrr, semantics of smtp and sendmail send should be the same with regard to setting return path
-
-# See test in spec/lib/sendmail_return_path_spec.rb
-
-module ActionMailer
- class Base
- def perform_delivery_sendmail(mail)
- sender = (mail['return-path'] && mail['return-path'].spec) || mail.from.first
-
- sendmail_args = sendmail_settings[:arguments].dup
- sendmail_args += " -f \"#{sender}\""
-
- IO.popen("#{sendmail_settings[:location]} #{sendmail_args}","w+") do |sm|
- sm.print(mail.encoded.gsub(/\r/, ''))
- sm.flush
- end
- end
- end
-end
-
diff --git a/spec/fixtures/track_things_sent_emails.yml b/lib/tasks/.gitkeep
index e69de29bb..e69de29bb 100644
--- a/spec/fixtures/track_things_sent_emails.yml
+++ b/lib/tasks/.gitkeep
diff --git a/lib/tasks/gettext.rake b/lib/tasks/gettext.rake
index c73c2584e..ace7205ae 100644
--- a/lib/tasks/gettext.rake
+++ b/lib/tasks/gettext.rake
@@ -1,7 +1,3 @@
-# Rails won't automatically load rakefiles from gems - see
-# http://stackoverflow.com/questions/1878640/including-rake-tasks-in-gems
-Dir["#{Gem.searcher.find('gettext_i18n_rails').full_gem_path}/lib/tasks/**/*.rake"].each { |ext| load ext }
-
namespace :gettext do
desc 'Rewrite .po files into a consistent msgmerge format'
diff --git a/lib/tasks/rspec.rake b/lib/tasks/rspec.rake
deleted file mode 100644
index d4fd4a9ff..000000000
--- a/lib/tasks/rspec.rake
+++ /dev/null
@@ -1,148 +0,0 @@
-rspec_gem_dir = nil
-Dir["#{Rails.root}/vendor/gems/*"].each do |subdir|
- rspec_gem_dir = subdir if subdir.gsub("#{Rails.root}/vendor/gems/","") =~ /^(\w+-)?rspec-(\d+)/ && File.exist?("#{subdir}/lib/spec/rake/spectask.rb")
-end
-rspec_plugin_dir = File.expand_path(File.dirname(__FILE__) + '/../../vendor/plugins/rspec')
-
-if rspec_gem_dir && (test ?d, rspec_plugin_dir)
- raise "\n#{'*'*50}\nYou have rspec installed in both vendor/gems and vendor/plugins\nPlease pick one and dispose of the other.\n#{'*'*50}\n\n"
-end
-
-if rspec_gem_dir
- $LOAD_PATH.unshift("#{rspec_gem_dir}/lib")
-elsif File.exist?(rspec_plugin_dir)
- $LOAD_PATH.unshift("#{rspec_plugin_dir}/lib")
-end
-
-# Don't load rspec if running "rake gems:*"
-unless ARGV.any? {|a| a =~ /^gems/}
-
-begin
- require 'spec/rake/spectask'
-rescue MissingSourceFile
- module Spec
- module Rake
- class SpecTask
- if defined?(::Rake::DSL)
- include ::Rake::DSL
- end
- def initialize(name)
- task name do
- # if rspec-rails is a configured gem, this will output helpful material and exit ...
- require File.expand_path(File.join(File.dirname(__FILE__),"..","..","config","environment"))
-
- # ... otherwise, do this:
- raise <<-MSG
-
-#{"*" * 80}
-* You are trying to run an rspec rake task defined in
-* #{__FILE__},
-* but rspec can not be found in vendor/gems, vendor/plugins or system gems.
-#{"*" * 80}
-MSG
- end
- end
- end
- end
- end
-end
-
-Rake.application.instance_variable_get('@tasks').delete('default')
-
-spec_prereq = File.exist?(File.join(Rails.root, 'config', 'database.yml')) ? "db:test:prepare" : :noop
-task :noop do
-end
-
-task :default => :spec
-task :stats => "spec:statsetup"
-task :test => ['spec']
-task :cruise => ['spec']
-
-desc "Run all specs in spec directory (excluding plugin specs)"
-Spec::Rake::SpecTask.new(:spec => spec_prereq) do |t|
- t.spec_opts = ['--options', "\"#{Rails.root}/spec/spec.opts\""]
- t.spec_files = FileList['spec/**/*_spec.rb']
-end
-
-namespace :spec do
- desc "Run all specs in spec directory with RCov (excluding plugin specs)"
- Spec::Rake::SpecTask.new(:rcov) do |t|
- t.spec_opts = ['--options', "\"#{Rails.root}/spec/spec.opts\""]
- t.spec_files = FileList['spec/**/*_spec.rb']
- t.rcov = true
- t.rcov_opts = lambda do
- IO.readlines("#{Rails.root}/spec/rcov.opts").map {|l| l.chomp.split " "}.flatten
- end
- end
-
- desc "Print Specdoc for all specs (excluding plugin specs)"
- Spec::Rake::SpecTask.new(:doc) do |t|
- t.spec_opts = ["--format", "specdoc", "--dry-run"]
- t.spec_files = FileList['spec/**/*_spec.rb']
- end
-
- desc "Print Specdoc for all plugin examples"
- Spec::Rake::SpecTask.new(:plugin_doc) do |t|
- t.spec_opts = ["--format", "specdoc", "--dry-run"]
- t.spec_files = FileList['vendor/plugins/**/spec/**/*_spec.rb'].exclude('vendor/plugins/rspec/*')
- end
-
- [:models, :controllers, :views, :helpers, :lib, :integration].each do |sub|
- desc "Run the code examples in spec/#{sub}"
- Spec::Rake::SpecTask.new(sub => spec_prereq) do |t|
- t.spec_opts = ['--options', "\"#{Rails.root}/spec/spec.opts\""]
- t.spec_files = FileList["spec/#{sub}/**/*_spec.rb"]
- end
- end
-
- desc "Run the code examples in vendor/plugins (except RSpec's own)"
- Spec::Rake::SpecTask.new(:plugins => spec_prereq) do |t|
- t.spec_opts = ['--options', "\"#{Rails.root}/spec/spec.opts\""]
- t.spec_files = FileList['vendor/plugins/**/spec/**/*_spec.rb'].exclude('vendor/plugins/rspec/*').exclude("vendor/plugins/rspec-rails/*")
- end
-
- namespace :plugins do
- desc "Runs the examples for rspec_on_rails"
- Spec::Rake::SpecTask.new(:rspec_on_rails) do |t|
- t.spec_opts = ['--options', "\"#{Rails.root}/spec/spec.opts\""]
- t.spec_files = FileList['vendor/plugins/rspec-rails/spec/**/*_spec.rb']
- end
- end
-
- # Setup specs for stats
- task :statsetup do
- require 'code_statistics'
- ::STATS_DIRECTORIES << %w(Model\ specs spec/models) if File.exist?('spec/models')
- ::STATS_DIRECTORIES << %w(View\ specs spec/views) if File.exist?('spec/views')
- ::STATS_DIRECTORIES << %w(Controller\ specs spec/controllers) if File.exist?('spec/controllers')
- ::STATS_DIRECTORIES << %w(Helper\ specs spec/helpers) if File.exist?('spec/helpers')
- ::STATS_DIRECTORIES << %w(Library\ specs spec/lib) if File.exist?('spec/lib')
- ::STATS_DIRECTORIES << %w(Routing\ specs spec/routing) if File.exist?('spec/routing')
- ::STATS_DIRECTORIES << %w(Integration\ specs spec/integration) if File.exist?('spec/integration')
- ::CodeStatistics::TEST_TYPES << "Model specs" if File.exist?('spec/models')
- ::CodeStatistics::TEST_TYPES << "View specs" if File.exist?('spec/views')
- ::CodeStatistics::TEST_TYPES << "Controller specs" if File.exist?('spec/controllers')
- ::CodeStatistics::TEST_TYPES << "Helper specs" if File.exist?('spec/helpers')
- ::CodeStatistics::TEST_TYPES << "Library specs" if File.exist?('spec/lib')
- ::CodeStatistics::TEST_TYPES << "Routing specs" if File.exist?('spec/routing')
- ::CodeStatistics::TEST_TYPES << "Integration specs" if File.exist?('spec/integration')
- end
-
- namespace :db do
- namespace :fixtures do
- desc "Load fixtures (from spec/fixtures) into the current environment's database. Load specific fixtures using FIXTURES=x,y. Load from subdirectory in test/fixtures using FIXTURES_DIR=z."
- task :load => :environment do
- ActiveRecord::Base.establish_connection(Rails.env)
- base_dir = File.join(Rails.root, 'spec', 'fixtures')
- fixtures_dir = ENV['FIXTURES_DIR'] ? File.join(base_dir, ENV['FIXTURES_DIR']) : base_dir
-
- require 'active_record/fixtures'
- (ENV['FIXTURES'] ? ENV['FIXTURES'].split(/,/).map {|f| File.join(fixtures_dir, f) } : Dir.glob(File.join(fixtures_dir, '*.{yml,csv}'))).each do |fixture_file|
- Fixtures.create_fixtures(File.dirname(fixture_file), File.basename(fixture_file, '.*'))
- end
- end
- end
- end
-end
-
-end
diff --git a/lib/tasks/temp.rake b/lib/tasks/temp.rake
index e49a84ecb..f0085b5e1 100644
--- a/lib/tasks/temp.rake
+++ b/lib/tasks/temp.rake
@@ -50,4 +50,154 @@ namespace :temp do
end
end
+ desc 'Create a CSV file of a random selection of raw emails, for comparing hexdigests'
+ task :random_attachments_hexdigests => :environment do
+
+ # The idea is to run this under the Rail 2 codebase, where
+ # Tmail was used to extract the attachements, and the task
+ # will output all of those file paths in a CSV file, and a
+ # list of the raw email files in another. The latter file is
+ # useful so that one can easily tar up the emails with:
+ #
+ # tar cvz -T raw-email-files -f raw_emails.tar.gz
+ #
+ # Then you can switch to the Rails 3 codebase, where
+ # attachment parsing is done via
+ # recompute_attachments_hexdigests
+
+ require 'csv'
+
+ File.open('raw-email-files', 'w') do |f|
+ CSV.open('attachment-hexdigests.csv', 'w') do |csv|
+ csv << ['filepath', 'i', 'url_part_number', 'hexdigest']
+ IncomingMessage.all(:order => 'RANDOM()', :limit => 1000).each do |incoming_message|
+ # raw_email.filepath fails unless the
+ # incoming_message has an associated request
+ next unless incoming_message.info_request
+ raw_email = incoming_message.raw_email
+ f.puts raw_email.filepath
+ incoming_message.foi_attachments.each_with_index do |attachment, i|
+ csv << [raw_email.filepath, i, attachment.url_part_number, attachment.hexdigest]
+ end
+ end
+ end
+ end
+
+ end
+
+
+ desc 'Check the hexdigests of attachments in emails on disk'
+ task :recompute_attachments_hexdigests => :environment do
+
+ require 'csv'
+ require 'digest/md5'
+
+ OldAttachment = Struct.new :filename, :attachment_index, :url_part_number, :hexdigest
+
+ filename_to_attachments = Hash.new {|h,k| h[k] = []}
+
+ header_line = true
+ CSV.foreach('attachment-hexdigests.csv') do |filename, attachment_index, url_part_number, hexdigest|
+ if header_line
+ header_line = false
+ else
+ filename_to_attachments[filename].push OldAttachment.new filename, attachment_index, url_part_number, hexdigest
+ end
+ end
+
+ total_attachments = 0
+ attachments_with_different_hexdigest = 0
+ files_with_different_numbers_of_attachments = 0
+ no_tnef_attachments = 0
+ no_parts_in_multipart = 0
+
+ multipart_error = "no parts on multipart mail"
+ tnef_error = "tnef produced no attachments"
+
+ # Now check each file:
+ filename_to_attachments.each do |filename, old_attachments|
+
+ # Currently it doesn't seem to be possible to reuse the
+ # attachment parsing code in Alaveteli without saving
+ # objects to the database, so reproduce what it does:
+
+ raw_email = nil
+ File.open(filename) do |f|
+ raw_email = f.read
+ end
+ mail = MailHandler.mail_from_raw_email(raw_email)
+
+ begin
+ attachment_attributes = MailHandler.get_attachment_attributes(mail)
+ rescue IOError => e
+ if e.message == tnef_error
+ puts "#{filename} #{tnef_error}"
+ no_tnef_attachments += 1
+ next
+ else
+ raise
+ end
+ rescue Exception => e
+ if e.message == multipart_error
+ puts "#{filename} #{multipart_error}"
+ no_parts_in_multipart += 1
+ next
+ else
+ raise
+ end
+ end
+
+ if attachment_attributes.length != old_attachments.length
+ puts "#{filename} the number of old attachments #{old_attachments.length} didn't match the number of new attachments #{attachment_attributes.length}"
+ files_with_different_numbers_of_attachments += 1
+ else
+ old_attachments.each_with_index do |old_attachment, i|
+ total_attachments += 1
+ attrs = attachment_attributes[i]
+ old_hexdigest = old_attachment.hexdigest
+ new_hexdigest = attrs[:hexdigest]
+ new_content_type = attrs[:content_type]
+ old_url_part_number = old_attachment.url_part_number.to_i
+ new_url_part_number = attrs[:url_part_number]
+ if old_url_part_number != new_url_part_number
+ puts "#{i} #{filename} old_url_part_number #{old_url_part_number}, new_url_part_number #{new_url_part_number}"
+ end
+ if old_hexdigest != new_hexdigest
+ body = attrs[:body]
+ # First, if the content type is one of
+ # text/plain, text/html or application/rtf try
+ # changing CRLF to LF and calculating a new
+ # digest - we generally don't worry about
+ # these changes:
+ new_converted_hexdigest = nil
+ if ["text/plain", "text/html", "application/rtf"].include? new_content_type
+ converted_body = body.gsub /\r\n/, "\n"
+ new_converted_hexdigest = Digest::MD5.hexdigest converted_body
+ puts "new_converted_hexdigest is #{new_converted_hexdigest}"
+ end
+ if (! new_converted_hexdigest) || (old_hexdigest != new_converted_hexdigest)
+ puts "#{i} #{filename} old_hexdigest #{old_hexdigest} wasn't the same as new_hexdigest #{new_hexdigest}"
+ puts " body was of length #{body.length}"
+ puts " content type was: #{new_content_type}"
+ path = "/tmp/#{new_hexdigest}"
+ f = File.new path, "w"
+ f.write body
+ f.close
+ puts " wrote body to #{path}"
+ attachments_with_different_hexdigest += 1
+ end
+ end
+ end
+ end
+
+ end
+
+ puts "total_attachments: #{total_attachments}"
+ puts "attachments_with_different_hexdigest: #{attachments_with_different_hexdigest}"
+ puts "files_with_different_numbers_of_attachments: #{files_with_different_numbers_of_attachments}"
+ puts "no_tnef_attachments: #{no_tnef_attachments}"
+ puts "no_parts_in_multipart: #{no_parts_in_multipart}"
+
+ end
+
end
diff --git a/lib/tasks/themes.rake b/lib/tasks/themes.rake
index 14aa15551..cbd3d123e 100644
--- a/lib/tasks/themes.rake
+++ b/lib/tasks/themes.rake
@@ -31,7 +31,7 @@ namespace :themes do
if system(clone_command)
Dir.chdir install_path do
# First try to checkout a specific branch of the theme
- tag_checked_out = checkout_remote_branch(Configuration::theme_branch) if Configuration::theme_branch
+ tag_checked_out = checkout_remote_branch(AlaveteliConfiguration::theme_branch) if AlaveteliConfiguration::theme_branch
if !tag_checked_out
# try to checkout a tag exactly matching ALAVETELI VERSION
tag_checked_out = checkout_tag(ALAVETELI_VERSION)
@@ -94,10 +94,10 @@ namespace :themes do
desc "Install themes specified in the config file's THEME_URLS"
task :install => :environment do
verbose = true
- Configuration::theme_urls.each{ |theme_url| install_theme(theme_url, verbose) }
- if ! Configuration::theme_url.blank?
+ AlaveteliConfiguration::theme_urls.each{ |theme_url| install_theme(theme_url, verbose) }
+ if ! AlaveteliConfiguration::theme_url.blank?
# Old version of the above, for backwards compatibility
- install_theme(Configuration::theme_url, verbose, deprecated=true)
+ install_theme(AlaveteliConfiguration::theme_url, verbose, deprecated=true)
end
end
-end \ No newline at end of file
+end
diff --git a/lib/tasks/translation.rake b/lib/tasks/translation.rake
index ff07fc6f6..351faef2c 100644
--- a/lib/tasks/translation.rake
+++ b/lib/tasks/translation.rake
@@ -42,14 +42,14 @@ namespace :translation do
output_file = File.open(File.join(ENV['DIR'], 'message_preview.txt'), 'w')
# outgoing mailer
- request_email = OutgoingMailer.create_initial_request(info_request, initial_request)
+ request_email = OutgoingMailer.initial_request(info_request, initial_request)
write_email(request_email, 'Initial Request', output_file)
- followup_email = OutgoingMailer.create_followup(info_request, follow_up, nil)
+ followup_email = OutgoingMailer.followup(info_request, follow_up, nil)
write_email(followup_email, 'Follow up', output_file)
# contact mailer
- contact_email = ContactMailer.create_to_admin_message(info_request.user_name,
+ contact_email = ContactMailer.to_admin_message(info_request.user_name,
info_request.user.email,
'A test message',
'Hello!',
@@ -59,20 +59,20 @@ namespace :translation do
write_email(contact_email, 'Contact email (to admin)', output_file)
- user_contact_email = ContactMailer.create_user_message(info_request.user,
+ user_contact_email = ContactMailer.user_message(info_request.user,
info_request.user,
'http://www.example.com/user',
'A test message',
'Hello!')
write_email(user_contact_email, 'Contact email (user to user)', output_file)
- admin_contact_email = ContactMailer.create_from_admin_message(info_request.user,
+ admin_contact_email = ContactMailer.from_admin_message(info_request.user,
'A test message',
'Hello!')
write_email(admin_contact_email, 'Contact email (admin to user)', output_file)
# request mailer
- fake_response_email = RequestMailer.create_fake_response(info_request,
+ fake_response_email = RequestMailer.fake_response(info_request,
info_request.user,
"test body",
"attachment.txt",
@@ -89,54 +89,54 @@ namespace :translation do
response_mail = MailHandler.mail_from_raw_email(content)
response_mail.from = "authority@example.com"
- stopped_responses_email = RequestMailer.create_stopped_responses(info_request,
+ stopped_responses_email = RequestMailer.stopped_responses(info_request,
response_mail,
content)
write_email(stopped_responses_email,
'Bounce if someone sends email to a request that has had responses stopped',
output_file)
- requires_admin_email = RequestMailer.create_requires_admin(info_request)
+ requires_admin_email = RequestMailer.requires_admin(info_request)
write_email(requires_admin_email, 'Drawing admin attention to a response', output_file)
- new_response_email = RequestMailer.create_new_response(info_request, incoming_message)
+ new_response_email = RequestMailer.new_response(info_request, incoming_message)
write_email(new_response_email,
'Telling the requester that a new response has arrived',
output_file)
- overdue_alert_email = RequestMailer.create_overdue_alert(info_request, info_request.user)
+ overdue_alert_email = RequestMailer.overdue_alert(info_request, info_request.user)
write_email(overdue_alert_email,
'Telling the requester that the public body is late in replying',
output_file)
- very_overdue_alert_email = RequestMailer.create_very_overdue_alert(info_request, info_request.user)
+ very_overdue_alert_email = RequestMailer.very_overdue_alert(info_request, info_request.user)
write_email(very_overdue_alert_email,
'Telling the requester that the public body is very late in replying',
output_file)
- response_reminder_alert_email = RequestMailer.create_new_response_reminder_alert(info_request,
+ response_reminder_alert_email = RequestMailer.new_response_reminder_alert(info_request,
incoming_message)
write_email(response_reminder_alert_email,
'Telling the requester that they need to say if the new response contains info or not',
output_file)
- old_unclassified_email = RequestMailer.create_old_unclassified_updated(info_request)
+ old_unclassified_email = RequestMailer.old_unclassified_updated(info_request)
write_email(old_unclassified_email,
'Telling the requester that someone updated their old unclassified request',
output_file)
- not_clarified_alert_email = RequestMailer.create_not_clarified_alert(info_request, incoming_message)
+ not_clarified_alert_email = RequestMailer.not_clarified_alert(info_request, incoming_message)
write_email(not_clarified_alert_email,
'Telling the requester that they need to clarify their request',
output_file)
- comment_on_alert_email = RequestMailer.create_comment_on_alert(info_request, comment)
+ comment_on_alert_email = RequestMailer.comment_on_alert(info_request, comment)
write_email(comment_on_alert_email,
'Telling requester that somebody added an annotation to their request',
output_file)
- comment_on_alert_plural_email = RequestMailer.create_comment_on_alert_plural(info_request, 2, comment)
+ comment_on_alert_plural_email = RequestMailer.comment_on_alert_plural(info_request, 2, comment)
write_email(comment_on_alert_plural_email,
'Telling requester that somebody added multiple annotations to their request',
output_file)
@@ -149,38 +149,38 @@ namespace :translation do
nil,
100,
1)
- event_digest_email = TrackMailer.create_event_digest(info_request.user,
+ event_digest_email = TrackMailer.event_digest(info_request.user,
[[track_thing,
xapian_object.results,
xapian_object]])
write_email(event_digest_email, 'Alerts on things the user is tracking', output_file)
# user mailer
- site_name = Configuration::site_name
+ site_name = AlaveteliConfiguration::site_name
reasons = {
:web => "",
:email => _("Then you can sign in to {{site_name}}", :site_name => site_name),
:email_subject => _("Confirm your account on {{site_name}}", :site_name => site_name)
}
- confirm_login_email = UserMailer.create_confirm_login(info_request.user,
+ confirm_login_email = UserMailer.confirm_login(info_request.user,
reasons,
'http://www.example.com')
write_email(confirm_login_email, 'Confirm a user login', output_file)
- already_registered_email = UserMailer.create_already_registered(info_request.user,
+ already_registered_email = UserMailer.already_registered(info_request.user,
reasons,
'http://www.example.com')
write_email(already_registered_email, 'Tell a user they are already registered', output_file)
new_email = 'new_email@example.com'
- changeemail_confirm_email = UserMailer.create_changeemail_confirm(info_request.user,
+ changeemail_confirm_email = UserMailer.changeemail_confirm(info_request.user,
new_email,
'http://www.example.com')
write_email(changeemail_confirm_email,
'Confirm that the user wants to change their email',
output_file)
- changeemail_already_used = UserMailer.create_changeemail_already_used('old_email@example.com',
+ changeemail_already_used = UserMailer.changeemail_already_used('old_email@example.com',
new_email)
write_email(changeemail_already_used,
'Tell a user that the email they want to change to is already used',
@@ -189,4 +189,4 @@ namespace :translation do
output_file.close
end
-end \ No newline at end of file
+end
diff --git a/lib/timezone_fixes.rb b/lib/timezone_fixes.rb
deleted file mode 100644
index 1bf326ccd..000000000
--- a/lib/timezone_fixes.rb
+++ /dev/null
@@ -1,26 +0,0 @@
-# Taken from
-# https://rails.lighthouseapp.com/projects/8994/tickets/2946
-# http://github.com/rails/rails/commit/6f97ad07ded847f29159baf71050c63f04282170
-
-# Otherwise times get stored wrong during British Summer Time
-
-# Hopefully fixed in later Rails. There is a test in spec/lib/timezone_fixes_spec.rb
-
-# This fix is applied in Rails 3.x. So, should be possible to remove this then!
-
-# Monkeypatch!
-module ActiveRecord
- module ConnectionAdapters # :nodoc:
- module Quoting
- def quoted_date(value)
- if value.acts_like?(:time)
- zone_conversion_method = ActiveRecord::Base.default_timezone == :utc ? :getutc : :getlocal
- value.respond_to?(zone_conversion_method) ? value.send(zone_conversion_method) : value
- else
- value
- end.to_s(:db)
- end
- end
- end
-end
-
diff --git a/lib/willpaginate_extension.rb b/lib/willpaginate_extension.rb
deleted file mode 100644
index 3cdb0ae60..000000000
--- a/lib/willpaginate_extension.rb
+++ /dev/null
@@ -1,59 +0,0 @@
-# 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!((?:\?|&amp;)#{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/locale/aln/app.po b/locale/aln/app.po
index 7d112692f..4a408ac88 100644
--- a/locale/aln/app.po
+++ b/locale/aln/app.po
@@ -4,14 +4,15 @@
#
# Translators:
# Valon <vbrestovci@gmail.com>, 2011
+# Valon <vbrestovci@gmail.com>, 2011
msgid ""
msgstr ""
"Project-Id-Version: alaveteli\n"
"Report-Msgid-Bugs-To: http://github.com/sebbacon/alaveteli/issues\n"
-"POT-Creation-Date: 2013-04-23 16:34+0100\n"
-"PO-Revision-Date: 2013-04-23 15:39+0000\n"
+"POT-Creation-Date: 2013-05-30 09:46+0100\n"
+"PO-Revision-Date: 2013-05-30 08:54+0000\n"
"Last-Translator: louisecrow <louise@mysociety.org>\n"
-"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language-Team: Albanian Gheg (http://www.transifex.com/projects/p/alaveteli/language/aln/)\n"
"Language: aln\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -291,6 +292,15 @@ msgstr ""
msgid "Act on what you've learnt"
msgstr ""
+msgid "Acts as xapian/acts as xapian job"
+msgstr ""
+
+msgid "ActsAsXapian::ActsAsXapianJob|Action"
+msgstr ""
+
+msgid "ActsAsXapian::ActsAsXapianJob|Model"
+msgstr ""
+
msgid "Add an annotation"
msgstr ""
@@ -588,6 +598,9 @@ msgstr ""
msgid "Date:"
msgstr ""
+msgid "Dear {{name}},"
+msgstr ""
+
msgid "Dear {{public_body_name}},"
msgstr ""
@@ -854,6 +867,18 @@ msgstr ""
msgid "Handled by post."
msgstr ""
+msgid "Has tag string/has tag string tag"
+msgstr ""
+
+msgid "HasTagString::HasTagStringTag|Model"
+msgstr ""
+
+msgid "HasTagString::HasTagStringTag|Name"
+msgstr ""
+
+msgid "HasTagString::HasTagStringTag|Value"
+msgstr ""
+
msgid "Hello! You can make Freedom of Information requests within {{country_name}} at {{link_to_website}}"
msgstr ""
@@ -1664,9 +1689,6 @@ msgstr ""
msgid "Public body"
msgstr ""
-msgid "Public body/translation"
-msgstr ""
-
msgid "Public notes"
msgstr ""
@@ -1676,33 +1698,6 @@ msgstr ""
msgid "Public page not available"
msgstr ""
-msgid "PublicBody::Translation|Disclosure log"
-msgstr ""
-
-msgid "PublicBody::Translation|First letter"
-msgstr ""
-
-msgid "PublicBody::Translation|Locale"
-msgstr ""
-
-msgid "PublicBody::Translation|Name"
-msgstr ""
-
-msgid "PublicBody::Translation|Notes"
-msgstr ""
-
-msgid "PublicBody::Translation|Publication scheme"
-msgstr ""
-
-msgid "PublicBody::Translation|Request email"
-msgstr ""
-
-msgid "PublicBody::Translation|Short name"
-msgstr ""
-
-msgid "PublicBody::Translation|Url name"
-msgstr ""
-
msgid "PublicBody|Api key"
msgstr ""
@@ -2185,6 +2180,9 @@ msgstr ""
msgid "The search index is currently offline, so we can't show the Freedom of Information requests this person has made."
msgstr ""
+msgid "The {{site_name}} team."
+msgstr ""
+
msgid "Then you can cancel the alert."
msgstr ""
@@ -2695,6 +2693,12 @@ msgstr ""
msgid "Was the response you got to your FOI request any good?"
msgstr ""
+msgid "We consider it is not a valid FOI request, and have therefore hidden it from other users."
+msgstr ""
+
+msgid "We consider it to be vexatious, and have therefore hidden it from other users."
+msgstr ""
+
msgid "We do not have a working request email address for this authority."
msgstr ""
@@ -2887,6 +2891,9 @@ msgstr ""
msgid "You will only get an answer to your request if you follow up\\nwith the clarification."
msgstr ""
+msgid "You will still be able to view it while logged in to the site. Please reply to this email if you would like to discuss this decision further."
+msgstr ""
+
msgid "You're in. <a href=\"#\" id=\"send-request\">Continue sending your request</a>"
msgstr ""
@@ -2953,6 +2960,12 @@ msgstr ""
msgid "Your photo will be shown in public <strong>on the Internet</strong>,\\n wherever you do something on {{site_name}}."
msgstr ""
+msgid "Your request '{{request}}' at {{url}} has been reviewed by moderators."
+msgstr ""
+
+msgid "Your request on {{site_name}} hidden"
+msgstr ""
+
msgid "Your request was called {{info_request}}. Letting everyone know whether you got the information will help us keep tabs on"
msgstr ""
@@ -2987,6 +3000,9 @@ msgstr ""
msgid "Yours sincerely,"
msgstr ""
+msgid "Yours,"
+msgstr ""
+
msgid "[FOI #{{request}} email]"
msgstr ""
diff --git a/locale/app.pot b/locale/app.pot
index 084bd7907..dea0b1243 100644
--- a/locale/app.pot
+++ b/locale/app.pot
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: version 0.0.1\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2013-04-23 16:34+0100\n"
+"POT-Creation-Date: 2013-05-30 09:46+0100\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"
@@ -289,6 +289,15 @@ msgstr ""
msgid "Act on what you've learnt"
msgstr ""
+msgid "Acts as xapian/acts as xapian job"
+msgstr ""
+
+msgid "ActsAsXapian::ActsAsXapianJob|Action"
+msgstr ""
+
+msgid "ActsAsXapian::ActsAsXapianJob|Model"
+msgstr ""
+
msgid "Add an annotation"
msgstr ""
@@ -586,6 +595,9 @@ msgstr ""
msgid "Date:"
msgstr ""
+msgid "Dear {{name}},"
+msgstr ""
+
msgid "Dear {{public_body_name}},"
msgstr ""
@@ -852,6 +864,18 @@ msgstr ""
msgid "Handled by post."
msgstr ""
+msgid "Has tag string/has tag string tag"
+msgstr ""
+
+msgid "HasTagString::HasTagStringTag|Model"
+msgstr ""
+
+msgid "HasTagString::HasTagStringTag|Name"
+msgstr ""
+
+msgid "HasTagString::HasTagStringTag|Value"
+msgstr ""
+
msgid "Hello! You can make Freedom of Information requests within {{country_name}} at {{link_to_website}}"
msgstr ""
@@ -1662,9 +1686,6 @@ msgstr ""
msgid "Public body"
msgstr ""
-msgid "Public body/translation"
-msgstr ""
-
msgid "Public notes"
msgstr ""
@@ -1674,33 +1695,6 @@ msgstr ""
msgid "Public page not available"
msgstr ""
-msgid "PublicBody::Translation|Disclosure log"
-msgstr ""
-
-msgid "PublicBody::Translation|First letter"
-msgstr ""
-
-msgid "PublicBody::Translation|Locale"
-msgstr ""
-
-msgid "PublicBody::Translation|Name"
-msgstr ""
-
-msgid "PublicBody::Translation|Notes"
-msgstr ""
-
-msgid "PublicBody::Translation|Publication scheme"
-msgstr ""
-
-msgid "PublicBody::Translation|Request email"
-msgstr ""
-
-msgid "PublicBody::Translation|Short name"
-msgstr ""
-
-msgid "PublicBody::Translation|Url name"
-msgstr ""
-
msgid "PublicBody|Api key"
msgstr ""
@@ -2183,6 +2177,9 @@ msgstr ""
msgid "The search index is currently offline, so we can't show the Freedom of Information requests this person has made."
msgstr ""
+msgid "The {{site_name}} team."
+msgstr ""
+
msgid "Then you can cancel the alert."
msgstr ""
@@ -2693,6 +2690,12 @@ msgstr ""
msgid "Was the response you got to your FOI request any good?"
msgstr ""
+msgid "We consider it is not a valid FOI request, and have therefore hidden it from other users."
+msgstr ""
+
+msgid "We consider it to be vexatious, and have therefore hidden it from other users."
+msgstr ""
+
msgid "We do not have a working request email address for this authority."
msgstr ""
@@ -2885,6 +2888,9 @@ msgstr ""
msgid "You will only get an answer to your request if you follow up\\nwith the clarification."
msgstr ""
+msgid "You will still be able to view it while logged in to the site. Please reply to this email if you would like to discuss this decision further."
+msgstr ""
+
msgid "You're in. <a href=\"#\" id=\"send-request\">Continue sending your request</a>"
msgstr ""
@@ -2951,6 +2957,12 @@ msgstr ""
msgid "Your photo will be shown in public <strong>on the Internet</strong>,\\n wherever you do something on {{site_name}}."
msgstr ""
+msgid "Your request '{{request}}' at {{url}} has been reviewed by moderators."
+msgstr ""
+
+msgid "Your request on {{site_name}} hidden"
+msgstr ""
+
msgid "Your request was called {{info_request}}. Letting everyone know whether you got the information will help us keep tabs on"
msgstr ""
@@ -2985,6 +2997,9 @@ msgstr ""
msgid "Yours sincerely,"
msgstr ""
+msgid "Yours,"
+msgstr ""
+
msgid "[FOI #{{request}} email]"
msgstr ""
diff --git a/locale/ar/app.po b/locale/ar/app.po
index b90213069..ce851db06 100644
--- a/locale/ar/app.po
+++ b/locale/ar/app.po
@@ -4,14 +4,18 @@
#
# Translators:
# aelharaty <aelharaty@gmail.com>, 2012
+# radproject <radhouanef@gmail.com>, 2013
+# radproject <radhouanef@gmail.com>, 2013
+# <rwiwina@live.fr>, 2013
+# <sana_bj@live.fr>, 2013
msgid ""
msgstr ""
"Project-Id-Version: alaveteli\n"
"Report-Msgid-Bugs-To: http://github.com/sebbacon/alaveteli/issues\n"
-"POT-Creation-Date: 2013-04-23 16:34+0100\n"
-"PO-Revision-Date: 2013-04-23 15:41+0000\n"
+"POT-Creation-Date: 2013-05-30 09:46+0100\n"
+"PO-Revision-Date: 2013-05-30 08:54+0000\n"
"Last-Translator: louisecrow <louise@mysociety.org>\n"
-"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language-Team: Arabic (http://www.transifex.com/projects/p/alaveteli/language/ar/)\n"
"Language: ar\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -19,109 +23,109 @@ msgstr ""
"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n"
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 ""
+msgstr "هذا سوف يظهر على حسابك {{site_name}} ، لتمكين الأخرين من المشاركة"
msgid " (<strong>no ranty</strong> politics, read our <a href=\"{{url}}\">moderation policy</a>)"
msgstr "(<strong>no ranty</strong>السياسة، وقراءة لدينا<a href={{url}}>الاعتدال سياسة</a>"
msgid " (<strong>patience</strong>, especially for large files, it may take a while!)"
-msgstr "<STRONG> الصبر</STRONG>، وخاصة بالنسبة للملفات كبيرة، قد يستغرق بعض الوقت!)"
+msgstr " (<strong>رجاء الانتظار</strong>, خصوصا بالنسبة للملفات الكبيرة, قد يستغرق هذا وقتا!)"
msgid " (you)"
-msgstr "(أنت)"
+msgstr " ( أنت )"
msgid " - view and make Freedom of Information requests"
-msgstr "- عرض وتقديم طلبات حرية المعلومات"
+msgstr "اطلع و قدم طلبات حق النفاذ إلى المعلومة"
msgid " - wall"
-msgstr ""
+msgstr "حائط-"
msgid " <strong>Note:</strong>\\n We will send you an email. Follow the instructions in it to change\\n your password."
-msgstr ""
+msgstr " <strong>ملاحظة:</strong>\\n سوف نمدكم برسالة إلكترونية. قوموا باتباع الإرشادات الموجودة لتتمكنوا من تغير\\n كلمة السر."
msgid " <strong>Privacy note:</strong> Your email address will be given to"
-msgstr "<strong> ملاحظة الخصوصية: </ STRONG> وستعطى عنوان بريدك الإلكتروني لل"
+msgstr " <strong/> ملاحظة حول الخصوصية :<strong> عنوان بريدكم الإلكتروني سيكون ضاهراً ل"
msgid " <strong>Summarise</strong> the content of any information returned. "
-msgstr "<strong>تلخيص على </STRONG> من أي محتوى المعلومات التي تم إرجاعها."
+msgstr " <strong>لخص </strong> مضمون أي معلومة تم إرجاعها. "
msgid " Advise on how to <strong>best clarify</strong> the request."
-msgstr "ننصح كيفية<strong> توضيح أفضل على </STRONG> الطلب."
+msgstr " Advise on how to <strong>best clarify</strong> the request."
msgid " Ideas on what <strong>other documents to request</strong> which the authority may hold. "
-msgstr "أفكار حول ما يجب طلب وثائق أخرى على <strong> </STRONG> التي قد تعقد السلطة."
+msgstr " فكرة عن <strong>وثائق أخرى يمكن طلبها <strong/> و التي قد تحجبها السلطات. "
msgid " If you know the address to use, then please <a href=\"{{url}}\">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 ""
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 ""
+msgstr "تضمين روابط ذات صلة مثل صفحة الحملة،المدوّنةأو صفحة التّويتر. تصبح هذه الروابط متاحة للجميع."
msgid " Link to the information requested, if it is <strong>already available</strong> on the Internet. "
-msgstr "طلب رابط للمعلومات، إذا كان </strong>على شبكة الإنترنت."
+msgstr "قوموا بالربط إلى المعلومة المطلوبة, إذا كانت<strong>موجودة مسبقاً</strong>على شبكة الأنترنات. "
msgid " Offer better ways of <strong>wording the request</strong> to get the information. "
-msgstr "تقديم أفضل طرق<strong>صيغة الطلب </strong>على المعلومات."
+msgstr "قدموا أفضل <strong>صيغة لآلطّلب</strong>من أجل الحصول على المعلومة. "
msgid " Say how you've <strong>used the information</strong>, with links if possible."
-msgstr "يقول كيف كنت قد<strong>استخدمت المعلومات</strong>,الروابط إذا كان ذلك ممكنا."
+msgstr " اذكروا كيفية <strong>استخدامكم للمعلومات</strong>,مع وضع روابط إن أمكن ."
msgid " Suggest <strong>where else</strong> the requester might find the information. "
-msgstr ""
+msgstr " قوموا باقتراح <strong>مكان اخر</strong>أين يمكن لصاحب الطلب أن يجد المعلومة. "
msgid " What are you investigating using Freedom of Information? "
-msgstr "ما الذي تستخدمه حرية المعلومات التحقيق؟"
+msgstr " في ماذا تحقق باستخدام حق الحصول على المعلومة?"
msgid " You are already being emailed updates about the request."
-msgstr "يجري بالفعل عبر البريد الالكتروني التحديثات حول الطلب."
+msgstr " يجري حصولكم على رسالةٍ إلكترونية تتضمن مستجدات متعلقة بطلبكم."
msgid " You will also be emailed updates about the request."
-msgstr "وسوف تكون عبر البريد الالكتروني لك تحديثات عن الطلب."
+msgstr "سنمدكم أيضاً برسالةٍ إلكترونية تتضمن مستجدات متعلقة بطلبكم."
msgid " made by "
-msgstr "أدلى به"
+msgstr "قام به"
msgid " or "
-msgstr "أو"
+msgstr " أو"
msgid " when you send this message."
-msgstr "عند إرسال هذه الرسالة."
+msgstr " عندما تقومون ببعث هذه الرسالة ."
msgid "\"Hello! We have an <a href=\\\"/help/alaveteli?country_name=#{CGI.escape(current_country)}\\\">important message</a> for visitors outside {{country_name}}\""
-msgstr ""
+msgstr "\"مرحباً! لدينا <a href=\\\"/help/alaveteli?country_name=#{CGI.escape(current_country)}\\\">رسالة هامة</a> لالزائرين من خارج {{country_name}}\""
msgid "'Crime statistics by ward level for Wales'"
-msgstr "'إحصاءات الجريمة حسب مستوى جناح في ويلز'"
+msgstr "إحصائيات الجريمة ب\"ويلز\" حسب مقياس \"وارد\" التفاضلي "
msgid "'Pollution levels over time for the River Tyne'"
-msgstr "\"مستويات التلوث مع مرور الوقت لنهر تاين\""
+msgstr "تطور درجة تلوث نهر التاين عبر الزمن "
msgid "'{{link_to_authority}}', a public authority"
-msgstr " '{{link_to_authority}}',سلطة عامة"
+msgstr "'{{link_to_authority}}', سلطة عامة"
msgid "'{{link_to_request}}', a request"
-msgstr "'{{link_to_request}}'"
+msgstr "'{{link_to_request}}', طلب"
msgid "'{{link_to_user}}', a person"
-msgstr ""
+msgstr "'{{link_to_user}}', شخص"
msgid "*unknown*"
msgstr ""
msgid ",\\n\\n\\n\\nYours,\\n\\n{{user_name}}"
-msgstr ""
+msgstr ",\\n\\n\\n\\nتحياتي,\\n\\n{{user_name}}"
msgid "- or -"
-msgstr "- أو -"
+msgstr "-أو-"
msgid "1. Select an authority"
-msgstr "1. حدد سلطة"
+msgstr "1. حدد سلطة "
msgid "2. Ask for Information"
-msgstr ""
+msgstr "2. اطلبوا المعلومة"
msgid "3. Now check your request"
-msgstr ""
+msgstr "3. تحققوا الان من طلبكم"
msgid "<a href=\"{{browse_url}}\">Browse all</a> or <a href=\"{{add_url}}\">ask us to add one</a>."
msgstr ""
@@ -133,37 +137,37 @@ msgid "<a href=\"{{url}}\">Sign in</a> to change password, subscriptions and mor
msgstr ""
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 ""
+msgstr "<p>انتهينا! شكراً جزيلاً على المساعدة.</p><p>هنالك <a href=\"{{helpus_url}}\">مزيدٌ من الأشياء التي يمكنكم القيام بها</a> لمساعدة {{site_name}}.</p>"
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 ""
+msgstr "<p>شكراً لكم! هذه بعض الأفكار حول ما يمكن القيام به لاحقاً:</p>\\n <ul>\\n <li>لكي يتم بعث رسالتكم إلى مؤسسة أخرى،أولاً وجب نسخ نص طلبكم أدناه، ثم <a href=\"{{find_authority_url}}\">البحث عن هذه المؤسسة</a>.</li>\\n <li>إذا كانت لديكم إعتراضات حول مزاعم المؤسسة عدم حجبها للمعلومة، إضغط على هذا الرابط\\n <a href=\"{{complain_url}}\">للتقدم بشكوى</a>.\\n </li>\\n <li>لدينا <a href=\"{{other_means_url}}\">إقتراحات</a>\\n للإجابة عن سؤالكم بوسائلٍ أخرى.\\n </li>\\n </ul>"
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 ""
+msgstr "<p>شكراً لكم! نتمنى أن لا يطول انتظاركم.</p> <p>By law, you should have got a response promptly, and normally before the end of <strong>{{date_response_required_by}}</strong>.</p>"
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 ""
+msgstr "<p> </ P> <p> حسب مايمليه القانون،سيصلك الرد في اقرب الآجال، ومن المفروض أن لايتجاوز ذلك تاريخ <strong> \\ N {{}} date_response_required_by </ STRONG> </ P >"
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 ""
+msgstr "<p>شكرا لك! نأمل أن انتظارك لم يطل.</p><p>يجب أن يصلك رد خلال {{late_number_of_days}} يوما،و سيتم اعلامك ان كان الأمر سيسنغرق وقتا أطول(<a href=\"{{review_url}}\">details</a>).</p>"
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 ""
+msgstr "<p>شكرا لك! طلبك متاخرا جدا, باكثر من{{very_late_number_of_days}}يوم عمل. يجب ان يتم الرد على اغلب المطالب في حدود {{late_number_of_days}} يوم عمل. اذا كنت ترغب في الاعتراض على ذلك ,انظر اسفله .</p>"
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 ""
+msgstr "<p>شكرا لتغيير النص الذي يصفك على حسابك .</p>\\n <p><strong>التالي...</strong>بامكانك تحميل صورة حساب ايضا.</p>"
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 ""
+msgstr "<p>شكرا لتحيينك صورة حسابك.</p>\\n <p><strong>التالي...</strong>بامكانك اضافة نص حولك و حول بحثك على حسابك .<pl>"
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 ""
+msgstr "<نوصيك بتغيير طلبك و ازالة عنوان البريد الالكترونيaddress.\\n اذا قمت بتركه, سيقع ارسال البريد الالكتروني الى السلطة, لكن لن يتم عرضه على الموقع.</p>"
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 ""
+msgstr "<p>نحن سعيدون لحصولك على كل المعلومات التي كنت ترغب في الحصول عليها. عندما تستفيد من المعلومة او تكتب حولها الرجاء العودة لترك ملحوظة اسفله تذكر ما فعلت/p><p>اذا وجدت {{site_name}} useful, <a href=\"{{donation_url}}\">تبرع</a>للمؤسسة الخيرية التي تديرها it.</p>"
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 ""
+msgstr "<p>سعيدون لحصولك على المعلومات التي اردت. اذا وجدتها {{site_name}} مفيدة, <a href=\"{{donation_url}}\">تبرع</a> للمؤسسة الخيرية التي تديرها it.</p><p>اذا اردت ان تجرب و تحصل على بقية المعلومات , تجد ما عليك فعله الان هنا.</p>"
msgid "<p>You do not need to include your email in the request in order to get a reply (<a href=\"{{url}}\">details</a>).</p>"
msgstr ""
@@ -172,202 +176,211 @@ msgid "<p>You do not need to include your email in the request in order to get a
msgstr ""
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 ""
+msgstr "<p>طلبك يحتوي على <strong>رمز بريدي</strong>.الرجاء ازالة كل عنوان الا اذا كان متعلقا مباشرة بموضوع طلبك لانه <strong>سيظهر علنياعلى الانترنات </strong>.</p>"
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 ""
+msgstr "<p> {{law_used_full}}وقع ارسال طلبك <strong> way</strong>!</p>\\n <p><strong>سنرسل لك رسالة الكترونية</strong> عندما يكون هناك رد, او بعد {{late_number_of_days}} يوم عمل ان لم تكن السلطة قد اجابت hasn't\\n الى ذلك الوفت .</p>\\n <p>اذا كتبت حول هذا الطلب (مثلا على منتدى او مدونة ) يرجى وضع رابط هذه الصفحة, و اضافة\\شرح اسفله يخبر الناس عن كنابتك.</p>"
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 "<p>{{site_name}}حاليا في الصيانة. يمكنك فقط عرض طلبات موجودة. لا يمكنك تكوين صداقات جديدة، أو إضافة التعليقات التوضيحية المتابعات، أو غير ذلك تغيير قاعدة البيانات..</p> <p>{{read_only}}</p>"
+msgstr "<p>{{site_name}} في صيانة حاليا.بامكانك الاطلاع على الطلبات الموجودة فقط.ليس بامكانك تقديم طلبات جدبدة, او ااضافة متابعات او ملاحظات, و الا تغيير قاعدة البيانات.</p> <p>{{read_only}}</p>"
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>"
-msgstr ""
+msgstr "<small>ان كنت تستعمل بريدا الكترونيا يستند الى الواب او محدد \"الرسائل الالكترونية غير المرغوب فيها\" , تثبت من\\nbulk/هذه الملفات. , رسائلنا قد نصنف كبريد الكتروني غير مرغوب فيه احيانا .</small>\\n</p>"
msgid "<strong> Can I request information about myself?</strong>\\n\t\t\t<a href=\"{{url}}\">No! (Click here for details)</a>"
msgstr ""
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>commented_by:tony_bowden</code></strong>للبحث الشروح التي أدلى بها توني بودين، وكتابة الاسم في عنوان URL لك."
+msgstr "<strong><code>تم التعليق عليه من قبل_:طوني_باودن</code></strong>للبحث عن ملاحظات طوني باودن, ادخل الاسم كما في عنوان الموقع."
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>filetype:pdf</code></strong>للعثور على كافة الردود مع المرفقات PDF. أو محاولة الرسالة: <code>{{list_of_file_extensions}}</code>"
+msgstr "<strong><code>نوعية الملف:pdf</code></strong>لايجاد كل الاجابات مرفوقة بملف PDF . او جرب <code>{{list_of_file_extensions}}</code>"
msgid "<strong><code>request:</code></strong> to restrict to a specific request, typing the title as in the URL."
-msgstr ""
+msgstr "<strong><code>الطلب:</code></strong> لتضييق مجال البحث, أدخل العنوان كما ورد في عنوان الموقع."
msgid "<strong><code>requested_by:julian_todd</code></strong> to search requests made by Julian Todd, typing the name as in the URL."
-msgstr ""
+msgstr "<strong><code>وقع الطلب من قبل_:جوليان_طود</code></strong> لايجاد بحوث جوليان طود, ادخل الاسم كما في عنوان الموقع."
msgid "<strong><code>requested_from:home_office</code></strong> to search requests from the Home Office, typing the name as in the URL."
-msgstr ""
+msgstr "<strong><code>وقع طلبه_من:الصفحة_الرئيسية</code></strong> لايجاد الطلبات من الصفحة الرئيسية , أدخل الاسم كما في الموقع ."
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 ""
+msgstr "<strong><code>الحالة:</code></strong>للاختيار استنادا على لحالة او تاريخ الطلب, انظر <a href=\"{{statuses_url}}\"> لائحة الاختيارات</a> أسفله."
msgid "<strong><code>tag:charity</code></strong> to find all public authorities 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 ""
+msgstr "<strong><code>الفئة:عمل خيري</code></strong> لايجاد كل السلط العمومية او الطلبات المحددة بفئة. بامكانك اختيار عدة فئات, \\n تفاضليا, e.g. <code>الفئة:محلي AND الفئة:معاملات_مالية:335633</code>. تذكر ان كل الفئات ستكون موجودة \\n اليا, عليك ان تتاكد من وضع <code>AND</code> اذا كنت تريد الحصول على كل النتائج."
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 ""
+msgstr "<strong><code>variety:</code></strong> لاختيار موضوع البحث , انظر <a href=\"{{varieties_url}}\">لائحة الاختيارات</a> اسفله."
msgid "<strong>Advice</strong> on how to get a response that will satisfy the requester. </li>"
-msgstr ""
+msgstr "<strong>نصيحة</strong>حول كيفية تمكين صاحب الطلب من إجابةٍ شافية. </li>"
msgid "<strong>All the information</strong> has been sent"
-msgstr ""
+msgstr "<strong>كل المعلومات</strong>قد تم ارسالها"
msgid "<strong>Anything else</strong>, such as clarifying, prompting, thanking"
-msgstr ""
+msgstr "<strong>أي شيء آخر</strong>,كالتوضيح، الاستفسار، الشكر"
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."
-msgstr ""
+msgstr "<strong>Caveat emptor!</strong>لاستعمال هذه البيانات بدون اساءة, ستحتاج \\na الى الاطلاع جيدا على سلوك مستعملي هذا الموقع على {{site_name}}. كيف, \\nلماذا و من قبل من تم تصنيف الطلبات ليس دقيقا, سيكون\\nهنالك اخطاء من قبل المستعمل و بعض الالتباس. عليك ان تفهم كذلك قانون حرية النفاذ الى المعلومة, و\\nطريقة استعمال السلطات لها. كما ستحتاج ان تكون خبيرا في الاحصاء. يرجى\\n<a href=\"{{contact_path}}\">الاتصال بنا</a> للاستفسار."
msgid "<strong>Clarification</strong> has been requested"
-msgstr ""
+msgstr "<strong>توضيح</strong> وقع الطلب"
msgid "<strong>No response</strong> has been received\\n <small>(maybe there's just an acknowledgement)</small>"
-msgstr ""
+msgstr "<strong>لم يقع تلقي اي طلب</strong> \\n <small>(قد يوجد اشعار استلام فحسب)</small>"
msgid "<strong>Note:</strong> Because we're testing, requests are being sent to {{email}} rather than to the actual authority."
-msgstr ""
+msgstr "<strong>ملاحظة:</strong> نظراً لكوننا في مرحلة التجارب، يفضّل إرسال المطالب إلى {{email}}على ارسالها للمؤسسة الحالية."
msgid "<strong>Note:</strong> You're sending a message to yourself, presumably\\n to try out how it works."
-msgstr ""
+msgstr "<strong>ملاحظة:</strong>من المفترض انك ترسل رسالة الى نفسك لتجرب سير العملية \\n ."
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 ""
+msgstr "<strong>Note:</strong>\\n سنرسل بريدا الكترونيا لعنوان بريدك الالكتروني الجديد. اتبع \\n التعليمات الواردة فيه لتؤكد تغيير بريدك الالكتروني ."
msgid "<strong>Privacy note:</strong> If you want to request private information about\\n yourself then <a href=\"{{url}}\">click here</a>."
msgstr ""
msgid "<strong>Privacy note:</strong> Your photo will be shown in public on the Internet,\\n wherever you do something on {{site_name}}."
-msgstr ""
+msgstr "<strong>Privacy note:</strong> صورتك ستظهر للعلن على الانترنات,\\n كلما قمت بشئ على {{site_name}}."
msgid "<strong>Privacy warning:</strong> Your message, and any response\\n to it, will be displayed publicly on this website."
-msgstr ""
+msgstr "<strong>تحذير خصوصية:<."
msgid "<strong>Some of the information</strong> has been sent "
-msgstr ""
+msgstr "<strong>بعض المعلومات</strong> تم ارسالها "
msgid "<strong>Thank</strong> the public authority or "
-msgstr ""
+msgstr "<strong>شكر</strong> السلطة العامة أو "
msgid "<strong>did not have</strong> the information requested."
-msgstr ""
+msgstr "<strong>لم تكن لدينا</strong>المعلومات المطلوبة."
msgid "A <a href=\"{{request_url}}\">follow up</a> to <em>{{request_title}}</em> was sent to {{public_body_name}} by {{info_request_user}} on {{date}}."
-msgstr ""
+msgstr "A <a href=\"{{request_url}}\">المتابعة</a> الى <em>{{request_title}}</em> وقع ارسالها {{public_body_name}} من قبل {{info_request_user}} بتاريخ {{date}}."
msgid "A <a href=\"{{request_url}}\">response</a> to <em>{{request_title}}</em> was sent by {{public_body_name}} to {{info_request_user}} on {{date}}. The request status is: {{request_status}}"
-msgstr ""
+msgstr "<a href=\"%s\"> هل تملك الحقوق التجارية </a>"
msgid "A <strong>summary</strong> of the response if you have received it by post. "
-msgstr ""
+msgstr "A <strong>ملخص</strong> الرد ان كنت تلقيته على الصفحة. "
msgid "A Freedom of Information request"
-msgstr ""
+msgstr "مطلب حق النفاذ إلى المعلومة"
msgid "A new request, <em><a href=\"{{request_url}}\">{{request_title}}</a></em>, was sent to {{public_body_name}} by {{info_request_user}} on {{date}}."
-msgstr ""
+msgstr "مطلب جديد, <em><a href=\"{{request_url}}\">{{request_title}}</a></em>, تم إرساله إلى {{public_body_name}} من طرف {{info_request_user}} في {{date}}."
msgid "A public authority"
-msgstr ""
+msgstr "مؤسسة عمومية"
msgid "A response will be sent <strong>by post</strong>"
-msgstr ""
+msgstr "سيقع الرد <strong>عبر البريد</strong>"
msgid "A strange reponse, required attention by the {{site_name}} team"
-msgstr ""
+msgstr "A strange reponse, required attention by the {{site_name}} team"
msgid "A vexatious request"
msgstr ""
msgid "A {{site_name}} user"
-msgstr ""
+msgstr "{{site_name}} مستخدم موقع"
msgid "About you:"
-msgstr ""
+msgstr "معلومات عنك:"
msgid "Act on what you've learnt"
+msgstr "العمل على ما تعلمته"
+
+msgid "Acts as xapian/acts as xapian job"
msgstr ""
-msgid "Add an annotation"
+msgid "ActsAsXapian::ActsAsXapianJob|Action"
msgstr ""
-msgid "Add an annotation to your request with choice quotes, or\\n a <strong>summary of the response</strong>."
+msgid "ActsAsXapian::ActsAsXapianJob|Model"
msgstr ""
+msgid "Add an annotation"
+msgstr "إضافة تعليق توضيحي"
+
+msgid "Add an annotation to your request with choice quotes, or\\n a <strong>summary of the response</strong>."
+msgstr "Add an annotation to your request with choice quotes, or \\n a <strong>summary of the response</strong>."
+
msgid "Added on {{date}}"
-msgstr ""
+msgstr "أضيف في {{date}}"
msgid "Admin level is not included in list"
-msgstr ""
+msgstr "مستوى المشرف غير مدرج في قائمة"
msgid "Administration URL:"
-msgstr ""
+msgstr "ادارة الموقع:"
msgid "Advanced search"
-msgstr ""
+msgstr "البحث المتقدم"
msgid "Advanced search tips"
-msgstr ""
+msgstr "نصائح للبحث المتقدم"
msgid "Advise on whether the <strong>refusal is legal</strong>, and how to complain about it if not."
-msgstr ""
+msgstr "نصيحة حول ما اذا كان الرفض قانونيا <strong> </strong>و حول طريقة الاحتجاج ان لم يكن كذلك."
msgid "Air, water, soil, land, flora and fauna (including how these effect\\n human beings)"
-msgstr ""
+msgstr "الهواء, الهواء, التربة, الارض, النباتات و الحيوانات (بالاضافة لتأثيرها على\\n الانسان)"
msgid "All of the information requested has been received"
-msgstr ""
+msgstr "وقع استيلام كل المعلومات المطلوبة"
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 ""
+msgstr "يمكن ان تستند كل الخيارات اسفله على <strong>الحالة</strong> or <strong>اخر_حالة</strong> قبل الفاصل. مثال, <strong>الحالة:غير_معتمدة</strong>سوف تتطابق مع الطلبات التي تعتبر غير معتمدة <em>ever</em> ; <strong>اخر_حالة:غير_معتمدة</strong> ستتطابق فقط مع الطلبات التي تعتبر <em>باستمرار</em> غير معتمدة."
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 ""
+msgstr "يمكن ان تستند كل الخيارات اسفله على <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."
msgid "Also called {{other_name}}."
-msgstr ""
+msgstr "المسماة أيضاً {{other_name}}."
msgid "Also send me alerts by email"
-msgstr ""
+msgstr "أرسل التحذيرات عبر البريد الالكتروني أيضا"
msgid "Alter your subscription"
-msgstr ""
+msgstr "غير اشتراكك"
msgid "Although all responses are automatically published, we depend on\\nyou, the original requester, to evaluate them."
-msgstr ""
+msgstr "على الرغم من ان كل الردود تنشر اليا, نعتمد على تقييم صاحب المطلب الاصلي\\nyou."
msgid "An <a href=\"{{request_url}}\">annotation</a> to <em>{{request_title}}</em> was made by {{event_comment_user}} on {{date}}"
-msgstr ""
+msgstr " <a href=\"{{request_url}}\">ملاحظة</a> ل <em>{{request_title}}</em> تمت من قبل {{event_comment_user}} بتاريخ {{date}}"
msgid "An <strong>error message</strong> has been received"
-msgstr ""
+msgstr "An <strong>رسالة خطأ</strong> تم تلقي"
msgid "An Environmental Information Regulations request"
-msgstr ""
+msgstr "طلب معلومات قوانين بيئية "
msgid "An anonymous user"
-msgstr ""
+msgstr "مستخدم غير معروف"
msgid "Annotation added to request"
-msgstr ""
+msgstr "تمت اضافة الحاشية الى الطّلب"
msgid "Annotations"
-msgstr ""
+msgstr "الحاشية"
msgid "Annotations are so anyone, including you, can help the requester with their request. For example:"
-msgstr ""
+msgstr "الملاحظات متوفرة ليستطيع ايا كان ،بمن فيهم انت ، مساعدة الباحثين في طلبهم. مثلا:"
msgid "Annotations will be posted publicly here, and are\\n <strong>not</strong> sent to {{public_body_name}}."
-msgstr ""
+msgstr "سيتم نشر الملاحظات علنيا هنا, وقد تم\\n <strong>not</strong> ارسالها الى {{public_body_name}}."
msgid "Anonymous user"
-msgstr ""
+msgstr "مستخدم غير معروف"
msgid "Anyone:"
-msgstr ""
+msgstr "أي شخص"
msgid "Applies to"
msgstr ""
@@ -379,43 +392,43 @@ msgid "Are you the owner of any commercial copyright on this page?"
msgstr ""
msgid "Ask for <strong>specific</strong> documents or information, this site is not suitable for general enquiries."
-msgstr ""
+msgstr "اطلب <strong>محددة</strong> ملفات او معلومات, هذا الموقع لا يتلاءم مع البحوث العامة."
msgid "At the bottom of this page, write a reply to them trying to persuade them to scan it in\\n (<a href=\"{{url}}\">more details</a>)."
msgstr ""
msgid "Attachment (optional):"
-msgstr ""
+msgstr "ملحق (اختياري) "
msgid "Attachment:"
-msgstr ""
+msgstr "ملحق"
msgid "Awaiting classification."
-msgstr ""
+msgstr "في انتظار التّصنيف"
msgid "Awaiting internal review."
-msgstr ""
+msgstr "في انتظار مراجعة داخلية"
msgid "Awaiting response."
-msgstr ""
+msgstr "في انتظار الرد"
msgid "Beginning with"
-msgstr ""
+msgstr "البدء ب"
msgid "Browse <a href='{{url}}'>other requests</a> for examples of how to word your request."
-msgstr ""
+msgstr "تصفح <a href='{{url}}'>طلبات اخرى</a> للاطلاع على امثلة لكيفية تحرير طلبك."
msgid "Browse <a href='{{url}}'>other requests</a> to '{{public_body_name}}' for examples of how to word your request."
-msgstr ""
+msgstr "تصفح <a href='{{url}}'>طلبات اخرى</a>ل '{{public_body_name}}' للاطلاع على امثلة لكيفية تحرير طلبك ."
msgid "Browse all authorities..."
-msgstr ""
+msgstr "تصفح كل السلطات "
msgid "By law, under all circumstances, {{public_body_link}} should have responded by now"
-msgstr ""
+msgstr "حسب مايمليه القانون ومهما كانت الظروف يجب أن يكون, {{public_body_link}} قد قام بالرد الآن"
msgid "By law, {{public_body_link}} should normally have responded <strong>promptly</strong> and"
-msgstr ""
+msgstr "حسب مايمليه القانون من المفروض أن يكون {{public_body_link}} قد أجاب<strong>promptly</strong> و"
msgid "Calculated home page"
msgstr ""
@@ -424,265 +437,268 @@ msgid "Can't find the one you want?"
msgstr ""
msgid "Cancel a {{site_name}} alert"
-msgstr ""
+msgstr "ألغي {{site_name}} انذار"
msgid "Cancel some {{site_name}} alerts"
-msgstr ""
+msgstr "الغاء بعض {{site_name}} التنبيهات"
msgid "Cancel, return to your profile page"
-msgstr ""
+msgstr "الغاء،عودة الى الصفحة الرئيسية"
msgid "Censor rule"
-msgstr ""
+msgstr "قاعدة تخص الرقابة"
msgid "CensorRule|Last edit comment"
-msgstr ""
+msgstr "ادارة الرقابة|اخر تعليق محوّر "
msgid "CensorRule|Last edit editor"
-msgstr ""
+msgstr "ادارة الرقابة |اخر تغيير للمحرر"
msgid "CensorRule|Regexp"
-msgstr ""
+msgstr "ادارة الرقابة|Regexp"
msgid "CensorRule|Replacement"
-msgstr ""
+msgstr "ادارة الرقابة|تعويض"
msgid "CensorRule|Text"
-msgstr ""
+msgstr "ادارة الرقابة|نص"
msgid "Change email on {{site_name}}"
-msgstr ""
+msgstr "غير البريد الالكتروني على {{site_name}}"
msgid "Change password on {{site_name}}"
-msgstr ""
+msgstr "غير كلمة السر على{{site_name}}"
msgid "Change profile photo"
-msgstr ""
+msgstr "تغيير صورة الشخصية"
msgid "Change the text about you on your profile at {{site_name}}"
-msgstr ""
+msgstr "نغيير النص الخاص بك على صفحتك الشخصية على {{site_name}}"
msgid "Change your email"
-msgstr ""
+msgstr "تغيير بريدك الالكتروني"
msgid "Change your email address used on {{site_name}}"
-msgstr ""
+msgstr "تغيير بريدك الالكتروني المستخدم على {{site_name}}"
msgid "Change your password"
-msgstr ""
+msgstr "تغيير كلمة السر"
msgid "Change your password on {{site_name}}"
-msgstr ""
+msgstr "تغيير كلمة السر على{{site_name}}"
msgid "Change your password {{site_name}}"
-msgstr ""
+msgstr " تغيير كلمة السر {{site_name}}"
msgid "Charity registration"
-msgstr ""
+msgstr "تسجيل خيري"
msgid "Check for mistakes if you typed or copied the address."
-msgstr ""
+msgstr ".تحقق من عدم وجود أخطاء إذا كتبت أو نسخت العنوان"
msgid "Check you haven't included any <strong>personal information</strong>."
-msgstr ""
+msgstr "تأكد من عدم اضافتك أي <strong>معلومات شخصية</strong>."
msgid "Choose your profile photo"
-msgstr ""
+msgstr "اختر صورتك الشخصية"
msgid "Clarification"
-msgstr ""
+msgstr "توضيح"
msgid "Clarify your FOI request - "
-msgstr ""
+msgstr "قم بتوضيح مطلب حرية النفاذ الى المعلومة - "
msgid "Classify an FOI response from "
-msgstr ""
+msgstr "صنف اجابة لحرية النفاذ للمعلومة من"
msgid "Clear photo"
-msgstr ""
+msgstr "إزالة الصورة"
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."
-msgstr ""
+msgstr "اظغط على الرابط اسفله لبعث رسالة ل {{public_body_name}} لطلب الاجابة على طلبك. قد ترغب في طلب \\nمراجعة داخلية, لمحاولة معرفة سبب تأخر الاجابة ."
msgid "Click on the link below to send a message to {{public_body}} reminding them to reply to your request."
-msgstr ""
+msgstr "اضغط على الرابط اسفله لبعث رسالة الى {{public_body}} لتذكيرهم بالاجابة على طلبك."
msgid "Close"
-msgstr ""
+msgstr "إغلاق"
msgid "Comment"
-msgstr ""
+msgstr "تعليق"
msgid "Comment|Body"
-msgstr ""
+msgstr "تعليق|هيكل"
msgid "Comment|Comment type"
-msgstr ""
+msgstr "تعليق|نوع النعليق"
msgid "Comment|Locale"
-msgstr ""
+msgstr "تعليق|مقر"
msgid "Comment|Visible"
-msgstr ""
+msgstr "تعليق|مرئي"
msgid "Confirm you want to follow all successful FOI requests"
-msgstr ""
+msgstr " أكد رغبتك متابعة كل طلبات حريةالنفاذ للمعلومة الناجحة"
msgid "Confirm you want to follow new requests"
-msgstr ""
+msgstr "تأكيد على الرغبة في متابعة المطالب الجديدة"
msgid "Confirm you want to follow new requests or responses matching your search"
-msgstr ""
+msgstr "تأكيد على الرغبة في متابعة المطالب الجديدة أو الردود الموافقة لبحثكم"
msgid "Confirm you want to follow requests by '{{user_name}}'"
-msgstr ""
+msgstr " تأكيد رغبتك في متابعة الطلبات من '{{user_name}}' "
msgid "Confirm you want to follow requests to '{{public_body_name}}'"
-msgstr ""
+msgstr "تأكيد على الرغبة في متابعة المطالب الموجهة إلى '{{public_body_name}}'"
msgid "Confirm you want to follow the request '{{request_title}}'"
-msgstr ""
+msgstr "تأكيد رغبتك في متابعة الطلب'{{request_title}}'"
msgid "Confirm your FOI request to "
-msgstr ""
+msgstr "أكد طلبك في حرية النفاذ للمعلومة"
msgid "Confirm your account on {{site_name}}"
-msgstr ""
+msgstr "Confirm your account on {{site_name}}"
msgid "Confirm your annotation to {{info_request_title}}"
-msgstr ""
+msgstr "أكد ملاحظتك المتعلقة ب {{info_request_title}}"
msgid "Confirm your email address"
-msgstr ""
+msgstr "تأكيد عنوان بريدك الالكتروني"
msgid "Confirm your new email address on {{site_name}}"
-msgstr ""
+msgstr "تأكيد عنوان بريدك الإلكتروني الجديد على {{site_name}}"
msgid "Considered by administrators as not an FOI request and hidden from site."
-msgstr ""
+msgstr "لم يعتبر طلب حرية النفاذ الى المعلومة من قبل المشرفين ووقع حذفه من الموقع."
msgid "Considered by administrators as vexatious and hidden from site."
-msgstr ""
+msgstr "اعتبر غير لائق من قبل المشرفين و وقع حذفه من الموقع"
msgid "Contact {{recipient}}"
-msgstr ""
+msgstr "اتصل ب {{recipient}}"
msgid "Contact {{site_name}}"
-msgstr ""
+msgstr "اتصل ب {{site_name}}"
msgid "Could not identify the request from the email address"
-msgstr ""
+msgstr "لا يمكن التعرف على الطلب من عنوان البريد الالكتروني"
msgid "Couldn't understand the image file that you uploaded. PNG, JPEG, GIF and many other common image file formats are supported."
-msgstr ""
+msgstr "لم يقع التعرف على ملف الصور الذي حملته.و يقع اعتماد PNG, JPEG, GIF و اشكال معتادة اخرى لملفات الصور ."
msgid "Crop your profile photo"
-msgstr ""
+msgstr "قص الصورة الشخصية"
msgid "Cultural sites and built structures (as they may be affected by the\\n environmental factors listed above)"
-msgstr ""
+msgstr "المواقع الثقافية و المنشات المبنية (التي قد تتأثر ب العوامل\\n البيئية المذكورة اعلاه)"
msgid "Currently <strong>waiting for a response</strong> from {{public_body_link}}, they must respond promptly and"
-msgstr ""
+msgstr "بصدد <strong>انتظار اجابة</strong> من {{public_body_link}}, عليهم الرد حالا و"
msgid "Date:"
+msgstr "التاريخ:"
+
+msgid "Dear {{name}},"
msgstr ""
msgid "Dear {{public_body_name}},"
-msgstr ""
+msgstr "عزيزي {{public_body_name}},"
msgid "Default locale"
msgstr ""
msgid "Delayed response to your FOI request - "
-msgstr ""
+msgstr "تاخر الاجابة على طلب حرية النفاذ الى المعلومة - "
msgid "Delayed."
-msgstr ""
+msgstr "مؤجل"
msgid "Delivery error"
-msgstr ""
+msgstr "خطأ ارسال"
msgid "Destroy {{name}}"
msgstr ""
msgid "Details of request '"
-msgstr ""
+msgstr "تفاصيل المطلب '"
msgid "Did you mean: {{correction}}"
-msgstr ""
+msgstr "هل قصدتم: {{correction}}"
msgid "Disclaimer: This message and any reply that you make will be published on the internet. Our privacy and copyright policies:"
-msgstr ""
+msgstr "تنويه: هذه الرسالة و اي رد تقوم به سيقع نشره على الانترنات . خصوصيتنا و سياسات حقوق النشر:"
msgid "Disclosure log"
-msgstr ""
+msgstr "سجل الكشف"
msgid "Disclosure log URL"
msgstr ""
msgid "Don't want to address your message to {{person_or_body}}? You can also write to:"
-msgstr ""
+msgstr "لا ترغب في توجيه رسالتك الى {{person_or_body}}? بامكانك ايضا ان تكتب ل:"
msgid "Done"
-msgstr ""
+msgstr "منجز"
msgid "Done &gt;&gt;"
-msgstr ""
+msgstr "تم &gt;&gt;"
msgid "Download a zip file of all correspondence"
-msgstr ""
+msgstr "تحميل ملف مضغوط لجميع المراسلات"
msgid "Download original attachment"
-msgstr ""
+msgstr "تحميل الملحقات الأصلية"
msgid "EIR"
-msgstr ""
+msgstr "EIR"
msgid "Edit"
msgstr ""
msgid "Edit and add <strong>more details</strong> to the message above,\\n explaining why you are dissatisfied with their response."
-msgstr ""
+msgstr "حذف و اضف ا<strong>تفاصيل اكثر</strong>للرسالةاعلاه,\\n لتفسير اسباب عدم رضاك على الرد."
msgid "Edit text about you"
-msgstr ""
+msgstr "تعديل النص الخاص بك"
msgid "Edit this request"
-msgstr ""
+msgstr "تعديل هذا الطلب"
msgid "Either the email or password was not recognised, please try again."
-msgstr ""
+msgstr "البريد الإلكتروني أو كلمة السر غير صحيحة. الرجاء اعادة المحاولة"
msgid "Either the email or password was not recognised, please try again. Or create a new account using the form on the right."
-msgstr ""
+msgstr "لم يتم التعرف على البريد الإلكتروني أو كلمة السر . الرجاء اعادة المحاولة أو انشاء حساب جديد باستعمال الاستمارة على اليمين"
msgid "Email doesn't look like a valid address"
-msgstr ""
+msgstr "قد يكون البريد الإلكتروني غير صحيح"
msgid "Email me future updates to this request"
-msgstr ""
+msgstr "ارسل لي بريدا الكترونيا بكل تحديث لهذا الطلب "
msgid "Enter words that you want to find separated by spaces, e.g. <strong>climbing lane</strong>"
-msgstr ""
+msgstr "ادخل الكلمات التي تريد ايجادها منفصلة , e.g. <strong>تسلق ممر</strong>"
msgid "Enter your response below. You may attach one file (use email, or\\n <a href=\"{{url}}\">contact us</a> if you need more)."
msgstr ""
msgid "Environmental Information Regulations"
-msgstr ""
+msgstr "معلومات القوانين البيئية"
msgid "Environmental Information Regulations requests made"
-msgstr ""
+msgstr "تم تقديم طلبات بخصوص معلومات القوانين البيئية "
msgid "Environmental Information Regulations requests made using this site"
-msgstr ""
+msgstr "تم تقديم طلبات بخصوص معلومات القوانين البيئية عن طريق هذا الموقع"
msgid "Event history"
-msgstr ""
+msgstr "تاريخ الحدث"
msgid "Event history details"
-msgstr ""
+msgstr "تفاصيل تاريخ الحدث"
msgid "Event {{id}}"
msgstr ""
@@ -694,115 +710,115 @@ msgid "Everything that you enter on this page\\n will be <strong>
msgstr ""
msgid "FOI"
-msgstr ""
+msgstr "حرية النفاذ الى المعلومة"
msgid "FOI email address for {{public_body}}"
-msgstr ""
+msgstr "عنوان البريد الالكتروني لحرية المعلومة ل {{public_body}}"
msgid "FOI request – {{title}}"
msgstr ""
msgid "FOI requests"
-msgstr ""
+msgstr "مطالب حرية المعلومة "
msgid "FOI requests by '{{user_name}}'"
-msgstr ""
+msgstr "مطالب حرية المعلومة المقدمة من قبل '{{user_name}}'"
msgid "FOI requests {{start_count}} to {{end_count}} of {{total_count}}"
-msgstr ""
+msgstr "مطالب لحرية النفاذ للمعلومة {{start_count}} ل {{end_count}}من {{total_count}}"
msgid "FOI response requires admin ({{reason}}) - {{title}}"
-msgstr ""
+msgstr "رد حرية النفاذ للمعلومة يتطلف مشرفا ({{reason}}) - {{title}}"
msgid "Failed to convert image to a PNG"
-msgstr ""
+msgstr "لم نتمكن من تحوبل الصورة الى PNG"
msgid "Failed to convert image to the correct size: at {{cols}}x{{rows}}, need {{width}}x{{height}}"
msgstr ""
msgid "Filter"
-msgstr ""
+msgstr "فلترة"
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=\"{{url}}\">why?</a>)."
msgstr ""
msgid "Foi attachment"
-msgstr ""
+msgstr "ملحق حرية النفاذ للمعلومة "
msgid "FoiAttachment|Charset"
-msgstr ""
+msgstr "ملحق حرية النفاذ للمعلومة|Charset"
msgid "FoiAttachment|Content type"
-msgstr ""
+msgstr "ملحق حرية النفاذ للمعلومة|نوع المضمون"
msgid "FoiAttachment|Display size"
-msgstr ""
+msgstr "ملحق حرية النفاذ للمعلومة|أظهر الحجم"
msgid "FoiAttachment|Filename"
-msgstr ""
+msgstr "ملحق حرية النفاذ للمعلومة|اسم الملف"
msgid "FoiAttachment|Hexdigest"
-msgstr ""
+msgstr "ملحق حرية النفاذ للمعلومة|Hexdigest"
msgid "FoiAttachment|Url part number"
-msgstr ""
+msgstr "ملحق حرية النفاذ للمعلومة|Url part number"
msgid "FoiAttachment|Within rfc822 subject"
-msgstr ""
+msgstr "ملحق حرية النفاذ للمعلومة|ضمن rfc822 subject"
msgid "Follow"
-msgstr ""
+msgstr "تابع"
msgid "Follow all new requests"
-msgstr ""
+msgstr "تابع كل المطالب الجديدة"
msgid "Follow new successful responses"
-msgstr ""
+msgstr "تابع الردود الجديدة الناجحة"
msgid "Follow requests to {{public_body_name}}"
-msgstr ""
+msgstr "تابع المطالب الموجهة ل {{public_body_name}}"
msgid "Follow these requests"
-msgstr ""
+msgstr "تابع هذة المطالب"
msgid "Follow things matching this search"
-msgstr ""
+msgstr "تابع الاشياء المرتبطة بهذا البحث"
msgid "Follow this authority"
-msgstr ""
+msgstr "تابع السلطة "
msgid "Follow this link to see the request:"
-msgstr ""
+msgstr "تابع الرابط لرؤية الطلب"
msgid "Follow this person"
-msgstr ""
+msgstr "تابع هذا الشخص"
msgid "Follow this request"
-msgstr ""
+msgstr "تابع هذا الطلب "
msgid "Follow up"
-msgstr ""
+msgstr "تابع"
msgid "Follow up message sent by requester"
-msgstr ""
+msgstr "تابع الرسالة المرسلة من صاحب الطلب"
msgid "Follow up messages to existing requests are sent to "
-msgstr ""
+msgstr "متابعة الرسائل المرسلة للطلبات الموجودة"
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 ""
+msgstr "المتابعات و الردود الجدبدة على هذا المطلب وقع ايقافها للتجنب الرسائل الغير مرغوب فيها. يرجى <a href=\"{{url}}\">الاتصال بنا</a> اذا كنت {{user_link}} و تحتاج الى ارسال متابعات."
msgid "Follow us on twitter"
-msgstr ""
+msgstr "تابعنا على التويتر"
msgid "Followups cannot be sent for this request, as it was made externally, and published here by {{public_body_name}} on the requester's behalf."
-msgstr ""
+msgstr "لا يمكن ارسال المتابعات لهذا الطلب, حيث نم خارجيا, و تم نشره هنا من قبل {{public_body_name}} نيابة عن صاحب الطلب."
msgid "For an unknown reason, it is not possible to make a request to this authority."
-msgstr ""
+msgstr "لسبب مجهول, لا يمكن تقديم مطلب لهذه السلطة."
msgid "Forgotten your password?"
-msgstr ""
+msgstr "نسيت كلمة السر ؟"
msgid "Found {{count}} public authority {{description}}"
msgid_plural "Found {{count}} public authorities {{description}}"
@@ -814,133 +830,145 @@ msgstr[4] ""
msgstr[5] ""
msgid "Freedom of Information"
-msgstr ""
+msgstr "حرية المعلومة "
msgid "Freedom of Information Act"
-msgstr ""
+msgstr "قانون حرية المعلومات "
msgid "Freedom of Information law does not apply to this authority, so you cannot make\\n a request to it."
-msgstr ""
+msgstr "قانون حرية المعلومات لا ينطبق على هذه السلطة ,لذلك ليس بامكانك تقديم مطلب لها\\n."
msgid "Freedom of Information law no longer applies to"
-msgstr ""
+msgstr "قانون حرية المعلومات لم يعد ينطبق على"
msgid "Freedom of Information law no longer applies to this authority.Follow up messages to existing requests are sent to "
-msgstr ""
+msgstr "قانون حرية النفاذ للمعلومة لم يعد ينطبق على هذه السلطة.تابع الرسائل المرسلة للطلبات الموجودة"
msgid "Freedom of Information requests made"
-msgstr ""
+msgstr "تم تقديم مطالب حرية المعلومة "
msgid "Freedom of Information requests made by this person"
-msgstr ""
+msgstr "مطالب حرية المعلومةالتي قدمت من قبل هذا الشخص"
msgid "Freedom of Information requests made by you"
-msgstr ""
+msgstr "مطالب حرية المعلومة التي قدمت من قبلك"
msgid "Freedom of Information requests made using this site"
-msgstr ""
+msgstr "مطالب حرية المعلومة التي قدمت على هذا الموقع"
msgid "Freedom of information requests to"
-msgstr ""
+msgstr "طلبات حرية النفاذ للمعلومة الى"
msgid "From"
-msgstr ""
+msgstr "من"
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=\"{{url}}\">send it to us</a>."
msgstr ""
msgid "From:"
-msgstr ""
+msgstr "من"
msgid "GIVE DETAILS ABOUT YOUR COMPLAINT HERE"
-msgstr ""
+msgstr "قوموا بإعطاء تفاصيل عن شكواكم هنا"
msgid "Handled by post."
+msgstr "تسلم بالبريد"
+
+msgid "Has tag string/has tag string tag"
msgstr ""
-msgid "Hello! You can make Freedom of Information requests within {{country_name}} at {{link_to_website}}"
+msgid "HasTagString::HasTagStringTag|Model"
msgstr ""
-msgid "Hello, {{username}}!"
+msgid "HasTagString::HasTagStringTag|Name"
msgstr ""
-msgid "Help"
+msgid "HasTagString::HasTagStringTag|Value"
msgstr ""
+msgid "Hello! You can make Freedom of Information requests within {{country_name}} at {{link_to_website}}"
+msgstr "مرحباً! بإمكانكم تقديم مطالب حق النفاذ إلى المعلومة من داخل {{country_name}} على هذا الموقع {{link_to_website}}"
+
+msgid "Hello, {{username}}!"
+msgstr "مرحباً, {{username}}!"
+
+msgid "Help"
+msgstr "المساعدة"
+
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."
msgstr ""
msgid "Here is the message you wrote, in case you would like to copy the text and save it for later."
-msgstr ""
+msgstr "هذه هي الرسالة التي قمتم بكتابتها، في صورة ما كانت لديكم رغبة في نسخها و حفظها لوقتٍ لاحق. "
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 ""
+msgstr "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."
msgid "Hide request"
msgstr ""
msgid "Holiday"
-msgstr ""
+msgstr "عطلة"
msgid "Holiday|Day"
-msgstr ""
+msgstr "عطلة|يوم"
msgid "Holiday|Description"
-msgstr ""
+msgstr "عطلة |وصف"
msgid "Home"
-msgstr ""
+msgstr "الصفحة الرئيسية"
msgid "Home page"
msgstr ""
msgid "Home page of authority"
-msgstr ""
+msgstr "الصفحة الرئيسية للمؤسسة"
msgid "However, you have the right to request environmental\\n information under a different law"
-msgstr ""
+msgstr "However, you have the right to request environmental\\n information under a different law"
msgid "Human health and safety"
-msgstr ""
+msgstr "صحة الإنسان و سلامته "
msgid "I am asking for <strong>new information</strong>"
-msgstr ""
+msgstr "ارغب في الحصول على <strong>معلومات جديدة</strong>"
msgid "I am requesting an <strong>internal review</strong>"
-msgstr ""
+msgstr "أنا اطلب <strong>مراجعة داخلية</strong>"
msgid "I don't like these ones &mdash; give me some more!"
-msgstr ""
+msgstr "لا تعجبني هذه الخيارات &mdash; الرجاء مدي بالمزيد!"
msgid "I don't want to do any more tidying now!"
-msgstr ""
+msgstr "ليست لدي الرغبة في القيام بمزيد من التنظيم الآن !"
msgid "I like this request"
-msgstr ""
+msgstr "أعجبني هذا المطلب"
msgid "I would like to <strong>withdraw this request</strong>"
-msgstr ""
+msgstr "ارغب في <strong>سحب هذا المطلب</strong>"
msgid "I'm still <strong>waiting</strong> for my information\\n <small>(maybe you got an acknowledgement)</small>"
-msgstr ""
+msgstr "مازلت بصدد<strong>انتظار</strong> معلوماتي\\n <small>(ربما تحصلت على اشعار بالاستلام)</small>"
msgid "I'm still <strong>waiting</strong> for the internal review"
-msgstr ""
+msgstr "مازلت بصدد <strong>انتظار</strong> مراجعة داخلية"
msgid "I'm waiting for an <strong>internal review</strong> response"
-msgstr ""
+msgstr "انا بانتظار <strong>مراجعة داخلية</strong> اجابة"
msgid "I've been asked to <strong>clarify</strong> my request"
-msgstr ""
+msgstr "لقد طُلب مني <strong>توضيح</strong> مطلبي"
msgid "I've received <strong>all the information"
-msgstr ""
+msgstr "لقد حصلت على <strong>كل المعلومات"
msgid "I've received <strong>some of the information</strong>"
-msgstr ""
+msgstr "لقد حصلت على <strong>بعض من المعلومات</strong>"
msgid "I've received an <strong>error message</strong>"
-msgstr ""
+msgstr "نلقيت <strong>رسالة خطأ</strong>"
msgid "I've received an error message"
msgstr ""
@@ -955,7 +983,7 @@ msgid "If the error was a delivery failure, and you can find an up to date FOI e
msgstr ""
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."
-msgstr ""
+msgstr "ان كان هذا خطأ, أو ان اردت ارسال رد متأخر على الطلب\\nأو رسالة الكترونية بخصوص موضوع اخر {{user}}, الرجاء\\nارسال بريد الكتروني {{contact_email}} طلبا للمساعدة."
msgid "If you are dissatisfied by the response you got from\\n the public authority, you have the right to\\n complain (<a href=\"{{url}}\">details</a>)."
msgstr ""
@@ -970,169 +998,169 @@ msgid "If you are thinking of using a pseudonym,\\n please <a hre
msgstr ""
msgid "If you are {{user_link}}, please"
-msgstr ""
+msgstr "إذا كنت {{user_link}}, من فضلك"
msgid "If you believe this request is not suitable, you can report it for attention by the site administrators"
-msgstr ""
+msgstr "ان كنت تعتقد ان هذا الطلب غير ملائم، الرجاء تبليغ ادارة الموقع"
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."
-msgstr ""
+msgstr "ان لم تستطع النقر عليه في البريد الالكتروني, عليك أن <strong>تنسخه\\nit</strong> من البريد الالكتروني. ثم <strong لصقه في المتصفح</strong>, في المكان الذي\\nترغب أن تكتب فيه عنوان أي صفحة أخرى على الواب"
msgid "If you can, scan in or photograph the response, and <strong>send us\\n a copy to upload</strong>."
-msgstr ""
+msgstr "ان استطعت, ادخل مسحا ضوئيا أو صورة للاجابة, <strong>أرسل لنا\\n نسخة للتحميل</strong>."
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 ""
+msgstr "ان وجدت هذه الخدمة مفيدة كمزود لحرية النفاذ للمعلومة، الرجاء الطلب من مزود الواب الخاص بك الربط معنا عن طريق صفحة حرية النفاذ للمعلومة الخاصة بمنظمتك."
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."
-msgstr ""
+msgstr "اذا تحصلت على البريد الالكتروني <strong>منذ اكثر من ستة اشهر </strong>, فان رابط الدخول هذا لن يعمل بعد الانn\\ الرجاء حاول اعادةالقيام بما قمت به سابقا منذ البداية ."
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 ""
+msgstr "ان لم يسبق لك ان فعلت ذلك،الرجاء كتابة رسالة أسفله لاخبار السلطات أنك قد سحبت طلبك والا لن يعرفوا بذلك."
msgid "If you reply to this message it will go directly to {{user_name}}, who will\\nlearn your email address. Only reply if that is okay."
-msgstr ""
+msgstr "اذا تجيب على هذا السؤال سيذهب مباشرة الى {{user_name}}, الذي\\nسيعرف بريدك الالكتروني. اجب فقط اذا كنت موافقا."
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."
-msgstr ""
+msgstr "ان كنت تستعمل بريدا الكترونيا يستند الى الواب او محدد \"الرسائل الالكترونية غير المرغوب فيها\", تثبت من\\nbulk/هذه الملفات. , رسائلنا قد نصنف كبريد الكتروني غير مرغوب فيه احيانا."
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 ""
+msgstr "ان أردت رفع هذا الحظر, بامكانك\\n<a href=\"/help/contact\">الاتصال بنا</a>ذاكرا أسبابك. n\\"
msgid "If you're new to {{site_name}}"
-msgstr ""
+msgstr "إذا كنت جديداً على هذا الموقع {{site_name}}"
msgid "If you've used {{site_name}} before"
-msgstr ""
+msgstr "إذا قمتم باستخدام هذا الموقع {{site_name}} من قبل"
msgid "If your browser is set to accept cookies and you are seeing this message,\\nthen there is probably a fault with our server."
-msgstr ""
+msgstr "ان كان المتصفح الذي تستعمله مبرمجا لقبول ملفات الارتباط ورأيت هذه الرسالة,\\nفهناك على الغالب خطأ بالخادم الخاص بنا"
msgid "Incoming email address"
msgstr ""
msgid "Incoming message"
-msgstr ""
+msgstr "رسالة واردة"
msgid "IncomingMessage|Cached attachment text clipped"
-msgstr ""
+msgstr "IncomingMessage|Cached attachment text clipped"
msgid "IncomingMessage|Cached main body text folded"
-msgstr ""
+msgstr "IncomingMessage|Cached main body text folded"
msgid "IncomingMessage|Cached main body text unfolded"
-msgstr ""
+msgstr "IncomingMessage|Cached main body text unfolded"
msgid "IncomingMessage|Last parsed"
-msgstr ""
+msgstr "الرسائل الواردة|اخر تحليل"
msgid "IncomingMessage|Mail from"
-msgstr ""
+msgstr "رسالة واردة|بريد الكتروني من"
msgid "IncomingMessage|Mail from domain"
-msgstr ""
+msgstr "الرسائل الواردة|بريد الكتروني من"
msgid "IncomingMessage|Sent at"
-msgstr ""
+msgstr "رسالة واردة|بعثت على "
msgid "IncomingMessage|Subject"
-msgstr ""
+msgstr "IncomingMessage|Subject"
msgid "IncomingMessage|Valid to reply to"
-msgstr ""
+msgstr "الرسائل الواردة|صالح للرد على"
msgid "Individual requests"
-msgstr ""
+msgstr "المطالب الفردية"
msgid "Info request"
-msgstr ""
+msgstr "طلب معلومة"
msgid "Info request event"
-msgstr ""
+msgstr "طلب المعلومة"
msgid "InfoRequestEvent|Calculated state"
-msgstr ""
+msgstr "طلب المعلومة|الحالة المحسوبة"
msgid "InfoRequestEvent|Described state"
-msgstr ""
+msgstr "طلب المعلومة|الحالة الموصوفة"
msgid "InfoRequestEvent|Event type"
-msgstr ""
+msgstr "طلب المعلومة|نوع الطلب"
msgid "InfoRequestEvent|Last described at"
-msgstr ""
+msgstr "طلب المعلومة|تم اخر وصف في"
msgid "InfoRequestEvent|Params yaml"
-msgstr ""
+msgstr "InfoRequestEvent|Params yaml"
msgid "InfoRequestEvent|Prominence"
-msgstr ""
+msgstr "طلب المعلومة|الأهمية"
msgid "InfoRequest|Allow new responses from"
-msgstr ""
+msgstr "طلب المعلومة|السماح للردود الجديدة من قبل"
msgid "InfoRequest|Attention requested"
-msgstr ""
+msgstr "طلب المعلومة|الرجاء الانتباه"
msgid "InfoRequest|Awaiting description"
-msgstr ""
+msgstr "طلب المعلومة|بانتظار الوصف"
msgid "InfoRequest|Comments allowed"
-msgstr ""
+msgstr "طلب المعلومة|السماح بالتعليقات"
msgid "InfoRequest|Described state"
-msgstr ""
+msgstr "طلب المعلومة|وصف الحالة"
msgid "InfoRequest|External url"
-msgstr ""
+msgstr "طلب المعلومة|الموقع الخارجي"
msgid "InfoRequest|External user name"
-msgstr ""
+msgstr "طلب المعلومة|اسم المستخدم الخارجي"
msgid "InfoRequest|Handle rejected responses"
-msgstr ""
+msgstr " طلب المعلومة|التعامل مع الردود الملغاة"
msgid "InfoRequest|Idhash"
-msgstr ""
+msgstr "InfoRequest|Idhash"
msgid "InfoRequest|Law used"
-msgstr ""
+msgstr "طلب المعلومة|القانون المعتمد"
msgid "InfoRequest|Prominence"
-msgstr ""
+msgstr "طلب المعلومة|الأهمية"
msgid "InfoRequest|Title"
-msgstr ""
+msgstr "طلب المعلومة|العنوان"
msgid "InfoRequest|Url title"
-msgstr ""
+msgstr "طلب المعلومة|عنوان الموقع"
msgid "Information not held."
-msgstr ""
+msgstr "معلومة غير معتمدة."
msgid "Information on emissions and discharges (e.g. noise, energy,\\n radiation, waste materials)"
-msgstr ""
+msgstr "معلومات عن الارسال والتصريف (مثل. ضجيج, طاقة,\\n اشعاعات, بقايا النفايات)"
msgid "Internal review request"
-msgstr ""
+msgstr "مطلب المراجعة الداخلية "
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 ""
+msgstr "هل عنوان هذا البريد الالكتروني {{email_address}} خاطئ بالنسبة ل{{type_of_request}} الطلبات ل {{public_body_name}}?في هذه الحالة الرجاء الاتصال بنا باستعمال الصيغة التالية:"
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."
msgstr ""
msgid "Items matching the following conditions are currently displayed on your wall."
-msgstr ""
+msgstr "يتم حاليا نشر المفردات المتطابقة مع الشروط التالية على حائطك."
msgid "Items sent in last month"
msgstr ""
msgid "Joined in"
-msgstr ""
+msgstr "تاريخ الإلتحاق"
msgid "Joined {{site_name}} in"
-msgstr ""
+msgstr "انظم الى {{site_name}} في"
msgid "Just one more thing"
msgstr ""
@@ -1141,25 +1169,25 @@ msgid "Keep it <strong>focused</strong>, you'll be more likely to get what you w
msgstr ""
msgid "Keywords"
-msgstr ""
+msgstr "كلمات البحث"
msgid "Last authority viewed: "
-msgstr ""
+msgstr "آخر مؤسسة تمّ الإطلاع عليها : "
msgid "Last request viewed: "
-msgstr ""
+msgstr "آخر مطلب وقع الإطلاع عليه: "
msgid "Let us know what you were doing when this message\\nappeared and your browser and operating system type and version."
-msgstr ""
+msgstr "اعلمنا ما كنت تفعل عندما ظهرت\\nهذه الرسالة ومتصفحك و نوع و نسخة نظام التشغيل."
msgid "Link to this"
-msgstr ""
+msgstr "اربط بهذا"
msgid "List all"
msgstr ""
msgid "List of all authorities (CSV)"
-msgstr ""
+msgstr "قائمة السلط (CSV)"
msgid "Listing FOI requests"
msgstr ""
@@ -1177,499 +1205,496 @@ msgid "Listing users"
msgstr ""
msgid "Log in to download a zip file of {{info_request_title}}"
-msgstr ""
+msgstr "تسجيل الدخول لتحميل ملف مضغوط من {{info_request_title}}"
msgid "Log into the admin interface"
-msgstr ""
+msgstr "سجل دخولك في مجال المشرف"
msgid "Long overdue."
-msgstr ""
+msgstr "تأخير مطول"
msgid "Made between"
-msgstr ""
+msgstr "تم بين"
msgid "Mail server log"
-msgstr ""
+msgstr "الدخول لبريد الخادم"
msgid "Mail server log done"
-msgstr ""
+msgstr "تم الدخول لبريد الخادم"
msgid "MailServerLogDone|Filename"
-msgstr ""
+msgstr "تم الدخول لبريد الخادم|اسم الملف"
msgid "MailServerLogDone|Last stat"
-msgstr ""
+msgstr "تم الدخول لبريد الخادم|اخر حالة"
msgid "MailServerLog|Line"
-msgstr ""
+msgstr " الدخول لبريد الخادم|الخط"
msgid "MailServerLog|Order"
-msgstr ""
+msgstr "الدخول لبريد الخادم|الترتيب"
msgid "Make a new <strong>Environmental Information</strong> request"
-msgstr ""
+msgstr "قم <strong>عن المعلومات البيئية</strong> بطلب جديد"
msgid "Make a new <strong>Freedom of Information</strong> request to {{public_body}}"
-msgstr ""
+msgstr "قدم مطالب جديدة <strong>لحرية النفاذ الى المعلومة</strong> ل {{public_body}}"
msgid "Make a new<br/>\\n <strong>Freedom <span>of</span><br/>\\n Information<br/>\\n request</strong>"
-msgstr ""
+msgstr "اضف<br/>\\n <strong>لحرية<span>of</span><br/>\\n النفاذ للمعلومة<br/>\\n طلبا جديدا</strong>"
msgid "Make a request"
-msgstr ""
+msgstr "قدم مطلبا"
msgid "Make an {{law_used_short}} request to '{{public_body_name}}'"
-msgstr ""
+msgstr "قدم {{law_used_short}}مطلبا ل '{{public_body_name}}'"
msgid "Make and browse Freedom of Information (FOI) requests"
-msgstr ""
+msgstr "اضف وتصفح طلبات لحرية النفاذ للمعلومةّ(FOI)"
msgid "Make your own request"
-msgstr ""
+msgstr "قدم مطلبك الخاص"
msgid "Many requests"
-msgstr ""
+msgstr "مطالب كثيرة"
msgid "Message"
-msgstr ""
+msgstr "رسالة"
msgid "Message sent using {{site_name}} contact form, "
-msgstr ""
+msgstr "تم بعث الرسالة باستخدام {{site_name}} نموذج الاتصال, "
msgid "Missing contact details for '"
-msgstr ""
+msgstr "تنقصنا بيانات اتصال ل '"
msgid "More about this authority"
-msgstr ""
+msgstr "المزيد عن هذه السلطة"
msgid "More requests..."
-msgstr ""
+msgstr "مزيد المطالب..."
msgid "More similar requests"
-msgstr ""
+msgstr "مزيد المطالب المماثلة"
msgid "More successful requests..."
-msgstr ""
+msgstr "مزيد المطالب الناجحة"
msgid "My profile"
-msgstr ""
+msgstr "حسابي"
msgid "My request has been <strong>refused</strong>"
-msgstr ""
+msgstr "قوبل طلبي <strong>بالرفض</strong>"
msgid "My requests"
-msgstr ""
+msgstr "مطالبي"
msgid "My wall"
-msgstr ""
+msgstr "حائطي"
msgid "Name can't be blank"
-msgstr ""
+msgstr "مكان الاسم لا يجب ان بظل فارغا"
msgid "Name is already taken"
-msgstr ""
+msgstr "تم اخذ الاسم من قبل "
msgid "New Freedom of Information requests"
-msgstr ""
+msgstr "مطالب جديدة لحرية النفاذ الى المعلومة"
msgid "New censor rule"
msgstr ""
msgid "New e-mail:"
-msgstr ""
+msgstr "رسالة إلكترونية جديدة:"
msgid "New email doesn't look like a valid address"
-msgstr ""
+msgstr "الرسالة الالكترونية الجديدة لاتبدو كعنوان صالح"
msgid "New password:"
-msgstr ""
+msgstr "كلمة العبور الجديدة:"
msgid "New password: (again)"
-msgstr ""
+msgstr "كلمة العبور الجديدة: (مرة أخرى)"
msgid "New response to '{{title}}'"
-msgstr ""
+msgstr "ردّ جديد على '{{title}}'"
msgid "New response to your FOI request - "
-msgstr ""
+msgstr "ردّ جديد على مطلبكم في حق النفاذ إلى المعلومة - "
msgid "New response to your request"
-msgstr ""
+msgstr "ردّ جديد على مطلبكم"
msgid "New response to {{law_used_short}} request"
-msgstr ""
+msgstr "ردّ جديد على {{law_used_short}} المطلب"
msgid "New updates for the request '{{request_title}}'"
-msgstr ""
+msgstr "مستجدات حديثة عن المطلب '{{request_title}}'"
msgid "Newest results first"
-msgstr ""
+msgstr "النتائج الأحدث أوّلاً"
msgid "Next"
-msgstr ""
+msgstr "التالي"
msgid "Next, crop your photo &gt;&gt;"
-msgstr ""
+msgstr "ثم قم بتقطيع صورتك &gt;&gt;"
msgid "No requests of this sort yet."
-msgstr ""
+msgstr "لا توجد طلبات من هذا النوع حتى الان"
msgid "No results found."
-msgstr ""
+msgstr "لم يتم العثور على أي نتائج."
msgid "No similar requests found."
-msgstr ""
+msgstr "لم يتم العثور على أي مطالب مماثلة."
msgid "No tracked things found."
msgstr ""
msgid "Nobody has made any Freedom of Information requests to {{public_body_name}} using this site yet."
-msgstr ""
+msgstr "لم يتمّ تقديم أي مطلب حقّ النفاذ إلى المعلومة إلى {{public_body_name}} باستخدام هذا الموقع إلى حدّ الآن ."
msgid "None found."
-msgstr ""
+msgstr "لم يقع العثور على شئ"
msgid "None made."
-msgstr ""
+msgstr "لم يحدث شئ"
msgid "Not a valid FOI request"
msgstr ""
msgid "Note that the requester will not be notified about your annotation, because the request was published by {{public_body_name}} on their behalf."
-msgstr ""
+msgstr "لاحظ أن صاحب الطلب لن يستقبل اشعارا بخصوص ملاحظتك, لأن الطلب تم نشره من قبل {{public_body_name}} نيابة عنهم."
msgid "Now check your email!"
-msgstr ""
+msgstr "تفقد بريدك الالكنروني"
msgid "Now preview your annotation"
-msgstr ""
+msgstr "الق نظرة على ملاحظتك الان"
msgid "Now preview your follow up"
-msgstr ""
+msgstr "الق نظرة على متابعتك الان"
msgid "Now preview your message asking for an internal review"
-msgstr ""
+msgstr "الق نظرة على رسالتك لطلب مراجعة داخلية"
msgid "OR remove the existing photo"
-msgstr ""
+msgstr "أو أزل الصورة الحالية"
msgid "Offensive? Unsuitable?"
-msgstr ""
+msgstr "مزعج؟ غير لائق؟"
msgid "Oh no! Sorry to hear that your request was refused. Here is what to do now."
-msgstr ""
+msgstr "نأسف لسماع ان طلبك قوبل بالرفض. هنا تجد ما عليك فعله"
msgid "Old e-mail:"
-msgstr ""
+msgstr "رسالة إلكترونية قديمة:"
msgid "Old email address isn't the same as the address of the account you are logged in with"
-msgstr ""
+msgstr "عنوان بريدكم الإلكتروني القديم يختلف عن عنوان الحساب الذي تمّ تسجيل دخولكم به"
msgid "Old email doesn't look like a valid address"
-msgstr ""
+msgstr "الرسالة الالكترونية القديمة لاتبدو كعنوان صالح"
msgid "On this page"
-msgstr ""
+msgstr "في هذه الصفحة"
msgid "One FOI request found"
-msgstr ""
+msgstr "تم العثور على مطلب لحرية النفاذ الى المعلومة "
msgid "One person found"
-msgstr ""
+msgstr "تمّ العثور على شخص واحد"
msgid "One public authority found"
-msgstr ""
+msgstr "تمّ العثور على مؤسسة عمومية واحدة"
msgid "Only put in abbreviations which are really used, otherwise leave blank. Short or long name is used in the URL – don't worry about breaking URLs through renaming, as the history is used to redirect"
msgstr ""
msgid "Only requests made using {{site_name}} are shown."
-msgstr ""
+msgstr "لا تظهر الا المطالب التي قدمت باستخدام{{site_name}}"
msgid "Only the authority can reply to this request, and I don't recognise the address this reply was sent from"
-msgstr ""
+msgstr "السلطو فقط بامكانها الاجابة على هذا الطلب, لا اقدر على التعرف على العنوان الذي ارسل منه الرد"
msgid "Only the authority can reply to this request, but there is no \"From\" address to check against"
-msgstr ""
+msgstr "السلطة فقط قادرة على الرد على هذا الطلب, ولكن لا يوجد اي عنوان وارد للرد عليه"
msgid "Or search in their website for this information."
-msgstr ""
+msgstr "أو قوموا بالبحث على هذه المعلومات على موقعهم ."
msgid "Original request sent"
-msgstr ""
+msgstr "تمّ إرسال المطلب الأصلي"
msgid "Other:"
-msgstr ""
+msgstr "غيرها:"
msgid "Outgoing message"
-msgstr ""
+msgstr "الرسائل الصادرة"
msgid "OutgoingMessage|Body"
-msgstr ""
+msgstr "الرسائل الصادرة|الهيكل"
msgid "OutgoingMessage|Last sent at"
-msgstr ""
+msgstr "الرسائل الصادرة|اخر تاريخ للارسال"
msgid "OutgoingMessage|Message type"
-msgstr ""
+msgstr "الرسائل الصادرة|نوع الرسالة"
msgid "OutgoingMessage|Status"
-msgstr ""
+msgstr "الرسائل الصادرة|الحالة"
msgid "OutgoingMessage|What doing"
-msgstr ""
+msgstr "الرسائل الصادرة|ما العمل"
msgid "Partially successful."
-msgstr ""
+msgstr "ناجحة جزئيا."
msgid "Password is not correct"
-msgstr ""
+msgstr "كلمة العبور خاطئة"
msgid "Password:"
-msgstr ""
+msgstr "كلمة العبور:"
msgid "Password: (again)"
-msgstr ""
+msgstr "كلمة العبور: (ثانيةً)"
msgid "Paste this link into emails, tweets, and anywhere else:"
-msgstr ""
+msgstr " الصق هذا الرابط على الرسائل الالكترونية,التغريدات و في اي مكان اخر."
msgid "People"
-msgstr ""
+msgstr "الناس"
msgid "People {{start_count}} to {{end_count}} of {{total_count}}"
-msgstr ""
+msgstr "الناس {{start_count}} الى {{end_count}} من {{total_count}}"
msgid "Photo of you:"
-msgstr ""
+msgstr "صورة لك:"
msgid "Plans and administrative measures that affect these matters"
-msgstr ""
+msgstr "الخطط والتدابير الإدارية التي تمسّ هذه المسائل "
msgid "Play the request categorisation game"
-msgstr ""
+msgstr "العب لعبة تصنيف الطلب"
msgid "Play the request categorisation game!"
-msgstr ""
+msgstr "العب لعبة تصنيف الطلب!"
msgid "Please"
-msgstr ""
+msgstr "من فضلكم"
msgid "Please <a href=\"{{url}}\">get in touch</a> with us so we can fix it."
msgstr ""
msgid "Please <strong>answer the question above</strong> so we know whether the "
-msgstr ""
+msgstr "من فضلكم <strong>قوموا بالإجابة عن السؤال أعلاه</strong> حتى نعرف ما إذا كان "
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 ""
+msgstr "الرجاء <strong>الذهاب الى الطلبات التالية</strong>,و اعلامنا\\n ان كانت هناك معلومات عنهم في الردود الحديثة."
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 ""
+msgstr "الرجاء <strong>الاكتفاء</strong> بكتابة رسائل متصلة بطلبك مباشرة {{request_link}}. اذا كنت ترغب في الحصول على معلومات غير موجودة في طلبك الاصلي , عليك <a href=\"{{new_request_link}}\">اضافة طلب جديد</a>."
msgid "Please ask for environmental information only"
-msgstr ""
+msgstr "الرجاء الاكتفاء بطلب معلومات بيئية"
msgid "Please check the URL (i.e. the long code of letters and numbers) is copied\\ncorrectly from your email."
-msgstr ""
+msgstr "الرجاء التحقق ان عنوان الصفحة (i.e. شيفرة الاحرف و الارقام ) قد تم نسخهn\\بطريقة صحيحة من بريدك الالكتروني."
msgid "Please choose a file containing your photo."
-msgstr ""
+msgstr "يرجى اختيار ملف يحتوي على صورة لكم ."
msgid "Please choose what sort of reply you are making."
-msgstr ""
+msgstr "الرجاء اختيار نوع الرد الذي تقوم به"
msgid "Please choose whether or not you got some of the information that you wanted."
-msgstr ""
+msgstr "الرجاء اختيار ان كنت حصلت على بعض من المعلومات التي اردت ام لا"
msgid "Please click on the link below to cancel or alter these emails."
-msgstr ""
+msgstr "الرجاء الظغط على الرابط اسفله لاغاء او تغيير هذه الرسائل الالكترونية ."
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}}"
-msgstr ""
+msgstr " يرجى الظغط على الرابط اسفله لتأكيد رغبتك في \\nتغيير البريد الالكتروني الذي تستعمله على {{site_name}}\\nمن {{old_email}} الى {{new_email}}"
msgid "Please click on the link below to confirm your email address."
-msgstr ""
+msgstr "يرجى الظغط على الرابط اسفله لتأكيد عنوان بريدك الالكتروني"
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 ""
+msgstr "الرجاء تدقيق وصف مايدور حوله الطلب في الموضوع. لاداعي للقول بانه طلب عن حرية النفاذ الى المعلومات لأننا نضيف ذلك في كل الحالات."
msgid "Please don't upload offensive pictures. We will take down images\\n that we consider inappropriate."
-msgstr ""
+msgstr "الرجاء عدم تحميل صور مخلة.سنحذف الصور التي\\n نعتبرها غير ملائمة."
msgid "Please enable \"cookies\" to carry on"
-msgstr ""
+msgstr "الرجاء ايقاف ملفات الارتباط \"cookies\""
msgid "Please enter a password"
-msgstr ""
+msgstr "الرجاء إدخال كلمة المرور"
msgid "Please enter a subject"
-msgstr ""
+msgstr "الرجاء ادخال الموضوع"
msgid "Please enter a summary of your request"
-msgstr ""
+msgstr "الرجاء إدخال ملخص لمطلبكم"
msgid "Please enter a valid email address"
-msgstr ""
+msgstr "الرجاء إدخال عنوان بريد إلكتروني صالح"
msgid "Please enter the message you want to send"
-msgstr ""
+msgstr "الرجاء ادخال الرسالة التي تريد بعثها "
msgid "Please enter the same password twice"
-msgstr ""
+msgstr "الرجاء إدخال كلمة المرور نفسها مرتين"
msgid "Please enter your annotation"
-msgstr ""
+msgstr "الرجاء ادخال ملاحظتك"
msgid "Please enter your email address"
-msgstr ""
+msgstr "يرجى إدخال عنوان البريد الإلكتروني"
msgid "Please enter your follow up message"
-msgstr ""
+msgstr "الرجاء ادخال رسالة متابعتك"
msgid "Please enter your letter requesting information"
-msgstr ""
+msgstr "الرجاء ادخال رسالتك لطلب المعلومة"
msgid "Please enter your name"
-msgstr ""
+msgstr "الرجاء إدخال الإسم"
msgid "Please enter your name, not your email address, in the name field."
-msgstr ""
+msgstr " يرجى ادخال اسمك,و ليس عنوانك البريدي, في المكان المخصص للاسم. "
msgid "Please enter your new email address"
-msgstr ""
+msgstr "يرجى إدخال عنوان البريد الإلكتروني الجديد"
msgid "Please enter your old email address"
-msgstr ""
+msgstr "يرجى إدخال عنوان البريد الإلكتروني القديم"
msgid "Please enter your password"
-msgstr ""
+msgstr "الرجاء إدخال كلمة المرور"
msgid "Please give details explaining why you want a review"
-msgstr ""
+msgstr "الرجاء ادخال تفاصيل تشرح سبب رغبتك في اعادة النظر"
msgid "Please keep it shorter than 500 characters"
-msgstr ""
+msgstr "الرجاء عدم تجاوز 500 رمز"
msgid "Please keep the summary short, like in the subject of an email. You can use a phrase, rather than a full sentence."
-msgstr ""
+msgstr "الرجاء ابقاء الملخص قصيرا, مثل الموضوع في الرسائل الالكترونية. يمكنك استعمال عبارات عوضا عن الجمل الكاملة."
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 ""
+msgstr "الرجاء طلب المعلومات التي تصنف ضمن هذه الفئات وحسب, <strong>لا تضيع\\n وقتك</strong> او وقت the السلطة العامة بطلب معلومات غير ذات صلة."
msgid "Please select each of these requests in turn, and <strong>let everyone know</strong>\\nif they are successful yet or not."
-msgstr ""
+msgstr "الرجاء اختيار كل من هذه الطلبات بدوره,و <strong>أعلم الجميع</strong>\\nان كانت الطلبات ناجحة ام ليس بعد."
msgid "Please sign at the bottom with your name, or alter the \"{{signoff}}\" signature"
msgstr ""
msgid "Please sign in as "
-msgstr ""
+msgstr "يرجى تسجيل الدخول ك"
msgid "Please sign in or make a new account."
msgstr ""
msgid "Please type a message and/or choose a file containing your response."
-msgstr ""
+msgstr "يرجى كتابة رسالة و / أو اختيار ملف يحتوي على ردكم."
msgid "Please use this email address for all replies to this request:"
-msgstr ""
+msgstr "يرجى استخدام البريد الإلكتروني لجميع الردود على هذا المطلب على هذا العنوان :"
msgid "Please write a summary with some text in it"
-msgstr ""
+msgstr "الرجاء كتابة نص صغير للتلخيص"
msgid "Please write the summary using a mixture of capital and lower case letters. This makes it easier for others to read."
-msgstr ""
+msgstr "الرجاء كتابة تلخيص واضح لتسهيل القراءة على الاخرين."
msgid "Please write your annotation using a mixture of capital and lower case letters. This makes it easier for others to read."
-msgstr ""
+msgstr "الرجاء كتابة ملاحظة واضحة لتسهيل القراءة على الاخرين."
msgid "Please write your follow up message containing the necessary clarifications below."
-msgstr ""
+msgstr "الرجاء كتابة رسالة المتابعة و تضمينها التوضيحات اللازمة اسفله."
msgid "Please write your message using a mixture of capital and lower case letters. This makes it easier for others to read."
-msgstr ""
+msgstr "الرجاء كتابة رسالة واضحة لتسهيل القراءة على الاخرين."
msgid "Point to <strong>related information</strong>, campaigns or forums which may be useful."
-msgstr ""
+msgstr "أشر الى <strong>المعلومات ذات الصلة</strong>, الحملات او المنتديات التي قد تكون مفيدة."
msgid "Possibly related requests:"
-msgstr ""
+msgstr "الطلبات التي قد تكون متصلة."
msgid "Post annotation"
-msgstr ""
+msgstr "انشر الملاحظة"
msgid "Post redirect"
-msgstr ""
+msgstr "إعادة توجيه النشر"
msgid "PostRedirect|Circumstance"
-msgstr ""
+msgstr "اعادة توجيه النشر|الظرف"
msgid "PostRedirect|Email token"
-msgstr ""
+msgstr "اعادة توجيه النشر|علامة البريد الالكتروني"
msgid "PostRedirect|Post params yaml"
-msgstr ""
+msgstr "اعادة توجيه الرابط|اعدادات الرابط yaml"
msgid "PostRedirect|Reason params yaml"
-msgstr ""
+msgstr "اعادة توجيه الرابط|سبب اعدادات yaml"
msgid "PostRedirect|Token"
-msgstr ""
+msgstr "اعادة توجيه النشر|علامة"
msgid "PostRedirect|Uri"
-msgstr ""
+msgstr "اعادة توجيه الرابط|Uri"
msgid "Posted on {{date}} by {{author}}"
-msgstr ""
+msgstr "نشر في {{date}} من قبل {{author}}"
msgid "Powered by <a href=\"http://www.alaveteli.org/\">Alaveteli</a>"
msgstr ""
msgid "Prev"
-msgstr ""
+msgstr "السابق"
msgid "Preview follow up to '"
-msgstr ""
+msgstr "الق نظرة على المتابعة ل"
msgid "Preview new annotation on '{{info_request_title}}'"
-msgstr ""
+msgstr "الق نظرة على الملاحظة الجديدة على '{{info_request_title}}'"
msgid "Preview your annotation"
-msgstr ""
+msgstr "الق نظرة على ملاحظتك"
msgid "Preview your message"
-msgstr ""
+msgstr "الق نظرة على رسالتك"
msgid "Preview your public request"
-msgstr ""
+msgstr "الق نظرة على طلبك العلني"
msgid "Profile photo"
-msgstr ""
+msgstr "صورة الحساب"
msgid "ProfilePhoto|Data"
-msgstr ""
+msgstr "صورة الحساب|بيانات"
msgid "ProfilePhoto|Draft"
-msgstr ""
+msgstr "صورة الحساب|مسودة"
msgid "Public authorities"
-msgstr ""
+msgstr "السلطات العامة "
msgid "Public authorities - {{description}}"
-msgstr ""
+msgstr "سلطات عامة - {{description}}"
msgid "Public authorities {{start_count}} to {{end_count}} of {{total_count}}"
-msgstr ""
+msgstr "السلطات العمومية {{start_count}} الى {{end_count}} من {{total_count}}"
msgid "Public authority – {{name}}"
msgstr ""
msgid "Public body"
-msgstr ""
-
-msgid "Public body/translation"
-msgstr ""
+msgstr "الهيكل العامّ"
msgid "Public notes"
msgstr ""
@@ -1680,230 +1705,203 @@ msgstr ""
msgid "Public page not available"
msgstr ""
-msgid "PublicBody::Translation|Disclosure log"
-msgstr ""
-
-msgid "PublicBody::Translation|First letter"
-msgstr ""
-
-msgid "PublicBody::Translation|Locale"
-msgstr ""
-
-msgid "PublicBody::Translation|Name"
-msgstr ""
-
-msgid "PublicBody::Translation|Notes"
-msgstr ""
-
-msgid "PublicBody::Translation|Publication scheme"
-msgstr ""
-
-msgid "PublicBody::Translation|Request email"
-msgstr ""
-
-msgid "PublicBody::Translation|Short name"
-msgstr ""
-
-msgid "PublicBody::Translation|Url name"
-msgstr ""
-
msgid "PublicBody|Api key"
-msgstr ""
+msgstr "الهيكل العام|مفتاح واجهة مبرمج التطبيقات"
msgid "PublicBody|Disclosure log"
-msgstr ""
+msgstr "الهيكل العامّ|كشف السجل"
msgid "PublicBody|First letter"
-msgstr ""
+msgstr "الهيكل العامّ|أول حرف"
msgid "PublicBody|Home page"
-msgstr ""
+msgstr "الهيكل العامّ|الصفحة الرئيسية"
msgid "PublicBody|Info requests count"
msgstr ""
msgid "PublicBody|Last edit comment"
-msgstr ""
+msgstr "الهيكل العامّ|اخر تعليق محوّر"
msgid "PublicBody|Last edit editor"
-msgstr ""
+msgstr "الهيكل العامّ|اخر تنقيح محوّر"
msgid "PublicBody|Name"
-msgstr ""
+msgstr "الهيكل العامّ|اسم"
msgid "PublicBody|Notes"
-msgstr ""
+msgstr "الهيكل العامّ|ّملاحظات"
msgid "PublicBody|Publication scheme"
-msgstr ""
+msgstr "الهيكل العامّ|مخطط مايقع نشره"
msgid "PublicBody|Request email"
-msgstr ""
+msgstr "الهيكل العامّ|طلب البريد الالكتروني"
msgid "PublicBody|Short name"
-msgstr ""
+msgstr "الهيكل العامّ|اسم مختصر"
msgid "PublicBody|Url name"
-msgstr ""
+msgstr "الهيكل العامّ|اسم الموقع"
msgid "PublicBody|Version"
-msgstr ""
+msgstr "الهيكل العامّ|نسخة"
msgid "Publication scheme"
-msgstr ""
+msgstr "مخطط مايقع نشره"
msgid "Publication scheme URL"
msgstr ""
msgid "Purge request"
-msgstr ""
+msgstr "مطلب تطهير"
msgid "PurgeRequest|Model"
-msgstr ""
+msgstr "نهاية الصلاحية|نموذج"
msgid "PurgeRequest|Url"
msgstr ""
msgid "RSS feed"
-msgstr ""
+msgstr "رد ال RSS "
msgid "RSS feed of updates"
-msgstr ""
+msgstr "ردود التحيينات الخاصة ب RSS ر س س"
msgid "Re-edit this annotation"
-msgstr ""
+msgstr "اعادة تحوير هذه الملاحظات"
msgid "Re-edit this message"
-msgstr ""
+msgstr "أعد-تغيير هذه الرسالة"
msgid "Read about <a href=\"{{advanced_search_url}}\">advanced search operators</a>, such as proximity and wildcards."
-msgstr ""
+msgstr "اقرأ عن <a href=\"{{advanced_search_url}}\">محركات البحث المتقدم </a>, مثل القرب و احرف البدل."
msgid "Read blog"
-msgstr ""
+msgstr "قراءة المدوَّنة الخاصة "
msgid "Received an error message, such as delivery failure."
-msgstr ""
+msgstr "تم استقبال رسالة خطأ، مثل فشل في الارسال"
msgid "Recently described results first"
-msgstr ""
+msgstr "اظهار أحدث النتائج أولا"
msgid "Refused."
-msgstr ""
+msgstr "مرفوض."
msgid "Remember me</label> (keeps you signed in longer;\\n do not use on a public computer) "
-msgstr ""
+msgstr "تذكرني</label> (البقاء متصلا;\\n عدم تسجيل الدخول على حاسوب عمومي) "
msgid "Report abuse"
-msgstr ""
+msgstr "الإبلاغ عن سوء استخدام"
msgid "Report an offensive or unsuitable request"
-msgstr ""
+msgstr "بلغ عن طلب غير ملائم أو مخل بالاداب"
msgid "Report this request"
-msgstr ""
+msgstr "التقرير عن هذا المطلب"
msgid "Reported for administrator attention."
-msgstr ""
+msgstr "تم التبليغ لادارة الموقع"
msgid "Request an internal review"
-msgstr ""
+msgstr "طلب مراجعة داخلية"
msgid "Request an internal review from {{person_or_body}}"
-msgstr ""
+msgstr "اطلب مراجعة داخلية من {{person_or_body}}"
msgid "Request email"
msgstr ""
msgid "Request has been removed"
-msgstr ""
+msgstr "تمت إزالة المطلب"
msgid "Request sent to {{public_body_name}} by {{info_request_user}} on {{date}}."
-msgstr ""
+msgstr "تمّ إرسال المطلب إلى {{public_body_name}} من طرف {{info_request_user}} في {{date}}."
msgid "Request to {{public_body_name}} by {{info_request_user}}. Annotated by {{event_comment_user}} on {{date}}."
-msgstr ""
+msgstr "طلب ل {{public_body_name}} من {{info_request_user}}. تمت اضافة الملاحظة من {{event_comment_user}}بتاريخ {{date}}."
msgid "Requested from {{public_body_name}} by {{info_request_user}} on {{date}}"
-msgstr ""
+msgstr "تم الطلب من قيل {{public_body_name}} من خلال {{info_request_user}} في {{date}}"
msgid "Requested on {{date}}"
-msgstr ""
+msgstr "تم الطلب بتاريخ {{date}}"
msgid "Requests for personal information and vexatious requests are not considered valid for FOI purposes (<a href=\"/help/about\">read more</a>)."
-msgstr ""
+msgstr "طلبات المعلومات الشخصية و الطلبات المخلة لا تعتبر صالحة لاقتراحات طلبات النفاذ الى المعلومة (<a href=\"/help/about\">اقرأ المزيد</a>)."
msgid "Requests or responses matching your saved search"
-msgstr ""
+msgstr "الطلبات أو الردود الموافقة لبحثك المسجل"
msgid "Respond by email"
-msgstr ""
+msgstr "الرد عبر البريد الإلكتروني"
msgid "Respond to request"
-msgstr ""
+msgstr "الرد على المطلب "
msgid "Respond to the FOI request"
-msgstr ""
+msgstr "رد على مطالب حرية المعلومة "
msgid "Respond using the web"
-msgstr ""
+msgstr "الرد عن طريق الشبكة العنكبوتية "
msgid "Response"
-msgstr ""
+msgstr "الرد"
msgid "Response from a public authority"
-msgstr ""
+msgstr "ردّ من طرف المؤسسة العمومية"
msgid "Response to '{{title}}'"
-msgstr ""
+msgstr "الردّ على '{{title}}'"
msgid "Response to this request is <strong>delayed</strong>."
-msgstr ""
+msgstr "الردّ على هذا المطلب <strong>وقع حذفه</strong>."
msgid "Response to this request is <strong>long overdue</strong>."
-msgstr ""
+msgstr "الردّ على هذا المطلب <strong>تأخر كثيراً</strong>."
msgid "Response to your request"
-msgstr ""
+msgstr "الردّ على مطلبكم"
msgid "Response:"
-msgstr ""
+msgstr "الردّ:"
msgid "Restrict to"
-msgstr ""
+msgstr "تقيد ب"
msgid "Results page {{page_number}}"
-msgstr ""
+msgstr "صفحة النتائج {{page_number}}"
msgid "Save"
-msgstr ""
+msgstr "الحفظ"
msgid "Search"
-msgstr ""
+msgstr "البحث "
msgid "Search Freedom of Information requests, public authorities and users"
-msgstr ""
+msgstr "ابحث عن مطالب حرية المعلومة و السلطات العامة و المستعملين"
msgid "Search contributions by this person"
-msgstr ""
+msgstr "البحث عن مساهمات هذا الشخص"
msgid "Search for words in:"
-msgstr ""
+msgstr "البحث عن كلمات في :"
msgid "Search in"
-msgstr ""
+msgstr "البحث في "
msgid "Search over<br/>\\n <strong>{{number_of_requests}} requests</strong> <span>and</span><br/>\\n <strong>{{number_of_authorities}} authorities</strong>"
-msgstr ""
+msgstr "ابحث عن<br/>\\n <strong>{{number_of_requests}} الطلبات</strong> <span>و</span><br/>\\n <strong>{{number_of_authorities}} السلطات</strong>"
msgid "Search queries"
-msgstr ""
+msgstr "استفسارات البحث"
msgid "Search results"
-msgstr ""
+msgstr "نتائج البحث"
msgid "Search the site to find what you were looking for."
-msgstr ""
+msgstr "ابحث عن الموقع لتجد ما تبحث عنه."
msgid "Search within the {{count}} Freedom of Information requests to {{public_body_name}}"
msgid_plural "Search within the {{count}} Freedom of Information requests made to {{public_body_name}}"
@@ -1915,271 +1913,271 @@ msgstr[4] ""
msgstr[5] ""
msgid "Search your contributions"
-msgstr ""
+msgstr "البحث عن مساهماتك"
msgid "See bounce message"
msgstr ""
msgid "Select one to see more information about the authority."
-msgstr ""
+msgstr "اختر واحدا لرؤية معلومات اكثر على السلطة"
msgid "Select the authority to write to"
-msgstr ""
+msgstr "تحديد المؤسسة التي يرجى مراسلتها"
msgid "Send a followup"
-msgstr ""
+msgstr "ابعث متابعة "
msgid "Send a message to "
-msgstr ""
+msgstr "إرسال رسالة إلى"
msgid "Send a public follow up message to {{person_or_body}}"
-msgstr ""
+msgstr "ابعث رسالة متابعة علنية ل {{person_or_body}}"
msgid "Send a public reply to {{person_or_body}}"
-msgstr ""
+msgstr "ارسل ردا علنيا ل {{person_or_body}}"
msgid "Send follow up to '{{title}}'"
-msgstr ""
+msgstr "ارسل متابعة ل '{{title}}'"
msgid "Send message"
-msgstr ""
+msgstr "ابعث رسالة "
msgid "Send message to "
-msgstr ""
+msgstr "ابعث رسالة ل"
msgid "Send request"
-msgstr ""
+msgstr "إرسال المطلب"
msgid "Set your profile photo"
-msgstr ""
+msgstr "ضع صورة لحسابك"
msgid "Short name"
msgstr ""
msgid "Short name is already taken"
-msgstr ""
+msgstr "تم اخذ الاسم المختصر"
msgid "Show most relevant results first"
-msgstr ""
+msgstr "اظهر النتائج الأكثر صلة بالموضوع أولا."
msgid "Show only..."
-msgstr ""
+msgstr "اظهر فقط"
msgid "Showing"
-msgstr ""
+msgstr "اظهار"
msgid "Sign in"
-msgstr ""
+msgstr "سجل الدخول"
msgid "Sign in or make a new account"
-msgstr ""
+msgstr "سجل دخولك او افتح حسابا جديدا"
msgid "Sign in or sign up"
-msgstr ""
+msgstr "اشترك او سجل دخولك"
msgid "Sign out"
-msgstr ""
+msgstr "تسجيل الخروج"
msgid "Sign up"
-msgstr ""
+msgstr "اشترك"
msgid "Similar requests"
-msgstr ""
+msgstr "طلبات مماثلة"
msgid "Simple search"
-msgstr ""
+msgstr "بحث بسيط"
msgid "Some notes have been added to your FOI request - "
-msgstr ""
+msgstr "بعض الملاحظات اضيفت لطلبك لحرية النفاذ للمعلومة"
msgid "Some of the information requested has been received"
-msgstr ""
+msgstr "وقع تلقي بعض المعلومات المطلوبة"
msgid "Some people who've made requests haven't let us know whether they were\\nsuccessful or not. We need <strong>your</strong> help &ndash;\\nchoose one of these requests, read it, and let everyone know whether or not the\\ninformation has been provided. Everyone'll be exceedingly grateful."
-msgstr ""
+msgstr "بعض الاشخاص الذين قدموا طلبات لم يعلمونا عم اذا \\n نجحوا بذلك ام لا. نحتاج <strong>مساعدنك</strong> &ndash;\\nاختر واحدا من هذه الطلبات, اقرأه, و اعلم الجميع عما اذا كانت\\nالمعلومة متوفرة. سيكون الجميع ممتنا."
msgid "Somebody added a note to your FOI request - "
-msgstr ""
+msgstr "احدهم اضاف ملحوظة لمطلب حرية النفاذ للمعلومة "
msgid "Someone has updated the status of your request"
-msgstr ""
+msgstr "قام شخص بتحيين حالة طلبك."
msgid "Someone, perhaps you, just tried to change their email address on\\n{{site_name}} from {{old_email}} to {{new_email}}."
-msgstr ""
+msgstr "احدهم, ربما انت, حاول تغيير عنوان بريده الالكتروني على on\\n{{site_name}} من {{old_email}} الى {{new_email}}."
msgid "Sorry - you cannot respond to this request via {{site_name}}, because this is a copy of the request originally at {{link_to_original_request}}."
-msgstr ""
+msgstr "اسف - لا تسطيع الاجابة عن هذا الطلب من خلال {{site_name}}, لأنه نسخة من الطلب الموجود اساسا على {{link_to_original_request}}."
msgid "Sorry, but only {{user_name}} is allowed to do that."
-msgstr ""
+msgstr "المعذرة, ولكن بامكان {{user_name}} فقط القيام بذلك."
msgid "Sorry, there was a problem processing this page"
-msgstr ""
+msgstr "نأسف, كان هناك مشكلة في فتح هذه الصفحة."
msgid "Sorry, we couldn't find that page"
-msgstr ""
+msgstr "المعذرة, لم نتمكن من ايجاد الصفحة "
msgid "Special note for this authority!"
-msgstr ""
+msgstr "ملاحظة خاصة بهذه السلطة."
msgid "Start"
-msgstr ""
+msgstr "ابدأ"
msgid "Start now &raquo;"
-msgstr ""
+msgstr "ابدأ الان &raquo;"
msgid "Start your own blog"
-msgstr ""
+msgstr "اطلق مدونتك الخاصة"
msgid "Stay up to date"
-msgstr ""
+msgstr "تلق كل التحيينات"
msgid "Still awaiting an <strong>internal review</strong>"
-msgstr ""
+msgstr "مازلت بانتظار <strong>مراجعة داخلية</strong>"
msgid "Subject"
-msgstr ""
+msgstr "موضوع"
msgid "Subject:"
-msgstr ""
+msgstr "موضوع"
msgid "Submit"
-msgstr ""
+msgstr "اضف"
msgid "Submit status"
-msgstr ""
+msgstr "اضف حالة"
msgid "Submit status and send message"
msgstr ""
msgid "Subscribe to blog"
-msgstr ""
+msgstr "الاشتراك في المدونة"
msgid "Successful Freedom of Information requests"
-msgstr ""
+msgstr "مطالب حرية النفاذ للمعلومة ناجحة"
msgid "Successful."
-msgstr ""
+msgstr "ناجح"
msgid "Suggest how the requester can find the <strong>rest of the information</strong>."
-msgstr ""
+msgstr "اقترح الطريقة التي يستطيع من خلالها صاحب الطلب ايجاد <strong>بقية المعلومات</strong>."
msgid "Summary:"
-msgstr ""
+msgstr "ملخص"
msgid "Table of statuses"
-msgstr ""
+msgstr "جدول الحالات"
msgid "Table of varieties"
-msgstr ""
+msgstr "جدول الخيارات"
msgid "Tags"
msgstr ""
msgid "Tags (separated by a space):"
-msgstr ""
+msgstr "اشارات (يفصلها فراغ):"
msgid "Tags:"
-msgstr ""
+msgstr "اشارات"
msgid "Technical details"
-msgstr ""
+msgstr "تفاصيل تقنية"
msgid "Thank you for helping us keep the site tidy!"
-msgstr ""
+msgstr "شكرا على مساعدتنا على ابقاء الموقع مرتبا!"
msgid "Thank you for making an annotation!"
-msgstr ""
+msgstr "شكرا على القيام بملاحظة!"
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 ""
+msgstr "شكرا للرد على طلب النفاذ الى المعلومة ! تم نشر طلبك اسفله, تم ارسال رابط لردك بواسطة البريد الالكتروني ل "
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 ""
+msgstr "شكرا لتحديث حالة الطلب '<a href=\"{{url}}\">{{info_request_title}}</a>'. تجد اسفله طلبات اخرى لتصنفها."
msgid "Thank you for updating this request!"
-msgstr ""
+msgstr "شكرا على تحيين الطلب"
msgid "Thank you for updating your profile photo"
-msgstr ""
+msgstr "شكرا على تحيين صورة الحساب"
msgid "Thank you! We'll look into what happened and try and fix it up."
msgstr ""
msgid "Thanks for helping - your work will make it easier for everyone to find successful\\nresponses, and maybe even let us make league tables..."
-msgstr ""
+msgstr "شكرا على المساعدة - سيساعد عملك الجميع في ايجاد\\nردود ناجحة, وحتى في انجاز جداول احصاء..."
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 ""
+msgstr "شكرا جزيلا - سيساعدهذا الاخرين في العثور على أشياء مفيدة. سوف\\n نمدك أيضا ان احتجت بنصائح حول ما يجب أن تفعل لاحقا بخصوص \\n طلباتك."
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 ""
+msgstr "شكرا جزيلا على مساعدتنا في الحفاظ على كل شيء <strong>واضحا ومنظما</strong>.\\n ان احتجت،سنمدك ايضا بنصائح حول مايجب ان تفعله لاحقا بخصوص\\n كل من طلباتك."
msgid "That doesn't look like a valid email address. Please check you have typed it correctly."
-msgstr ""
+msgstr "هذا لا يبدو كعنوان بريد الكتروني صالح.الرجاء التأكد من أنك كتبته بطريقة صحيحة."
msgid "The <strong>review has finished</strong> and overall:"
-msgstr ""
+msgstr "تم <strong>اتمام المراجعة</strong> بطريقة شاملة:"
msgid "The Freedom of Information Act <strong>does not apply</strong> to"
-msgstr ""
+msgstr "قانون حرية المعلومات <strong>لا ينطبق</strong> على"
msgid "The accounts have been left as they previously were."
-msgstr ""
+msgstr "تم ترك كل حساب كما كان سابقا"
msgid "The authority do <strong>not have</strong> the information <small>(maybe they say who does)"
-msgstr ""
+msgstr "السلطة <strong>لا تملك</strong> المعلومة <small>(ربما يقولون من يملكها)"
msgid "The authority only has a <strong>paper copy</strong> of the information."
-msgstr ""
+msgstr "السلطة لا تملك سوى <strong>نسخة</strong> من المعلومة"
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 ""
+msgstr "السلطات تقول انها <strong>تحتاج عنوانا\\n بريديا</strong>, لا بريدا الكترونيا فقط, ليكون طلب حرية النفاذ الى المعلومة صالحا"
msgid "The authority would like to / has <strong>responded by post</strong> to this request."
-msgstr ""
+msgstr "هذه السلطة ترغب في / قامت ب <strong>الرد عبر النشر</strong> على هذا الطلب."
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."
-msgstr ""
+msgstr "البريد الالكتروني الذي, ارسلته عوضا عن {{public_body}} الى\\n{{user}} للرد على {{ law_used_short}}\\n لم يقع ارسال الطلب."
msgid "The page doesn't exist. Things you can try now:"
-msgstr ""
+msgstr "هذه الصفحة غير موجودة. الاشياء التي لمكن ان تجربها:"
msgid "The public authority does not have the information requested"
-msgstr ""
+msgstr "السلطة العامة لا تملك المعلومة المطلوبة"
msgid "The public authority would like part of the request explained"
-msgstr ""
+msgstr "السلطة العامة تريد تفسيرا لجزء من الطلب"
msgid "The public authority would like to / has responded by post"
-msgstr ""
+msgstr "ترغب السلطة العامة في /الرد عبر النشر"
msgid "The request has been <strong>refused</strong>"
-msgstr ""
+msgstr "وقع رفض <strong>الطلب</strong>"
msgid "The request has been updated since you originally loaded this page. Please check for any new incoming messages below, and try again."
-msgstr ""
+msgstr " تم تحيين الطلب منذ حملت الصفحة. الرجاء التحقق من ورود اي رسائل اسفله, و حاول مجددا."
msgid "The request is <strong>waiting for clarification</strong>."
-msgstr ""
+msgstr "الطلب <strong>بانتظار توضيح</strong>."
msgid "The request was <strong>partially successful</strong>."
-msgstr ""
+msgstr "الطلب كان <strong>ناجحا جزئيا</strong>."
msgid "The request was <strong>refused</strong> by"
-msgstr ""
+msgstr "تم <strong>رفص الطلب</strong> من طرف"
msgid "The request was <strong>successful</strong>."
-msgstr ""
+msgstr "كان الطلب <strong>ناجحا</strong>."
msgid "The request was refused by the public authority"
-msgstr ""
+msgstr "تم رفض الطلب من طرف السلطة العامةّ"
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=\"{{url}}\">contact us</a> if you have any questions."
msgstr ""
msgid "The requester has abandoned this request for some reason"
-msgstr ""
+msgstr "تخلى صاحب الطلب عن هذا الطلب لأسباب معينة"
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 ""
@@ -2188,91 +2186,94 @@ msgid "The response to your request is <strong>long overdue</strong>. You can
msgstr ""
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 ""
+msgstr "مؤشر البحث خارج الخدمة حاليا,لذلك لا يمكننا اظهار طلبات حرية النفاذ للمعلومة التي قامت بها هذه السلطة."
msgid "The search index is currently offline, so we can't show the Freedom of Information requests this person has made."
+msgstr "مؤشر البحث خارج الخدمة حاليا, لذلك ليس بامكاننا اظهار طلبات حرية النفاذ الى المعلومة التي قدمها هذا الشخص."
+
+msgid "The {{site_name}} team."
msgstr ""
msgid "Then you can cancel the alert."
-msgstr ""
+msgstr "تستطيع بعد ذلك الغاء التنبيه"
msgid "Then you can cancel the alerts."
-msgstr ""
+msgstr "تستطيع بعد ذلك الغاء التنبيهات"
msgid "Then you can change your email address used on {{site_name}}"
-msgstr ""
+msgstr "ثم بامكانك تغيير عنوان بريدك الالكتروني المستعمل على{{site_name}}"
msgid "Then you can change your password on {{site_name}}"
-msgstr ""
+msgstr "ثم يمكنك تغيير كلمة السر على {{site_name}}"
msgid "Then you can classify the FOI response you have got from "
-msgstr ""
+msgstr "ثم يمكنك تصنيف رد حرية النفاذ للمعلومة الذي تحصلت عليه من "
msgid "Then you can download a zip file of {{info_request_title}}."
-msgstr ""
+msgstr "ثم يمكنك تنويل ملف مظغوط من{{info_request_title}}."
msgid "Then you can log into the administrative interface"
-msgstr ""
+msgstr "ثم يمكنك تسجيل دخولك للمجال الاداري"
msgid "Then you can play the request categorisation game."
-msgstr ""
+msgstr "ثم بامكانك ان تلعب لعبة تصنيف الطلب"
msgid "Then you can report the request '{{title}}'"
-msgstr ""
+msgstr "ثم يمكنك التبليغ عن الطلب '{{title}}'"
msgid "Then you can send a message to "
-msgstr ""
+msgstr "ثم يمكنك بعث رسالة"
msgid "Then you can sign in to {{site_name}}"
-msgstr ""
+msgstr "ثم يمكنك تسجيل دخولك ل {{site_name}}"
msgid "Then you can update the status of your request to "
-msgstr ""
+msgstr "ثم بامكانك نحيين حالة طلباتك ل"
msgid "Then you can upload an FOI response. "
-msgstr ""
+msgstr "بامكانك تحميل طلب لحريةالنفاذ الى المعلومة ."
msgid "Then you can write follow up message to "
-msgstr ""
+msgstr "ثم بامكانك كتابة رسالة متابعة ل"
msgid "Then you can write your reply to "
-msgstr ""
+msgstr "ثم بامكانك كتابة ردك ل"
msgid "Then you will be following all new FOI requests."
-msgstr ""
+msgstr "ثم ستتمكن من متابعة كل الطلبات الجديدة لحرية النفاذ الى المعلومة."
msgid "Then you will be notified whenever '{{user_name}}' requests something or gets a response."
-msgstr ""
+msgstr " ثم سيتم إعلامك كلما قام '{{user_name}}' بتقديم طلب او تحصل على رد."
msgid "Then you will be notified whenever a new request or response matches your search."
-msgstr ""
+msgstr "ثم سيتم إعلامك كلما تتطابق طلب جديد او رد مع بحثك."
msgid "Then you will be notified whenever an FOI request succeeds."
-msgstr ""
+msgstr "ثم سيتم إعلامك كلما نجح طلبحرية النفاذ الى المعلومة"
msgid "Then you will be notified whenever someone requests something or gets a response from '{{public_body_name}}'."
-msgstr ""
+msgstr "ثم سيتم إعلامك كلما طلب شخص ما شيئا ما او تحصل على رد من '{{public_body_name}}'."
msgid "Then you will be updated whenever the request '{{request_title}}' is updated."
-msgstr ""
+msgstr "ثم سيتم إعلامك كلما تم '{{request_title}}' تحيين الطلب."
msgid "Then you'll be allowed to send FOI requests."
-msgstr ""
+msgstr "ثم سيكون بامكانك ارسال طلبات حرية الولوج الى المعلومة."
msgid "Then your FOI request to {{public_body_name}} will be sent."
-msgstr ""
+msgstr "ثم سيقع ارسال طلباتك لحرية النفاذ الى المعلومة ل{{public_body_name}} ."
msgid "Then your annotation to {{info_request_title}} will be posted."
-msgstr ""
+msgstr "ثم سيقع نشر {{info_request_title}}ملاحظتك."
msgid "There are {{count}} new annotations on your {{info_request}} request. Follow this link to see what they wrote."
-msgstr ""
+msgstr "يوجد {{count}} ملاحظات جديدة {{info_request}} تخص طلبك. اتبع هذا الرابط لرؤية ما كتبوا."
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 ""
+msgstr "هنالك <strong>اكثر من شخص</strong> يستعمل هذا الموقع و له هذا الاسم.\\n احدهم يظهر اسفله, ربما تعني اسما اخرا:"
msgid "There is a limit on the number of requests you can make in a day, because we don’t want public authorities to be bombarded with large numbers of inappropriate requests. If you feel you have a good reason to ask for the limit to be lifted in your case, please <a href='{{help_contact_path}}'>get in touch</a>."
-msgstr ""
+msgstr "عدد المطالب التي بامكانك تقديمها في اليوم الواحد محدود, لاننا لاننا لا تريد ان تكثر على السلطات العامة الطلبات الغير ملائمة. ان كان لديك سبب وجيه لتسألهم الترفيع في العدد المحدد للطلبات في حالتك, الرجاء <a href='{{help_contact_path}}'>الاتصال بنا</a>."
msgid "There is {{count}} person following this request"
msgid_plural "There are {{count}} people following this request"
@@ -2284,76 +2285,76 @@ msgstr[4] ""
msgstr[5] ""
msgid "There was a <strong>delivery error</strong> or similar, which needs fixing by the {{site_name}} team."
-msgstr ""
+msgstr "كان هنالك <strong>خطأ في التسلبم</strong> او ما شابه ذلك, و يحتاج اصلاحه من قبل {{site_name}} الفريق."
msgid "There was an error with the words you entered, please try again."
-msgstr ""
+msgstr "كان هتالك خطأ في الكلمات التي ادخلتها الرجاء المحاولة ثانية"
msgid "There were no requests matching your query."
-msgstr ""
+msgstr "لا يوجد ردود تتعلق بتساؤلك,"
msgid "There were no results matching your query."
-msgstr ""
+msgstr "لا يوجد نتائج تتعلق بتساؤلك"
msgid "They are going to reply <strong>by post</strong>"
-msgstr ""
+msgstr "سيقومون بالرد <strong>عبر البريد</strong>"
msgid "They do <strong>not have</strong> the information <small>(maybe they say who does)</small>"
-msgstr ""
+msgstr "لا <strong>يملكون</strong> المعلومة <small>(ربما سيعلمونك بمن يملكها )</small>"
msgid "They have been given the following explanation:"
-msgstr ""
+msgstr "قدم لهم الشرح التالي:"
msgid "They have not replied to your {{law_used_short}} request {{title}} promptly, as normally required by law"
-msgstr ""
+msgstr "لم يقوموا بالرد على {{law_used_short}}طلبك {{title}}, \\n فورا كما هو مطلوب بموجب القانون عادة"
msgid "They have not replied to your {{law_used_short}} request {{title}}, \\nas required by law"
-msgstr ""
+msgstr "لم يقوموا بالرد على {{law_used_short}}طلبك {{title}}, \\nكما هو مطلوب بموجب القانون"
msgid "Things to do with this request"
-msgstr ""
+msgstr "مايمكن فعله بهذا الطلب"
msgid "Things you're following"
-msgstr ""
+msgstr "الاشياء التي تتابعها"
msgid "This authority no longer exists, so you cannot make a request to it."
-msgstr ""
+msgstr "هذه السلطة لم تعد موجودة, لم يعد بامكانك تقديم طلب لها."
msgid "This comment has been hidden. See annotations to\\n find out why. If you are the requester, then you may <a href=\"{{url}}\">sign in</a> to view the response."
msgstr ""
msgid "This covers a very wide spectrum of information about the state of\\n the <strong>natural and built environment</strong>, such as:"
-msgstr ""
+msgstr "هذا يغطي مجالا واسعا من المعلومات حول حالة \\n <strong>البيئة الطبيعية و الاصطناعية</strong>, مثل :"
msgid "This external request has been hidden"
-msgstr ""
+msgstr "تم اخفاء الطلب الخارجي"
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 ""
+msgstr " هذه نسخة نص مجرد بخصوص حرية النفاذ للمعلومة \"{{request_title}}\". يمكنك الحصول على النسخة الأخيرة الكاملة على {{full_url}}"
msgid "This is an HTML version of an attachment to the Freedom of Information request"
-msgstr ""
+msgstr " هذه النسخة من ملحق حرية النفاذ الى المعلومة ترد في صيغة لغة توصيف النصوص المترابطة HTML"
msgid "This is because {{title}} is an old request that has been\\nmarked to no longer receive responses."
-msgstr ""
+msgstr "حدث هذا لأن {{title}} طلب قديم قد تم \\nبرمجته بحيث لا يستقبل مزيدا من الردود."
msgid "This is the first version."
msgstr ""
msgid "This is your own request, so you will be automatically emailed when new responses arrive."
-msgstr ""
+msgstr "هذا طلبك الشخصي, ستبعث لك رسالة الكترونية بصفة الية عندما يصل الرد الجديد."
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=\"{{url}}\">sign in</a> to view the response."
msgstr ""
msgid "This particular request is finished:"
-msgstr ""
+msgstr "تم انهاء هذا الطلب المحدد:"
msgid "This person has made no Freedom of Information requests using this site."
-msgstr ""
+msgstr "هذا الشخص لم يقدم اي طلب لحرية النفاذ ابى المعلومة باستخدام هذا الموقع"
msgid "This person's annotations"
-msgstr ""
+msgstr "ملاحظات هذا الشخص"
msgid "This person's {{count}} Freedom of Information request"
msgid_plural "This person's {{count}} Freedom of Information requests"
@@ -2374,271 +2375,271 @@ msgstr[4] ""
msgstr[5] ""
msgid "This request <strong>requires administrator attention</strong>"
-msgstr ""
+msgstr "هذا الطلب <strong> يتطلب اهتمام المسؤول </strong>"
msgid "This request has already been reported for administrator attention"
-msgstr ""
+msgstr "لقد تم تبليغ الادارة بهذا الطلب"
msgid "This request has an <strong>unknown status</strong>."
-msgstr ""
+msgstr "هذا الطلب لديه <strong>حالة مجهولة</strong>."
msgid "This request has been <strong>hidden</strong> from the site, because an administrator considers it not to be an FOI request"
-msgstr ""
+msgstr "تم اخفاء <strong>هذا الطلب</strong> من الموقع, لان مسؤولا لم يعتبره طلبا لحرية النفاذ الى المعلومة"
msgid "This request has been <strong>hidden</strong> from the site, because an administrator considers it vexatious"
-msgstr ""
+msgstr "هذا الطلب وقع <strong>حذفه</strong> من الموقع, لان مسؤولا وجده مخلا"
msgid "This request has been <strong>reported</strong> as needing administrator attention (perhaps because it is vexatious, or a request for personal information)"
-msgstr ""
+msgstr "قد تم <strong>التبليغ عن هذا الطلب على اساس انه يحتاج اهتماما من الادارة (ربما لاعتباره مخلا, او طلبا لمعلومات شخصية)"
msgid "This request has been <strong>withdrawn</strong> by the person who made it.\\n There may be an explanation in the correspondence below."
-msgstr ""
+msgstr "هذا الطلب <strong>وقع سحبه</strong>من قبل الشخص الذي قام به .\\n قد يوجد تفسير في المراسلات اسفله ."
msgid "This request has been marked for review by the site administrators, who have not hidden it at this time. If you believe it should be hidden, please <a href=\"{{url}}\">contact us</a>."
msgstr ""
msgid "This request has been reported for administrator attention"
-msgstr ""
+msgstr "تم التبليغ عن هذا الطلب لتهتم به الادارة"
msgid "This request has been set by an administrator to \"allow new responses from nobody\""
-msgstr ""
+msgstr "تمت برمجة هذا الطلب من قبل مشرف ل \"لعدم السماح باي ردود جديدة\""
msgid "This request has had an unusual response, and <strong>requires attention</strong> from the {{site_name}} team."
-msgstr ""
+msgstr "الرد على هذا الطلب غير مألوف, و <strong>يستوجب اهتماما</strong> من {{site_name}} الفريق."
msgid "This request has prominence 'hidden'. You can only see it because you are logged\\n in as a super user."
-msgstr ""
+msgstr "تم اخفاء اهمية هذا الطلب. تستطيع رؤيته فقط لانك سجلت دخولك\\n iكمستخدم متميز."
msgid "This request is hidden, so that only you the requester can see it. Please\\n <a href=\"{{url}}\">contact us</a> if you are not sure why."
msgstr ""
msgid "This request is still in progress:"
-msgstr ""
+msgstr "لا يزال الطلب قيد الانجاز"
msgid "This request requires administrator attention"
msgstr ""
msgid "This request was not made via {{site_name}}"
-msgstr ""
+msgstr "لم يقدم هذا الطلب عبر {{site_name}}"
msgid "This response has been hidden. See annotations to find out why.\\n If you are the requester, then you may <a href=\"{{url}}\">sign in</a> to view the response."
msgstr ""
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."
-msgstr ""
+msgstr "هذا الجدول يظهر التفاصيل التقنية للاحداث الداخلية التي وقعت لهذا الطلب على\\ {{site_name}}. يمكن استخدام هذا لتعميم المعلومة حول\\nسرعة رد السلطات على الطلبات , عدد الطلبات\\nالتي تسوجب ردا بريديا و اكثر ."
msgid "This user has been banned from {{site_name}} "
-msgstr ""
+msgstr "تم منع هذا المستخدم من {{site_name}} "
msgid "This was not possible because there is already an account using \\nthe email address {{email}}."
-msgstr ""
+msgstr "هذا الطلب غير ممكن اذ يوجد حساب اخر يستعمل \\nنفس البريد الالكتروني {{email}}."
msgid "To cancel these alerts"
-msgstr ""
+msgstr "لالغاء اشارات التنبيه"
msgid "To cancel this alert"
-msgstr ""
+msgstr "لالغاء اشارة التنبيه"
msgid "To carry on, you need to sign in or make an account. Unfortunately, there\\nwas a technical problem trying to do this."
-msgstr ""
+msgstr "للمواصلة, تحتاج تسجيل الدخول او انشاء حساب جديد. للاسف, واجهنا\\nخطأ تقنيا اثناء القيام بهذا."
msgid "To change your email address used on {{site_name}}"
-msgstr ""
+msgstr "لتغيير عنوان بريد الالكتروني المستخدم على {{site_name}}"
msgid "To classify the response to this FOI request"
-msgstr ""
+msgstr "لتصنيف الرد على هذا الطلب لحرية النفاذ للمعلومة"
msgid "To do that please send a private email to "
-msgstr ""
+msgstr "للقيام بذلك يرجى ارسال رسالة الكترونية ل"
msgid "To do this, first click on the link below."
-msgstr ""
+msgstr "للقيام بذلك, اضغط اولا على الرابط اسفله."
msgid "To download the zip file"
-msgstr ""
+msgstr "لتنزيل الملف المضغوط"
msgid "To follow all successful requests"
-msgstr ""
+msgstr "لمتابعة كل الطلبات الناجحة"
msgid "To follow new requests"
-msgstr ""
+msgstr "لمتابعة الطلبات الجديدة"
msgid "To follow requests and responses matching your search"
-msgstr ""
+msgstr "لمتابعة الطلبات و الاجوبة المتعلقة ببحثك"
msgid "To follow requests by '{{user_name}}'"
-msgstr ""
+msgstr "لمتابعة طلبات '{{user_name}}'"
msgid "To follow requests made using {{site_name}} to the public authority '{{public_body_name}}'"
-msgstr ""
+msgstr "لمتابعة الطلبات المقدمة باستعمال {{site_name}} للسلطة العمومية '{{public_body_name}}'"
msgid "To follow the request '{{request_title}}'"
-msgstr ""
+msgstr "لمتابعة الطلب '{{request_title}}'"
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 ""
msgid "To let everyone know, follow this link and then select the appropriate box."
-msgstr ""
+msgstr "لاعلام الجميع, اتبع الرابط ثم قم باختيار الخانة الملائمة."
msgid "To log into the administrative interface"
-msgstr ""
+msgstr " لتسجيل الدخول في المجال الاداري"
msgid "To play the request categorisation game"
-msgstr ""
+msgstr "للعب لعبة تصنيف الطلب"
msgid "To post your annotation"
-msgstr ""
+msgstr "لنشر ملاحظتك"
msgid "To reply to "
-msgstr ""
+msgstr "اجب على "
msgid "To report this FOI request"
-msgstr ""
+msgstr "لتبليغ طلب حرية النفاذ الى المعلومة "
msgid "To send a follow up message to "
-msgstr ""
+msgstr "لبعث رسالة متابعة الى"
msgid "To send a message to "
-msgstr ""
+msgstr "لبعث رسالة الى"
msgid "To send your FOI request"
-msgstr ""
+msgstr "لبعث طلبك لحرية النفاذ للمعلومة"
msgid "To update the status of this FOI request"
-msgstr ""
+msgstr "لتحيين حالة طلب حرية النفاذ للمعلومة هذا"
msgid "To upload a response, you must be logged in using an email address from "
-msgstr ""
+msgstr " لتحميل رد, عليك تسجيل دخولك باستخدام عنوان بريد الكتروني من "
msgid "To use the advanced search, combine phrases and labels as described in the search tips below."
-msgstr ""
+msgstr "لاستخدام البحث المتقدم , ادمج عبارات و رقعة تعريف كم تم وصف ذلك في نصائح الحث اسفله."
msgid "To view the email address that we use to send FOI requests to {{public_body_name}}, please enter these words."
-msgstr ""
+msgstr "لرؤية البريد الالكتروني الذي نستعمله لنرسل طلبات حرية النفاذ للمعلومة {{public_body_name}}, الرجاء ادخال الكلمات التالية ."
msgid "To view the response, click on the link below."
-msgstr ""
+msgstr "لرؤية الاجابة, انقر على الرابط اسفله."
msgid "To {{public_body_link_absolute}}"
-msgstr ""
+msgstr "ل {{public_body_link_absolute}}"
msgid "To:"
-msgstr ""
+msgstr "الى:"
msgid "Today"
-msgstr ""
+msgstr "اليوم"
msgid "Too many requests"
-msgstr ""
+msgstr "طلبات كثيرة جدا"
msgid "Top search results:"
-msgstr ""
+msgstr "افضل نتائج بحث:"
msgid "Track thing"
-msgstr ""
+msgstr "تتبع"
msgid "Track this person"
-msgstr ""
+msgstr "تتبع هذا الشخص"
msgid "Track this search"
-msgstr ""
+msgstr "تتبع هذا البحث"
msgid "TrackThing|Track medium"
-msgstr ""
+msgstr "تتبع|تتبع الوسيط"
msgid "TrackThing|Track query"
-msgstr ""
+msgstr "تتبع|تتبع السؤال"
msgid "TrackThing|Track type"
-msgstr ""
+msgstr "تتبع شيئا|نوع المتابعة"
msgid "Turn off email alerts"
-msgstr ""
+msgstr " اطفئ اشارات تنبيه البريد الالكتروني"
msgid "Tweet this request"
-msgstr ""
+msgstr "ضع هذا الطلب على التويتر"
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 ""
+msgstr "ادخل <strong><code>01/01/2008..14/01/2008</code></strong> لاظهار ما حدث في اول اسبوعين من جانفي فقط."
msgid "URL name can't be blank"
-msgstr ""
+msgstr "لا يمكن ترك مكان عنوان الموقع فارغا"
msgid "Unable to change email address on {{site_name}}"
-msgstr ""
+msgstr "غير قادر على تغيير عنوان البريد الالكتروني على {{site_name}}"
msgid "Unable to send a reply to {{username}}"
-msgstr ""
+msgstr "غير قادر على ارسال رد ل {{username}}"
msgid "Unable to send follow up message to {{username}}"
-msgstr ""
+msgstr "غير قادر على بعث رسالة متابعة ل {{username}}"
msgid "Unexpected search result type"
-msgstr ""
+msgstr "نوع نتيجة البحث غير متوقع"
msgid "Unexpected search result type "
-msgstr ""
+msgstr "نوع نتيجة البحث غير متوقع "
msgid "Unfortunately we don't know the FOI\\nemail address for that authority, so we can't validate this.\\nPlease <a href=\"{{url}}\">contact us</a> to sort it out."
msgstr ""
msgid "Unfortunately, we do not have a working {{info_request_law_used_full}}\\naddress for"
-msgstr ""
+msgstr "للأسف, لا نملك{{info_request_law_used_full}}\\nعنوانا صالحا ل"
msgid "Unknown"
-msgstr ""
+msgstr "مجهول"
msgid "Unsubscribe"
-msgstr ""
+msgstr "إلغاء الاشتراك"
msgid "Unusual response."
-msgstr ""
+msgstr "اجابة غير مألوفة"
msgid "Update the status of this request"
-msgstr ""
+msgstr "حين حالة هذا الطلب"
msgid "Update the status of your request to "
-msgstr ""
+msgstr "حين حالة طلبك ل"
msgid "Upload FOI response"
-msgstr ""
+msgstr "حمل طلب حرية النفاذ للمعلومة"
msgid "Use OR (in capital letters) where you don't mind which word, e.g. <strong><code>commons OR lords</code></strong>"
msgstr ""
msgid "Use quotes when you want to find an exact phrase, e.g. <strong><code>\"Liverpool City Council\"</code></strong>"
-msgstr ""
+msgstr "استخدم اقتباسات عندما تريد ايجاد جملة بعينها, مثال. <strong><code>\"مجلس مدينة ليفربول\"</code></strong>"
msgid "User"
-msgstr ""
+msgstr "المستخدم"
msgid "User info request sent alert"
-msgstr ""
+msgstr "مستخدم طلب المعلومة بعث تنبيها"
msgid "User – {{name}}"
msgstr ""
msgid "UserInfoRequestSentAlert|Alert type"
-msgstr ""
+msgstr "التنبيه المرسل للمستخدم صاحب الطلب|نوع التنبيه"
msgid "User|About me"
-msgstr ""
+msgstr "مستخدم|معلومات عني"
msgid "User|Address"
-msgstr ""
+msgstr "المستخدم|العنوان"
msgid "User|Admin level"
-msgstr ""
+msgstr "مستخدم|مستوى المشرف"
msgid "User|Ban text"
-msgstr ""
+msgstr "مستخدم|منع النص"
msgid "User|Dob"
msgstr ""
msgid "User|Email"
-msgstr ""
+msgstr "المستخدم|البريد الالكتروني"
msgid "User|Email bounce message"
msgstr ""
@@ -2647,346 +2648,361 @@ msgid "User|Email bounced at"
msgstr ""
msgid "User|Email confirmed"
-msgstr ""
+msgstr "المستخدم|تم تأكيد البريد الالكتروني"
msgid "User|Hashed password"
msgstr ""
msgid "User|Last daily track email"
-msgstr ""
+msgstr "مستخدم|اخر بريد الكتروني للمتابعة اليومية"
msgid "User|Locale"
-msgstr ""
+msgstr "مستخدم|موقع"
msgid "User|Name"
-msgstr ""
+msgstr "المستخدم|الاسم"
msgid "User|No limit"
-msgstr ""
+msgstr "مستخدم|لاحدود"
msgid "User|Receive email alerts"
-msgstr ""
+msgstr "المستخدم|تلقي اشارات تنبيه للرسائل الالكترونية"
msgid "User|Salt"
msgstr ""
msgid "User|Url name"
-msgstr ""
+msgstr "المستخدم|Url name"
msgid "Version {{version}}"
msgstr ""
msgid "View FOI email address"
-msgstr ""
+msgstr "رؤية البريد الالكتروني لحرية النفاذ الى المعلومة"
msgid "View FOI email address for '{{public_body_name}}'"
-msgstr ""
+msgstr "رؤية البريد الالكتروني لحرية النفاذ الى المعلومة ل '{{public_body_name}}'"
msgid "View FOI email address for {{public_body_name}}"
-msgstr ""
+msgstr "رؤية البريد الالكتروني لحرية النفاذ الى المعلومة {{public_body_name}}"
msgid "View Freedom of Information requests made by {{user_name}}:"
-msgstr ""
+msgstr "الاطلاع على طلبات حرية النفاذ الى المعلومة المقدمة من قبل {{user_name}}:"
msgid "View and search requests"
-msgstr ""
+msgstr "عرض والبحث عن الطلبات"
msgid "View authorities"
-msgstr ""
+msgstr "عرض السلطات"
msgid "View email"
-msgstr ""
+msgstr "عرض البريد الالكتروني"
msgid "View requests"
-msgstr ""
+msgstr "عرض الطلبات"
msgid "Waiting clarification."
-msgstr ""
+msgstr "انتظار التوضيحات"
msgid "Waiting for an <strong>internal review</strong> by {{public_body_link}} of their handling of this request."
-msgstr ""
+msgstr "بانتظار <strong>مراجعة داخلية</strong> من طرف {{public_body_link}} عن كيفية التعامل مع هذا الطلب."
msgid "Waiting for the public authority to complete an internal review of their handling of the request"
-msgstr ""
+msgstr "بانتظار ان تكمل السلطة العامة مراجعة داخلية عن كيفية التعامل مع هذا الطلب."
msgid "Waiting for the public authority to reply"
-msgstr ""
+msgstr "انتظار رد السلطة العامة"
msgid "Was the response you got to your FOI request any good?"
+msgstr "هل كان الرد الذي تحصلت عليه بخصوص طلب حرية النفاذ للمعلومة جيدا؟"
+
+msgid "We consider it is not a valid FOI request, and have therefore hidden it from other users."
msgstr ""
-msgid "We do not have a working request email address for this authority."
+msgid "We consider it to be vexatious, and have therefore hidden it from other users."
msgstr ""
+msgid "We do not have a working request email address for this authority."
+msgstr "لا نملك طلب عنوان بريد الكتروني صالح لهذه السلطة"
+
msgid "We do not have a working {{law_used_full}} address for {{public_body_name}}."
-msgstr ""
+msgstr "لا نملك {{law_used_full}} عنوان بريد الكتروني صالح ل{{public_body_name}}."
msgid "We don't know whether the most recent response to this request contains\\n information or not\\n &ndash;\\n\tif you are {{user_link}} please <a href=\"{{url}}\">sign in</a> and let everyone know."
-msgstr ""
+msgstr "لا نعرف ان كان أحدث رد على هذا الطلب يحتوي\\n على المعلومات أم لا\\n &ndash;\\n\tان كنت {{user_link}} الرجاء <a href=\"{{url}}\">تسجيل الدخول</a>واعلام الجميع ."
msgid "We will not reveal your email address to anybody unless you or\\n the law tell us to (<a href=\"{{url}}\">details</a>). "
msgstr ""
msgid "We will not reveal your email address to anybody unless you\\nor the law tell us to."
-msgstr ""
+msgstr " لن نكشف عنوان بريدك الالكتروني لاحد الا اذا قررت انت\\nاو القانون عكس ذلك ."
msgid "We will not reveal your email addresses to anybody unless you\\nor the law tell us to."
-msgstr ""
+msgstr " لن نكشف عناوين بريدك الالكتروني لاحد الا اذا قررت انت\\nاو القانون عكس ذلك ."
msgid "We're waiting for"
-msgstr ""
+msgstr "نحن بانتظار"
msgid "We're waiting for someone to read"
-msgstr ""
+msgstr "نحن بانتظار احد ليقرأ"
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."
-msgstr ""
+msgstr "قمنا بارسال رسالة الكتروني على عنوان بريدك الاكتروني الجديد. اضغط على الرابط الموجود\\nبالرسالة قبل ان يتغير عنوان بريدك الالكتروني."
msgid "We've sent you an email, and you'll need to click the link in it before you can\\ncontinue."
-msgstr ""
+msgstr "بعثنا لك رسالة الكترونية, اضغط على الرابط الموجود بها حتى تستطيع \\nالمواصلة."
msgid "We've sent you an email, click the link in it, then you can change your password."
-msgstr ""
+msgstr "ارسلنا لك رسالة الكترونية, اضغط على الرابط الموجود بها, ثم بامكانك تغيير كلمة السر."
msgid "What are you doing?"
-msgstr ""
+msgstr "ما ذا تفعل؟"
msgid "What best describes the status of this request now?"
-msgstr ""
+msgstr "ما هو افضل وصف لحالة الطلب الان؟"
msgid "What information has been released?"
-msgstr ""
+msgstr "ما هي المعلومات التي تم اصادرها؟"
msgid "What information has been requested?"
-msgstr ""
+msgstr "ما هي المعلومات التي تم طلبها ؟"
msgid "When you get there, please update the status to say if the response \\ncontains any useful information."
-msgstr ""
+msgstr "عندما تصل هناك, الرجاء تحيين الحالة لاخبارنا ان كان الرد يحتوي\\n على معلومات مفيدة."
msgid "When you receive the paper response, please help\\n others find out what it says:"
-msgstr ""
+msgstr "عندما تستقبل ورقة الرد, الرجاء مساعدة الاخرين\\n معرفة محتواها:"
msgid "When you're done, <strong>come back here</strong>, <a href=\"{{url}}\">reload this page</a> and file your new request."
msgstr ""
msgid "Which of these is happening?"
-msgstr ""
+msgstr "أي من هذه يحدث الان؟"
msgid "Who can I request information from?"
-msgstr ""
+msgstr "ممن يمكنني طلب المعلومة؟"
msgid "Withdrawn by the requester."
-msgstr ""
+msgstr "وقع سحبها من قبل صاحب الطلب"
msgid "Wk"
-msgstr ""
+msgstr "Wk"
msgid "Would you like to see a website like this in your country?"
-msgstr ""
+msgstr "هل ترغب في ايجاد موقع كهذا في بلدك؟"
msgid "Write a reply"
-msgstr ""
+msgstr "اكتب ردا"
msgid "Write a reply to "
-msgstr ""
+msgstr "اكتب اجابة ل "
msgid "Write your FOI follow up message to "
-msgstr ""
+msgstr "اكتب رسالة المتابعة على حرية النفاذ للمعلومة الى"
msgid "Write your request in <strong>simple, precise language</strong>."
-msgstr ""
+msgstr "اكتب طلبك <strong>بلغة بسيطة ودقيقة</strong>."
msgid "You"
-msgstr ""
+msgstr "انت"
msgid "You are already following new requests"
-msgstr ""
+msgstr "سبق لك أن بدأت متابعة طلبات جديدة"
msgid "You are already following requests to {{public_body_name}}"
-msgstr ""
+msgstr "سبق لك أن بدأت متابعة الطلبات ل {{public_body_name}}"
msgid "You are already following things matching this search"
-msgstr ""
+msgstr "سبق لك أن بدأت متابعة طلبات تتطابق مع هذا البحث"
msgid "You are already following this person"
-msgstr ""
+msgstr "سبق لك أن بدأت متابعة هذا الشخص"
msgid "You are already following this request"
-msgstr ""
+msgstr "سبق لك أن بدأت متابعة هذا الطلب"
msgid "You are already following updates about {{track_description}}"
-msgstr ""
+msgstr "سبق لك أن بدأت متابعةالتحيينات بخصوص {{track_description}}"
msgid "You are currently receiving notification of new activity on your wall by email."
-msgstr ""
+msgstr "انت بصدد استقبال اشعار بخصوص نشاط جديد على حائطك عن طريق البريد الالكتروني"
msgid "You are following all new successful responses"
-msgstr ""
+msgstr "انت بصدد متابعة كل الردود الجديدة الناجحة."
msgid "You are no longer following {{track_description}}."
-msgstr ""
+msgstr "لم تعد متابعا ل {{track_description}}."
msgid "You are now <a href=\"{{wall_url_user}}\">following</a> updates about {{track_description}}"
-msgstr ""
+msgstr "أنت الان <a href=\"{{wall_url_user}}\">بصدد متابعة</a> التحيينات بخصوص {{track_description}}"
msgid "You can <strong>complain</strong> by"
-msgstr ""
+msgstr "تستطيع <strong>تقديم شكوى</strong> من خلال"
msgid "You can change the requests and users you are following on <a href=\"{{profile_url}}\">your profile page</a>."
-msgstr ""
+msgstr "بامكانك تغيير ماتتابعه من طلبات ومستخدمين على <a href=\"{{profile_url}}\">صفحتك الرئيسية</a>."
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>."
msgstr ""
msgid "You can only request information about the environment from this authority."
-msgstr ""
+msgstr "لا تستطيع طلب معلومات عن البيئة الا من خلال هذه السلطة."
msgid "You have a new response to the {{law_used_full}} request "
-msgstr ""
+msgstr "لديك اجابة جديدة على {{law_used_full}} طلب "
msgid "You have found a bug. Please <a href=\"{{contact_url}}\">contact us</a> to tell us about the problem"
-msgstr ""
+msgstr "لقد وجدت خللا. الرجاء <a href=\"{{contact_url}}\">الاتصال بنا</a> لاعلامنا بالمشكل"
msgid "You have hit the rate limit on new requests. Users are ordinarily limited to {{max_requests_per_user_per_day}} requests in any rolling 24-hour period. You will be able to make another request in {{can_make_another_request}}."
-msgstr ""
+msgstr "لقد بلغت السقف الأقصى للطلبات الجديدة. المستخدمون محددون عادة ب {{max_requests_per_user_per_day}} طلب في كل 24 ساعة. ستتمكن من القيام بطلب جديد خلال{{can_make_another_request}}."
msgid "You have made no Freedom of Information requests using this site."
-msgstr ""
+msgstr "لم تقم بأي طلب يخص حرية النفاذ للمعلومة من خلال هذا الموقع"
msgid "You have now changed the text about you on your profile."
-msgstr ""
+msgstr "لقد قمت الان بتغيير النص الخاص بك على حسابك."
msgid "You have now changed your email address used on {{site_name}}"
-msgstr ""
+msgstr "لقد قمت الان بتغيير بريدك الالكتروني المستخدم على address {{site_name}}"
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."
-msgstr ""
+msgstr "لقد حاولت للتو تسجيل دخولك ل {{site_name}}, في حين انك\\nتملك حسابا. لقد تم الحفاظ على\\nالاسم و كلمة السر الخاصتين بك كما كانا.\\n\\nيرجى الضغط على الرابط اسفله."
msgid "You know what caused the error, and can <strong>suggest a solution</strong>, such as a working email address."
-msgstr ""
+msgstr "انت تعرف سبب الخطأ, وتستطيع <strong>اقتراح حل</strong>, مثل مد بريد الكتروني صحيح."
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 ""
+msgstr "بامكانك <strong>تضمين ملحقات</strong>. اذا كنت ترغب في الحاق \\n ملف كبير ليبعث على البريد الاكتروني, استعمل الصيغة اسفله."
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=\"{{url}}\">send it to us</a>."
msgstr ""
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>."
-msgstr ""
+msgstr "قد تتمكن من ايجاد واحد\\nعلى موقعهم, او عبر مهاتفتهم و الاستفسار عن ذلك. اذا تمكنت \\nمن ايجاد واحد, اذا يرجى <a href=\"{{help_url}}\">ارساله الينا</a>."
msgid "You need to be logged in to change the text about you on your profile."
-msgstr ""
+msgstr "يجب أن تسجل دخولك لتتمكن من تغيير النص المتعلق بك على حسابك. "
msgid "You need to be logged in to change your profile photo."
-msgstr ""
+msgstr "يجب أن تسجل دخولك لتتمكن من تغيير صورة حسابك."
msgid "You need to be logged in to clear your profile photo."
-msgstr ""
+msgstr "يجب أن تسجل دخولك لتتمكن من حذف صورة حسابك."
msgid "You need to be logged in to edit your profile."
-msgstr ""
+msgstr "يجب أن تسجل دخولك لتتمكن من القيام بتغييرات في حسابك."
msgid "You previously submitted that exact follow up message for this request."
-msgstr ""
+msgstr "لقد سبق لك أن قدمت نفس رسالة المتابعة لهذا الطلب."
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 ""
+msgstr "كان يجب ان تحصل على نسخة من الطلب عبر البريد الاكتروني, و بامكانك الرد\\n ب <strong>مجرد الاجابة</strong> على تلك الرسالة الالكترونية. لراحتك, هذا هو العنوان:"
msgid "You want to <strong>give your postal address</strong> to the authority in private."
-msgstr ""
+msgstr "سترغب في <strong>مد عنوانك البريدي</strong> الى السلطة بشكل سري."
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."
-msgstr ""
+msgstr "لن تتمكن من القيام باية طلبات جديدة, ابعث متابعات, اضف ملاحظات او\\nابعث رسائل لمستخدمين اخرين. قد تستمر في رؤية طلبات اخرى , و set\\n وضع\\nاشارات تنبيه خاصة بالبريد الالكتروني."
msgid "You will no longer be emailed updates for those alerts"
-msgstr ""
+msgstr "لن تستقبل رسائل الكترونية متعلقة بتحيين اشارات التنبيه"
msgid "You will now be emailed updates about {{track_description}}. <a href=\"{{change_email_alerts_url}}\">Prefer not to receive emails?</a>"
-msgstr ""
+msgstr "ستبدأ في استقبال رسائل الكترونية عن التحيينات بخصوص {{track_description}}. <a href=\"{{change_email_alerts_url}}\">اختر ان لا تصلك هذه الرسائل?</a>"
msgid "You will only get an answer to your request if you follow up\\nwith the clarification."
+msgstr "لن تصلك اجابة عن طلبك الا اذا تابعت \\nمع التوضيح"
+
+msgid "You will still be able to view it while logged in to the site. Please reply to this email if you would like to discuss this decision further."
msgstr ""
msgid "You're in. <a href=\"#\" id=\"send-request\">Continue sending your request</a>"
-msgstr ""
+msgstr "انت في. <a href=\"#\" id=\"ارسل-طلب\">واصل ارسال طلبك</a>"
msgid "You're long overdue a response to your FOI request - "
-msgstr ""
+msgstr "طال انتظارك للاجابة على طلبك بخصوص حرة النفاذ للمعلومة"
msgid "You're not following anything."
-msgstr ""
+msgstr "لست متابعا لأي شيء"
msgid "You've now cleared your profile photo"
-msgstr ""
+msgstr "قمت بحذف صورة حسابك"
msgid "Your <strong>name will appear publicly</strong>\\n (<a href=\"{{why_url}}\">why?</a>)\\n on this website and in search engines. If you\\n are thinking of using a pseudonym, please\\n <a href=\"{{help_url}}\">read this first</a>."
msgstr ""
msgid "Your annotations"
-msgstr ""
+msgstr "ملاحظاتك"
msgid "Your details, including your email address, have not been given to anyone."
-msgstr ""
+msgstr "لم يقع اعطاء المعلومات الخاصة بك , بما فيها, بريدك الالكتروني لأحد"
msgid "Your e-mail:"
-msgstr ""
+msgstr "بريدك الالكتروني"
msgid "Your follow up has not been sent because this request has been stopped to prevent spam. Please <a href=\"{{url}}\">contact us</a> if you really want to send a follow up message."
msgstr ""
msgid "Your follow up message has been sent on its way."
-msgstr ""
+msgstr "تم بعث رسالتك للمتابعة"
msgid "Your internal review request has been sent on its way."
-msgstr ""
+msgstr "تم ارسال طلبك للمراجعة الداخلية"
msgid "Your message has been sent. Thank you for getting in touch! We'll get back to you soon."
-msgstr ""
+msgstr "تم بعث رسالتك. شكرا للتواصل معنا .سيصلك الرد قريبا"
msgid "Your message to {{recipient_user_name}} has been sent"
-msgstr ""
+msgstr "نم بعث رسالتك لr_name}} has been sent"
msgid "Your message to {{recipient_user_name}} has been sent!"
-msgstr ""
+msgstr "رسالتك الى {{recipient_user_name}} قد تم بعثها"
msgid "Your message will appear in <strong>search engines</strong>"
-msgstr ""
+msgstr "ستظهر رسالتك على <strongمحركات البحث</strong>"
msgid "Your name and annotation will appear in <strong>search engines</strong>."
-msgstr ""
+msgstr "اسمك و ملاحظتك ستظهر على <strong>محركات البحث</strong>."
msgid "Your name, request and any responses will appear in <strong>search engines</strong>\\n (<a href=\"{{url}}\">details</a>)."
msgstr ""
msgid "Your name:"
-msgstr ""
+msgstr "اسمك:"
msgid "Your original message is attached."
-msgstr ""
+msgstr "تم ربط رسالتك الاصلية"
msgid "Your password has been changed."
-msgstr ""
+msgstr "تم تغيير كلمة السر"
msgid "Your password:"
-msgstr ""
+msgstr "كلمة السر:"
msgid "Your photo will be shown in public <strong>on the Internet</strong>,\\n wherever you do something on {{site_name}}."
+msgstr "ستظهر صورتك للعموم <strong>على الانترنات</strong>,\\n كلما تفاعلت على {{site_name}}."
+
+msgid "Your request '{{request}}' at {{url}} has been reviewed by moderators."
msgstr ""
-msgid "Your request was called {{info_request}}. Letting everyone know whether you got the information will help us keep tabs on"
+msgid "Your request on {{site_name}} hidden"
msgstr ""
+msgid "Your request was called {{info_request}}. Letting everyone know whether you got the information will help us keep tabs on"
+msgstr "تمت تسمية طلبك {{info_request}}. اعلام الجميع عما اذا تحصلت على المعلومات سيساعدنا في التبويب"
+
msgid "Your request:"
-msgstr ""
+msgstr "طلبك :"
msgid "Your response to an FOI request was not delivered"
-msgstr ""
+msgstr "لم يقع ارسال ردك على طلب حرية النفاذ الى المعلومة بنجاح"
msgid "Your response will <strong>appear on the Internet</strong>, <a href=\"{{url}}\">read why</a> and answers to other questions."
msgstr ""
msgid "Your thoughts on what the {{site_name}} <strong>administrators</strong> should do about the request."
-msgstr ""
+msgstr "رأيك بخصوص انسب طريقة {{site_name}} <strong>للمشرفين</strong> للاجابة على الطلب ."
msgid "Your {{count}} Freedom of Information request"
msgid_plural "Your {{count}} Freedom of Information requests"
@@ -3007,226 +3023,229 @@ msgstr[4] ""
msgstr[5] ""
msgid "Your {{site_name}} email alert"
-msgstr ""
+msgstr "اشارة تنبيه {{site_name}} بريدك الالكتروني"
msgid "Yours faithfully,"
-msgstr ""
+msgstr "تحياتي"
msgid "Yours sincerely,"
+msgstr "تحياتي"
+
+msgid "Yours,"
msgstr ""
msgid "[FOI #{{request}} email]"
-msgstr ""
+msgstr "[حرية النفاذ للمعلومة #{{request}}البريد الالكتروني]"
msgid "[{{public_body}} request email]"
-msgstr ""
+msgstr "[{{public_body}} طلب البريد الالكتروني]"
msgid "[{{site_name}} contact email]"
-msgstr ""
+msgstr "[{{site_name}} اتصل بالبريد الالكتروني"
msgid "\\n\\n[ {{site_name}} note: The above text was badly encoded, and has had strange characters removed. ]"
msgstr ""
msgid "a one line summary of the information you are requesting, \\n\t\t\te.g."
-msgstr ""
+msgstr "ملخص بسطر واحد يخصوص المعلومة التي تطلبها , \\n\t\t\te.g."
msgid "admin"
-msgstr ""
+msgstr "مشرف"
msgid "alaveteli_foi:The software that runs {{site_name}}"
msgstr ""
msgid "all requests"
-msgstr ""
+msgstr "كل الطلبات"
msgid "also called {{public_body_short_name}}"
-msgstr ""
+msgstr "يدعى كذلك {{public_body_short_name}}"
msgid "an anonymous user"
-msgstr ""
+msgstr "مستخدم مجهول"
msgid "and"
-msgstr ""
+msgstr "و"
msgid "and update the status accordingly. Perhaps <strong>you</strong> might like to help out by doing that?"
-msgstr ""
+msgstr "و قم بتحيين الحالة اعتمادا على ذلك. قد <strong>ترغب</strong> في المساعذة عبر القيام بذلك?"
msgid "and update the status."
-msgstr ""
+msgstr "و قم بتحميل الحالة"
msgid "and we'll suggest <strong>what to do next</strong>"
-msgstr ""
+msgstr "و سنقترح <strong>الخطوة الموالية</strong>"
msgid "any <a href=\"/list\">new requests</a>"
-msgstr ""
+msgstr "اي <a href=\"/list\">طلبات جديدة</a>"
msgid "any <a href=\"/list/successful\">successful requests</a>"
-msgstr ""
+msgstr "اي <a href=\"/list/successful\">طلبات ناجحة</a>"
msgid "anything"
-msgstr ""
+msgstr "اي شيئ"
msgid "are long overdue."
-msgstr ""
+msgstr "تم تأخيريهم كثيرا"
msgid "at"
msgstr ""
msgid "authorities"
-msgstr ""
+msgstr "سلطات"
msgid "awaiting a response"
-msgstr ""
+msgstr "بانتظار اجابة"
msgid "beginning with ‘{{first_letter}}’"
-msgstr ""
+msgstr "تبدأ ب ‘{{first_letter}}’"
msgid "between two dates"
-msgstr ""
+msgstr "بين تاريخين"
msgid "but followupable"
msgstr ""
msgid "by"
-msgstr ""
+msgstr "من قبل"
msgid "by <strong>{{date}}</strong>"
-msgstr ""
+msgstr "في حدود <strong>{{date}}</strong>"
msgid "by {{public_body_name}} to {{info_request_user}} on {{date}}."
-msgstr ""
+msgstr "من قبل {{public_body_name}} الى {{info_request_user}} في {{date}}."
msgid "by {{user_link_absolute}}"
-msgstr ""
+msgstr "من {{user_link_absolute}}"
msgid "comments"
-msgstr ""
+msgstr "تعاليق"
msgid "containing your postal address, and asking them to reply to this request.\\n Or you could phone them."
-msgstr ""
+msgstr "تحتوي على عنوانك البريدي, تطلب منهم الرد على هذا الطلب .\\n او بامكانك مهاتفتهم."
msgid "details"
-msgstr ""
+msgstr "تفاصيل"
msgid "display_status only works for incoming and outgoing messages right now"
-msgstr ""
+msgstr "عرض_الحالة غير ممكن حاليا الا بالنسبة للرسائل الواردة و الصادرة"
msgid "during term time"
-msgstr ""
+msgstr "في الوقت المحدد"
msgid "edit text about you"
-msgstr ""
+msgstr "غير النص المتعلق بك"
msgid "even during holidays"
-msgstr ""
+msgstr "حتى خلال العطل"
msgid "everything"
-msgstr ""
+msgstr "كل شيئ"
msgid "external"
-msgstr ""
+msgstr "خارجي"
msgid "has reported an"
-msgstr ""
+msgstr "بلغ عن"
msgid "have delayed."
-msgstr ""
+msgstr "قمت بتأجيل"
msgid "hide quoted sections"
-msgstr ""
+msgstr "اخف الاجزاء المقتبسة"
msgid "in term time"
-msgstr ""
+msgstr "في الوقت المحدد"
msgid "in the category ‘{{category_name}}’"
-msgstr ""
+msgstr "في فئة ‘{{category_name}}’"
msgid "internal error"
-msgstr ""
+msgstr "خطأ داخلي"
msgid "internal reviews"
-msgstr ""
+msgstr "مراجعات داخلية"
msgid "is <strong>waiting for your clarification</strong>."
-msgstr ""
+msgstr "في <strong>انتظار توضيحك</strong>."
msgid "just to see how it works"
-msgstr ""
+msgstr "فقط لمشاهدة كيفية الاشتغال"
msgid "left an annotation"
-msgstr ""
+msgstr "ترك ملاحظة"
msgid "made."
-msgstr ""
+msgstr "قام ب"
msgid "matching the tag ‘{{tag_name}}’"
-msgstr ""
+msgstr "متوافق مع الفئة ‘{{tag_name}}’"
msgid "messages from authorities"
-msgstr ""
+msgstr "رسائل من السلطات"
msgid "messages from users"
-msgstr ""
+msgstr "رسائل من المستخدمين"
msgid "move..."
msgstr ""
msgid "no later than"
-msgstr ""
+msgstr "لن تتأخر اكثر من"
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=\"{{url}}\">send it to us</a>."
msgstr ""
msgid "normally"
-msgstr ""
+msgstr "من المفروض"
msgid "not requestable due to: {{reason}}"
msgstr ""
msgid "please sign in as "
-msgstr ""
+msgstr "الرجاء تسجيل الدخول ك "
msgid "requesting an internal review"
-msgstr ""
+msgstr "طلب مراجعة داخلية"
msgid "requests"
-msgstr ""
+msgstr "طلبات"
msgid "requests which are {{list_of_statuses}}"
-msgstr ""
+msgstr "الطلبات التي {{list_of_statuses}}"
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."
-msgstr ""
+msgstr "الرد بانه يحتاج اهتمام الادارة. الق نظرة, و اجب على البريد الالكتروني هذا\\ne لاعلامهم بما فعلت بهذا الخصوص ."
msgid "send a follow up message"
-msgstr ""
+msgstr "ابعث رسالة متابعة"
msgid "sent to {{public_body_name}} by {{info_request_user}} on {{date}}."
-msgstr ""
+msgstr "تم ارساله الى {{public_body_name}} من قبل {{info_request_user}} في {{date}}."
msgid "set to <strong>blank</strong> (empty string) if can't find an address; these emails are <strong>public</strong> as anyone can view with a CAPTCHA"
msgstr ""
msgid "show quoted sections"
-msgstr ""
+msgstr "اظهر الاجزاء المقتبسة"
msgid "sign in"
-msgstr ""
+msgstr "تسجيل الدخول"
msgid "simple_date_format"
-msgstr ""
+msgstr "صيغة التاريخ البسيطة"
msgid "successful"
-msgstr ""
+msgstr "ناجح"
msgid "successful requests"
-msgstr ""
+msgstr "طلبات ناجحة"
msgid "that you made to"
-msgstr ""
+msgstr "الذي قمت به ل"
msgid "the main FOI contact address for {{public_body}}"
-msgstr ""
+msgstr "عنوان الاتصال بحرية النفاذ للمعلومة {{public_body}}"
#. This phrase completes the following sentences:
#. Request an internal review from...
@@ -3234,58 +3253,58 @@ msgstr ""
#. Send a public reply to...
#. Don't want to address your message to... ?
msgid "the main FOI contact at {{public_body}}"
-msgstr ""
+msgstr "ابرز علاقة اتصال لحرية النفاذ للمعلومة على {{public_body}}"
msgid "the requester"
-msgstr ""
+msgstr "صاحب الطلب"
msgid "the {{site_name}} team"
-msgstr ""
+msgstr "فريق {{site_name}} العمل"
msgid "to read"
-msgstr ""
+msgstr "لقراءة"
msgid "to send a follow up message."
-msgstr ""
+msgstr "لبعث رسالة متابعة"
msgid "to {{public_body}}"
-msgstr ""
+msgstr "الى {{public_body}}"
msgid "unexpected prominence on request event"
-msgstr ""
+msgstr "أهمية غير متوقعة لطلب الحدث"
msgid "unknown reason "
-msgstr ""
+msgstr "سبب مجهول"
msgid "unknown status "
-msgstr ""
+msgstr "حالة مجهولة"
msgid "unresolved requests"
-msgstr ""
+msgstr "طلبات لم يتم حلها"
msgid "unsubscribe"
-msgstr ""
+msgstr "إلغاء الاشتراك"
msgid "unsubscribe all"
-msgstr ""
+msgstr "إلغاء كل الاشتراكات"
msgid "unsuccessful"
-msgstr ""
+msgstr "غير ناجح"
msgid "unsuccessful requests"
-msgstr ""
+msgstr "طلبات غير ناجحة"
msgid "useful information."
-msgstr ""
+msgstr "معلومات مفيدة"
msgid "users"
-msgstr ""
+msgstr "المستخدمون"
msgid "what's that?"
msgstr ""
msgid "{{count}} FOI requests found"
-msgstr ""
+msgstr "{{count}} تم ايجاد طلبات حرية النفاذ الى المعلومة"
msgid "{{count}} Freedom of Information request to {{public_body_name}}"
msgid_plural "{{count}} Freedom of Information requests to {{public_body_name}}"
@@ -3324,97 +3343,97 @@ msgstr[4] ""
msgstr[5] ""
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 ""
+msgstr "{{existing_request_user}} قد سبق له أن\\n قام بنفس الطلب بتاريخ {{date}}.يمكنك أن تشاهد <a href=\"{{existing_request}}\">الطلب الموجود</a>,\\n أو تحوير التفاصيل أسفله للقيام بطلب جديد وان كان مشابها."
msgid "{{info_request_user_name}} only:"
-msgstr ""
+msgstr "{{info_request_user_name}} فقط:"
msgid "{{law_used_full}} request - {{title}}"
-msgstr ""
+msgstr "{{law_used_full}} طلب - {{title}}"
msgid "{{law_used_full}} request GQ - {{title}}"
-msgstr ""
+msgstr "{{law_used_full}} طلب GQ - {{title}}"
msgid "{{law_used}} requests at {{public_body}}"
-msgstr ""
+msgstr "{{law_used}} طلبات في {{public_body}}"
msgid "{{length_of_time}} ago"
-msgstr ""
+msgstr "{{length_of_time}} منذ"
msgid "{{list_of_things}} matching text '{{search_query}}'"
-msgstr ""
+msgstr "{{list_of_things}} النص الموافق '{{search_query}}'"
msgid "{{number_of_comments}} comments"
-msgstr ""
+msgstr "{{number_of_comments}} تعليق"
msgid "{{public_body_link}} answered a request about"
-msgstr ""
+msgstr "{{public_body_link}} اجاب على طلب عن"
msgid "{{public_body_link}} was sent a request about"
-msgstr ""
+msgstr "{{public_body_link}} ارسل له طلب حول"
msgid "{{public_body_name}} only:"
-msgstr ""
+msgstr "{{public_body_name}}فقط:"
msgid "{{public_body}} has asked you to explain part of your {{law_used}} request."
-msgstr ""
+msgstr "{{public_body}} طلب منك شرح جزء من {{law_used}} طلبك."
msgid "{{public_body}} sent a response to {{user_name}}"
-msgstr ""
+msgstr "{{public_body}} ارسل اجابة الى {{user_name}}"
msgid "{{reason}}, please sign in or make a new account."
msgstr ""
msgid "{{search_results}} matching '{{query}}'"
-msgstr ""
+msgstr "{{search_results}} يتوافق مع '{{query}}'"
msgid "{{site_name}} blog and tweets"
-msgstr ""
+msgstr "{{site_name}} مدونة و تغريدات"
msgid "{{site_name}} covers requests to {{number_of_authorities}} authorities, including:"
-msgstr ""
+msgstr "{{site_name}} يغطي طلبات ل {{number_of_authorities}} سلطة, بما فيها:"
msgid "{{site_name}} sends new requests to <strong>{{request_email}}</strong> for this authority."
-msgstr ""
+msgstr "{{site_name}} ارسل طلبات جديدة ل <strong>{{request_email}}</strong> بخصوص هذه السلطة."
msgid "{{site_name}} users have made {{number_of_requests}} requests, including:"
-msgstr ""
+msgstr "{{site_name}} قام المستخدمون بتقديم {{number_of_requests}}طلب, بما فيها:"
msgid "{{thing_changed}} was changed from <code>{{from_value}}</code> to <code>{{to_value}}</code>"
msgstr ""
msgid "{{title}} - a Freedom of Information request to {{public_body}}"
-msgstr ""
+msgstr "{{title}} - طلب حرية النفاذ للمعلومة الى {{public_body}}"
msgid "{{user_name}} (Account suspended)"
-msgstr ""
+msgstr "{{user_name}} (حساب معلق)"
msgid "{{user_name}} - Freedom of Information requests"
-msgstr ""
+msgstr "{{user_name}} - طلبات حرية النفاذ للمعلومة"
msgid "{{user_name}} - user profile"
-msgstr ""
+msgstr "{{user_name}} -حساب المستخدم"
msgid "{{user_name}} added an annotation"
-msgstr ""
+msgstr "{{user_name}} اضاف ملاحظة"
msgid "{{user_name}} has annotated your {{law_used_short}} \\nrequest. Follow this link to see what they wrote."
-msgstr ""
+msgstr "{{user_name}} اضاف ملاحظة على {{law_used_short}} \\nطلبك. اتبع هذا الرابط للاطلاع."
msgid "{{user_name}} has used {{site_name}} to send you the message below."
-msgstr ""
+msgstr "{{user_name}}استخدم {{site_name}}ليرسل لك الرسالة أسفله"
msgid "{{user_name}} sent a follow up message to {{public_body}}"
-msgstr ""
+msgstr "{{user_name}} بعث رسالة متابعة الى {{public_body}}"
msgid "{{user_name}} sent a request to {{public_body}}"
-msgstr ""
+msgstr "{{user_name}} أرسل طلبا الى {{public_body}}"
msgid "{{username}} left an annotation:"
-msgstr ""
+msgstr "{{username}} ترك ملاحظة:"
msgid "{{user}} ({{user_admin_link}}) 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 ""
+msgstr "{{user}} ({{user_admin_link}})قدم هذا {{law_used_full}} الطلب (<a href=\"{{request_admin_url}}\">مشرف</a>) الى {{public_body_link}} (<a href=\"{{public_body_admin_url}}\">مشرف</a>)"
msgid "{{user}} made this {{law_used_full}} request"
-msgstr ""
+msgstr "{{user}}قام بهذا {{law_used_full}} الطلب"
diff --git a/locale/bs/app.po b/locale/bs/app.po
index 2e3d51f89..8e96147dc 100644
--- a/locale/bs/app.po
+++ b/locale/bs/app.po
@@ -10,10 +10,10 @@ msgid ""
msgstr ""
"Project-Id-Version: alaveteli\n"
"Report-Msgid-Bugs-To: http://github.com/sebbacon/alaveteli/issues\n"
-"POT-Creation-Date: 2013-04-23 16:34+0100\n"
-"PO-Revision-Date: 2013-04-23 15:41+0000\n"
+"POT-Creation-Date: 2013-05-30 09:46+0100\n"
+"PO-Revision-Date: 2013-05-30 08:54+0000\n"
"Last-Translator: louisecrow <louise@mysociety.org>\n"
-"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language-Team: Bosnian (http://www.transifex.com/projects/p/alaveteli/language/bs/)\n"
"Language: bs\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -325,6 +325,15 @@ msgstr "O Vama:"
msgid "Act on what you've learnt"
msgstr "Radite na osnovu onoga što ste naučili"
+msgid "Acts as xapian/acts as xapian job"
+msgstr ""
+
+msgid "ActsAsXapian::ActsAsXapianJob|Action"
+msgstr ""
+
+msgid "ActsAsXapian::ActsAsXapianJob|Model"
+msgstr ""
+
msgid "Add an annotation"
msgstr "Dodati napomenu"
@@ -634,6 +643,9 @@ msgstr "Trenutno <strong>čeka odgovor</strong> od {{public_body_link}}, moraju
msgid "Date:"
msgstr "Datum:"
+msgid "Dear {{name}},"
+msgstr ""
+
msgid "Dear {{public_body_name}},"
msgstr "Poštovani {{public_body_name}},"
@@ -909,6 +921,18 @@ msgstr "OVDJE IZNESITE DETALJE VAŠE ŽALBE"
msgid "Handled by post."
msgstr "Riješen poštom."
+msgid "Has tag string/has tag string tag"
+msgstr ""
+
+msgid "HasTagString::HasTagStringTag|Model"
+msgstr ""
+
+msgid "HasTagString::HasTagStringTag|Name"
+msgstr ""
+
+msgid "HasTagString::HasTagStringTag|Value"
+msgstr ""
+
msgid "Hello! You can make Freedom of Information requests within {{country_name}} at {{link_to_website}}"
msgstr "Dobrodošli! Možete podnositi Zahtjeve za slobodan pristup informacijama u {{country_name}} na ovom linku: {{link_to_website}}"
@@ -1770,9 +1794,6 @@ msgstr ""
msgid "Public body"
msgstr ""
-msgid "Public body/translation"
-msgstr ""
-
msgid "Public notes"
msgstr ""
@@ -1782,33 +1803,6 @@ msgstr ""
msgid "Public page not available"
msgstr ""
-msgid "PublicBody::Translation|Disclosure log"
-msgstr ""
-
-msgid "PublicBody::Translation|First letter"
-msgstr ""
-
-msgid "PublicBody::Translation|Locale"
-msgstr ""
-
-msgid "PublicBody::Translation|Name"
-msgstr ""
-
-msgid "PublicBody::Translation|Notes"
-msgstr ""
-
-msgid "PublicBody::Translation|Publication scheme"
-msgstr ""
-
-msgid "PublicBody::Translation|Request email"
-msgstr ""
-
-msgid "PublicBody::Translation|Short name"
-msgstr ""
-
-msgid "PublicBody::Translation|Url name"
-msgstr ""
-
msgid "PublicBody|Api key"
msgstr ""
@@ -2319,6 +2313,9 @@ msgstr "Indeks za pretragu je trenutno isključen, ne možemo prikazati Zahtjeve
msgid "The search index is currently offline, so we can't show the Freedom of Information requests this person has made."
msgstr "Indeks za pretragu je trenutno isključen, radi toga ne možemo prikazati Zahtjeve za slobodan pristup informacijama koje je ova osoba napravila."
+msgid "The {{site_name}} team."
+msgstr ""
+
msgid "Then you can cancel the alert."
msgstr "Tada možete poništiti upozorenje."
@@ -2849,6 +2846,12 @@ msgstr "Čekamo na odgovor javne ustanove"
msgid "Was the response you got to your FOI request any good?"
msgstr "Da li je odgovor koji ste dobili na Vaš Zahtjev o slobodnom pristupu informacijama bio od ikakve koristi?"
+msgid "We consider it is not a valid FOI request, and have therefore hidden it from other users."
+msgstr ""
+
+msgid "We consider it to be vexatious, and have therefore hidden it from other users."
+msgstr ""
+
msgid "We do not have a working request email address for this authority."
msgstr "Ne posjedujemo ispravnu e-mail adresu za zahtjeve ove ustanove."
@@ -3068,6 +3071,9 @@ msgstr ""
msgid "You will only get an answer to your request if you follow up\\nwith the clarification."
msgstr ""
+msgid "You will still be able to view it while logged in to the site. Please reply to this email if you would like to discuss this decision further."
+msgstr ""
+
msgid "You're in. <a href=\"#\" id=\"send-request\">Continue sending your request</a>"
msgstr ""
@@ -3136,6 +3142,12 @@ msgstr "Vaš password:"
msgid "Your photo will be shown in public <strong>on the Internet</strong>,\\n wherever you do something on {{site_name}}."
msgstr ""
+msgid "Your request '{{request}}' at {{url}} has been reviewed by moderators."
+msgstr ""
+
+msgid "Your request on {{site_name}} hidden"
+msgstr ""
+
msgid "Your request was called {{info_request}}. Letting everyone know whether you got the information will help us keep tabs on"
msgstr "Naziv Vašeg zahtjeva je {{info_request}}. Obavijest o tome da li ste dobili odgovor će nam pomoći da bolje pratimo."
@@ -3172,6 +3184,9 @@ msgstr "S poštovanjem,"
msgid "Yours sincerely,"
msgstr "S poštovanjem,"
+msgid "Yours,"
+msgstr ""
+
msgid "[FOI #{{request}} email]"
msgstr ""
diff --git a/locale/ca/app.po b/locale/ca/app.po
index bb8d1f2fc..1e80a5a59 100644
--- a/locale/ca/app.po
+++ b/locale/ca/app.po
@@ -10,10 +10,10 @@ msgid ""
msgstr ""
"Project-Id-Version: alaveteli\n"
"Report-Msgid-Bugs-To: http://github.com/sebbacon/alaveteli/issues\n"
-"POT-Creation-Date: 2013-04-23 16:34+0100\n"
-"PO-Revision-Date: 2013-04-23 15:40+0000\n"
+"POT-Creation-Date: 2013-05-30 09:46+0100\n"
+"PO-Revision-Date: 2013-05-30 08:54+0000\n"
"Last-Translator: louisecrow <louise@mysociety.org>\n"
-"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language-Team: Catalan (http://www.transifex.com/projects/p/alaveteli/language/ca/)\n"
"Language: ca\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -338,6 +338,15 @@ msgstr "Sobre mi:"
msgid "Act on what you've learnt"
msgstr "Utilitza aquesta informació"
+msgid "Acts as xapian/acts as xapian job"
+msgstr ""
+
+msgid "ActsAsXapian::ActsAsXapianJob|Action"
+msgstr ""
+
+msgid "ActsAsXapian::ActsAsXapianJob|Model"
+msgstr ""
+
msgid "Add an annotation"
msgstr "Afegeix un comentari"
@@ -649,6 +658,9 @@ msgstr "Actualmente <strong>esperando la respuesta</strong> de {{public_body_lin
msgid "Date:"
msgstr "Fecha:"
+msgid "Dear {{name}},"
+msgstr ""
+
msgid "Dear {{public_body_name}},"
msgstr "Estimado {{public_body_name}},"
@@ -926,6 +938,18 @@ msgstr "DETALLA TU QUEJA AQUÍ"
msgid "Handled by post."
msgstr "Resuelta por correo ordinario"
+msgid "Has tag string/has tag string tag"
+msgstr ""
+
+msgid "HasTagString::HasTagStringTag|Model"
+msgstr ""
+
+msgid "HasTagString::HasTagStringTag|Name"
+msgstr ""
+
+msgid "HasTagString::HasTagStringTag|Value"
+msgstr ""
+
msgid "Hello! You can make Freedom of Information requests within {{country_name}} at {{link_to_website}}"
msgstr "¡Hola! Puede hacer solicitudes de información en {{country_name}} usando {{link_to_website}}"
@@ -1790,9 +1814,6 @@ msgstr ""
msgid "Public body"
msgstr ""
-msgid "Public body/translation"
-msgstr ""
-
msgid "Public notes"
msgstr ""
@@ -1802,33 +1823,6 @@ msgstr ""
msgid "Public page not available"
msgstr ""
-msgid "PublicBody::Translation|Disclosure log"
-msgstr ""
-
-msgid "PublicBody::Translation|First letter"
-msgstr ""
-
-msgid "PublicBody::Translation|Locale"
-msgstr ""
-
-msgid "PublicBody::Translation|Name"
-msgstr ""
-
-msgid "PublicBody::Translation|Notes"
-msgstr ""
-
-msgid "PublicBody::Translation|Publication scheme"
-msgstr ""
-
-msgid "PublicBody::Translation|Request email"
-msgstr ""
-
-msgid "PublicBody::Translation|Short name"
-msgstr ""
-
-msgid "PublicBody::Translation|Url name"
-msgstr ""
-
msgid "PublicBody|Api key"
msgstr ""
@@ -2344,6 +2338,9 @@ msgstr "El motor de búsqueda no está accesible en estos momentos: no podemos m
msgid "The search index is currently offline, so we can't show the Freedom of Information requests this person has made."
msgstr "El motor de búsqueda no está accesible en estos momentos: no podemos mostrar las solicitudes de información que ha hecho esta persona"
+msgid "The {{site_name}} team."
+msgstr ""
+
msgid "Then you can cancel the alert."
msgstr "Entonces podrás cancelar tu alerta."
@@ -2885,6 +2882,12 @@ msgstr "Esperando que el organismo responda"
msgid "Was the response you got to your FOI request any good?"
msgstr "¿Fue la respuesta a tu solicitud satisfactoria?"
+msgid "We consider it is not a valid FOI request, and have therefore hidden it from other users."
+msgstr ""
+
+msgid "We consider it to be vexatious, and have therefore hidden it from other users."
+msgstr ""
+
msgid "We do not have a working request email address for this authority."
msgstr "No tenemos una dirección de correo válida para este organismo."
@@ -3113,6 +3116,9 @@ msgstr ""
"Sólo recibirás una respuesta a tu solicitud si continúas\n"
"con la aclaración."
+msgid "You will still be able to view it while logged in to the site. Please reply to this email if you would like to discuss this decision further."
+msgstr ""
+
msgid "You're in. <a href=\"#\" id=\"send-request\">Continue sending your request</a>"
msgstr ""
@@ -3186,6 +3192,12 @@ msgstr "Tu contraseña:"
msgid "Your photo will be shown in public <strong>on the Internet</strong>,\\n wherever you do something on {{site_name}}."
msgstr ""
+msgid "Your request '{{request}}' at {{url}} has been reviewed by moderators."
+msgstr ""
+
+msgid "Your request on {{site_name}} hidden"
+msgstr ""
+
msgid "Your request was called {{info_request}}. Letting everyone know whether you got the information will help us keep tabs on"
msgstr "Tu solicitud se llamaba {{info_request}}. Haznos saber si has recibido la información para ayudarnos a controlar a"
@@ -3220,6 +3232,9 @@ msgstr "Un saludo,"
msgid "Yours sincerely,"
msgstr "Un saludo,"
+msgid "Yours,"
+msgstr ""
+
msgid "[FOI #{{request}} email]"
msgstr ""
diff --git a/locale/cs/app.po b/locale/cs/app.po
index 9663e890f..33f5737c6 100644
--- a/locale/cs/app.po
+++ b/locale/cs/app.po
@@ -4,8 +4,8 @@
#
# Translators:
# jui <appukonrad@gmail.com>, 2012
-# Hana Huntova <>, 2012
-# Jana Kneschke <>, 2012
+# Hana Huntova <>, 2012-2013
+# Jana Kneschke <>, 2012-2013
# janakneschke <jana.kneschke@gmail.com>, 2013
# janakneschke <jana.kneschke@gmail.com>, 2012-2013
# janakneschke <jana.kneschke@gmail.com>, 2013
@@ -19,10 +19,10 @@ msgid ""
msgstr ""
"Project-Id-Version: alaveteli\n"
"Report-Msgid-Bugs-To: http://github.com/sebbacon/alaveteli/issues\n"
-"POT-Creation-Date: 2013-04-23 16:34+0100\n"
-"PO-Revision-Date: 2013-04-23 15:42+0000\n"
+"POT-Creation-Date: 2013-05-30 09:46+0100\n"
+"PO-Revision-Date: 2013-05-30 08:54+0000\n"
"Last-Translator: louisecrow <louise@mysociety.org>\n"
-"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language-Team: Czech (http://www.transifex.com/projects/p/alaveteli/language/cs/)\n"
"Language: cs\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -121,7 +121,7 @@ msgid "'{{link_to_user}}', a person"
msgstr "od uživatele '{{link_to_user}}'."
msgid "*unknown*"
-msgstr ""
+msgstr "*neznámá data*"
msgid ",\\n\\n\\n\\nYours,\\n\\n{{user_name}}"
msgstr ""
@@ -143,7 +143,7 @@ msgid "2. Ask for Information"
msgstr "2. Vzneste dotaz"
msgid "3. Now check your request"
-msgstr "3. Nyní dotaz zkontrolujte"
+msgstr "3. Nyní dotaz zkontrolujte "
msgid "<a href=\"{{browse_url}}\">Browse all</a> or <a href=\"{{add_url}}\">ask us to add one</a>."
msgstr "<a href=\"{{browse_url}}\">Prohlížet všel</a> nebo <a href=\"{{add_url}}\">požádat o přidání kontaktu</a>."
@@ -330,7 +330,7 @@ msgid "A strange reponse, required attention by the {{site_name}} team"
msgstr "Neobvyklá reakce, která vyžaduje pozornost týmu stránek {{site_name}}."
msgid "A vexatious request"
-msgstr ""
+msgstr "Nepovolená operace"
msgid "A {{site_name}} user"
msgstr "Uživatel stránek {{site_name}} "
@@ -341,6 +341,15 @@ msgstr "O vás:"
msgid "Act on what you've learnt"
msgstr "Jednejte na základě toho, co jste se dozvěděli"
+msgid "Acts as xapian/acts as xapian job"
+msgstr ""
+
+msgid "ActsAsXapian::ActsAsXapianJob|Action"
+msgstr ""
+
+msgid "ActsAsXapian::ActsAsXapianJob|Model"
+msgstr ""
+
msgid "Add an annotation"
msgstr "Přidat poznámku"
@@ -376,7 +385,7 @@ msgid "All of the information requested has been received"
msgstr "Všechny požadované informace byly přijaty"
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 "Všechny níže uvedené možnosti mohou mít<strong>status</strong> nebo <strong>last_status</strong> před dvojtečkou. Například, <strong>status:not_held</strong> vyhledá dotazy, které byly <em>někdy</em> označeny štítkem \"není k dispozici\"; <strong>latest_status:not_held</strong> vyhledá jen ty dotazy, které jsou <em>v současnosti</em> označeny štítkem ůnení k dispozici\"."
+msgstr "Všechny níže uvedené možnosti mohou mít <strong>status</strong> nebo <strong>last_status</strong> před dvojtečkou. Například, <strong>status:not_held</strong> vyhledá dotazy, které byly <em>někdy</em> označeny štítkem \"není k dispozici\"; <strong>latest_status:not_held</strong> vyhledá jen ty dotazy, které jsou <em>v současnosti</em> označeny štítkem není k dispozici\"."
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 "Všechny níže uvedené možnosti <strong>variety</strong> or <strong>latest_variety</strong> před dvojtečkou. Například, <strong>variety:sent</strong> zahrne dotazy, které byly <em>někdy</em> vzneseny; <strong>latest_variety:sent</strong> zahrne pouze dotazy <em>v současnosti</em> označené jako odeslané."
@@ -426,7 +435,7 @@ msgid "Anyone:"
msgstr "Kdokoli:"
msgid "Applies to"
-msgstr ""
+msgstr "Týká se"
msgid "Are we missing a public authority?"
msgstr "Chybí nám nějaká instituce?"
@@ -476,7 +485,7 @@ msgid "By law, {{public_body_link}} should normally have responded <strong>promp
msgstr "Podle zákona, by měla instituce {{public_body_link}} odpovědět okamžitě a "
msgid "Calculated home page"
-msgstr ""
+msgstr "Domů"
msgid "Can't find the one you want?"
msgstr "Nemůžete najít, co hledáte?"
@@ -648,6 +657,9 @@ msgstr "V současnosti <strong> se čeká na odpověď</strong> od instituce {{p
msgid "Date:"
msgstr "Datum:"
+msgid "Dear {{name}},"
+msgstr ""
+
msgid "Dear {{public_body_name}},"
msgstr ""
"Povinný subjekt: {{public_body_name}}\n"
@@ -657,7 +669,7 @@ msgstr ""
"Vážená paní, vážený pane,"
msgid "Default locale"
-msgstr ""
+msgstr "Původní nastavení"
msgid "Delayed response to your FOI request - "
msgstr "Zpožděná odpověď na váš dotaz –"
@@ -669,7 +681,7 @@ msgid "Delivery error"
msgstr "Chyba při doručení"
msgid "Destroy {{name}}"
-msgstr ""
+msgstr "Zrušit {{name}}"
msgid "Details of request '"
msgstr "Podrobnosti dotazu"
@@ -684,7 +696,7 @@ msgid "Disclosure log"
msgstr "Disclosure log"
msgid "Disclosure log URL"
-msgstr ""
+msgstr "Disclosure log URL"
msgid "Don't want to address your message to {{person_or_body}}? You can also write to:"
msgstr "Nechcete svou zprávu adresovat na {{person_or_body}}? Můžete také napsat:"
@@ -705,7 +717,7 @@ msgid "EIR"
msgstr "Informace o životním prostředí"
msgid "Edit"
-msgstr ""
+msgstr "Editovat"
msgid "Edit and add <strong>more details</strong> to the message above,\\n explaining why you are dissatisfied with their response."
msgstr ""
@@ -752,7 +764,7 @@ msgid "Event history details"
msgstr "Historie případu, detaily"
msgid "Event {{id}}"
-msgstr ""
+msgstr "Aktivita {{id}}"
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=\"{{url}}\">why?</a>)."
msgstr ""
@@ -772,7 +784,7 @@ msgid "FOI email address for {{public_body}}"
msgstr "E-mailová adresa podatelny pro instituci {{public_body}}"
msgid "FOI request – {{title}}"
-msgstr ""
+msgstr "Žádost – {{title}}"
msgid "FOI requests"
msgstr "Dotazy"
@@ -931,6 +943,18 @@ msgstr "ZDE UPŘESNĚTE DETAILY VAŠÍ STÍŽNOSTI"
msgid "Handled by post."
msgstr "Vyřizováno poštou."
+msgid "Has tag string/has tag string tag"
+msgstr ""
+
+msgid "HasTagString::HasTagStringTag|Model"
+msgstr ""
+
+msgid "HasTagString::HasTagStringTag|Name"
+msgstr ""
+
+msgid "HasTagString::HasTagStringTag|Value"
+msgstr ""
+
msgid "Hello! You can make Freedom of Information requests within {{country_name}} at {{link_to_website}}"
msgstr "Dobrý den, můžete vznést dotaz v zemi {{country_name}} na stránkách {{link_to_website}}"
@@ -953,7 +977,7 @@ msgid "Hi! We need your help. The person who made the following request\\n ha
msgstr "Haló! Potřebujeme vaši pomoc. Osoba, která vznesla tento dotaz nám nesdělila, jestli byla zodpovězena úspěšně. Můžete si dotaz i odpověď přečíst a pomoci nám tak udržovat stránky přehledné? Děkujeme."
msgid "Hide request"
-msgstr ""
+msgstr "Skrýt dotaz"
msgid "Holiday"
msgstr "Státní svátek"
@@ -968,7 +992,7 @@ msgid "Home"
msgstr "Domů"
msgid "Home page"
-msgstr ""
+msgstr "Domovská stránka"
msgid "Home page of authority"
msgstr "Domovská stránka instituce"
@@ -1021,16 +1045,16 @@ msgid "I've received an <strong>error message</strong>"
msgstr "Obdržel jsem <strong>chybovou zprávu</strong>"
msgid "I've received an error message"
-msgstr ""
+msgstr "Obdržel/a jsem chybovou zprávu"
msgid "Id"
-msgstr ""
+msgstr "ID"
msgid "If the address is wrong, or you know a better address, please <a href=\"{{url}}\">contact us</a>."
msgstr "Pokud je adresa nesprávná, nebo víte o lepší adrese, prosíme <a href=\"{{url}}\">kontaktujte nás</a>."
msgid "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."
-msgstr ""
+msgstr "Pokud zpráva nebyla doručena a podaří se vám vyhledat správnou e-mailovou adresu dané instituce, prosím napište nám ji. "
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."
msgstr ""
@@ -1098,7 +1122,7 @@ msgstr ""
"pravděpodobně je nějaký problém s naším serverem."
msgid "Incoming email address"
-msgstr ""
+msgstr "Adresa pro příchozí e-maily"
msgid "Incoming message"
msgstr "Příchozí zpráva"
@@ -1218,7 +1242,7 @@ msgid "Items matching the following conditions are currently displayed on your w
msgstr "Témata týkající se následujících kritérií jsou zobrazeny na vaší nástěnce."
msgid "Items sent in last month"
-msgstr ""
+msgstr "Odesláno poslední měsíc"
msgid "Joined in"
msgstr "Zapojen v"
@@ -1227,7 +1251,7 @@ msgid "Joined {{site_name}} in"
msgstr "Registrován/a na stránkách {{site_name}} od"
msgid "Just one more thing"
-msgstr ""
+msgstr "Popište stručně co se stalo"
msgid "Keep it <strong>focused</strong>, you'll be more likely to get what you want (<a href=\"{{url}}\">why?</a>)."
msgstr "Snažte se svůj dotaz vyjádřit <strong>jasně a jednoduše</strong>, zvýší se tak vaše šance, že se dozvíte, co potřebujete (<a href=\"{{url}}\">proč?</a>)."
@@ -1250,25 +1274,25 @@ msgid "Link to this"
msgstr "Odkaz"
msgid "List all"
-msgstr ""
+msgstr "Vypsat vše"
msgid "List of all authorities (CSV)"
msgstr "Vytvořit seznam všech institucí (CSV)"
msgid "Listing FOI requests"
-msgstr ""
+msgstr "Výpis dotazů"
msgid "Listing public authorities"
-msgstr ""
+msgstr "Výpis institucí"
msgid "Listing public authorities matching '{{query}}'"
-msgstr ""
+msgstr "Výpis institucí odpovídajících zadanému vyhledávání '{{query}}'"
msgid "Listing tracks"
-msgstr ""
+msgstr "Generování seznamu"
msgid "Listing users"
-msgstr ""
+msgstr "Výpis uživatelů"
msgid "Log in to download a zip file of {{info_request_title}}"
msgstr "Přihlaste se ke stažení komprimovaného souboru {{info_request_title}}"
@@ -1353,7 +1377,7 @@ msgid "My profile"
msgstr "Můj profil"
msgid "My request has been <strong>refused</strong>"
-msgstr "Zopodvězení mého dotazu bylo <strong>zadmítnuto</strong>"
+msgstr "Zodpovězení mého dotazu bylo <strong>zamítnuto</strong>"
msgid "My requests"
msgstr "Moje dotazy"
@@ -1371,7 +1395,7 @@ msgid "New Freedom of Information requests"
msgstr "Nové dotazy "
msgid "New censor rule"
-msgstr ""
+msgstr "Nové pravidlo "
msgid "New e-mail:"
msgstr "Nový e-mail:"
@@ -1419,7 +1443,7 @@ msgid "No similar requests found."
msgstr "Žádné podobné dotazy nebyly nalezeny. "
msgid "No tracked things found."
-msgstr ""
+msgstr "Nic nebylo nalezeno."
msgid "Nobody has made any Freedom of Information requests to {{public_body_name}} using this site yet."
msgstr "Ještě nikdo na {{public_body_name}} dotaz v rámci stránek Informace pro všechny nevznesl. "
@@ -1431,7 +1455,7 @@ msgid "None made."
msgstr "Nic tu není"
msgid "Not a valid FOI request"
-msgstr ""
+msgstr "Neplatné vznesení dotazu"
msgid "Note that the requester will not be notified about your annotation, because the request was published by {{public_body_name}} on their behalf."
msgstr "Rádi bychom vás upozornili, že tazatel nebude o vašem komentáři informován, jelikož tento dotaz byl zveřejněn na žádost instituce {{public_body_name}}."
@@ -1479,7 +1503,7 @@ msgid "One public authority found"
msgstr "Nalezena jedna instituce"
msgid "Only put in abbreviations which are really used, otherwise leave blank. Short or long name is used in the URL – don't worry about breaking URLs through renaming, as the history is used to redirect"
-msgstr ""
+msgstr "Vložte pouze zkratky, které jsou opravdu používány, nebo nevyplňujte. Krátké nebo dlouhé jméno se používá v URL - nemusíte se obávat porušení pravidel pojmenovávání URL, bude použito přesměrování"
msgid "Only requests made using {{site_name}} are shown."
msgstr "Zobrazí se pouze dotazy vznesené prostřednictvím stránek {{site_name}}"
@@ -1610,7 +1634,7 @@ msgid "Please enter a subject"
msgstr "Vložte předmět zprávy. "
msgid "Please enter a summary of your request"
-msgstr "Vložte shrnutí vašeho dotazu. "
+msgstr "Vložte předmět dotazu. "
msgid "Please enter a valid email address"
msgstr "Vložte platnou e-mailovou adresu. "
@@ -1655,7 +1679,7 @@ msgid "Please keep it shorter than 500 characters"
msgstr "Váš text musí být kratší než 500 znaků."
msgid "Please keep the summary short, like in the subject of an email. You can use a phrase, rather than a full sentence."
-msgstr "Zkraťte shrnutí, podobně jako v předmětu e-mailové zprávy. Můžete použít několik klíčových slov spíše než celou větu. "
+msgstr "Předmět dotazu musí být krátký, podobně jako v předmětu e-mailové zprávy. Použijte například několik klíčových slov spíše než celou větu. "
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 "Požádejte o informace, které jsou uvedeny v těchto kategoriích, <strong>neplýtvejte svým časem</strong> nebo časem lidí v institucích dotazy na nesouvisející informace."
@@ -1681,10 +1705,10 @@ msgid "Please use this email address for all replies to this request:"
msgstr "Prosíme používejte tuto e-mailovou adresu pro všechny odpovědi na tento dotaz:"
msgid "Please write a summary with some text in it"
-msgstr "Napište text do shrnutí. "
+msgstr "Napište text do předmětu zprávy."
msgid "Please write the summary using a mixture of capital and lower case letters. This makes it easier for others to read."
-msgstr "Ve shrnutí je třeba použít text s malými i velkými písmeny. Bude se tak lépe číst i ostatním. "
+msgstr "Ve předmětu zprávy je třeba použít text s malými i velkými písmeny. Bude se tak lépe číst i ostatním. "
msgid "Please write your annotation using a mixture of capital and lower case letters. This makes it easier for others to read."
msgstr "V poznámce je třeba použít text s malými i velkými písmeny. Bude se tak lépe číst i ostatním. "
@@ -1768,49 +1792,19 @@ msgid "Public authorities {{start_count}} to {{end_count}} of {{total_count}}"
msgstr "Instituce od {{start_count}} do {{end_count}} z {{total_count}}"
msgid "Public authority – {{name}}"
-msgstr ""
+msgstr "Veřejná instituce – {{name}}"
msgid "Public body"
msgstr "Instituce"
-msgid "Public body/translation"
-msgstr "PublicBody | Verze ??"
-
msgid "Public notes"
-msgstr ""
+msgstr "Poznámka (viditelná pro všechny)"
msgid "Public page"
-msgstr ""
+msgstr "Stránka (viditelná pro všechny)"
msgid "Public page not available"
-msgstr ""
-
-msgid "PublicBody::Translation|Disclosure log"
-msgstr "PublicBody::Translation|Disclosure log"
-
-msgid "PublicBody::Translation|First letter"
-msgstr "PublicBody | Začáteční písmeno"
-
-msgid "PublicBody::Translation|Locale"
-msgstr "PublicBody | Lokální ??"
-
-msgid "PublicBody::Translation|Name"
-msgstr "PublicBody | Název"
-
-msgid "PublicBody::Translation|Notes"
-msgstr "PublicBody | Poznámka"
-
-msgid "PublicBody::Translation|Publication scheme"
-msgstr "PublicBody | Publikační schéma ??"
-
-msgid "PublicBody::Translation|Request email"
-msgstr "PublicBody::Translation|Zadejte e-mail ??"
-
-msgid "PublicBody::Translation|Short name"
-msgstr "PublicBody::Translation|Krátké jméno ??"
-
-msgid "PublicBody::Translation|Url name"
-msgstr "PublicBody::Translation|Název URL"
+msgstr "Stránku nelze načíst"
msgid "PublicBody|Api key"
msgstr "PublicBody | Název ??"
@@ -1858,7 +1852,7 @@ msgid "Publication scheme"
msgstr "Systém publikování"
msgid "Publication scheme URL"
-msgstr ""
+msgstr "Schéma publikací URL"
msgid "Purge request"
msgstr "Vyčistit formulář dotazu"
@@ -1920,7 +1914,7 @@ msgid "Request an internal review from {{person_or_body}}"
msgstr "Požádat o doplnění dotazu od instituce či jmenovitě jejím pracovníkem {{person_or_body}}"
msgid "Request email"
-msgstr ""
+msgstr "E-mailová adresa dotazu"
msgid "Request has been removed"
msgstr "Dotaz byl odstraněn"
@@ -2025,7 +2019,7 @@ msgid "Search your contributions"
msgstr "Prohledávat vlastní příspěvky"
msgid "See bounce message"
-msgstr ""
+msgstr "Prohlédněte si odmítnutou zprávu"
msgid "Select one to see more information about the authority."
msgstr "Vyberte jednu instituci pro zobrazení podrobnějších informací"
@@ -2061,7 +2055,7 @@ msgid "Set your profile photo"
msgstr "Nastavte své profilové foto"
msgid "Short name"
-msgstr ""
+msgstr "Krátké jméno"
msgid "Short name is already taken"
msgstr "Krátké jméno je již obsazeno."
@@ -2162,7 +2156,7 @@ msgid "Submit status"
msgstr "Odešlete status"
msgid "Submit status and send message"
-msgstr ""
+msgstr "Odeslat"
msgid "Subscribe to blog"
msgstr "Sledujte náš blog"
@@ -2177,7 +2171,7 @@ msgid "Suggest how the requester can find the <strong>rest of the information</s
msgstr "Doporučte, jak tazatel může najít <strong>úplné informace</strong>."
msgid "Summary:"
-msgstr "Shrnutí:"
+msgstr "Předmět:"
msgid "Table of statuses"
msgstr "Tabulka stavů"
@@ -2186,7 +2180,7 @@ msgid "Table of varieties"
msgstr "Tabulka možností"
msgid "Tags"
-msgstr ""
+msgstr "Tagy"
msgid "Tags (separated by a space):"
msgstr "Tagy (oddělené mezerou):"
@@ -2216,7 +2210,7 @@ msgid "Thank you for updating your profile photo"
msgstr "Děkujeme vám za aktualizaci svého profilového fota"
msgid "Thank you! We'll look into what happened and try and fix it up."
-msgstr ""
+msgstr "Děkujeme! Zjistíme co se stalo a zkusíme to spravit. "
msgid "Thanks for helping - your work will make it easier for everyone to find successful\\nresponses, and maybe even let us make league tables..."
msgstr ""
@@ -2324,6 +2318,9 @@ msgstr "Vyhledávací rejstřík je nyní mimo provoz, nemůžeme vám proto uk
msgid "The search index is currently offline, so we can't show the Freedom of Information requests this person has made."
msgstr "Došlo ke krátkému výpadku vyhledávání, nemůžeme proto zobrazit dotazy, které tato osoba vznesla. Omlouváme se."
+msgid "The {{site_name}} team."
+msgstr ""
+
msgid "Then you can cancel the alert."
msgstr "Pak můžete upozornění zrušit."
@@ -2472,7 +2469,7 @@ msgid "This is because {{title}} is an old request that has been\\nmarked to no
msgstr "Důvodem je, že dotaz s názvem {{title}} je staršího data a byl uzavřen, tudíž, na něj již nelze odpovědět."
msgid "This is the first version."
-msgstr ""
+msgstr "Toto je první verze."
msgid "This is your own request, so you will be automatically emailed when new responses arrive."
msgstr "Toto je váš vlastní dotaz, proto budete odpovědi dostávat e-mailem automaticky."
@@ -2550,7 +2547,7 @@ msgid "This request is still in progress:"
msgstr "Tento dotaz je stále aktivní:"
msgid "This request requires administrator attention"
-msgstr ""
+msgstr "Tento dotaz vyžaduje pozornost administrátora"
msgid "This request was not made via {{site_name}}"
msgstr "Tento dotaz nebyl vznesen pomocí stránek {{site_name}}"
@@ -2760,7 +2757,7 @@ msgid "User info request sent alert"
msgstr "User info request sent alert ??"
msgid "User – {{name}}"
-msgstr ""
+msgstr "Uživatel – {{name}}"
msgid "UserInfoRequestSentAlert|Alert type"
msgstr "UserInfoRequestSentAlert| Typ upozornění"
@@ -2817,7 +2814,7 @@ msgid "User|Url name"
msgstr "User | Název URL"
msgid "Version {{version}}"
-msgstr ""
+msgstr "Version {{version}}"
msgid "View FOI email address"
msgstr "Zobrazit e-mailovou adresu Informace pro všechny (????)"
@@ -2858,6 +2855,12 @@ msgstr "Čeká se na odpověď instituce"
msgid "Was the response you got to your FOI request any good?"
msgstr "Byla odpověď na váš dotaz kompletní a v pořádku?"
+msgid "We consider it is not a valid FOI request, and have therefore hidden it from other users."
+msgstr ""
+
+msgid "We consider it to be vexatious, and have therefore hidden it from other users."
+msgstr ""
+
msgid "We do not have a working request email address for this authority."
msgstr "Nemáme funkční e-mailovou adresu pro tuto instituci."
@@ -3084,6 +3087,9 @@ msgstr ""
"Odpověď na váš dotaz obdržíte, pouze pokud odpovíte \n"
"bližším vysvětlením."
+msgid "You will still be able to view it while logged in to the site. Please reply to this email if you would like to discuss this decision further."
+msgstr ""
+
msgid "You're in. <a href=\"#\" id=\"send-request\">Continue sending your request</a>"
msgstr "Odesláno. <a href=\"#\" id=\"send-request\"> Můžete vznést další dotaz.</a>"
@@ -3157,6 +3163,12 @@ msgstr "Vaše heslo:"
msgid "Your photo will be shown in public <strong>on the Internet</strong>,\\n wherever you do something on {{site_name}}."
msgstr "<strong>Důležité upozornění:</strong> Vaše fotografie bude zveřejněna na stránkách Informace pro všechny pokaždé, kdy vznesete dotaz nebo přidáte komentář."
+msgid "Your request '{{request}}' at {{url}} has been reviewed by moderators."
+msgstr ""
+
+msgid "Your request on {{site_name}} hidden"
+msgstr ""
+
msgid "Your request was called {{info_request}}. Letting everyone know whether you got the information will help us keep tabs on"
msgstr "Informace se týká vašeho dotazu {{info_request}}. Můžete všechny informovat, zda jste požadovanou informaci obdrželi a bude tak přehled o odpovědích této instituce"
@@ -3193,6 +3205,9 @@ msgstr "S přátelským pozdravem,"
msgid "Yours sincerely,"
msgstr "S pozdravem,"
+msgid "Yours,"
+msgstr ""
+
msgid "[FOI #{{request}} email]"
msgstr "[FOI #{{request}} e-mail] ??"
@@ -3207,14 +3222,14 @@ msgstr "\\n\\n[ {{site_name}} Poznámka: výše uvedený text byl špatně kódo
msgid "a one line summary of the information you are requesting, \\n\t\t\te.g."
msgstr ""
-"Shrnutí vašeho dotazu na jeden řádek.\n"
+"stručný obsah vašeho dotazu na jeden řádek.\n"
"Například:"
msgid "admin"
msgstr "admin"
msgid "alaveteli_foi:The software that runs {{site_name}}"
-msgstr ""
+msgstr "alaveteli_foi: Software, na kterém běží {{site_name}}"
msgid "all requests"
msgstr "všechny dotazy"
@@ -3250,7 +3265,7 @@ msgid "are long overdue."
msgstr "– tato instituce výrazně překročila zákonem daný termín."
msgid "at"
-msgstr ""
+msgstr "na"
msgid "authorities"
msgstr "instituce"
@@ -3265,7 +3280,7 @@ msgid "between two dates"
msgstr "mezi dvěma daty"
msgid "but followupable"
-msgstr ""
+msgstr "ale "
msgid "by"
msgstr "od"
@@ -3351,7 +3366,7 @@ msgid "messages from users"
msgstr "zprávy od uživatelů"
msgid "move..."
-msgstr ""
+msgstr "přesunout..."
msgid "no later than"
msgstr "nejpozději do"
@@ -3365,7 +3380,7 @@ msgid "normally"
msgstr "to"
msgid "not requestable due to: {{reason}}"
-msgstr ""
+msgstr "nelze žádat kvůli {{reason}}"
msgid "please sign in as "
msgstr "prosíme přihlašte se jako"
@@ -3380,7 +3395,7 @@ msgid "requests which are {{list_of_statuses}}"
msgstr "dotazy které jsou {{list_of_statuses}}"
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."
-msgstr "adminsitrátorovi. Podívejte se prosím na vznesený dotaz i odpověď. Až uděláte nezbytné kroky, odpovězte na tento e-mail a stručně je popište."
+msgstr "administrátorovi. Podívejte se prosím na vznesený dotaz i odpověď. Až uděláte nezbytné kroky, odpovězte na tento e-mail a stručně je popište."
msgid "send a follow up message"
msgstr "poslat odpověď"
@@ -3389,7 +3404,7 @@ msgid "sent to {{public_body_name}} by {{info_request_user}} on {{date}}."
msgstr "posláno instituci {{public_body_name}} uživatelem {{info_request_user}} dne {{date}}."
msgid "set to <strong>blank</strong> (empty string) if can't find an address; these emails are <strong>public</strong> as anyone can view with a CAPTCHA"
-msgstr ""
+msgstr "nastaveno <strong>jako prázdné </strong> (empty string) pokud nelze nalézt adresu; tyto e-maily jsou <strong>veřejné</strong> a kdokoliv je může vidět pomocí CAPTCHA"
msgid "show quoted sections"
msgstr "ukázat citované pasáže"
@@ -3505,7 +3520,7 @@ msgid "{{info_request_user_name}} only:"
msgstr "Pouze {{info_request_user_name}}:"
msgid "{{law_used_full}} request - {{title}}"
-msgstr "Dotaz o informace podle {{law_used_full}} - {{title}}"
+msgstr "Žádost o informace podle {{law_used_full}} - {{title}}"
msgid "{{law_used_full}} request GQ - {{title}}"
msgstr "{{law_used_full}} žádejte GQ - {{title}} ??"
@@ -3556,7 +3571,7 @@ msgid "{{site_name}} users have made {{number_of_requests}} requests, including:
msgstr "Na stránkách {{site_name}} tazatelé podali {{number_of_requests}} dotazů, včetně:"
msgid "{{thing_changed}} was changed from <code>{{from_value}}</code> to <code>{{to_value}}</code>"
-msgstr ""
+msgstr "{{thing_changed}} je změněno z <code>{{from_value}}</code> na <code>{{to_value}}</code>"
msgid "{{title}} - a Freedom of Information request to {{public_body}}"
msgstr "{{title}} - dotaz vznesený podle zákona 106/1999 Sb., o svobodném přístupu k informacím na instituci {{public_body}}"
diff --git a/locale/cy/app.po b/locale/cy/app.po
index 1e2201a20..1db212feb 100644
--- a/locale/cy/app.po
+++ b/locale/cy/app.po
@@ -11,10 +11,10 @@ msgid ""
msgstr ""
"Project-Id-Version: alaveteli\n"
"Report-Msgid-Bugs-To: http://github.com/sebbacon/alaveteli/issues\n"
-"POT-Creation-Date: 2013-04-23 16:34+0100\n"
-"PO-Revision-Date: 2013-04-23 15:41+0000\n"
+"POT-Creation-Date: 2013-05-30 09:46+0100\n"
+"PO-Revision-Date: 2013-05-30 08:54+0000\n"
"Last-Translator: louisecrow <louise@mysociety.org>\n"
-"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language-Team: Welsh (http://www.transifex.com/projects/p/alaveteli/language/cy/)\n"
"Language: cy\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -294,6 +294,15 @@ msgstr ""
msgid "Act on what you've learnt"
msgstr ""
+msgid "Acts as xapian/acts as xapian job"
+msgstr ""
+
+msgid "ActsAsXapian::ActsAsXapianJob|Action"
+msgstr ""
+
+msgid "ActsAsXapian::ActsAsXapianJob|Model"
+msgstr ""
+
msgid "Add an annotation"
msgstr ""
@@ -591,6 +600,9 @@ msgstr ""
msgid "Date:"
msgstr "Dyddiad"
+msgid "Dear {{name}},"
+msgstr ""
+
msgid "Dear {{public_body_name}},"
msgstr "Annwyl {{public_body_name}},"
@@ -859,6 +871,18 @@ msgstr "RHOWCH MANYLION EICH CWYN YMA"
msgid "Handled by post."
msgstr ""
+msgid "Has tag string/has tag string tag"
+msgstr ""
+
+msgid "HasTagString::HasTagStringTag|Model"
+msgstr ""
+
+msgid "HasTagString::HasTagStringTag|Name"
+msgstr ""
+
+msgid "HasTagString::HasTagStringTag|Value"
+msgstr ""
+
msgid "Hello! You can make Freedom of Information requests within {{country_name}} at {{link_to_website}}"
msgstr "Shwmae! Rydych chi'n gallu gwneud ceisiadau Rhyddid Gwybodaeth yn {{country_name}} yma:{{link_to_website}}"
@@ -1669,9 +1693,6 @@ msgstr ""
msgid "Public body"
msgstr ""
-msgid "Public body/translation"
-msgstr ""
-
msgid "Public notes"
msgstr ""
@@ -1681,33 +1702,6 @@ msgstr ""
msgid "Public page not available"
msgstr ""
-msgid "PublicBody::Translation|Disclosure log"
-msgstr ""
-
-msgid "PublicBody::Translation|First letter"
-msgstr ""
-
-msgid "PublicBody::Translation|Locale"
-msgstr ""
-
-msgid "PublicBody::Translation|Name"
-msgstr ""
-
-msgid "PublicBody::Translation|Notes"
-msgstr ""
-
-msgid "PublicBody::Translation|Publication scheme"
-msgstr ""
-
-msgid "PublicBody::Translation|Request email"
-msgstr ""
-
-msgid "PublicBody::Translation|Short name"
-msgstr ""
-
-msgid "PublicBody::Translation|Url name"
-msgstr ""
-
msgid "PublicBody|Api key"
msgstr ""
@@ -2192,6 +2186,9 @@ msgstr ""
msgid "The search index is currently offline, so we can't show the Freedom of Information requests this person has made."
msgstr ""
+msgid "The {{site_name}} team."
+msgstr ""
+
msgid "Then you can cancel the alert."
msgstr ""
@@ -2708,6 +2705,12 @@ msgstr ""
msgid "Was the response you got to your FOI request any good?"
msgstr ""
+msgid "We consider it is not a valid FOI request, and have therefore hidden it from other users."
+msgstr ""
+
+msgid "We consider it to be vexatious, and have therefore hidden it from other users."
+msgstr ""
+
msgid "We do not have a working request email address for this authority."
msgstr ""
@@ -2900,6 +2903,9 @@ msgstr ""
msgid "You will only get an answer to your request if you follow up\\nwith the clarification."
msgstr ""
+msgid "You will still be able to view it while logged in to the site. Please reply to this email if you would like to discuss this decision further."
+msgstr ""
+
msgid "You're in. <a href=\"#\" id=\"send-request\">Continue sending your request</a>"
msgstr ""
@@ -2968,6 +2974,12 @@ msgstr ""
msgid "Your photo will be shown in public <strong>on the Internet</strong>,\\n wherever you do something on {{site_name}}."
msgstr ""
+msgid "Your request '{{request}}' at {{url}} has been reviewed by moderators."
+msgstr ""
+
+msgid "Your request on {{site_name}} hidden"
+msgstr ""
+
msgid "Your request was called {{info_request}}. Letting everyone know whether you got the information will help us keep tabs on"
msgstr ""
@@ -3006,6 +3018,9 @@ msgstr "Yr eiddoch yn gywir,"
msgid "Yours sincerely,"
msgstr "Yn gywir"
+msgid "Yours,"
+msgstr ""
+
msgid "[FOI #{{request}} email]"
msgstr ""
diff --git a/locale/de/app.po b/locale/de/app.po
index e293c9f9f..38b00b519 100644
--- a/locale/de/app.po
+++ b/locale/de/app.po
@@ -11,10 +11,10 @@ msgid ""
msgstr ""
"Project-Id-Version: alaveteli\n"
"Report-Msgid-Bugs-To: http://github.com/sebbacon/alaveteli/issues\n"
-"POT-Creation-Date: 2013-04-23 16:34+0100\n"
-"PO-Revision-Date: 2013-04-23 15:40+0000\n"
+"POT-Creation-Date: 2013-05-30 09:46+0100\n"
+"PO-Revision-Date: 2013-05-30 08:54+0000\n"
"Last-Translator: louisecrow <louise@mysociety.org>\n"
-"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language-Team: German (http://www.transifex.com/projects/p/alaveteli/language/de/)\n"
"Language: de\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -320,6 +320,15 @@ msgstr "Zu Ihrer Person:"
msgid "Act on what you've learnt"
msgstr "Handel aus Deinen Erfahrungen"
+msgid "Acts as xapian/acts as xapian job"
+msgstr ""
+
+msgid "ActsAsXapian::ActsAsXapianJob|Action"
+msgstr ""
+
+msgid "ActsAsXapian::ActsAsXapianJob|Model"
+msgstr ""
+
msgid "Add an annotation"
msgstr "Fügen Sie einee Anmerkung bei"
@@ -621,6 +630,9 @@ msgstr "<strong>Antwort</strong> von {{public_body_link}} wird erwartet. Sie sol
msgid "Date:"
msgstr "Datum:"
+msgid "Dear {{name}},"
+msgstr ""
+
msgid "Dear {{public_body_name}},"
msgstr "Sehr geehrte / Sehr geehrter {{public_body_name}},"
@@ -895,6 +907,18 @@ msgstr "HINTELASSEN SIE HIER DETAILS ZU IHRER BESCHWERDE"
msgid "Handled by post."
msgstr "Postalisch bearbeitet."
+msgid "Has tag string/has tag string tag"
+msgstr ""
+
+msgid "HasTagString::HasTagStringTag|Model"
+msgstr ""
+
+msgid "HasTagString::HasTagStringTag|Name"
+msgstr ""
+
+msgid "HasTagString::HasTagStringTag|Value"
+msgstr ""
+
msgid "Hello! You can make Freedom of Information requests within {{country_name}} at {{link_to_website}}"
msgstr "Hallo! IFG-Anfragen innerhalb von {{country_name}} können Sie hier stellen: {{link_to_website}} "
@@ -1720,9 +1744,6 @@ msgstr ""
msgid "Public body"
msgstr ""
-msgid "Public body/translation"
-msgstr ""
-
msgid "Public notes"
msgstr ""
@@ -1732,33 +1753,6 @@ msgstr ""
msgid "Public page not available"
msgstr ""
-msgid "PublicBody::Translation|Disclosure log"
-msgstr ""
-
-msgid "PublicBody::Translation|First letter"
-msgstr ""
-
-msgid "PublicBody::Translation|Locale"
-msgstr ""
-
-msgid "PublicBody::Translation|Name"
-msgstr ""
-
-msgid "PublicBody::Translation|Notes"
-msgstr ""
-
-msgid "PublicBody::Translation|Publication scheme"
-msgstr ""
-
-msgid "PublicBody::Translation|Request email"
-msgstr ""
-
-msgid "PublicBody::Translation|Short name"
-msgstr ""
-
-msgid "PublicBody::Translation|Url name"
-msgstr ""
-
msgid "PublicBody|Api key"
msgstr ""
@@ -2251,6 +2245,9 @@ msgstr "Da die Suchanzeige momentan offline ist, können wir die an diese Behör
msgid "The search index is currently offline, so we can't show the Freedom of Information requests this person has made."
msgstr "Da die Suchanzeige momentan offline ist, können wir durch diese Person gestellten Informationsfreiheitsanfragen gerade leider nicht anzeigen. "
+msgid "The {{site_name}} team."
+msgstr ""
+
msgid "Then you can cancel the alert."
msgstr "Dann können Sie die Statusnachricht abmelden "
@@ -2769,6 +2766,12 @@ msgstr "Antwort der Behörde wird erwartet"
msgid "Was the response you got to your FOI request any good?"
msgstr ""
+msgid "We consider it is not a valid FOI request, and have therefore hidden it from other users."
+msgstr ""
+
+msgid "We consider it to be vexatious, and have therefore hidden it from other users."
+msgstr ""
+
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. "
@@ -2966,6 +2969,9 @@ msgstr ""
msgid "You will only get an answer to your request if you follow up\\nwith the clarification."
msgstr "Sie können nur eine Antwort auf Ihre Anfrage erhalten wenn Sie mti der Aufklärung fortfahren. "
+msgid "You will still be able to view it while logged in to the site. Please reply to this email if you would like to discuss this decision further."
+msgstr ""
+
msgid "You're in. <a href=\"#\" id=\"send-request\">Continue sending your request</a>"
msgstr ""
@@ -3038,6 +3044,12 @@ msgstr "Ihr Passwort:"
msgid "Your photo will be shown in public <strong>on the Internet</strong>,\\n wherever you do something on {{site_name}}."
msgstr ""
+msgid "Your request '{{request}}' at {{url}} has been reviewed by moderators."
+msgstr ""
+
+msgid "Your request on {{site_name}} hidden"
+msgstr ""
+
msgid "Your request was called {{info_request}}. Letting everyone know whether you got the information will help us keep tabs on"
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."
@@ -3072,6 +3084,9 @@ msgstr "Mit freundlichem Gruß, "
msgid "Yours sincerely,"
msgstr "Mit freundlichem Gruß, "
+msgid "Yours,"
+msgstr ""
+
msgid "[FOI #{{request}} email]"
msgstr ""
diff --git a/locale/en/app.po b/locale/en/app.po
index e3c95fbad..eb31d7a2e 100644
--- a/locale/en/app.po
+++ b/locale/en/app.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: alaveteli\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2013-04-23 16:34+0100\n"
+"POT-Creation-Date: 2013-05-30 09:46+0100\n"
"PO-Revision-Date: 2011-02-24 07:11-0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -290,6 +290,15 @@ msgstr ""
msgid "Act on what you've learnt"
msgstr ""
+msgid "Acts as xapian/acts as xapian job"
+msgstr ""
+
+msgid "ActsAsXapian::ActsAsXapianJob|Action"
+msgstr ""
+
+msgid "ActsAsXapian::ActsAsXapianJob|Model"
+msgstr ""
+
msgid "Add an annotation"
msgstr ""
@@ -587,6 +596,9 @@ msgstr ""
msgid "Date:"
msgstr ""
+msgid "Dear {{name}},"
+msgstr ""
+
msgid "Dear {{public_body_name}},"
msgstr ""
@@ -853,6 +865,18 @@ msgstr ""
msgid "Handled by post."
msgstr ""
+msgid "Has tag string/has tag string tag"
+msgstr ""
+
+msgid "HasTagString::HasTagStringTag|Model"
+msgstr ""
+
+msgid "HasTagString::HasTagStringTag|Name"
+msgstr ""
+
+msgid "HasTagString::HasTagStringTag|Value"
+msgstr ""
+
msgid "Hello! You can make Freedom of Information requests within {{country_name}} at {{link_to_website}}"
msgstr ""
@@ -1663,9 +1687,6 @@ msgstr ""
msgid "Public body"
msgstr ""
-msgid "Public body/translation"
-msgstr ""
-
msgid "Public notes"
msgstr ""
@@ -1675,33 +1696,6 @@ msgstr ""
msgid "Public page not available"
msgstr ""
-msgid "PublicBody::Translation|Disclosure log"
-msgstr ""
-
-msgid "PublicBody::Translation|First letter"
-msgstr ""
-
-msgid "PublicBody::Translation|Locale"
-msgstr ""
-
-msgid "PublicBody::Translation|Name"
-msgstr ""
-
-msgid "PublicBody::Translation|Notes"
-msgstr ""
-
-msgid "PublicBody::Translation|Publication scheme"
-msgstr ""
-
-msgid "PublicBody::Translation|Request email"
-msgstr ""
-
-msgid "PublicBody::Translation|Short name"
-msgstr ""
-
-msgid "PublicBody::Translation|Url name"
-msgstr ""
-
msgid "PublicBody|Api key"
msgstr ""
@@ -2184,6 +2178,9 @@ msgstr ""
msgid "The search index is currently offline, so we can't show the Freedom of Information requests this person has made."
msgstr ""
+msgid "The {{site_name}} team."
+msgstr ""
+
msgid "Then you can cancel the alert."
msgstr ""
@@ -2694,6 +2691,12 @@ msgstr ""
msgid "Was the response you got to your FOI request any good?"
msgstr ""
+msgid "We consider it is not a valid FOI request, and have therefore hidden it from other users."
+msgstr ""
+
+msgid "We consider it to be vexatious, and have therefore hidden it from other users."
+msgstr ""
+
msgid "We do not have a working request email address for this authority."
msgstr ""
@@ -2886,6 +2889,9 @@ msgstr ""
msgid "You will only get an answer to your request if you follow up\\nwith the clarification."
msgstr ""
+msgid "You will still be able to view it while logged in to the site. Please reply to this email if you would like to discuss this decision further."
+msgstr ""
+
msgid "You're in. <a href=\"#\" id=\"send-request\">Continue sending your request</a>"
msgstr ""
@@ -2952,6 +2958,12 @@ msgstr ""
msgid "Your photo will be shown in public <strong>on the Internet</strong>,\\n wherever you do something on {{site_name}}."
msgstr ""
+msgid "Your request '{{request}}' at {{url}} has been reviewed by moderators."
+msgstr ""
+
+msgid "Your request on {{site_name}} hidden"
+msgstr ""
+
msgid "Your request was called {{info_request}}. Letting everyone know whether you got the information will help us keep tabs on"
msgstr ""
@@ -2986,6 +2998,9 @@ msgstr ""
msgid "Yours sincerely,"
msgstr ""
+msgid "Yours,"
+msgstr ""
+
msgid "[FOI #{{request}} email]"
msgstr ""
diff --git a/locale/en_IE/app.po b/locale/en_IE/app.po
index d2f0f5e47..932268081 100644
--- a/locale/en_IE/app.po
+++ b/locale/en_IE/app.po
@@ -9,10 +9,10 @@ msgid ""
msgstr ""
"Project-Id-Version: alaveteli\n"
"Report-Msgid-Bugs-To: http://github.com/sebbacon/alaveteli/issues\n"
-"POT-Creation-Date: 2013-04-23 16:34+0100\n"
-"PO-Revision-Date: 2013-04-23 15:39+0000\n"
+"POT-Creation-Date: 2013-05-30 09:46+0100\n"
+"PO-Revision-Date: 2013-05-30 08:54+0000\n"
"Last-Translator: louisecrow <louise@mysociety.org>\n"
-"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language-Team: English (Ireland) (http://www.transifex.com/projects/p/alaveteli/language/en_IE/)\n"
"Language: en_IE\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -292,6 +292,15 @@ msgstr ""
msgid "Act on what you've learnt"
msgstr ""
+msgid "Acts as xapian/acts as xapian job"
+msgstr ""
+
+msgid "ActsAsXapian::ActsAsXapianJob|Action"
+msgstr ""
+
+msgid "ActsAsXapian::ActsAsXapianJob|Model"
+msgstr ""
+
msgid "Add an annotation"
msgstr ""
@@ -589,6 +598,9 @@ msgstr ""
msgid "Date:"
msgstr ""
+msgid "Dear {{name}},"
+msgstr ""
+
msgid "Dear {{public_body_name}},"
msgstr ""
@@ -855,6 +867,18 @@ msgstr ""
msgid "Handled by post."
msgstr ""
+msgid "Has tag string/has tag string tag"
+msgstr ""
+
+msgid "HasTagString::HasTagStringTag|Model"
+msgstr ""
+
+msgid "HasTagString::HasTagStringTag|Name"
+msgstr ""
+
+msgid "HasTagString::HasTagStringTag|Value"
+msgstr ""
+
msgid "Hello! You can make Freedom of Information requests within {{country_name}} at {{link_to_website}}"
msgstr ""
@@ -1665,9 +1689,6 @@ msgstr ""
msgid "Public body"
msgstr ""
-msgid "Public body/translation"
-msgstr ""
-
msgid "Public notes"
msgstr ""
@@ -1677,33 +1698,6 @@ msgstr ""
msgid "Public page not available"
msgstr ""
-msgid "PublicBody::Translation|Disclosure log"
-msgstr ""
-
-msgid "PublicBody::Translation|First letter"
-msgstr ""
-
-msgid "PublicBody::Translation|Locale"
-msgstr ""
-
-msgid "PublicBody::Translation|Name"
-msgstr ""
-
-msgid "PublicBody::Translation|Notes"
-msgstr ""
-
-msgid "PublicBody::Translation|Publication scheme"
-msgstr ""
-
-msgid "PublicBody::Translation|Request email"
-msgstr ""
-
-msgid "PublicBody::Translation|Short name"
-msgstr ""
-
-msgid "PublicBody::Translation|Url name"
-msgstr ""
-
msgid "PublicBody|Api key"
msgstr ""
@@ -2186,6 +2180,9 @@ msgstr ""
msgid "The search index is currently offline, so we can't show the Freedom of Information requests this person has made."
msgstr ""
+msgid "The {{site_name}} team."
+msgstr ""
+
msgid "Then you can cancel the alert."
msgstr ""
@@ -2696,6 +2693,12 @@ msgstr ""
msgid "Was the response you got to your FOI request any good?"
msgstr ""
+msgid "We consider it is not a valid FOI request, and have therefore hidden it from other users."
+msgstr ""
+
+msgid "We consider it to be vexatious, and have therefore hidden it from other users."
+msgstr ""
+
msgid "We do not have a working request email address for this authority."
msgstr ""
@@ -2888,6 +2891,9 @@ msgstr ""
msgid "You will only get an answer to your request if you follow up\\nwith the clarification."
msgstr ""
+msgid "You will still be able to view it while logged in to the site. Please reply to this email if you would like to discuss this decision further."
+msgstr ""
+
msgid "You're in. <a href=\"#\" id=\"send-request\">Continue sending your request</a>"
msgstr ""
@@ -2954,6 +2960,12 @@ msgstr ""
msgid "Your photo will be shown in public <strong>on the Internet</strong>,\\n wherever you do something on {{site_name}}."
msgstr ""
+msgid "Your request '{{request}}' at {{url}} has been reviewed by moderators."
+msgstr ""
+
+msgid "Your request on {{site_name}} hidden"
+msgstr ""
+
msgid "Your request was called {{info_request}}. Letting everyone know whether you got the information will help us keep tabs on"
msgstr ""
@@ -2988,6 +3000,9 @@ msgstr ""
msgid "Yours sincerely,"
msgstr ""
+msgid "Yours,"
+msgstr ""
+
msgid "[FOI #{{request}} email]"
msgstr ""
diff --git a/locale/es/app.po b/locale/es/app.po
index 48992d442..515f6a491 100644
--- a/locale/es/app.po
+++ b/locale/es/app.po
@@ -12,10 +12,10 @@ msgid ""
msgstr ""
"Project-Id-Version: alaveteli\n"
"Report-Msgid-Bugs-To: http://github.com/sebbacon/alaveteli/issues\n"
-"POT-Creation-Date: 2013-04-23 16:34+0100\n"
-"PO-Revision-Date: 2013-04-23 16:05+0000\n"
+"POT-Creation-Date: 2013-05-30 09:46+0100\n"
+"PO-Revision-Date: 2013-05-30 08:54+0000\n"
"Last-Translator: louisecrow <louise@mysociety.org>\n"
-"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language-Team: Spanish (http://www.transifex.com/projects/p/alaveteli/language/es/)\n"
"Language: es\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -359,6 +359,15 @@ msgstr "Sobre mí:"
msgid "Act on what you've learnt"
msgstr "Utiliza esta información"
+msgid "Acts as xapian/acts as xapian job"
+msgstr ""
+
+msgid "ActsAsXapian::ActsAsXapianJob|Action"
+msgstr ""
+
+msgid "ActsAsXapian::ActsAsXapianJob|Model"
+msgstr ""
+
msgid "Add an annotation"
msgstr "Añada un comentario"
@@ -670,6 +679,9 @@ msgstr "Actualmente <strong>esperando la respuesta</strong> de {{public_body_lin
msgid "Date:"
msgstr "Fecha:"
+msgid "Dear {{name}},"
+msgstr ""
+
msgid "Dear {{public_body_name}},"
msgstr "Estimado {{public_body_name}},"
@@ -947,6 +959,18 @@ msgstr "DETALLA TU QUEJA AQUÍ"
msgid "Handled by post."
msgstr "Resuelta por correo ordinario"
+msgid "Has tag string/has tag string tag"
+msgstr ""
+
+msgid "HasTagString::HasTagStringTag|Model"
+msgstr ""
+
+msgid "HasTagString::HasTagStringTag|Name"
+msgstr ""
+
+msgid "HasTagString::HasTagStringTag|Value"
+msgstr ""
+
msgid "Hello! You can make Freedom of Information requests within {{country_name}} at {{link_to_website}}"
msgstr "¡Hola! Puede hacer solicitudes de información en {{country_name}} usando {{link_to_website}}"
@@ -1811,9 +1835,6 @@ msgstr ""
msgid "Public body"
msgstr "Autoridad/Organismo Publico"
-msgid "Public body/translation"
-msgstr "Organismo publico/traduccion"
-
msgid "Public notes"
msgstr ""
@@ -1823,43 +1844,6 @@ msgstr ""
msgid "Public page not available"
msgstr ""
-msgid "PublicBody::Translation|Disclosure log"
-msgstr ""
-
-msgid "PublicBody::Translation|First letter"
-msgstr "Organismo Publico:: traduccion Primera solicitud"
-
-msgid "PublicBody::Translation|Locale"
-msgstr "PublicBody::Translation|Locale"
-
-msgid "PublicBody::Translation|Name"
-msgstr "Nombre"
-
-msgid "PublicBody::Translation|Notes"
-msgstr "Notas"
-
-msgid "PublicBody::Translation|Publication scheme"
-msgstr "Transparencia Activa"
-
-msgid "PublicBody::Translation|Request email"
-msgstr "Solicitar Correo"
-
-msgid "PublicBody::Translation|Short name"
-msgstr "Nombre Corto"
-
-msgid "PublicBody::Translation|Url name"
-msgstr ""
-"<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>"
-
msgid "PublicBody|Api key"
msgstr ""
@@ -2375,6 +2359,9 @@ msgstr "El motor de búsqueda no está accesible en estos momentos: no podemos m
msgid "The search index is currently offline, so we can't show the Freedom of Information requests this person has made."
msgstr "El motor de búsqueda no está accesible en estos momentos: no podemos mostrar las solicitudes de información que ha hecho esta persona"
+msgid "The {{site_name}} team."
+msgstr ""
+
msgid "Then you can cancel the alert."
msgstr "Entonces podrás cancelar tu alerta."
@@ -2916,6 +2903,12 @@ msgstr "Esperando que el organismo responda"
msgid "Was the response you got to your FOI request any good?"
msgstr "¿Fue la respuesta a tu solicitud satisfactoria?"
+msgid "We consider it is not a valid FOI request, and have therefore hidden it from other users."
+msgstr ""
+
+msgid "We consider it to be vexatious, and have therefore hidden it from other users."
+msgstr ""
+
msgid "We do not have a working request email address for this authority."
msgstr "No tenemos una dirección de correo válida para este organismo."
@@ -3144,6 +3137,9 @@ msgstr ""
"Sólo recibirás una respuesta a tu solicitud si continúas\n"
"con la aclaración."
+msgid "You will still be able to view it while logged in to the site. Please reply to this email if you would like to discuss this decision further."
+msgstr ""
+
msgid "You're in. <a href=\"#\" id=\"send-request\">Continue sending your request</a>"
msgstr ""
@@ -3217,6 +3213,12 @@ msgstr "Tu contraseña:"
msgid "Your photo will be shown in public <strong>on the Internet</strong>,\\n wherever you do something on {{site_name}}."
msgstr ""
+msgid "Your request '{{request}}' at {{url}} has been reviewed by moderators."
+msgstr ""
+
+msgid "Your request on {{site_name}} hidden"
+msgstr ""
+
msgid "Your request was called {{info_request}}. Letting everyone know whether you got the information will help us keep tabs on"
msgstr "Tu solicitud se llamaba {{info_request}}. Haznos saber si has recibido la información para ayudarnos a controlar a"
@@ -3251,6 +3253,9 @@ msgstr "Un saludo,"
msgid "Yours sincerely,"
msgstr "Un saludo,"
+msgid "Yours,"
+msgstr ""
+
msgid "[FOI #{{request}} email]"
msgstr "[Dirección de correo de la solicitud #{{request}}]"
diff --git a/locale/eu/app.po b/locale/eu/app.po
index c224c3001..7e90214d0 100644
--- a/locale/eu/app.po
+++ b/locale/eu/app.po
@@ -9,10 +9,10 @@ msgid ""
msgstr ""
"Project-Id-Version: alaveteli\n"
"Report-Msgid-Bugs-To: http://github.com/sebbacon/alaveteli/issues\n"
-"POT-Creation-Date: 2013-04-23 16:34+0100\n"
-"PO-Revision-Date: 2013-04-23 15:41+0000\n"
+"POT-Creation-Date: 2013-05-30 09:46+0100\n"
+"PO-Revision-Date: 2013-05-30 08:54+0000\n"
"Last-Translator: louisecrow <louise@mysociety.org>\n"
-"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language-Team: Basque (http://www.transifex.com/projects/p/alaveteli/language/eu/)\n"
"Language: eu\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -319,6 +319,15 @@ msgstr "Zeure buruaz:"
msgid "Act on what you've learnt"
msgstr "Erabil ezazu informazio hau"
+msgid "Acts as xapian/acts as xapian job"
+msgstr ""
+
+msgid "ActsAsXapian::ActsAsXapianJob|Action"
+msgstr ""
+
+msgid "ActsAsXapian::ActsAsXapianJob|Model"
+msgstr ""
+
msgid "Add an annotation"
msgstr "Gehitu iruzkina"
@@ -618,6 +627,9 @@ msgstr "Orain {{public_body_link}}-eko <strong>erantzunaren zain</strong> gaude,
msgid "Date:"
msgstr "Data:"
+msgid "Dear {{name}},"
+msgstr ""
+
msgid "Dear {{public_body_name}},"
msgstr "{{public_body_name}} agurgarria,"
@@ -887,6 +899,18 @@ msgstr "ZEHAZTU HEMEN ZURE KEXA"
msgid "Handled by post."
msgstr "Posta arruntaren bidez bidalita"
+msgid "Has tag string/has tag string tag"
+msgstr ""
+
+msgid "HasTagString::HasTagStringTag|Model"
+msgstr ""
+
+msgid "HasTagString::HasTagStringTag|Name"
+msgstr ""
+
+msgid "HasTagString::HasTagStringTag|Value"
+msgstr ""
+
msgid "Hello! You can make Freedom of Information requests within {{country_name}} at {{link_to_website}}"
msgstr "Kaixo! {{country_name}}-ean egin ahal dituzu informazio eskabideak {{link_to_website}} erabiliz."
@@ -1709,9 +1733,6 @@ msgstr ""
msgid "Public body"
msgstr ""
-msgid "Public body/translation"
-msgstr ""
-
msgid "Public notes"
msgstr ""
@@ -1721,33 +1742,6 @@ msgstr ""
msgid "Public page not available"
msgstr ""
-msgid "PublicBody::Translation|Disclosure log"
-msgstr ""
-
-msgid "PublicBody::Translation|First letter"
-msgstr ""
-
-msgid "PublicBody::Translation|Locale"
-msgstr ""
-
-msgid "PublicBody::Translation|Name"
-msgstr ""
-
-msgid "PublicBody::Translation|Notes"
-msgstr ""
-
-msgid "PublicBody::Translation|Publication scheme"
-msgstr ""
-
-msgid "PublicBody::Translation|Request email"
-msgstr ""
-
-msgid "PublicBody::Translation|Short name"
-msgstr ""
-
-msgid "PublicBody::Translation|Url name"
-msgstr ""
-
msgid "PublicBody|Api key"
msgstr ""
@@ -2247,6 +2241,9 @@ msgstr "Bilatzailea ez dago orain eskuragarri: ezin ditugu erakutsi erakunde hon
msgid "The search index is currently offline, so we can't show the Freedom of Information requests this person has made."
msgstr "Bilatzailea ez dago orain eskuragarri: ezin ditugu erakutsi pertsona honek egin dituen informazio eskabideak."
+msgid "The {{site_name}} team."
+msgstr ""
+
msgid "Then you can cancel the alert."
msgstr "Orduan ezeztatu ahal izango duzu zure alerta."
@@ -2761,6 +2758,12 @@ msgstr "Erakundearen erantzunaren zain"
msgid "Was the response you got to your FOI request any good?"
msgstr "Zure eskabideari emandako erantzuna behar bezalakoa izan da?"
+msgid "We consider it is not a valid FOI request, and have therefore hidden it from other users."
+msgstr ""
+
+msgid "We consider it to be vexatious, and have therefore hidden it from other users."
+msgstr ""
+
msgid "We do not have a working request email address for this authority."
msgstr "Ez daukagu erakunde honetako helbide baliagarririk."
@@ -2962,6 +2965,9 @@ msgstr ""
msgid "You will only get an answer to your request if you follow up\\nwith the clarification."
msgstr "Azalpenarekin jarraituz gero zure eskabidearen erantzun bakarra jasoko duzu."
+msgid "You will still be able to view it while logged in to the site. Please reply to this email if you would like to discuss this decision further."
+msgstr ""
+
msgid "You're in. <a href=\"#\" id=\"send-request\">Continue sending your request</a>"
msgstr ""
@@ -3033,6 +3039,12 @@ msgstr "Zure pasahitza:"
msgid "Your photo will be shown in public <strong>on the Internet</strong>,\\n wherever you do something on {{site_name}}."
msgstr ""
+msgid "Your request '{{request}}' at {{url}} has been reviewed by moderators."
+msgstr ""
+
+msgid "Your request on {{site_name}} hidden"
+msgstr ""
+
msgid "Your request was called {{info_request}}. Letting everyone know whether you got the information will help us keep tabs on"
msgstr "Zure eskabidearen izenburua {{info_request}} zen. Jakinarazi informazioa jaso duzun, kontrolatzen laguntzearren."
@@ -3067,6 +3079,9 @@ msgstr "Adeitasunez,"
msgid "Yours sincerely,"
msgstr "Agur bero bat,"
+msgid "Yours,"
+msgstr ""
+
msgid "[FOI #{{request}} email]"
msgstr ""
diff --git a/locale/fr/app.po b/locale/fr/app.po
index 149e59238..db5a128ff 100644
--- a/locale/fr/app.po
+++ b/locale/fr/app.po
@@ -5,21 +5,30 @@
# Translators:
# skenaja <alex@alexskene.com>, 2011
# andreas.pavlou <andreas@access-info.org>, 2013
+# andreas.pavlou <andreas@access-info.org>, 2013
+# Bbear <borisjf@post.harvard.edu>, 2011
# sim51 <contact@bsimard.com>, 2013
# Bbear <borisjf@post.harvard.edu>, 2011
+# radproject <radhouanef@gmail.com>, 2013
+# radproject <radhouanef@gmail.com>, 2013
# rrobert <rrobertpolson@gmail.com>, 2013
+# rrobert <rrobertpolson@gmail.com>, 2013
+# sebbacon <seb.bacon@gmail.com>, 2012
# sebbacon <seb.bacon@gmail.com>, 2012
+# sim51 <contact@bsimard.com>, 2013
# skenaja <alex@alexskene.com>, 2011
# teymour <tanguim@gmail.com>, 2011
+# teymour <tanguim@gmail.com>, 2011
+# vickyanderica <victoria@access-info.org>, 2011
# vickyanderica <victoria@access-info.org>, 2011
msgid ""
msgstr ""
"Project-Id-Version: alaveteli\n"
"Report-Msgid-Bugs-To: http://github.com/sebbacon/alaveteli/issues\n"
-"POT-Creation-Date: 2013-04-23 16:34+0100\n"
-"PO-Revision-Date: 2013-04-23 15:39+0000\n"
+"POT-Creation-Date: 2013-05-30 09:46+0100\n"
+"PO-Revision-Date: 2013-05-30 09:00+0000\n"
"Last-Translator: louisecrow <louise@mysociety.org>\n"
-"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language-Team: French (http://www.transifex.com/projects/p/alaveteli/language/fr/)\n"
"Language: fr\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -27,22 +36,22 @@ msgstr ""
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
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 ""
+msgstr "Ceci apparaîtra sur votre profil {{site_name}}, pour permettre \\n aux autres de s'impliquer dans ce que vous faites."
msgid " (<strong>no ranty</strong> politics, read our <a href=\"{{url}}\">moderation policy</a>)"
msgstr "(<strong>aucune garantie</strong> politique, lire notre <a href=\"{{url}}\">politique de modération</a>)"
msgid " (<strong>patience</strong>, especially for large files, it may take a while!)"
-msgstr "(<strong>patience</strong>, surtout pour les fichiers volumineux, cela peut prendre un certains temps !)"
+msgstr "(<strong>patience</strong>, surtout pour les fichiers volumineux, ça peut prendre un moment !)"
msgid " (you)"
msgstr "(vous)"
msgid " - view and make Freedom of Information requests"
-msgstr ""
+msgstr "-Voir et faire des demandes d'accès a l'information "
msgid " - wall"
-msgstr ""
+msgstr "-mur"
msgid " <strong>Note:</strong>\\n We will send you an email. Follow the instructions in it to change\\n your password."
msgstr ""
@@ -50,16 +59,16 @@ msgstr ""
" Nous allons vous envoyer un courrier électronique. Suivez les instructions de ce courrier pour changer votre mot de passe."
msgid " <strong>Privacy note:</strong> Your email address will be given to"
-msgstr " <strong>Protection de vos données :</strong> Votre adresse e-mail sera communiquée à"
+msgstr " <strong>Note de confidentialité :</strong> Votre adresse e-mail sera communiquée à"
msgid " <strong>Summarise</strong> the content of any information returned. "
-msgstr " <strong>Résumez</strong>le contenu des informations transmises. "
+msgstr " <strong>Résumez</strong>le contenu de toute information transmise. "
msgid " Advise on how to <strong>best clarify</strong> the request."
msgstr "Indiquez comment rendre la demande <strong>plus claire</strong>."
msgid " Ideas on what <strong>other documents to request</strong> which the authority may hold. "
-msgstr "Idées d'<strong>autres documents à demander</strong> que cette administration pourrait détenir."
+msgstr "Idées sur <strong>d'autres documents à demander</strong> que cette administration pourrait détenir."
msgid " If you know the address to use, then please <a href=\"{{url}}\">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 ""
@@ -67,7 +76,7 @@ msgstr ""
" Vous êtes susceptible de trouver l'adresse sur leur site Internet ou en la leur demandant par téléphone."
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 ""
+msgstr "Intégrez des liens pertinants comme votre blog , page twitter \\n . Les liens sont cliquables . \\n e.g"
msgid " Link to the information requested, if it is <strong>already available</strong> on the Internet. "
msgstr "Lien vers les informations demandées, si elle sont <strong>déjà disponibles</strong> sur Internet."
@@ -76,13 +85,13 @@ msgid " Offer better ways of <strong>wording the request</strong> to get the inf
msgstr " Proposez d'autres <strong>formulations</strong> pour accéder à ces informations. "
msgid " Say how you've <strong>used the information</strong>, with links if possible."
-msgstr " Dites-nous comment vous avez <strong>utilisé ces informations</strong>, à l'aide de liens si possible."
+msgstr " Dites-nous comment vous avez <strong>utilisé ces informations</strong>, à l'aide des liens si possible."
msgid " Suggest <strong>where else</strong> the requester might find the information. "
msgstr " Suggérez <strong>un autre endroit</strong> où l'utilisateur pourrait trouver ces informations. "
msgid " What are you investigating using Freedom of Information? "
-msgstr ""
+msgstr "Sur quoi vous enquêtez en utilisant la liberté d'accès a l'information"
msgid " You are already being emailed updates about the request."
msgstr "Un courriel vous à déjà été envoyé au sujet de cette demande."
@@ -91,34 +100,34 @@ msgid " You will also be emailed updates about the request."
msgstr "Il vous sera également envoyé un courriel au sujet de cette demande."
msgid " made by "
-msgstr "Réalisé par"
+msgstr "faite par"
msgid " or "
msgstr "ou"
msgid " when you send this message."
-msgstr "quand vous envoyé ce message."
+msgstr "quand vous envoyez ce message."
msgid "\"Hello! We have an <a href=\\\"/help/alaveteli?country_name=#{CGI.escape(current_country)}\\\">important message</a> for visitors outside {{country_name}}\""
-msgstr ""
+msgstr "\"Bonjour! Nous avons <a href=\\\"/help/alaveteli?country_name=#{CGI.escape(current_country)}\\\">un message important </a> pour les visiteurs à l'extérieur de {{country_name}}\""
msgid "'Crime statistics by ward level for Wales'"
-msgstr ""
+msgstr "'Statistiques de la criminalité par niveau de paroisse au Pays de Galles'"
msgid "'Pollution levels over time for the River Tyne'"
msgstr "« Évolution dans le temps des niveaux de pollution de la rivière Tyne »"
msgid "'{{link_to_authority}}', a public authority"
-msgstr "'{{lien_vers_administration}}', une administration public"
+msgstr "'{{lien_vers_administration}}', une administration publique"
msgid "'{{link_to_request}}', a request"
-msgstr "'{{lien_vers_demande}}', une demande"
+msgstr "'{{link_to_request}}', une demande"
msgid "'{{link_to_user}}', a person"
-msgstr "{{lien_vers_utilisateur}}', une persone"
+msgstr "{{lien_vers_utilisateur}}', une personne"
msgid "*unknown*"
-msgstr ""
+msgstr "*unknown*"
msgid ",\\n\\n\\n\\nYours,\\n\\n{{user_name}}"
msgstr ",\\n\\n\\n\\nCordialement,\\n\\n{{user_name}}"
@@ -133,7 +142,7 @@ msgid "2. Ask for Information"
msgstr "2. Posez une question"
msgid "3. Now check your request"
-msgstr "3. Maintenant, vérifier vos demandes"
+msgstr "3. Maintenant, vérifier votre demande"
msgid "<a href=\"{{browse_url}}\">Browse all</a> or <a href=\"{{add_url}}\">ask us to add one</a>."
msgstr "<a href=\"{{browse_url}}\">Voir tout</a> ou <a href=\"{{add_url}}\"> demandez nous d'ajouter une</a>."
@@ -145,58 +154,58 @@ msgid "<a href=\"{{url}}\">Sign in</a> to change password, subscriptions and mor
msgstr "<a href=\"{{url}}\">Connectez-vous</a> pour changer le mot de passe, les abonnements et plus encore ({{user_name}} only)"
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 "<p>Tout est fait ! Merci beaucoup pour votre aide.</p><p> Il y a <a href=\"{{helpus_url}}\"> encre beaucoup de choses que vous pouvez faire</a> pour nous aider {{site_name}}.</p>"
+msgstr "<p>Tout est fait ! Merci beaucoup pour votre aide.</p><p> Il y a <a href=\"{{helpus_url}}\"> autres choses que vous pouvez faire</a> pour nous aider {{site_name}}.</p>"
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 ""
+msgstr "<p>Merci! Voici quelques idées sur ce qu'il faut faire ensuite :</p>\\n <ul>\\n <li>Pour envoyer votre demande à une autre autorité, d'abord copier le texte de votre demande ci-dessous, puis <a href=\"{{find_authority_url}}\">trouver l'autre autorité</a>.</li>\\n <li>Si vous souhaitez contester l'affirmation de l'autorité qu'ils ne détiennent pas l'information, voici \\n <a href=\"{{complain_url}}\">comment se plaindre </a>.\\n </li>\\n <li>Nous avons des <a href=\"{{other_means_url}}\">suggestions </a>\\n sur d'autres moyens pour répondre à votre question .\\n </li>\\n </ul>"
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 "<p> Merci ! J'espère que vous n'avez pas à attendre plus longtemps. </ P> Selon la loi, vous devriez recevoir une réponse rapidement, et normalement avant la fin du <strong> {{date_response_required_by}} </ strong>. </ p>"
+msgstr "<p> Merci ! J'espère que vous n'aurez pas à attendre plus longtemps. </ P> Selon la loi, vous devriez recevoir une réponse rapidement, et normalement avant la fin du <strong> {{date_response_required_by}} </ strong>. </ p>"
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 ""
+msgstr "<p>Merci! Espérons que votre attente n'est pas trop longue.</p> <p>Selon la loi, vous devriez obtenir une réponse rapidement, et normalement avant la fin de <strong>\\n{{date_response_required_by}}</strong>.</p>"
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>Merci ! Nous espérons que votre attente ne sera pas trop longue. </p><p> Vous devriez obtenir une réponse dans les {{late_number_of_days}} jours, ou bien vous serez prévenu si cela prendra plus de temps (href=\"{{review_url}}\"> <a détails </ a>). </ p>"
+msgstr "<p>Merci ! Nous espérons que votre attente ne sera pas trop longue. </p><p> Vous devrez obtenir une réponse dans les {{late_number_of_days}} jours, ou bien vous serez prévenus si cela prendra plus de temps (href=\"{{review_url}}\"> <a détails </ a>). </ p>"
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 ""
+msgstr "<p>Merci ! Votre demande est en retard de plus de {{very_late_number_of_days}} jours ouvrables. La plupart des demandes doivent être traitées dans les {{late_number_of_days}} jours ouvrables. Pour vous plaindre, veuillez vous reporter ci-dessous.</p>"
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 ""
+msgstr "<p>Merci pour modifier le texte de vous sur votre profil .</p>\\n <p><strong>Ensuite...</strong> vous pouvez uploader une photo de profil.</p>"
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 ""
+msgstr "<p>Merci pour mettre à jour votre photo de profil.</p>\\n<p><strong>Ensuite...</strong> Vous pouvez mettre un texte sur vous et votre recherche sur votre profil.</p>"
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 ""
+msgstr "<p>Nous vous conseillons de modifier votre demande et de supprimer l'adresse e-mail.\\n Si vous la laissez, l'adresse e-mail sera envoyée à l'autorité, mais ne sera pas affichée sur le site.</p>"
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 ""
+msgstr "<p>Nous sommes heureux que vous avez obtenu toutes les informations que vous vouliez . Si vous écrivez ou faites usage de l'information, veuillez revenir et ajouter une annotation en dessous décrivant ce que vous avez fait.</p><p>si vous avez trouvé {{site_name}} utile, <a href=\"{{donation_url}}\">Faites une donation</a> a l'organisation qui le gère.</p>"
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 ""
+msgstr "<p>Nous sommes heureux que vous avez partie de l'information que vous vouliez. si vous avez trouvé {{site_name}} utile, <a href=\"{{donation_url}}\">Faites une donation</a> a l'organisation qui le gère.</p><p>Si vous voulez essayer et obtenir le reste de l'information, voici ce qu'il faut faire maintenant.</p>"
msgid "<p>You do not need to include your email in the request in order to get a reply (<a href=\"{{url}}\">details</a>).</p>"
msgstr "<p>Vous n'avez pas besoin d'inclure votre adresse mail à votre demande pour obtenir une réponse(<a href=\"{{url}}\">details</a>).</p>"
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=\"{{url}}\">details</a>).</p>"
-msgstr ""
+msgstr "<p> Vous n'avez pas besoin d'inclure votre email dans la demande afin d'obtenir une réponse, vu que nous allons le demander sur l'écran suivant (<a href=\"{{url}}\">details</a>).</p>"
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 ""
+msgstr "<p>Vous avez demandé un certain <strong>code postal</strong>. Sauf s'il est directement lié a l'objet de vôtre demande , veuillez supprimer toute adresse car elle va <strong>apparaître publiquement sur ​​Internet</strong>.</p>"
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 ""
+msgstr "<p>Votre demande {{law_used_full}} a été <strong>envoyée</strong>!</p>\\n <p><strong>On va vous envoyer un email </strong>dès qu'il ya une réponse ou apres {{late_number_of_days}} jours ouvrables si l'autorité n'a toujours pas \\n répondu .</p>\\n <p>Si vous écrivez à propos de cette demande (par exemple dans un forum ou un blog) veuillez mettre un lien vers cette page et ajoutez une \\n remarque en dessous pour partager avec les autres citoyens. </p>"
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 ""
+msgstr "<p>{{site_name}} est actuellement en maintenance. Vous pouvez uniquement afficher les demandes existantes. Vous ne pouvez pas faire de nouveaux, ajouter des suivis ou des annotations, ou par ailleurs changer la base de données .</p> <p>{{read_only}}</p>"
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>"
-msgstr ""
+msgstr "<small> Si vous utiliser le courrier électronique basé sur le Web ou des filtres de \"courrier indésirable\", vérifiez également vos dossiers de courrier spam . Parfois, nos messages sont marqués de cette façon</small> /n</p>"
msgid "<strong> Can I request information about myself?</strong>\\n\t\t\t<a href=\"{{url}}\">No! (Click here for details)</a>"
-msgstr ""
+msgstr "<strong>Puis -je demander des informations sur moi ?</strong>\\n\t\t\t<a href=\"{{url}}\">Non! (cliquer ici pour plus de détails)</a>"
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>commented_by:tony_bowden</code></strong> Pour chercher des commentaires faits par Tony Bowden, écrivez le nom comme dans l'URL"
@@ -208,19 +217,19 @@ msgid "<strong><code>request:</code></strong> to restrict to a specific request,
msgstr "<strong><code>request:</code></strong> Pour vous limiter à une sollicitude concrète, tapez le titre comme dans l'URL."
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>requested_by:julian_todd</code></strong> Pour chercher les sollicitudes faites par Julian Todd, écrivez le nom comme dans l'URL. "
+msgstr "<strong><code>requested_by:julian_todd</code></strong> Pour chercher les demandes faites par Julian Todd, écrivez le nom comme dans l'URL. "
msgid "<strong><code>requested_from:home_office</code></strong> to search requests from the Home Office, typing the name as in the URL."
-msgstr "<strong><code>requested_from:home_office</code></strong> Pour chercher les sollicitudes du Home Office, écrivez le nom comme dans l'URL. "
+msgstr "<strong><code>requested_from:home_office</code></strong> Pour chercher les demandes du Home Office, écrivez le nom comme dans l'URL. "
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 ""
+msgstr "<strong><code>statut :</code></strong>pour sélectionner en fonction du statut ou du statut historique de la demande, voir la <a href=\"{{statuses_url}}\">table des status</a> below."
msgid "<strong><code>tag:charity</code></strong> to find all public authorities 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>tag:charity</code></strong> pour trouvez tous les institutions publiques ou les sollicitudes avec la même étiquette. Vous pouvez inclure plusieurs étiquettes,\\n ou plusieurs étiquettes, ex. <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>tag:charity</code></strong> pour trouvez tous les institutions publiques ou les sollicitudes avec la même étiquette. Vous pouvez inclure plusieurs étiquettes,\\n ou plusieurs étiquettes, ex. <code>tag:openlylocal AND tag:financial_transaction:335633</code>. A noter que par défaut n'importe quel tag \\n peut etre présent , vous devez mettre <code>AND</code>explicitement si vous voulez que tout les résultats s'affichent ."
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 ""
+msgstr "<strong> <code> divers: </ code> </ strong> pour sélectionner le type de chose à rechercher, consulter le <a href=\"{{varieties_url}}\">tableau des divers</a> below."
msgid "<strong>Advice</strong> on how to get a response that will satisfy the requester. </li>"
msgstr "<strong>Conseils</strong> sur la façon d'obtenir une réponse qui satisfera le demandeur. </li>"
@@ -229,34 +238,34 @@ msgid "<strong>All the information</strong> has been sent"
msgstr "<strong>Toutes les informations</strong> ont été envoyées"
msgid "<strong>Anything else</strong>, such as clarifying, prompting, thanking"
-msgstr ""
+msgstr "<strong>D'autres choses</strong>, comme clarifier, inciter, et remercier. "
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."
-msgstr ""
+msgstr "<strong>Caveat emptor!</strong> Pour utiliser ces données d'une façon honorable, vous devrez \\n avoir une bonne connaissance interne du comportement de l'utilisateur sur {{site_name}}. Comment , \\n pourquoi et par qui les demandes sont categorisées .Vous aurez également besoin de comprendre la loi accès à l'information, et les \\n manières dont les autorités fonctionnet . De plus, vous aurez besoin d'être un statisticien élite . Veuillez \\n<a href=\"{{contact_path}}\">Nous contacter </a> avec vos questions."
msgid "<strong>Clarification</strong> has been requested"
msgstr "<strong>Des précisions</strong> ont été demandées"
msgid "<strong>No response</strong> has been received\\n <small>(maybe there's just an acknowledgement)</small>"
-msgstr ""
+msgstr "<strong>Aucune réponse</strong> n'a été reçue \\n <small>(peut-être il ya juste une reconnaissance)</small>"
msgid "<strong>Note:</strong> Because we're testing, requests are being sent to {{email}} rather than to the actual authority."
-msgstr ""
+msgstr "<strong>Note:</strong> Because we're testing, requests are being sent to {{email}} rather than to the actual authority."
msgid "<strong>Note:</strong> You're sending a message to yourself, presumably\\n to try out how it works."
-msgstr ""
+msgstr "<strong>Remarque:</strong> Vous envoyez un message à vous-même, sans doute \\n pour essayer de voir comment cela fonctionne."
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 ""
+msgstr "<strong>Remarque :</strong> Nous allons vous envoyer un courrier électronique à avotre nouvelle adresse . Suivez les instructions de ce courrier pour confirmer le changement de votre mail."
msgid "<strong>Privacy note:</strong> If you want to request private information about\\n yourself then <a href=\"{{url}}\">click here</a>."
-msgstr ""
+msgstr "<strong>Note de confidentialité:</strong> Si vous voulez demander des informations privées sur \\n vous-même alors <a href=\"{{url}}\">cliquez ici</a>."
msgid "<strong>Privacy note:</strong> Your photo will be shown in public on the Internet,\\n wherever you do something on {{site_name}}."
-msgstr ""
+msgstr "<strong>Note de confidentialité :</strong> votre photo va apparaitre publiquement sur internet ,\\n a chaque fois que vous changez quelque chose sur {{site_name}}."
msgid "<strong>Privacy warning:</strong> Your message, and any response\\n to it, will be displayed publicly on this website."
-msgstr ""
+msgstr "<strong>Avertissement de confidentialité:</strong> Votre message, et toute réponse \\n sera affichée publiquement sur ​​ce site."
msgid "<strong>Some of the information</strong> has been sent "
msgstr "<strong>Certaines informations</strong> ont été envoyées "
@@ -268,19 +277,19 @@ msgid "<strong>did not have</strong> the information requested."
msgstr "<strong>n'avait pas </strong> les informations demandées."
msgid "A <a href=\"{{request_url}}\">follow up</a> to <em>{{request_title}}</em> was sent to {{public_body_name}} by {{info_request_user}} on {{date}}."
-msgstr ""
+msgstr "Un <a href=\"{{request_url}}\">suivi</a> à <em>{{request_title}}</em> a été envoyé à {{public_body_name}} par {{info_request_user}} le {{date}}."
msgid "A <a href=\"{{request_url}}\">response</a> to <em>{{request_title}}</em> was sent by {{public_body_name}} to {{info_request_user}} on {{date}}. The request status is: {{request_status}}"
-msgstr ""
+msgstr "Une <a href=\"{{request_url}}\">réponse</a> à <em>{{request_title}}</em>a été envoyée par {{public_body_name}} à {{info_request_user}} le {{date}}. L'état de la demande est: {{request_status}}"
msgid "A <strong>summary</strong> of the response if you have received it by post. "
msgstr "Un <strong>résumé</strong> si vous l'avez reçue par la poste."
msgid "A Freedom of Information request"
-msgstr "Une liberté d'accès à l'information"
+msgstr "Une demande d'accès à l'information"
msgid "A new request, <em><a href=\"{{request_url}}\">{{request_title}}</a></em>, was sent to {{public_body_name}} by {{info_request_user}} on {{date}}."
-msgstr ""
+msgstr "Une nouvelle demande , <em><a href=\"{{request_url}}\">{{request_title}}</a></em>, a été envoyée à {{public_body_name}} par {{info_request_user}} le {{date}}."
msgid "A public authority"
msgstr "Une autorité administrative"
@@ -289,25 +298,34 @@ msgid "A response will be sent <strong>by post</strong>"
msgstr "Une réponse vous sera <strong>envoyée par la poste</strong>"
msgid "A strange reponse, required attention by the {{site_name}} team"
-msgstr "Une réponse étrange réclame de l'attention {{site_name}} à l'équipe"
+msgstr "Une réponse étrange réclame de l'attention de l'équipe {{site_name}} "
msgid "A vexatious request"
-msgstr ""
+msgstr "Une demande vexatoire"
msgid "A {{site_name}} user"
-msgstr "Un {{site_name}} utilisateur"
+msgstr "Un utilisateur {{site_name}} "
msgid "About you:"
-msgstr "A propos de vous&nbsp;:"
+msgstr "A propos de vous:"
msgid "Act on what you've learnt"
msgstr "Agissez en fonction de ce que vous avez appris."
+msgid "Acts as xapian/acts as xapian job"
+msgstr ""
+
+msgid "ActsAsXapian::ActsAsXapianJob|Action"
+msgstr ""
+
+msgid "ActsAsXapian::ActsAsXapianJob|Model"
+msgstr ""
+
msgid "Add an annotation"
msgstr "Ajouter une remarque"
msgid "Add an annotation to your request with choice quotes, or\\n a <strong>summary of the response</strong>."
-msgstr ""
+msgstr "Ajouter une annotation à votre demande avec des citations de choix, ou \\n un <strong> résumé de réponse</strong>."
msgid "Added on {{date}}"
msgstr "Ajouté le {{date}}"
@@ -328,31 +346,31 @@ msgid "Advise on whether the <strong>refusal is legal</strong>, and how to compl
msgstr "Donner des conseils <strong>si le refus est légal</strong>, et comment se plaindre si il ne l'est pas."
msgid "Air, water, soil, land, flora and fauna (including how these effect\\n human beings)"
-msgstr ""
+msgstr "Air, l'eau, les sols, la flore et la faune (y compris la manière dont ils influent \\n les êtres humains)"
msgid "All of the information requested has been received"
-msgstr "Tous les renseignements demandés ont été reçus"
+msgstr "Tout les renseignements demandés ont été reçus"
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 ""
+msgstr "Toutes les options ci-dessous peuvent utiliser <strong>Etat</strong> ou <strong>dernier_etat</strong>avant les deux points . par exemple, <strong>Etat: non_tenu</strong>correspondra aux demandes qui ont <em>déjà</em> été marquées comme non tenues; <strong>dernier_etat:non_tenu</strong> correspondra uniquement aux demandes sont ont<em>actuellement</em> marquées comme non tenues."
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 ""
+msgstr "Toutes les options ci-dessous peuvent utiliser <strong>Etat</strong> ou <strong>dernier_etat</strong>avant les deux points . par exemple, <strong>Etat: non_tenu</strong>correspondra aux demandes qui ont <em>déjà</em> été marquées comme non tenues; <strong>dernier_etat:non_tenu</strong> correspondra uniquement aux demandes sont ont<em>actuellement</em> marquées comme non tenues."
msgid "Also called {{other_name}}."
msgstr "Également appelé {{other_name}}."
msgid "Also send me alerts by email"
-msgstr ""
+msgstr "Envoyer moi aussi les alertes par mail "
msgid "Alter your subscription"
msgstr "Modifier votre abonnement."
msgid "Although all responses are automatically published, we depend on\\nyou, the original requester, to evaluate them."
-msgstr ""
+msgstr "Bien que toutes les réponses sont automatiquement publiés, nous dépendons \\n de vous, le demandeur d'origine, pour les évaluer."
msgid "An <a href=\"{{request_url}}\">annotation</a> to <em>{{request_title}}</em> was made by {{event_comment_user}} on {{date}}"
-msgstr ""
+msgstr "Une <a href=\"{{request_url}}\">remarque</a> sur <em>{{request_title}}</em>a été faite {{event_comment_user}} le {{date}}"
msgid "An <strong>error message</strong> has been received"
msgstr "Un <strong>message d'erreur</strong> a été reçu."
@@ -361,7 +379,7 @@ msgid "An Environmental Information Regulations request"
msgstr "Une demande sur les règlements concernant l'information sur l'environnement"
msgid "An anonymous user"
-msgstr ""
+msgstr "Un utilisateur anonyme"
msgid "Annotation added to request"
msgstr "Remarque ajoutée à la demande"
@@ -370,31 +388,31 @@ msgid "Annotations"
msgstr "Remarque"
msgid "Annotations are so anyone, including you, can help the requester with their request. For example:"
-msgstr ""
+msgstr "Les annotations sont là afin que toute personne, y compris vous, puisse aider le demandeur Avec leur demande. Par exemple:"
msgid "Annotations will be posted publicly here, and are\\n <strong>not</strong> sent to {{public_body_name}}."
-msgstr ""
+msgstr "Les remarques seront postées ici et seront <strong>pas</strong> envoyées au {{public_body_name}}."
msgid "Anonymous user"
-msgstr ""
+msgstr "Utilisateur anonyme"
msgid "Anyone:"
msgstr "Personne:"
msgid "Applies to"
-msgstr ""
+msgstr "S'applique à"
msgid "Are we missing a public authority?"
msgstr "Vous ne trouvez pas celui que vous voulez ?"
msgid "Are you the owner of any commercial copyright on this page?"
-msgstr ""
+msgstr "Êtes-vous le propriétaire d'un droit d'auteur commercial sur cette page?"
msgid "Ask for <strong>specific</strong> documents or information, this site is not suitable for general enquiries."
msgstr "Demandez des documents ou des <strong>informations spécifiques</strong>, ce site ne convient pas pour des renseignements d'ordre général."
msgid "At the bottom of this page, write a reply to them trying to persuade them to scan it in\\n (<a href=\"{{url}}\">more details</a>)."
-msgstr ""
+msgstr "Au bas de cette page, écrire une réponse à leur essayant de les persuader de le numériser (<a href=\"{{url}}\">plus de détails</a>)."
msgid "Attachment (optional):"
msgstr "Pièce jointe (optionnel):"
@@ -427,13 +445,13 @@ msgid "By law, under all circumstances, {{public_body_link}} should have respond
msgstr "Selon la loi, en toutes circonstances, {{public_body_link}} aurait répondu en maintenant"
msgid "By law, {{public_body_link}} should normally have responded <strong>promptly</strong> and"
-msgstr ""
+msgstr "Selon la loi, {{public_body_link}} devrait normalement avoir répondu <strong>rapidement</strong> et"
msgid "Calculated home page"
-msgstr ""
+msgstr "Page d'accueil calculée"
msgid "Can't find the one you want?"
-msgstr ""
+msgstr "Vous ne trouvez pas celui que vous voulez?"
msgid "Cancel a {{site_name}} alert"
msgstr "Annuler une {{site_name}} alerte"
@@ -445,22 +463,22 @@ msgid "Cancel, return to your profile page"
msgstr "Annuler, retourner à votre page de profil"
msgid "Censor rule"
-msgstr ""
+msgstr "Règle de censure"
msgid "CensorRule|Last edit comment"
-msgstr ""
+msgstr "CensorRule|Last edit comment"
msgid "CensorRule|Last edit editor"
-msgstr ""
+msgstr "CensorRule|Last edit editor"
msgid "CensorRule|Regexp"
-msgstr ""
+msgstr "CensorRule|Regexp"
msgid "CensorRule|Replacement"
-msgstr ""
+msgstr "CensorRule|Replacement"
msgid "CensorRule|Text"
-msgstr ""
+msgstr "CensorRule|Text"
msgid "Change email on {{site_name}}"
msgstr "Changer le courriel sur {{site_name}}"
@@ -505,25 +523,25 @@ msgid "Clarification"
msgstr "Précisions"
msgid "Clarify your FOI request - "
-msgstr ""
+msgstr "Clarifier votre demande -"
msgid "Classify an FOI response from "
msgstr "Classer comme FOI une réponse venant de"
msgid "Clear photo"
-msgstr ""
+msgstr "Supprimer la photo"
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."
-msgstr ""
+msgstr "Cliquez sur le lien ci-dessous pour envoyer un message à {{public_body_name}} en leur demandant de répondre à votre demande. Vous pourriez vous demander une révision \\n interne, leur demandant de savoir pourquoi la réponse à la demande a été si lente."
msgid "Click on the link below to send a message to {{public_body}} reminding them to reply to your request."
msgstr "Cliquez sur le lien ci-dessous pour envoyer un message à {{public_body}} afin de leur rappeler de répondre à votre demande."
msgid "Close"
-msgstr ""
+msgstr "Fermer"
msgid "Comment"
-msgstr ""
+msgstr "Commentaire"
msgid "Comment|Body"
msgstr "Commentaire|Texte"
@@ -538,22 +556,22 @@ msgid "Comment|Visible"
msgstr "Commentaire|Visible"
msgid "Confirm you want to follow all successful FOI requests"
-msgstr ""
+msgstr "Confirmer que vous voulez suivre toutes les demandes d'accès a l'information réussies"
msgid "Confirm you want to follow new requests"
-msgstr ""
+msgstr "Confirmez que vous souhaitez suivre les nouvelles demandes"
msgid "Confirm you want to follow new requests or responses matching your search"
-msgstr ""
+msgstr "Confirmez que vous souhaitez suivre les nouvelles demandes ou les réponses correspondant à votre recherche"
msgid "Confirm you want to follow requests by '{{user_name}}'"
-msgstr ""
+msgstr "Confirmez que vous voulez suivre les demandes de '{{user_name}}'"
msgid "Confirm you want to follow requests to '{{public_body_name}}'"
-msgstr ""
+msgstr "Confirmez que vous voulez suivre les demandes à '{{public_body_name}}'"
msgid "Confirm you want to follow the request '{{request_title}}'"
-msgstr ""
+msgstr "Confirmez que vous voulez suivre la demande '{{request_title}}'"
msgid "Confirm your FOI request to "
msgstr "Confirmer votre demande FOI pour"
@@ -571,13 +589,13 @@ msgid "Confirm your new email address on {{site_name}}"
msgstr "Confirmer votre nouvelle adresse sur {{site_name}}"
msgid "Considered by administrators as not an FOI request and hidden from site."
-msgstr ""
+msgstr "N'est pas considérée par les administrateurs comme une demande d'accès à l'information et supprimée."
msgid "Considered by administrators as vexatious and hidden from site."
-msgstr ""
+msgstr "Considérée par les administrateurs comme vexatoire et cachée sur le site."
msgid "Contact {{recipient}}"
-msgstr ""
+msgstr "Contacter {{recipient}}"
msgid "Contact {{site_name}}"
msgstr "Contact {{site_name}}"
@@ -592,7 +610,7 @@ msgid "Crop your profile photo"
msgstr "Recadrer votre photo de profil"
msgid "Cultural sites and built structures (as they may be affected by the\\n environmental factors listed above)"
-msgstr ""
+msgstr "Les sites culturels et les batiments (ils peuvent être affectés par \\n les facteurs environnementaux listés ci dessus) "
msgid "Currently <strong>waiting for a response</strong> from {{public_body_link}}, they must respond promptly and"
msgstr "Acutuellement <strong>en attente d'une réponse</strong> du {{public_body_link}}, Ils doivent répondre rapidement et"
@@ -600,11 +618,14 @@ msgstr "Acutuellement <strong>en attente d'une réponse</strong> du {{public_bod
msgid "Date:"
msgstr "Date:"
+msgid "Dear {{name}},"
+msgstr ""
+
msgid "Dear {{public_body_name}},"
msgstr "Cher {{public_body_name}},"
msgid "Default locale"
-msgstr ""
+msgstr "Langue par défaut"
msgid "Delayed response to your FOI request - "
msgstr "Réponse à votre demande FOI en retard- "
@@ -616,7 +637,7 @@ msgid "Delivery error"
msgstr "Erreur lors de l'envoi"
msgid "Destroy {{name}}"
-msgstr ""
+msgstr "Détruire {{name}}"
msgid "Details of request '"
msgstr "Détails de la demande"
@@ -628,10 +649,10 @@ msgid "Disclaimer: This message and any reply that you make will be published on
msgstr "Attention : Ce message et les éventuelles réponses que vous écrivez seront publiées sur l'internet. Notre politique en matière de confidentialité et de droits d'auteur :"
msgid "Disclosure log"
-msgstr ""
+msgstr "Journal d'information"
msgid "Disclosure log URL"
-msgstr ""
+msgstr "adresse du journal d'information"
msgid "Don't want to address your message to {{person_or_body}}? You can also write to:"
msgstr "Vous ne voulez pas envoyer votre message à {{person_or_body}}? Vous pouvez aussi écrire à : "
@@ -640,7 +661,7 @@ msgid "Done"
msgstr "Fait"
msgid "Done &gt;&gt;"
-msgstr ""
+msgstr "Fait &gt;&gt;"
msgid "Download a zip file of all correspondence"
msgstr "Télécharger un fichier zip de toute la correspondance"
@@ -649,13 +670,13 @@ msgid "Download original attachment"
msgstr "Télécharger la pièce jointe originale"
msgid "EIR"
-msgstr ""
+msgstr "EIR"
msgid "Edit"
-msgstr ""
+msgstr "Modifier"
msgid "Edit and add <strong>more details</strong> to the message above,\\n explaining why you are dissatisfied with their response."
-msgstr ""
+msgstr "Modifier et ajouter <strong> plus de détails </strong> au message ci-dessus, \\n expliquant pourquoi vous n'êtes pas satisfait de leur réponse."
msgid "Edit text about you"
msgstr "Modifier le texte sur vous"
@@ -679,7 +700,7 @@ msgid "Enter words that you want to find separated by spaces, e.g. <strong>climb
msgstr "Entrez les mots que vous voulez trouver séparés avec des espaces. ex. : <strong>voie rapide</strong>"
msgid "Enter your response below. You may attach one file (use email, or\\n <a href=\"{{url}}\">contact us</a> if you need more)."
-msgstr ""
+msgstr "Entrez votre réponse ci-dessous. Vous pouvez joindre un fichier (utiliser le courrier électronique, ou \\n <a href=\"{{url}}\">contactez nous</a>)."
msgid "Environmental Information Regulations"
msgstr "Règlements nationaux en matière d'information sur l'environnement"
@@ -697,22 +718,22 @@ msgid "Event history details"
msgstr "Détails de l'historique des événements"
msgid "Event {{id}}"
-msgstr ""
+msgstr "Evènement {{id}}"
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=\"{{url}}\">why?</a>)."
-msgstr ""
+msgstr "Tout ce que vous indiquez dans cette page, y compris <strong>votre nom </strong>,\\n va etre <strong>public </strong> sur \\n ce site (<a href=\"{{url}}\">pourquoi?</a>)."
msgid "Everything that you enter on this page\\n will be <strong>displayed publicly</strong> on\\n this website forever (<a href=\"{{url}}\">why?</a>)."
-msgstr ""
+msgstr "Tout ce que vous ecrivez sur cette page \\n va etre <strong>public</strong> sur \\n ce site (<a href=\"{{url}}\">pouquoi?</a>)."
msgid "FOI"
-msgstr ""
+msgstr "DAI"
msgid "FOI email address for {{public_body}}"
msgstr "Courriel FOI pour {{public_body}}"
msgid "FOI request – {{title}}"
-msgstr ""
+msgstr "Demande d'acceès a l'information– {{title}}"
msgid "FOI requests"
msgstr "Demandes FOI"
@@ -724,7 +745,7 @@ msgid "FOI requests {{start_count}} to {{end_count}} of {{total_count}}"
msgstr "Demandes FOI {{start_count}} à {{end_count}} sur {{total_count}}"
msgid "FOI response requires admin ({{reason}}) - {{title}}"
-msgstr ""
+msgstr "Réponse necessitant l'administration ({{reason}}) - {{title}}"
msgid "Failed to convert image to a PNG"
msgstr "Nous n'avons pas pu convertir l'image au format PNG."
@@ -736,49 +757,49 @@ msgid "Filter"
msgstr "Filtre"
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=\"{{url}}\">why?</a>)."
-msgstr ""
+msgstr "Commencer par écrire le <strong>nom de l'organisme Tunisien</strong> à \\n solliciter. <strong>Légalement , Ils sont obligés de répondre </strong>\\n (<a href=\"{{url}}\">pourquoi?</a>)."
msgid "Foi attachment"
-msgstr ""
+msgstr "Piece jointe"
msgid "FoiAttachment|Charset"
-msgstr ""
+msgstr "FoiAttachment|Charset"
msgid "FoiAttachment|Content type"
-msgstr ""
+msgstr "FoiAttachment|Content type"
msgid "FoiAttachment|Display size"
-msgstr ""
+msgstr "FoiAttachment|Display size"
msgid "FoiAttachment|Filename"
-msgstr ""
+msgstr "FoiAttachment|Filename"
msgid "FoiAttachment|Hexdigest"
-msgstr ""
+msgstr "FoiAttachment|Hexdigest"
msgid "FoiAttachment|Url part number"
-msgstr ""
+msgstr "FoiAttachment|Url part number"
msgid "FoiAttachment|Within rfc822 subject"
-msgstr ""
+msgstr "FoiAttachment|Within rfc822 subject"
msgid "Follow"
-msgstr ""
+msgstr "Suivre"
msgid "Follow all new requests"
-msgstr ""
+msgstr "Suivre toutes les nouvelles demandes "
msgid "Follow new successful responses"
-msgstr ""
+msgstr "Suivre les nouvelles réponses réussies"
msgid "Follow requests to {{public_body_name}}"
-msgstr ""
+msgstr "Suivre les demandes à {{public_body_name}}"
msgid "Follow these requests"
msgstr "Suivre ces demandes"
msgid "Follow things matching this search"
-msgstr ""
+msgstr "Suivre ce qui correspond a cette recherche "
msgid "Follow this authority"
msgstr "Suivre cette autorité administrative"
@@ -787,7 +808,7 @@ msgid "Follow this link to see the request:"
msgstr "Suivez ce lien pour voir la demande:"
msgid "Follow this person"
-msgstr ""
+msgstr "Suivre cette personne "
msgid "Follow this request"
msgstr "Suivre cette demande"
@@ -802,13 +823,13 @@ msgid "Follow up messages to existing requests are sent to "
msgstr "Le suivi des demandes existantes sont envoyés à"
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 ""
+msgstr "Les suivis et les nouvelles réponses à cette demande ont été arrêtés afin de prévenir le spam. Veuillez <a href=\"{{url}}\">Nous contacter </a> si vous êtes {{user_link}} et vous avez besoin d'envoyer un suivi."
msgid "Follow us on twitter"
msgstr "Suivre sur Twitter"
msgid "Followups cannot be sent for this request, as it was made externally, and published here by {{public_body_name}} on the requester's behalf."
-msgstr ""
+msgstr "Il est impossible de suivre cette demande , elle a été faite ailleurs et publiée ici par {{public_body_name}} au nom du demandeur"
msgid "For an unknown reason, it is not possible to make a request to this authority."
msgstr "Par des raisons que nous ne pouvons pas déterminer, il est impossible d'envoyer des demandes à cette institution."
@@ -818,8 +839,8 @@ msgstr "Vous avez oublié votre mot de passe?"
msgid "Found {{count}} public authority {{description}}"
msgid_plural "Found {{count}} public authorities {{description}}"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] " {{count}} organisme public trouvé {{description}}"
+msgstr[1] " {{count}} organismes publics trouvés {{description}}"
msgid "Freedom of Information"
msgstr "Liberté d'accès à l'information"
@@ -828,13 +849,13 @@ msgid "Freedom of Information Act"
msgstr "Loi pour la liberté d'information"
msgid "Freedom of Information law does not apply to this authority, so you cannot make\\n a request to it."
-msgstr ""
+msgstr "Le droit d'accès à l'information ne s'applique pas à cette autorité, ainsi vous ne pouvez pas \\n lui adresser des demandes."
msgid "Freedom of Information law no longer applies to"
msgstr "La loi pour la liberté d'information ne s'applique plus à"
msgid "Freedom of Information law no longer applies to this authority.Follow up messages to existing requests are sent to "
-msgstr ""
+msgstr "Le droit d'accès à l'information ne s'applique plus à cet etablissement .le suivi des messages aux demandes existantes sont envoyés à"
msgid "Freedom of Information requests made"
msgstr "sollicitudes d'accès à l'information envoyées"
@@ -852,10 +873,10 @@ msgid "Freedom of information requests to"
msgstr "Demandes d'accès à l'information faites à"
msgid "From"
-msgstr ""
+msgstr "De"
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=\"{{url}}\">send it to us</a>."
-msgstr ""
+msgstr "Sur la page de demande, essayez répondre à un message particulier, plutôt que d'envoyer \\n un suivi général. Si vous avez besoin de faire un suivi général, et vous saviez \\ n quel e-mail ira à la bonne place, s'il vous plaît <a href=\"{{url}}\">Envoyez le nous </a>."
msgid "From:"
msgstr "De:"
@@ -866,9 +887,21 @@ msgstr "DONNER DES DETAILS SUR VOTRE PLAINTE ICI"
msgid "Handled by post."
msgstr "Envoyé par voie postale"
-msgid "Hello! You can make Freedom of Information requests within {{country_name}} at {{link_to_website}}"
+msgid "Has tag string/has tag string tag"
msgstr ""
+msgid "HasTagString::HasTagStringTag|Model"
+msgstr ""
+
+msgid "HasTagString::HasTagStringTag|Name"
+msgstr ""
+
+msgid "HasTagString::HasTagStringTag|Value"
+msgstr ""
+
+msgid "Hello! You can make Freedom of Information requests within {{country_name}} at {{link_to_website}}"
+msgstr "Bonjour! Vous pouvez faire des demandes d'accès à l'information en {{country_name}} au {{link_to_website}}"
+
msgid "Hello, {{username}}!"
msgstr "Bonjour, {{username}}!"
@@ -876,19 +909,19 @@ msgid "Help"
msgstr "Aide"
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."
-msgstr ""
+msgstr "Ici e mot <strong> décrit </ strong> signifie quand un utilisateur a sélectionné un état ​​de la requête, et \\n l'événement le plus récent a mis à jour son statut à cette valeur. <strong> calculée </ strong> est alors déduite par \\n {{site_name}] pour les événements intermédiaires, qui n'ont pas reçu une description explicite \\n par un utilisateur. Voir les <a href=\"{{search_path}}\"> conseils de recherche </ a> pour la description des états."
msgid "Here is the message you wrote, in case you would like to copy the text and save it for later."
-msgstr ""
+msgstr "Voici le message que vous avez écrit, au cas où vous souhaitez copier le texte et l'enregistrer pour plus tard."
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 ""
+msgstr "Bonjour, Nous avons besoin de votre aide . La personne qui a effectué cette demande \\n ne nous a pas dit si'il a reçu une bonne réponse . Veuillez prendre quelques minutes pour lire et nous aider a classifier la demande . \\n Merci"
msgid "Hide request"
-msgstr ""
+msgstr "Cacher la demande"
msgid "Holiday"
-msgstr ""
+msgstr "Vacances"
msgid "Holiday|Day"
msgstr "JoursFériés|Jour"
@@ -900,13 +933,13 @@ msgid "Home"
msgstr "Accueil"
msgid "Home page"
-msgstr ""
+msgstr "Page d'accueil"
msgid "Home page of authority"
msgstr "Page web de l'institution"
msgid "However, you have the right to request environmental\\n information under a different law"
-msgstr ""
+msgstr "Cependant, vous avez le droit de demander des \\n informations environnementales en vertu d'une loi différente."
msgid "Human health and safety"
msgstr "Santé et sécurité des personnes"
@@ -918,19 +951,19 @@ msgid "I am requesting an <strong>internal review</strong>"
msgstr "Je demande <strong>réexamen interne</strong>."
msgid "I don't like these ones &mdash; give me some more!"
-msgstr ""
+msgstr "Je n'aime pas ceux-ci &mdash; Donnez moi d'autres!"
msgid "I don't want to do any more tidying now!"
-msgstr ""
+msgstr "Je ne veux plus faire de rangement maintenant!"
msgid "I like this request"
-msgstr ""
+msgstr "J'aime cette demande "
msgid "I would like to <strong>withdraw this request</strong>"
msgstr "Je voudrais <strong>retirer cette demande</strong>."
msgid "I'm still <strong>waiting</strong> for my information\\n <small>(maybe you got an acknowledgement)</small>"
-msgstr ""
+msgstr "Je suis enocre <strong>en attente </strong>de réponse \\n <small>(peut etre vous avez reçu un accusé de reception )</small>"
msgid "I'm still <strong>waiting</strong> for the internal review"
msgstr "Je suis toujours en <strong>attente</strong> d'un réexamen interne."
@@ -951,22 +984,22 @@ msgid "I've received an <strong>error message</strong>"
msgstr "J'ai reçu un <strong>message d'erreur</strong>."
msgid "I've received an error message"
-msgstr ""
+msgstr "J'ai reçu un <strong>message d'erreur</strong>."
msgid "Id"
-msgstr ""
+msgstr "Id"
msgid "If the address is wrong, or you know a better address, please <a href=\"{{url}}\">contact us</a>."
msgstr "Si l'adresse est erronée, ou si vous connaissez une meilleure adresse, s'il vous plaît <a href=\"{{url}}\">contactez-nous</a>."
msgid "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."
-msgstr ""
+msgstr "Si l'erreur a été un échec de livraison, et vous pouvez trouver une mise à jour adresse email accès à l'information pour l'autorité, s'il vous plaît nous dire en utilisant le formulaire ci-dessous."
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."
-msgstr ""
+msgstr "Si c'est incorrect, ou si vous souhaitez envoyer une réponse tardive à la demande \\n ou un e-mail sur un autre sujet pour{{user}}, alors s'il vous plait contacter nous {{contact_email}} ."
msgid "If you are dissatisfied by the response you got from\\n the public authority, you have the right to\\n complain (<a href=\"{{url}}\">details</a>)."
-msgstr ""
+msgstr "Si vous n'etes pad satisfait de la réponse faite par l'organisme public , vous avez le droit de porter plainte (<a href=\"{{url}}\">details</a>)."
msgid "If you are still having trouble, please <a href=\"{{url}}\">contact us</a>."
msgstr "Si vous rencontrez toujours des problèmes, s'il vous plaît <a href=\"{{url}}\">contact us</a>."
@@ -975,37 +1008,37 @@ msgid "If you are the requester, then you may <a href=\"{{url}}\">sign in</a> to
msgstr "Si vous êtes le demandeur, alors vous pouvez <a href=\"{{url}}\">sign in</a> voir à la demande."
msgid "If you are thinking of using a pseudonym,\\n please <a href=\"{{url}}\">read this first</a>."
-msgstr ""
+msgstr "Si vous envisagez d'utiliser un pseudonyme, \\\\ veuillez <a href=\"{{url}}\">lire ça</a>."
msgid "If you are {{user_link}}, please"
msgstr "Si vous êtes {{user_link}}, merci de "
msgid "If you believe this request is not suitable, you can report it for attention by the site administrators"
-msgstr ""
+msgstr "Si vous pensez que cette demande n'est pas appropriée, vous pouvez la signaler à l'attention des administrateurs du site"
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."
-msgstr ""
+msgstr "Si vous ne pouvez pas cliquer dans le mail , vous devrier <strong> selectionner et copier \\n<strong> a partir du mail . Apres , <strong> coller dans votre navigateur</strong> dans la barre d'adresse ."
msgid "If you can, scan in or photograph the response, and <strong>send us\\n a copy to upload</strong>."
-msgstr ""
+msgstr "Si vous pouvez , scannez ou photographiez une réponse , et <strong> envoyez nous une copie pour l'uploader </strong>"
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 ""
+msgstr "Si vous trouvez ce service utile en tant qu'agent d'accès à l'information, veuillez demander à votre webmaster de mette un lien vers notre site à partir de la page droit d'accès à l'information de votre organisation."
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."
-msgstr ""
+msgstr "Si vous avez reçu un email <strong> il ya plus de 6 mois </strong> , alors le lien pour vous connecter ne marche plus Veuillez recommencer depuis le debut "
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 ""
+msgstr "Si vous ne l'avez pas déjà fait, veuillez ecrire un message à l'autorité que vous avez retiré votre demande. Sinon, ils ne sauront pas qu'il a été retirée."
msgid "If you reply to this message it will go directly to {{user_name}}, who will\\nlearn your email address. Only reply if that is okay."
-msgstr ""
+msgstr "Si vous répondez a ce message ça ira directement à {{user_name}}, qui va \\n connaitre votre adresse mail Ne répondez que si cela ne vous dérange pas "
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."
-msgstr ""
+msgstr "Si vous utilisez gmail , yahoo , live ou vous avez un dossier 'courrier indésirable' . Parfois nos mails sont marqués comme spam"
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 ""
+msgstr "Si vous souhaitez que nous levons cette interdiction, alors vous pouvez poliment <a href=\"/help/contact\">Nous contacter </a> avec des explications . \\n"
msgid "If you're new to {{site_name}}"
msgstr "Si vous êtes nouveau {{site_name}}"
@@ -1014,127 +1047,127 @@ msgid "If you've used {{site_name}} before"
msgstr "Si vous avez utilisé {{site_name}} avant"
msgid "If your browser is set to accept cookies and you are seeing this message,\\nthen there is probably a fault with our server."
-msgstr ""
+msgstr "Si votre navigateur accepte les coockies et ce message affiché , \\n l'erreur est probablement liée a notre serveur"
msgid "Incoming email address"
-msgstr ""
+msgstr "Adresse du courrier entrant"
msgid "Incoming message"
-msgstr ""
+msgstr "Message entrant"
msgid "IncomingMessage|Cached attachment text clipped"
-msgstr ""
+msgstr "IncomingMessage|Cached attachment text clipped"
msgid "IncomingMessage|Cached main body text folded"
-msgstr ""
+msgstr "IncomingMessage|Cached main body text folded"
msgid "IncomingMessage|Cached main body text unfolded"
-msgstr ""
+msgstr "IncomingMessage|Cached main body text unfolded"
msgid "IncomingMessage|Last parsed"
-msgstr ""
+msgstr "IncomingMessage|Last parsed"
msgid "IncomingMessage|Mail from"
-msgstr ""
+msgstr "IncomingMessage|Mail from"
msgid "IncomingMessage|Mail from domain"
-msgstr ""
+msgstr "IncomingMessage|Mail from domain"
msgid "IncomingMessage|Sent at"
-msgstr ""
+msgstr "IncomingMessage|Sent at"
msgid "IncomingMessage|Subject"
-msgstr ""
+msgstr "IncomingMessage|Subject"
msgid "IncomingMessage|Valid to reply to"
-msgstr ""
+msgstr "IncomingMessage|Valid to reply to"
msgid "Individual requests"
-msgstr ""
+msgstr "Les demandes individuelles"
msgid "Info request"
-msgstr ""
+msgstr "Info request"
msgid "Info request event"
-msgstr ""
+msgstr "Info request event"
msgid "InfoRequestEvent|Calculated state"
-msgstr ""
+msgstr "InfoRequestEvent|Calculated state"
msgid "InfoRequestEvent|Described state"
-msgstr ""
+msgstr "InfoRequestEvent|Described state"
msgid "InfoRequestEvent|Event type"
-msgstr ""
+msgstr "InfoRequestEvent|Event type"
msgid "InfoRequestEvent|Last described at"
-msgstr ""
+msgstr "InfoRequestEvent|Last described at"
msgid "InfoRequestEvent|Params yaml"
-msgstr ""
+msgstr "InfoRequestEvent|Params yaml"
msgid "InfoRequestEvent|Prominence"
-msgstr ""
+msgstr "InfoRequestEvent|Prominence"
msgid "InfoRequest|Allow new responses from"
-msgstr ""
+msgstr "InfoRequest|Allow new responses from"
msgid "InfoRequest|Attention requested"
-msgstr ""
+msgstr "InfoRequest|Attention requested"
msgid "InfoRequest|Awaiting description"
-msgstr ""
+msgstr "InfoRequest|Awaiting description"
msgid "InfoRequest|Comments allowed"
-msgstr ""
+msgstr "InfoRequest|Comments allowed"
msgid "InfoRequest|Described state"
-msgstr ""
+msgstr "InfoRequest|Described state"
msgid "InfoRequest|External url"
-msgstr ""
+msgstr "InfoRequest|External url"
msgid "InfoRequest|External user name"
-msgstr ""
+msgstr "InfoRequest|External user name"
msgid "InfoRequest|Handle rejected responses"
-msgstr ""
+msgstr "InfoRequest|Handle rejected responses"
msgid "InfoRequest|Idhash"
-msgstr ""
+msgstr "InfoRequest|Idhash"
msgid "InfoRequest|Law used"
-msgstr ""
+msgstr "InfoRequest|Law used"
msgid "InfoRequest|Prominence"
-msgstr ""
+msgstr "InfoRequest|Prominence"
msgid "InfoRequest|Title"
-msgstr ""
+msgstr "InfoRequest|Title"
msgid "InfoRequest|Url title"
-msgstr ""
+msgstr "InfoRequest|Url title"
msgid "Information not held."
-msgstr ""
+msgstr "Information non tenue."
msgid "Information on emissions and discharges (e.g. noise, energy,\\n radiation, waste materials)"
-msgstr ""
+msgstr "Informations sur les émissions et rejets (par exemple, le bruit, l'énergie, \\ n radiations, déchets)"
msgid "Internal review request"
-msgstr ""
+msgstr "Demande de révision interne"
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 ""
+msgstr "Est ce que {{email_address}} la mauvaise adresse pour les demandes du type {{type_of_request}} à {{public_body_name}}? Si c'est le cas veuillez nous contacter en utilisant ce formulaire:"
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."
-msgstr ""
+msgstr "Peut etre que votre navigateur n'accepte pas les coockies \\n . Si vous pouvez veuillez les activer ou utilisez un autre navigateur . apres cliquez sur le bouton refresh ."
msgid "Items matching the following conditions are currently displayed on your wall."
-msgstr ""
+msgstr "Elements correspondant aux conditions suivantes sont actuellement affichés sur votre mur."
msgid "Items sent in last month"
-msgstr ""
+msgstr "Éléments envoyés le mois dernier"
msgid "Joined in"
msgstr "Inscrit dans"
@@ -1143,10 +1176,10 @@ msgid "Joined {{site_name}} in"
msgstr "Inscrit dans {{site_name}}"
msgid "Just one more thing"
-msgstr ""
+msgstr "Juste une dernierre chose "
msgid "Keep it <strong>focused</strong>, you'll be more likely to get what you want (<a href=\"{{url}}\">why?</a>)."
-msgstr ""
+msgstr "Soyez <strong> précis </strong>, vous aurez plus de chances d'obtenir ce que vous voulez (<a href=\"{{url}}\">pourquoi?</a>)."
msgid "Keywords"
msgstr "Mots-clés"
@@ -1164,31 +1197,31 @@ msgid "Link to this"
msgstr "Créer un lien vers"
msgid "List all"
-msgstr ""
+msgstr "Lister tout "
msgid "List of all authorities (CSV)"
msgstr "Liste de toutes les intitutions (CSV)"
msgid "Listing FOI requests"
-msgstr ""
+msgstr "Liste des demandes DAI"
msgid "Listing public authorities"
-msgstr ""
+msgstr "Liste des organismes publics"
msgid "Listing public authorities matching '{{query}}'"
-msgstr ""
+msgstr "Liste des organismes publics correspondant à '{{query}}'"
msgid "Listing tracks"
-msgstr ""
+msgstr "Liste des suivis"
msgid "Listing users"
-msgstr ""
+msgstr "Liste des utilisateurs"
msgid "Log in to download a zip file of {{info_request_title}}"
msgstr "Connectez-vous pour télécharger un fichier zip de {{info_request_title}}"
msgid "Log into the admin interface"
-msgstr ""
+msgstr "Se connecter a l'interface Admin"
msgid "Long overdue."
msgstr "En retard depuis longtemps"
@@ -1197,37 +1230,37 @@ msgid "Made between"
msgstr "Fait entre"
msgid "Mail server log"
-msgstr ""
+msgstr "Journal du serveur de mailing"
msgid "Mail server log done"
-msgstr ""
+msgstr "Journal du serveur mailing effectué"
msgid "MailServerLogDone|Filename"
-msgstr ""
+msgstr "MailServerLogDone|Filename"
msgid "MailServerLogDone|Last stat"
-msgstr ""
+msgstr "MailServerLogDone|Last stat"
msgid "MailServerLog|Line"
-msgstr ""
+msgstr "MailServerLog|Line"
msgid "MailServerLog|Order"
-msgstr ""
+msgstr "MailServerLog|Order"
msgid "Make a new <strong>Environmental Information</strong> request"
-msgstr ""
+msgstr "Faire une nouvelle demande <strong>d'information environnementale </strong> "
msgid "Make a new <strong>Freedom of Information</strong> request to {{public_body}}"
-msgstr ""
+msgstr "Faire une nouvelle demande <strong>d'accès a l'information </strong> à {{public_body}}"
msgid "Make a new<br/>\\n <strong>Freedom <span>of</span><br/>\\n Information<br/>\\n request</strong>"
-msgstr ""
+msgstr "Faire une<br/>\\n <strong>Nouvelle <span>demande</span><br/>\\n d'accès<br/>\\n à l'information</strong>"
msgid "Make a request"
msgstr "Faire une demande"
msgid "Make an {{law_used_short}} request to '{{public_body_name}}'"
-msgstr ""
+msgstr "Faire une {{law_used_short}} demande à '{{public_body_name}}'"
msgid "Make and browse Freedom of Information (FOI) requests"
msgstr "Envoyer et rechercher des sollicitudes d'accès à lìnformation"
@@ -1236,10 +1269,10 @@ msgid "Make your own request"
msgstr "Créer votre propre demande"
msgid "Many requests"
-msgstr ""
+msgstr "Beaucoup de demandes"
msgid "Message"
-msgstr ""
+msgstr "Message"
msgid "Message sent using {{site_name}} contact form, "
msgstr "Message envoyé en utilisant le formulaire {{site_name}}"
@@ -1251,7 +1284,7 @@ msgid "More about this authority"
msgstr "Plus d'infos sur cet administration"
msgid "More requests..."
-msgstr ""
+msgstr "Plus de demandes ..."
msgid "More similar requests"
msgstr "Plus de demandes similaires"
@@ -1269,7 +1302,7 @@ msgid "My requests"
msgstr "Mes demandes"
msgid "My wall"
-msgstr ""
+msgstr "Mon mur"
msgid "Name can't be blank"
msgstr "Le nom ne peut pas être effacé"
@@ -1278,10 +1311,10 @@ msgid "Name is already taken"
msgstr "Le nom est déjà pris"
msgid "New Freedom of Information requests"
-msgstr ""
+msgstr "Nouvelles demandes d'accès a l'information "
msgid "New censor rule"
-msgstr ""
+msgstr "Une nouvelle règle de censure"
msgid "New e-mail:"
msgstr "Nouvel e-mail :"
@@ -1296,19 +1329,19 @@ msgid "New password: (again)"
msgstr "Nouveau mot de passe : (confirmation)"
msgid "New response to '{{title}}'"
-msgstr ""
+msgstr "Nouvelle réponse à '{{title}}'"
msgid "New response to your FOI request - "
-msgstr ""
+msgstr "Nouvelle réponse à votre demande d'açcès à l'information"
msgid "New response to your request"
msgstr "Nouvelle réponse à votre demande"
msgid "New response to {{law_used_short}} request"
-msgstr ""
+msgstr "Nouvelle réponse à la {{law_used_short}} demande "
msgid "New updates for the request '{{request_title}}'"
-msgstr ""
+msgstr "Nouvelles mises à jour pour la demande '{{request_title}}'"
msgid "Newest results first"
msgstr "Les résultats les plus nouveaux en premier lieu"
@@ -1329,7 +1362,7 @@ msgid "No similar requests found."
msgstr "Pas de demandes similaires trouvés."
msgid "No tracked things found."
-msgstr ""
+msgstr "Aucun suivi trouvé"
msgid "Nobody has made any Freedom of Information requests to {{public_body_name}} using this site yet."
msgstr "Personne n'a jamais envoyée une sollicitude d'accès à l'information à {{public_body_name}} en utilisant cette page."
@@ -1338,13 +1371,13 @@ msgid "None found."
msgstr "Aucun résultat trouvé."
msgid "None made."
-msgstr ""
+msgstr "Aucune demande "
msgid "Not a valid FOI request"
-msgstr ""
+msgstr "Pas une demande d'accès a l'information valide"
msgid "Note that the requester will not be notified about your annotation, because the request was published by {{public_body_name}} on their behalf."
-msgstr ""
+msgstr "Notez que le demandeur ne sera pas informé de votre annotation, parce que la demande a été publié par {{public_body_name}} en leur nom"
msgid "Now check your email!"
msgstr "Maintenant, relevez votre email !"
@@ -1362,76 +1395,76 @@ msgid "OR remove the existing photo"
msgstr "Ou effacer la photo éxistante"
msgid "Offensive? Unsuitable?"
-msgstr ""
+msgstr "Offensif? inadapté?"
msgid "Oh no! Sorry to hear that your request was refused. Here is what to do now."
-msgstr ""
+msgstr "Oh non! Désolés d'apprendre que votre demande a été refusée. Voici ce qu'il faut faire maintenant."
msgid "Old e-mail:"
msgstr "Ancien e-mail :"
msgid "Old email address isn't the same as the address of the account you are logged in with"
-msgstr ""
+msgstr "Ancienne adresse mail n'est pas la même adresse du compte que vous êtes connecté avec"
msgid "Old email doesn't look like a valid address"
-msgstr ""
+msgstr "L'ancienne adresse mail ne ressemble pas à une adresse valide"
msgid "On this page"
msgstr "Sur cette page"
msgid "One FOI request found"
-msgstr ""
+msgstr "Une demande d'accès à l'information trouvée"
msgid "One person found"
-msgstr ""
+msgstr "Une personne trouvée"
msgid "One public authority found"
-msgstr ""
+msgstr "Une autorité administrative trouvée"
msgid "Only put in abbreviations which are really used, otherwise leave blank. Short or long name is used in the URL – don't worry about breaking URLs through renaming, as the history is used to redirect"
-msgstr ""
+msgstr "Seulement mettre les abréviations qui sont réellement utilisés, sinon laisser vide."
msgid "Only requests made using {{site_name}} are shown."
msgstr "Seules les demandes faites en utilisant {{site_name}} sont présentés."
msgid "Only the authority can reply to this request, and I don't recognise the address this reply was sent from"
-msgstr ""
+msgstr "Seule l'autorité peut répondre à cette demande, et je ne reconnais pas l'adresse à partir de laquelle cette réponse a été envoyée"
msgid "Only the authority can reply to this request, but there is no \"From\" address to check against"
-msgstr ""
+msgstr "Seule l'autorité peut répondre à cette demande, mais il n'y a pas d'adresse \"From\" pour vérifier avec "
msgid "Or search in their website for this information."
-msgstr ""
+msgstr "Ou rechercher sur leur site Internet pour obtenir cette information."
msgid "Original request sent"
-msgstr ""
+msgstr "Demande originale envoyée"
msgid "Other:"
-msgstr ""
+msgstr "Autre:"
msgid "Outgoing message"
-msgstr ""
+msgstr "Message sortant"
msgid "OutgoingMessage|Body"
-msgstr ""
+msgstr "OutgoingMessage|Body"
msgid "OutgoingMessage|Last sent at"
-msgstr ""
+msgstr "OutgoingMessage|Last sent at"
msgid "OutgoingMessage|Message type"
-msgstr ""
+msgstr "OutgoingMessage|Message type"
msgid "OutgoingMessage|Status"
-msgstr ""
+msgstr "OutgoingMessage|Status"
msgid "OutgoingMessage|What doing"
-msgstr ""
+msgstr "OutgoingMessage|What doing"
msgid "Partially successful."
-msgstr ""
+msgstr "partiellement réussi."
msgid "Password is not correct"
-msgstr ""
+msgstr "Mot de passe incorrect"
msgid "Password:"
msgstr "Mot de passe :"
@@ -1440,22 +1473,22 @@ msgid "Password: (again)"
msgstr "Mot de passe : (confirmation)"
msgid "Paste this link into emails, tweets, and anywhere else:"
-msgstr ""
+msgstr "Coller ce lien dans les emails , tweets ou ailleurs"
msgid "People"
-msgstr ""
+msgstr "Citoyens"
msgid "People {{start_count}} to {{end_count}} of {{total_count}}"
-msgstr ""
+msgstr "Les gens {{start_count}} à {{end_count}} de {{total_count}}"
msgid "Photo of you:"
msgstr "Votre photo :"
msgid "Plans and administrative measures that affect these matters"
-msgstr ""
+msgstr "Les plans et les mesures administratives qui touchent ces questions"
msgid "Play the request categorisation game"
-msgstr ""
+msgstr "Jouez au jeu de catégorisation de la demande!"
msgid "Play the request categorisation game!"
msgstr "Jouez au jeu de catégorisation des demandes !"
@@ -1464,22 +1497,22 @@ msgid "Please"
msgstr "S'il vous plait"
msgid "Please <a href=\"{{url}}\">get in touch</a> with us so we can fix it."
-msgstr ""
+msgstr "Veuillez <a href=\"{{url}}\">nous contacter </a> afin que nous puissions le corriger."
msgid "Please <strong>answer the question above</strong> so we know whether the "
-msgstr ""
+msgstr "Veuillez <strong>répondre a la question ci-dessus</strong> pour qu'on sache si "
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 ""
+msgstr "Veuillez <strong> aller aux demandes suivantes </strong> et dites \\n nous si les réponses contiennent l'information demandée."
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 ""
+msgstr "Veuillez écrire des messages <strong>Uniquement</strong>reliés à votre demande {{request_link}}. Si vous souhaitez demander des informations qui n'étaient pas dans votre demande initiale , alors <a href=\"{{new_request_link}}\">déposer une nouvelle demande</a>."
msgid "Please ask for environmental information only"
-msgstr ""
+msgstr "Veuillez demander uniquement des informations environnementales"
msgid "Please check the URL (i.e. the long code of letters and numbers) is copied\\ncorrectly from your email."
-msgstr ""
+msgstr "Veuillez voir si l'URL ( ie: la longue suite d'adresse contenant des chiffres et des lettres ) est correctement copiée depuis votre mail "
msgid "Please choose a file containing your photo."
msgstr "Choisissez un fichier qui contient votre photo."
@@ -1488,25 +1521,25 @@ msgid "Please choose what sort of reply you are making."
msgstr "Merci de choisir le type de réponse que vous entrez."
msgid "Please choose whether or not you got some of the information that you wanted."
-msgstr ""
+msgstr "Veuillez choisir si vous avez obtenu une partie de l'information que vous demandez ou pas . "
msgid "Please click on the link below to cancel or alter these emails."
-msgstr ""
+msgstr "Veuillez cliquer sur le lien ci dessous pour annuler ou modifer les email"
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}}"
-msgstr ""
+msgstr "Veuillez cliquer sur le lien ci dessous pour confirmer que vous voulez \\n changer l'adresse email que vous utilisez sur {{site_name}}\\n de {{old_email}} à {{new_email}}"
msgid "Please click on the link below to confirm your email address."
-msgstr ""
+msgstr "Veuillez cliquer sur le lien ci dessous pour confirmer votre adresse mail "
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 "Merci d'indiquer le thème de votre requête dans le champ \"Sujet\". Il n'est pas nécessaire d'indiquer qu'il s'agit d'une demande d'accès aux documents administratifs, nous le précisons par défaut."
msgid "Please don't upload offensive pictures. We will take down images\\n that we consider inappropriate."
-msgstr ""
+msgstr "Veuillez ne pas uploader des images agressives . nous allons supprimer les images qui nous semblent inappropriées."
msgid "Please enable \"cookies\" to carry on"
-msgstr ""
+msgstr "Veuillez autoriser les \"cookies\" pour poursuivre"
msgid "Please enter a password"
msgstr "Merci d'entrer un mot de passe"
@@ -1563,25 +1596,25 @@ msgid "Please keep the summary short, like in the subject of an email. You can u
msgstr "S'il vous plait soyez bref dans le résumé, comme dans le titre d'un email."
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 ""
+msgstr "Veuillez uniquement demander les informations qui appartiennent à ces catégories <strong> ne perdez pas votre temps </strong> ou celui de l'administration publique a demander des informations sans rapport avec ces catégories ."
msgid "Please select each of these requests in turn, and <strong>let everyone know</strong>\\nif they are successful yet or not."
-msgstr ""
+msgstr "Veuillez choisir ces demandes une par une et <strong> laisser tout le monde savoir </strong> si elles ont abouti ou pas ."
msgid "Please sign at the bottom with your name, or alter the \"{{signoff}}\" signature"
msgstr "S'il vous plait signer à la fin avec votre nom, ou changez la \"{{signoff}}\" signature"
msgid "Please sign in as "
-msgstr ""
+msgstr "Veuillez vous connecter en tant que "
msgid "Please sign in or make a new account."
-msgstr ""
+msgstr "Veuillez vous connecter ou créer un compte."
msgid "Please type a message and/or choose a file containing your response."
-msgstr ""
+msgstr "Veuillez ecrire un message et/ou choisir un fichier contenant votre réponse."
msgid "Please use this email address for all replies to this request:"
-msgstr ""
+msgstr "Veuillez utiliser cette adresse mail pour toutes les réponses sur cette demande"
msgid "Please write a summary with some text in it"
msgstr "S'il vous plait écrivez un résumé avec du texte"
@@ -1593,298 +1626,268 @@ msgid "Please write your annotation using a mixture of capital and lower case le
msgstr "S'il vous plait écrivez votre commentaire en utilisant des lettres majuscules et minuscules. Ce sera plus facile de lire."
msgid "Please write your follow up message containing the necessary clarifications below."
-msgstr ""
+msgstr "Veuillez ecrire votre message de suivi contenant toutes les clarifications necessaires présentes ci-dessous "
msgid "Please write your message using a mixture of capital and lower case letters. This makes it easier for others to read."
msgstr "S'il vous plait écrivez votre message en utilisant des lettres majuscules et minuscules. Ce sera plus facile de lire."
msgid "Point to <strong>related information</strong>, campaigns or forums which may be useful."
-msgstr ""
+msgstr "Indiquez <strong>les informations liées</strong>, compagnes ou forums qui peuvent être utiles"
msgid "Possibly related requests:"
-msgstr ""
+msgstr "Demandes similaires:"
msgid "Post annotation"
-msgstr ""
+msgstr "Ecrire une remarque"
msgid "Post redirect"
-msgstr ""
+msgstr "Post redirect"
msgid "PostRedirect|Circumstance"
-msgstr ""
+msgstr "PostRedirect|Circumstance"
msgid "PostRedirect|Email token"
-msgstr ""
+msgstr "PostRedirect|Email token"
msgid "PostRedirect|Post params yaml"
-msgstr ""
+msgstr "PostRedirect|Post params yaml"
msgid "PostRedirect|Reason params yaml"
-msgstr ""
+msgstr "PostRedirect|Reason params yaml"
msgid "PostRedirect|Token"
-msgstr ""
+msgstr "PostRedirect|Token"
msgid "PostRedirect|Uri"
-msgstr ""
+msgstr "PostRedirect|Uri"
msgid "Posted on {{date}} by {{author}}"
-msgstr ""
+msgstr "Ecrit le {{date}} par {{author}}"
msgid "Powered by <a href=\"http://www.alaveteli.org/\">Alaveteli</a>"
-msgstr ""
+msgstr "Powered by <a href=\"http://www.alaveteli.org/\">Alaveteli</a>"
msgid "Prev"
-msgstr ""
+msgstr "Pre"
msgid "Preview follow up to '"
-msgstr ""
+msgstr "Prévisualiser le suivi à '"
msgid "Preview new annotation on '{{info_request_title}}'"
-msgstr ""
+msgstr "Prévisualiser la nouvelle remarque sur '{{info_request_title}}'"
msgid "Preview your annotation"
-msgstr ""
+msgstr "Prévisualiser votre remarque"
msgid "Preview your message"
-msgstr ""
+msgstr "Prévisualiser votre message"
msgid "Preview your public request"
-msgstr ""
+msgstr "Prévisualiser votre demande "
msgid "Profile photo"
-msgstr ""
+msgstr "Photo de profil"
msgid "ProfilePhoto|Data"
-msgstr ""
+msgstr "ProfilePhoto|Data"
msgid "ProfilePhoto|Draft"
-msgstr ""
+msgstr "ProfilePhoto|Draft"
msgid "Public authorities"
-msgstr ""
+msgstr "Organismes publics"
msgid "Public authorities - {{description}}"
-msgstr ""
+msgstr "Organismes publics - {{description}}"
msgid "Public authorities {{start_count}} to {{end_count}} of {{total_count}}"
-msgstr ""
+msgstr "Organismes publics {{start_count}} à {{end_count}} de {{total_count}}"
msgid "Public authority – {{name}}"
-msgstr ""
+msgstr "Organisme public – {{name}}"
msgid "Public body"
-msgstr ""
-
-msgid "Public body/translation"
-msgstr ""
+msgstr "Organisme public"
msgid "Public notes"
-msgstr ""
+msgstr "Notes publiques"
msgid "Public page"
-msgstr ""
+msgstr "Paque publique "
msgid "Public page not available"
-msgstr ""
-
-msgid "PublicBody::Translation|Disclosure log"
-msgstr ""
-
-msgid "PublicBody::Translation|First letter"
-msgstr ""
-
-msgid "PublicBody::Translation|Locale"
-msgstr ""
-
-msgid "PublicBody::Translation|Name"
-msgstr ""
-
-msgid "PublicBody::Translation|Notes"
-msgstr ""
-
-msgid "PublicBody::Translation|Publication scheme"
-msgstr ""
-
-msgid "PublicBody::Translation|Request email"
-msgstr ""
-
-msgid "PublicBody::Translation|Short name"
-msgstr ""
-
-msgid "PublicBody::Translation|Url name"
-msgstr ""
+msgstr "Page publique indisponible"
msgid "PublicBody|Api key"
-msgstr ""
+msgstr "PublicBody|Api key"
msgid "PublicBody|Disclosure log"
-msgstr ""
+msgstr "PublicBody|Disclosure log"
msgid "PublicBody|First letter"
-msgstr ""
+msgstr "PublicBody|First letter"
msgid "PublicBody|Home page"
-msgstr ""
+msgstr "PublicBody|Home page"
msgid "PublicBody|Info requests count"
-msgstr ""
+msgstr "PublicBody|Info requests count"
msgid "PublicBody|Last edit comment"
-msgstr ""
+msgstr "PublicBody|Last edit comment"
msgid "PublicBody|Last edit editor"
-msgstr ""
+msgstr "PublicBody|Last edit editor"
msgid "PublicBody|Name"
-msgstr ""
+msgstr "PublicBody|Name"
msgid "PublicBody|Notes"
-msgstr ""
+msgstr "PublicBody|Notes"
msgid "PublicBody|Publication scheme"
-msgstr ""
+msgstr "PublicBody|Publication scheme"
msgid "PublicBody|Request email"
-msgstr ""
+msgstr "PublicBody|Request email"
msgid "PublicBody|Short name"
-msgstr ""
+msgstr "PublicBody|Short name"
msgid "PublicBody|Url name"
-msgstr ""
+msgstr "PublicBody|Url name"
msgid "PublicBody|Version"
-msgstr ""
+msgstr "PublicBody|Version"
msgid "Publication scheme"
msgstr "Diffusions d'Infos Publiques"
msgid "Publication scheme URL"
-msgstr ""
+msgstr "Publication scheme URL"
msgid "Purge request"
-msgstr ""
+msgstr "Supprimer la demande"
msgid "PurgeRequest|Model"
-msgstr ""
+msgstr "PurgeRequest|Model"
msgid "PurgeRequest|Url"
-msgstr ""
+msgstr "PurgeRequest|Url"
msgid "RSS feed"
-msgstr ""
+msgstr "Flux RSS "
msgid "RSS feed of updates"
-msgstr ""
+msgstr "Flux RSS de mises à jour"
msgid "Re-edit this annotation"
-msgstr ""
+msgstr "Réditer cette annotation"
msgid "Re-edit this message"
-msgstr ""
+msgstr "Réediter ce message"
msgid "Read about <a href=\"{{advanced_search_url}}\">advanced search operators</a>, such as proximity and wildcards."
-msgstr ""
+msgstr "Lire sur <a href=\"{{advanced_search_url}}\">Les opérateurs de recherche avancée</a>, tels que la proximité et caractères génériques."
msgid "Read blog"
msgstr "Lire le blog"
msgid "Received an error message, such as delivery failure."
-msgstr ""
+msgstr "Reçu un message d'erreur, tel que l'échec de la livraison."
msgid "Recently described results first"
-msgstr ""
+msgstr "Les résultats récemment décris en premier "
msgid "Refused."
-msgstr ""
+msgstr "Refusé"
msgid "Remember me</label> (keeps you signed in longer;\\n do not use on a public computer) "
-msgstr ""
+msgstr "Se rappeler du mot de passse </label> (vous permet de rester connecté ;\\n à ne pas utiliser sur un ordinateur public) "
msgid "Report abuse"
-msgstr ""
+msgstr "Signaler un abus"
msgid "Report an offensive or unsuitable request"
-msgstr ""
+msgstr "Signaler une demande offensive ou inappropriée"
msgid "Report this request"
-msgstr ""
+msgstr "Signaler cette demande"
msgid "Reported for administrator attention."
-msgstr ""
+msgstr "Rapporté à l'attention de l'administrateur."
msgid "Request an internal review"
-msgstr ""
+msgstr "Solliciter une révision interne "
msgid "Request an internal review from {{person_or_body}}"
-msgstr ""
+msgstr "Solliciter une révision interne de {{person_or_body}}"
msgid "Request email"
-msgstr ""
+msgstr "Adresse mail"
msgid "Request has been removed"
-msgstr ""
+msgstr "Demande supprimée"
msgid "Request sent to {{public_body_name}} by {{info_request_user}} on {{date}}."
-msgstr ""
+msgstr "Demande envoyée à {{public_body_name}} par {{info_request_user}} Le {{date}}."
msgid "Request to {{public_body_name}} by {{info_request_user}}. Annotated by {{event_comment_user}} on {{date}}."
-msgstr ""
+msgstr "Demande à {{public_body_name}} par {{info_request_user}}. Commentée par {{event_comment_user}} Le {{date}}."
msgid "Requested from {{public_body_name}} by {{info_request_user}} on {{date}}"
-msgstr ""
+msgstr "Demande de {{public_body_name}} par {{info_request_user}} le {{date}}"
msgid "Requested on {{date}}"
-msgstr ""
+msgstr "Demandé le {{date}}"
msgid "Requests for personal information and vexatious requests are not considered valid for FOI purposes (<a href=\"/help/about\">read more</a>)."
-msgstr ""
+msgstr "Les demandes de renseignements personnels et les demandes abusives ne sont pas considérées comme demandes valides (<a href=\"/help/about\">Lire plus</a>)."
msgid "Requests or responses matching your saved search"
-msgstr ""
+msgstr "Les demandes ou les réponses correspondant à votre recherche sauvegardée"
msgid "Respond by email"
-msgstr ""
+msgstr "Répondre par e-mail "
msgid "Respond to request"
-msgstr ""
+msgstr "Répondre à la demande"
msgid "Respond to the FOI request"
-msgstr ""
+msgstr "Répondre a la demande d'accès à l'information"
msgid "Respond using the web"
-msgstr ""
+msgstr "Répondre en utilisant le web"
msgid "Response"
-msgstr ""
+msgstr "Réponse"
msgid "Response from a public authority"
-msgstr ""
+msgstr "Réponse d'une autorité publique"
msgid "Response to '{{title}}'"
-msgstr ""
+msgstr "Réponse à '{{title}}'"
msgid "Response to this request is <strong>delayed</strong>."
-msgstr ""
+msgstr "La réponse à cette demande est <strong> retardée </ strong"
msgid "Response to this request is <strong>long overdue</strong>."
-msgstr ""
+msgstr "Réponse à cette demande est <strong> très en retard </ strong"
msgid "Response to your request"
-msgstr ""
+msgstr "Réponse a vôtre requête "
msgid "Response:"
-msgstr ""
+msgstr "Réponse"
msgid "Restrict to"
-msgstr ""
+msgstr "Limiter à "
msgid "Results page {{page_number}}"
msgstr "Page de résultats {{page_number}}"
msgid "Save"
-msgstr ""
+msgstr "Enregistrer"
msgid "Search"
msgstr "Rechercher"
@@ -1893,72 +1896,72 @@ msgid "Search Freedom of Information requests, public authorities and users"
msgstr "Chercher des sollicitudes d'accès à l'information, des institutions publiques et utilisateurs"
msgid "Search contributions by this person"
-msgstr ""
+msgstr "Rechercher les contributions de cette personne"
msgid "Search for words in:"
-msgstr ""
+msgstr "Rechercher des mots dans"
msgid "Search in"
-msgstr ""
+msgstr "Rechercher dans"
msgid "Search over<br/>\\n <strong>{{number_of_requests}} requests</strong> <span>and</span><br/>\\n <strong>{{number_of_authorities}} authorities</strong>"
-msgstr ""
+msgstr "Rechercher parmi<br/>\\n <strong>{{number_of_requests}} demandes</strong> <span>et</span><br/>\\n <strong>{{number_of_authorities}} organismes</strong>"
msgid "Search queries"
-msgstr ""
+msgstr "Requêtes de recherche"
msgid "Search results"
-msgstr ""
+msgstr "Résultats de recherche"
msgid "Search the site to find what you were looking for."
-msgstr ""
+msgstr "Rechercher dans le site pour trouver ce que vous cherchez"
msgid "Search within the {{count}} Freedom of Information requests to {{public_body_name}}"
msgid_plural "Search within the {{count}} Freedom of Information requests made to {{public_body_name}}"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "Cherchez parmis la {{count}} demande faite à{{public_body_name}}"
+msgstr[1] "Cherchez parmis les {{count}} demandes faites à{{public_body_name}}"
msgid "Search your contributions"
-msgstr ""
+msgstr "Chercher vos contributions"
msgid "See bounce message"
-msgstr ""
+msgstr "Voir le message de rebond"
msgid "Select one to see more information about the authority."
-msgstr ""
+msgstr "Sélectionnez l'une pour voir plus d'informations sur l'autorité."
msgid "Select the authority to write to"
-msgstr ""
+msgstr "Sélectionner un etablissement pour lui écrire "
msgid "Send a followup"
-msgstr ""
+msgstr "Envoyer un suivi"
msgid "Send a message to "
-msgstr ""
+msgstr "Envoyer un message à"
msgid "Send a public follow up message to {{person_or_body}}"
-msgstr ""
+msgstr "envoyer un message de suivi public à {{person_or_body}}"
msgid "Send a public reply to {{person_or_body}}"
-msgstr ""
+msgstr "Envoyer une réponse publique à {{person_or_body}}"
msgid "Send follow up to '{{title}}'"
-msgstr ""
+msgstr "Envoyer suivi à '{{title}}'"
msgid "Send message"
-msgstr ""
+msgstr "Envoyer un message"
msgid "Send message to "
-msgstr ""
+msgstr "Envoyer un message à"
msgid "Send request"
-msgstr ""
+msgstr "Envoyer une demande "
msgid "Set your profile photo"
-msgstr ""
+msgstr "Définir vôtre photo de profil"
msgid "Short name"
-msgstr ""
+msgstr "Abbréviation "
msgid "Short name is already taken"
msgstr "Ce nom est déjà pris"
@@ -1967,16 +1970,16 @@ msgid "Show most relevant results first"
msgstr "Afficher les résultats les plus pertinents en premier"
msgid "Show only..."
-msgstr ""
+msgstr "Afficher uniquement..."
msgid "Showing"
-msgstr ""
+msgstr "Il y a"
msgid "Sign in"
-msgstr ""
+msgstr "Connexion"
msgid "Sign in or make a new account"
-msgstr ""
+msgstr "Se connecter ou créer un nouveau compte"
msgid "Sign in or sign up"
msgstr "Se connecter ou s'inscrire"
@@ -1985,568 +1988,571 @@ msgid "Sign out"
msgstr "Se déconnecter"
msgid "Sign up"
-msgstr ""
+msgstr "Créer un compte"
msgid "Similar requests"
-msgstr ""
+msgstr "Demandes similaires"
msgid "Simple search"
-msgstr ""
+msgstr "Recherche simple"
msgid "Some notes have been added to your FOI request - "
-msgstr ""
+msgstr "Quelques commentaires ont été ajoutés à vôtre demande -"
msgid "Some of the information requested has been received"
-msgstr ""
+msgstr "Quelques informations demandées ont été reçues"
msgid "Some people who've made requests haven't let us know whether they were\\nsuccessful or not. We need <strong>your</strong> help &ndash;\\nchoose one of these requests, read it, and let everyone know whether or not the\\ninformation has been provided. Everyone'll be exceedingly grateful."
-msgstr ""
+msgstr "Quelques uns parmis ceux qui ont fait les demandes ne nous ont pas fourni un retour \\n . Nous avons besoin de <strong> votre </strong> aide &ndash;\\n choisissez une de ces demandes , lisez la et faites nous savoir si l'information demandée est fournie ou pas . Tout le monde sera extrêmement reconnaissant."
msgid "Somebody added a note to your FOI request - "
-msgstr ""
+msgstr "Quelqu'un à ajouté un commentaire à votre demande -"
msgid "Someone has updated the status of your request"
-msgstr ""
+msgstr "Quelqu'un a mis à jour l'état de votre demande"
msgid "Someone, perhaps you, just tried to change their email address on\\n{{site_name}} from {{old_email}} to {{new_email}}."
-msgstr ""
+msgstr "Quelqu'un, peut-être vous, viens d'essayer de changer son adresse email sur {{site_name}} de {{old_email}} à {{new_email}}."
msgid "Sorry - you cannot respond to this request via {{site_name}}, because this is a copy of the request originally at {{link_to_original_request}}."
-msgstr ""
+msgstr "Vous ne pouvez pas répondre a cette demande via {{site_name}}, parce que c'est une copie de la demande originale ici {{link_to_original_request}}."
msgid "Sorry, but only {{user_name}} is allowed to do that."
-msgstr ""
+msgstr "Désolés , mais uniquement {{user_name}} est autorisé à faire ça."
msgid "Sorry, there was a problem processing this page"
-msgstr ""
+msgstr "Désolés, il y a eu un problème durant le traitement de la page"
msgid "Sorry, we couldn't find that page"
-msgstr ""
+msgstr "Page introuvable."
msgid "Special note for this authority!"
-msgstr ""
+msgstr "Remarque spéciale pour cette autorité"
msgid "Start"
-msgstr ""
+msgstr "Commencer "
msgid "Start now &raquo;"
-msgstr ""
+msgstr "Commencez dès maintenant &raquo;"
msgid "Start your own blog"
-msgstr ""
+msgstr "Commencez votre blog"
msgid "Stay up to date"
-msgstr ""
+msgstr "Restez à jour"
msgid "Still awaiting an <strong>internal review</strong>"
-msgstr ""
+msgstr "En attente d'une <strong>révision interne</strong>"
msgid "Subject"
-msgstr ""
+msgstr "Sujet"
msgid "Subject:"
-msgstr ""
+msgstr "Sujet:"
msgid "Submit"
-msgstr ""
+msgstr "Envoyer"
msgid "Submit status"
-msgstr ""
+msgstr "Etat d'envoi"
msgid "Submit status and send message"
-msgstr ""
+msgstr "Soumettre statut et envoyer un message"
msgid "Subscribe to blog"
-msgstr ""
+msgstr "s'abonner au blog"
msgid "Successful Freedom of Information requests"
-msgstr ""
+msgstr "Demandes d'accès à l'information réussies"
msgid "Successful."
-msgstr ""
+msgstr "réussi."
msgid "Suggest how the requester can find the <strong>rest of the information</strong>."
-msgstr ""
+msgstr "Indiquer comment le demandeur peut trouver le <strong>reste de l'information</strong>."
msgid "Summary:"
-msgstr ""
+msgstr "Résumé"
msgid "Table of statuses"
msgstr "Table d'états"
msgid "Table of varieties"
-msgstr ""
+msgstr "Tables des variétés "
msgid "Tags"
-msgstr ""
+msgstr "Tags"
msgid "Tags (separated by a space):"
-msgstr ""
+msgstr "Tags (séparés par un espace )"
msgid "Tags:"
-msgstr ""
+msgstr "Tags:"
msgid "Technical details"
-msgstr ""
+msgstr "Détails techniques:"
msgid "Thank you for helping us keep the site tidy!"
-msgstr ""
+msgstr "Merci de nous avoir aidé à maintenir le site en ordre!"
msgid "Thank you for making an annotation!"
-msgstr ""
+msgstr "Merci pour votre annotation!"
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 ""
+msgstr "Merci d'avoir répondu à cette demande d'accès à l'information ! Votre réponse a été publiée ci-dessous, et un lien vers votre réponse a été envoyé par courrier à "
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 ""
+msgstr "Merci pour la mise à jour de l'état de cette demande '<a href=\"{{url}}\">{{info_request_title}}</a>'. Il ya encore quelques demandes ci-dessous à classer ."
msgid "Thank you for updating this request!"
-msgstr ""
+msgstr "Merci pour la mise à jour de cette demande "
msgid "Thank you for updating your profile photo"
-msgstr ""
+msgstr "Merci pour la mise à jour de votre photo de profil"
msgid "Thank you! We'll look into what happened and try and fix it up."
-msgstr ""
+msgstr "Merci! Nous allons examiner ce qui s'est passé et essayer de le corriger."
msgid "Thanks for helping - your work will make it easier for everyone to find successful\\nresponses, and maybe even let us make league tables..."
-msgstr ""
+msgstr "Merci de nous aider - avec votre travail il sera plus facile pour tout le monde de trouver avec succès \\ n des réponses."
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 ""
+msgstr "Merci beaucoup - cela aidera les autres à trouver des choses utiles. Nous allons \\n aussi, si vous en avez besoin, donner des conseils sur ce qu'il faut faire au sujet de vos \\n demandes."
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 ""
+msgstr "Merci beaucoup - cela aidera les autres à trouver des choses utiles. Nous allons \\ n aussi, si vous en avez besoin, donner des conseils sur ce qu'il faut faire au sujet de votre \\ n demandes."
msgid "That doesn't look like a valid email address. Please check you have typed it correctly."
-msgstr ""
+msgstr "Ceci n'est pas une adresse mail valide . veuillez vérifier ce que vous avez entré "
msgid "The <strong>review has finished</strong> and overall:"
-msgstr ""
+msgstr "La <strong>révision terminée</strong> et en total:"
msgid "The Freedom of Information Act <strong>does not apply</strong> to"
-msgstr ""
+msgstr "Le droit d'accès à l'information <strong>ne s'applique pas </strong> à"
msgid "The accounts have been left as they previously were."
-msgstr ""
+msgstr "Les comptes sont laissés tels qu'ils étaient "
msgid "The authority do <strong>not have</strong> the information <small>(maybe they say who does)"
-msgstr ""
+msgstr "l'autorité <strong>ne détient pas </strong> l'information <small>(peut-être qu'ils disent qui l'a )</small>"
msgid "The authority only has a <strong>paper copy</strong> of the information."
-msgstr ""
+msgstr "L'autorité a uniquement <strong>la version en papier </strong> de cette information ."
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 ""
+msgstr "l'etablissement public dit qu'ils ont besoin d'une <strong> adresse postale </ strong>, et pas seulement un email, pour que ce soit une demande valide"
msgid "The authority would like to / has <strong>responded by post</strong> to this request."
-msgstr ""
+msgstr "L'autorité aimerait / a répondu <strong> par la poste </strong> à cette demande."
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."
-msgstr ""
+msgstr "Le message que vous , au nom de {{public_body}}, avez envoyé à \\n{{user}} en réponse à la demande {{law_used_short}}\\n n'a pas été delivré"
msgid "The page doesn't exist. Things you can try now:"
-msgstr ""
+msgstr "La page n'existe pas . Vous pouvez essayer de :"
msgid "The public authority does not have the information requested"
-msgstr ""
+msgstr "L'autorité administrative n'a pas les informations demandées"
msgid "The public authority would like part of the request explained"
-msgstr ""
+msgstr "L'autorité administrative aimerait l'explication de la demande "
msgid "The public authority would like to / has responded by post"
-msgstr ""
+msgstr "L'autorité administrative aimerait / a répondu par courrier"
msgid "The request has been <strong>refused</strong>"
-msgstr ""
+msgstr "La demande a été <strong>refusée</strong>"
msgid "The request has been updated since you originally loaded this page. Please check for any new incoming messages below, and try again."
-msgstr ""
+msgstr "La demande a été mise à jour depuis que vous avez chargé cette page. Veuillez vérifier tous les nouveaux messages ci-dessous et réessayez."
msgid "The request is <strong>waiting for clarification</strong>."
-msgstr ""
+msgstr "La demande est <strong>En attente de clarification</strong>."
msgid "The request was <strong>partially successful</strong>."
-msgstr ""
+msgstr "La demande est <strong>partiellement reussie</strong>."
msgid "The request was <strong>refused</strong> by"
-msgstr ""
+msgstr "La demande est <strong>rejetée</strong> par"
msgid "The request was <strong>successful</strong>."
-msgstr ""
+msgstr "La demande est <strong>réussie</strong>."
msgid "The request was refused by the public authority"
-msgstr ""
+msgstr "La demande a été rejetée par l'autorité publique"
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=\"{{url}}\">contact us</a> if you have any questions."
-msgstr ""
+msgstr "La demande que vous avez essayé de voir a été retiré. Il ya \\n plusieurs raisons pour lesquelles nous aurions fait cela, désolé nous ne pouvons pas être plus précis ici . Veuillez <a\\n href=\"{{url}}\">nous contacter </a>si vous avez des questions."
msgid "The requester has abandoned this request for some reason"
-msgstr ""
+msgstr "Le demandeur a renoncé à cette demandepour une raison quelconque"
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 ""
+msgstr "La réponse a votre demande a été <strong> retardée </strong> . Vous pouvez dire que \\n légalement ; l'organisme public aurait dû répondre \\n <strong>rapidement</strong> et "
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 ""
+msgstr "La réponse a votre demande est <strong>très en retard </strong>. Vous pouvez dire que selon la loi , en toutes circonstances, l'autorité aurait dû répondre \\n maintenant "
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 "Les fonctionnalités de recherche sont temporairement indisponibles. C'est pour cette raison que nous ne pouvons afficher les demandes d'information relative à cette institution."
msgid "The search index is currently offline, so we can't show the Freedom of Information requests this person has made."
+msgstr "Les fonctionnalités de recherche sont temporairement indisponibles , donc nous ne pouvons pas afficher les demandes d'accès à l'information que cette personne a effectué"
+
+msgid "The {{site_name}} team."
msgstr ""
msgid "Then you can cancel the alert."
-msgstr ""
+msgstr "Vous pouvez annuler l'alerte"
msgid "Then you can cancel the alerts."
-msgstr ""
+msgstr "après vous pouvez annuler les alertes "
msgid "Then you can change your email address used on {{site_name}}"
-msgstr ""
+msgstr "après vous pouvez changer l'adresse mail utilisée sur {{site_name}}"
msgid "Then you can change your password on {{site_name}}"
-msgstr ""
+msgstr "Ensuite, vous pouvez changer votre mot de passe sur {{site_name}}"
msgid "Then you can classify the FOI response you have got from "
-msgstr ""
+msgstr "Ensuite, vous pouvez classer la réponse que vous avez obtenu à partir de"
msgid "Then you can download a zip file of {{info_request_title}}."
-msgstr ""
+msgstr "Ensuite, vous pouvez télécharger un fichier zip {{info_request_title}}."
msgid "Then you can log into the administrative interface"
-msgstr ""
+msgstr "Ensuite, vous pouvez vous connecter à l'interface d'administration"
msgid "Then you can play the request categorisation game."
-msgstr ""
+msgstr "Ensuite, vous pouvez jouer le jeu de catégorisation de demande."
msgid "Then you can report the request '{{title}}'"
-msgstr ""
+msgstr "Ensuite, vous pouvez signaler la demande '{{title}}'"
msgid "Then you can send a message to "
-msgstr ""
+msgstr "Ensuite, vous pouvez envoyer un message à"
msgid "Then you can sign in to {{site_name}}"
-msgstr ""
+msgstr "Ensuite, vous pouvez vous connecter à {{site_name}}"
msgid "Then you can update the status of your request to "
-msgstr ""
+msgstr "Ensuite, vous pouvez mettre à jour l'état de votre demande à"
msgid "Then you can upload an FOI response. "
-msgstr ""
+msgstr "Ensuite, vous pouvez uploader une réponse "
msgid "Then you can write follow up message to "
-msgstr ""
+msgstr "Ensuite, vous pouvez écrire un message suivi pour"
msgid "Then you can write your reply to "
-msgstr ""
+msgstr "Ensuite, vous pouvez écrire votre réponse à"
msgid "Then you will be following all new FOI requests."
-msgstr ""
+msgstr "Ensuite vous suiverez toutes les nouvelles demandes ."
msgid "Then you will be notified whenever '{{user_name}}' requests something or gets a response."
-msgstr ""
+msgstr "Ensuite, vous serez averti à chaque fois '{{user_name}}' demande quelque chose ou obtient une réponse."
msgid "Then you will be notified whenever a new request or response matches your search."
-msgstr ""
+msgstr "Ensuite, vous serez averti à chaque fois une nouvelle demande ou d'une réponse correspond à votre recherche."
msgid "Then you will be notified whenever an FOI request succeeds."
-msgstr ""
+msgstr "Ensuite, vous serez averti à chaque fois qu'une demande réussit."
msgid "Then you will be notified whenever someone requests something or gets a response from '{{public_body_name}}'."
-msgstr ""
+msgstr "Ensuite, vous serez averti chaque fois que quelqu'un demande quelque chose ou obtient une réponse de '{{public_body_name}}'."
msgid "Then you will be updated whenever the request '{{request_title}}' is updated."
-msgstr ""
+msgstr "Ensuite, vous serez notifié à chaque fois que la demande '{{request_title}}' est mise à jour"
msgid "Then you'll be allowed to send FOI requests."
msgstr "Ensuite, vous serez autorisé à envoyer des demandes d'accès."
msgid "Then your FOI request to {{public_body_name}} will be sent."
-msgstr ""
+msgstr "Ensuite vôtre demande à {{public_body_name}} sera envoyée."
msgid "Then your annotation to {{info_request_title}} will be posted."
-msgstr ""
+msgstr "Ensuite vôtre remarque sur {{info_request_title}} va être postée "
msgid "There are {{count}} new annotations on your {{info_request}} request. Follow this link to see what they wrote."
-msgstr ""
+msgstr "Il y a {{count}} nouvelles annotations sur vôtre demande {{info_request}} . Suivez ce lien pour voir ce qu'ils ont écrit."
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 ""
+msgstr "Il ya plus <strong> d'une personne </strong> qui utilise ce site et qui a ce nom \\n , dont un est affiché ci dessous , peut etre vous cherchez une personne différente ."
msgid "There is a limit on the number of requests you can make in a day, because we don’t want public authorities to be bombarded with large numbers of inappropriate requests. If you feel you have a good reason to ask for the limit to be lifted in your case, please <a href='{{help_contact_path}}'>get in touch</a>."
-msgstr ""
+msgstr "Il ya une limite sur le nombre de demandes que vous pouvez faire en une journée, parce que nous ne voulons pas que les autorités publiques soient bombardés avec un grand nombre de demandes inappropriées. Si vous sentez que vous avez une bonne raison de demander que la limite soit levée pour vous, veuillez <a href='{{help_contact_path}}'>contacter nous</a>."
msgid "There is {{count}} person following this request"
msgid_plural "There are {{count}} people following this request"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "Il ya une personne suivant cette demande "
+msgstr[1] "Il ya {{count}} personnes suivant cette demande "
msgid "There was a <strong>delivery error</strong> or similar, which needs fixing by the {{site_name}} team."
-msgstr ""
+msgstr "Il y avait <strong> une erreur de transmission r</strong> ou autre , qui doit être réparée par l'équipe {{site_name}}."
msgid "There was an error with the words you entered, please try again."
-msgstr ""
+msgstr "Il y a une erreur liée aux mots que vous avez saisies, veuillez réessayer."
msgid "There were no requests matching your query."
msgstr "Aucune demande d'information ne correspond à votre recherche."
msgid "There were no results matching your query."
-msgstr ""
+msgstr "Aucun résultat correspondant à votre recherche."
msgid "They are going to reply <strong>by post</strong>"
-msgstr ""
+msgstr "Ils vont répondre <strong>par courrier</strong>"
msgid "They do <strong>not have</strong> the information <small>(maybe they say who does)</small>"
-msgstr ""
+msgstr "Ils <strong>ne détiennent pas </strong> l'information <small>(peut-être qu'ils disent qui l'a )</small>"
msgid "They have been given the following explanation:"
-msgstr ""
+msgstr "On leur a donné l'explication suivante:"
msgid "They have not replied to your {{law_used_short}} request {{title}} promptly, as normally required by law"
-msgstr ""
+msgstr "Ils n'ont pas répondu à votre {{law_used_short}} demande {{title}} rapidement , normalement requis par la loi."
msgid "They have not replied to your {{law_used_short}} request {{title}}, \\nas required by law"
-msgstr ""
+msgstr "N'ont pas répondu à votre {{law_used_short}} demande {{title}}, \\n comme la loi l'oblige "
msgid "Things to do with this request"
-msgstr ""
+msgstr "Choses à faire avec cette demande"
msgid "Things you're following"
-msgstr ""
+msgstr "Choses que vous suivez"
msgid "This authority no longer exists, so you cannot make a request to it."
msgstr "Cette institution n'existe plus."
msgid "This comment has been hidden. See annotations to\\n find out why. If you are the requester, then you may <a href=\"{{url}}\">sign in</a> to view the response."
-msgstr ""
+msgstr "Ce commentaire a été caché . Voir les annotations ci dessous pour \\n savoir pourquoi. Si vous êtes le demandeur, alors vous pouvez<a href=\"{{url}}\">vous connecter </a> pour voir la réponse."
msgid "This covers a very wide spectrum of information about the state of\\n the <strong>natural and built environment</strong>, such as:"
msgstr "Cela couvre un très large spectre d'informations sur l'état de <strong>l'environnement naturel et construit par l'homme,</strong> comme par exemple :"
msgid "This external request has been hidden"
-msgstr ""
+msgstr "Demande externe cachée"
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 ""
+msgstr "Ceci est une version textuelle de la demande d'accès à l'information \"{{request_title}}\". La dernière version complète est disponible en ligne à {{full_url}}"
msgid "This is an HTML version of an attachment to the Freedom of Information request"
-msgstr ""
+msgstr "Ceci est une version HTML d'une pièce jointe à la demande d'accès à l'information"
msgid "This is because {{title}} is an old request that has been\\nmarked to no longer receive responses."
-msgstr ""
+msgstr "C'est parce que {{title}} est une vieille demande qui a été \\n marquée pour ne plus recevoir de réponses."
msgid "This is the first version."
-msgstr ""
+msgstr "Ceci est la première version."
msgid "This is your own request, so you will be automatically emailed when new responses arrive."
-msgstr ""
+msgstr "Ceci est votre propre demande, afin que vous recevrez automatiquement un e-mail dès que de nouvelles réponses arrivent"
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=\"{{url}}\">sign in</a> to view the response."
-msgstr ""
+msgstr "Ce message sortant a été caché. Voir les commentaires pour \\n\t\t\t\t\t\tsavoir pourquoi. Si vous êtes le demandeur, alors vous pouvez <a href=\"{{url}}\">vous connecter </a>pour voir la réponse."
msgid "This particular request is finished:"
-msgstr ""
+msgstr "Cette demande particulière est achevée:"
msgid "This person has made no Freedom of Information requests using this site."
-msgstr ""
+msgstr "Cette personne n'a pas fait de demandes d'accès à l'information via de ce site"
msgid "This person's annotations"
-msgstr ""
+msgstr "Les annotations de cette personne"
msgid "This person's {{count}} Freedom of Information request"
msgid_plural "This person's {{count}} Freedom of Information requests"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "La demande d'accès a l'infromation de cette personne"
+msgstr[1] "Les {{count}} demandes d'accès a l'infromation de cette personne"
msgid "This person's {{count}} annotation"
msgid_plural "This person's {{count}} annotations"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "Le commentaire de cette personne "
+msgstr[1] "Les {{count}} commentaires de cette personne "
msgid "This request <strong>requires administrator attention</strong>"
-msgstr ""
+msgstr "Cette demande <strong> nécessite une attention de l'administrateur </strong>"
msgid "This request has already been reported for administrator attention"
-msgstr ""
+msgstr "Cette demande a déjà été signalé à l'attention de l'administrateur"
msgid "This request has an <strong>unknown status</strong>."
-msgstr ""
+msgstr "Cette demande a <strong> un statut inconnu </strong>."
msgid "This request has been <strong>hidden</strong> from the site, because an administrator considers it not to be an FOI request"
-msgstr ""
+msgstr "Cette demande a été <strong>cachée</strong> du site parce que l'administrateur la considere comme étant non liée au droit d'accès a l'information"
msgid "This request has been <strong>hidden</strong> from the site, because an administrator considers it vexatious"
-msgstr ""
+msgstr "Cette demande a été <strong>cachée</strong> du site parce qu'un administrateur la considère comme contrariante"
msgid "This request has been <strong>reported</strong> as needing administrator attention (perhaps because it is vexatious, or a request for personal information)"
-msgstr ""
+msgstr "Cette demande a été <strong>signalée</strong> (peut-être parce qu'elle est vexatoire, ou une demande de renseignements personnels)"
msgid "This request has been <strong>withdrawn</strong> by the person who made it.\\n There may be an explanation in the correspondence below."
-msgstr ""
+msgstr "Cette demande a été <strong> retirée </strong> par la personne qui l'a fait . \\n Il ya peut etre une explication ci dessous ."
msgid "This request has been marked for review by the site administrators, who have not hidden it at this time. If you believe it should be hidden, please <a href=\"{{url}}\">contact us</a>."
-msgstr ""
+msgstr "Cette demande a été marquée pour révision par les administrateurs du site, qui ne l'ont pas cachés à ce moment. Si vous pensez qu'elle doit être cachée , Veuillez <a href=\"{{url}}\">Nous contacter</a>."
msgid "This request has been reported for administrator attention"
-msgstr ""
+msgstr "Cette demande a été signalée "
msgid "This request has been set by an administrator to \"allow new responses from nobody\""
-msgstr ""
+msgstr "Cette demande a été définie par un administrateur de sorte à \" permettre à de nouvelles réponses de nobody\""
msgid "This request has had an unusual response, and <strong>requires attention</strong> from the {{site_name}} team."
-msgstr ""
+msgstr "Cette demande a eu une réponse inhabituelle, et <strong>necessite l'attention</strong> de l'équipe {{site_name}} ."
msgid "This request has prominence 'hidden'. You can only see it because you are logged\\n in as a super user."
-msgstr ""
+msgstr "Cette demande est cachée . Vous pouvez uniquement la voir parce que vous etes administrateur ."
msgid "This request is hidden, so that only you the requester can see it. Please\\n <a href=\"{{url}}\">contact us</a> if you are not sure why."
-msgstr ""
+msgstr "Cette demande est masquée, uniquement le demandeur peut la voir.Veuillez <a href=\"{{url}}\">Nous contacter </a> si vous voulez en savoir plus "
msgid "This request is still in progress:"
-msgstr ""
+msgstr "Cette demande est encore en cours:"
msgid "This request requires administrator attention"
-msgstr ""
+msgstr "Cette demande nécessite une attention de l'administrateur "
msgid "This request was not made via {{site_name}}"
-msgstr ""
+msgstr "cette demande n'a pas été faite à travers {{site_name}}"
msgid "This response has been hidden. See annotations to find out why.\\n If you are the requester, then you may <a href=\"{{url}}\">sign in</a> to view the response."
-msgstr ""
+msgstr "Cette réponse a été cachée. Voir les commentaires pour savoir pourquoi. \\n Si vous êtes le demandeur, alors vous pouvez <a href=\"{{url}}\">vous connecter</a> pour voir la réponse."
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."
-msgstr ""
+msgstr "Ce tableau présente les détails techniques des événements internes qui ont eu lieu \\n à cette demande sur {{site_name}}. Cela pourrait être utilisé pour générer des informations sur \\n la vitesse avec laquelle les autorités répondent aux demandes, le nombre de demandes \\n qui nécessitent une réponse postale et bien plus encore."
msgid "This user has been banned from {{site_name}} "
-msgstr ""
+msgstr "Cet utilisateur a été banni de {{site_name}}"
msgid "This was not possible because there is already an account using \\nthe email address {{email}}."
-msgstr ""
+msgstr "Ceci n'est pas possible parce qu'il existe deja un compte utilisant l'adresse mail {{email}}."
msgid "To cancel these alerts"
-msgstr ""
+msgstr "Pour annuler ces alertes"
msgid "To cancel this alert"
-msgstr ""
+msgstr "Pour annuler cette alerte"
msgid "To carry on, you need to sign in or make an account. Unfortunately, there\\nwas a technical problem trying to do this."
-msgstr ""
+msgstr "Pour continuer, vous devez vous connecter ou créer un compte. Malheureusement, il \\n avait un problème technique en essayant de le faire."
msgid "To change your email address used on {{site_name}}"
-msgstr ""
+msgstr "Pour changer votre adresse e-mail utilisée sur {{site_name}}"
msgid "To classify the response to this FOI request"
-msgstr ""
+msgstr "Pour classer la réponse à cette demande d'accès a l'information"
msgid "To do that please send a private email to "
-msgstr ""
+msgstr "Pour ce faire, veuillez envoyer un courriel privé à"
msgid "To do this, first click on the link below."
-msgstr ""
+msgstr "Pour ce faire, cliquez d'abord sur le lien ci-dessous."
msgid "To download the zip file"
-msgstr ""
+msgstr "Pour télécharger le fichier zip"
msgid "To follow all successful requests"
-msgstr ""
+msgstr "Pour suivre toutes les demandes réussies"
msgid "To follow new requests"
-msgstr ""
+msgstr "Pour suivre les nouvelles demandes"
msgid "To follow requests and responses matching your search"
msgstr "Pour suivre les demandes d'information et les réponses correspondant à votre recherche"
msgid "To follow requests by '{{user_name}}'"
-msgstr ""
+msgstr "Pour suivre toutes les demandes effectuées par '{{user_name}}'"
msgid "To follow requests made using {{site_name}} to the public authority '{{public_body_name}}'"
-msgstr ""
+msgstr "Pour suivre les demandes effectuées a travers {{site_name}} a l'organisme publique '{{public_body_name}}'"
msgid "To follow the request '{{request_title}}'"
-msgstr ""
+msgstr "Pour suivre la demande '{{request_title}}'"
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 ""
+msgstr "Pour nous aider à maintenir ce site , une personne a mis a jour l'état de la \\n{{law_used_full}} demande {{title}} - que vous avez adressée à {{public_body}} - à \"{{display_status}}\" . Si vous êtes en désaccord avec leur catégorisation, s'il vous plaît mettre à jour le statut de nouveau vous-même à ce que vous croyez être plus précis."
msgid "To let everyone know, follow this link and then select the appropriate box."
-msgstr ""
+msgstr "Pour faire savoira tout le monde , suivez ce lien et sélectionnez ensuite la case appropriée"
msgid "To log into the administrative interface"
-msgstr ""
+msgstr "Pour vous connecter à l'interface Admin"
msgid "To play the request categorisation game"
-msgstr ""
+msgstr "Pour jouer au jeu de catégorisation de demande"
msgid "To post your annotation"
-msgstr ""
+msgstr "Pour soumettre votre annotation"
msgid "To reply to "
-msgstr ""
+msgstr "Répondre à"
msgid "To report this FOI request"
-msgstr ""
+msgstr "Pour signaler cette demande "
msgid "To send a follow up message to "
-msgstr ""
+msgstr "Pour envoyer un message de suivi à"
msgid "To send a message to "
-msgstr ""
+msgstr "Pour envoyer un message à"
msgid "To send your FOI request"
-msgstr ""
+msgstr "Pour envoyer une demande d'accès à l'information "
msgid "To update the status of this FOI request"
-msgstr ""
+msgstr "Pour mettre à jour l'état de cette demande "
msgid "To upload a response, you must be logged in using an email address from "
-msgstr ""
+msgstr "Pour télécharger une réponse, vous devez être connecté en utilisant une adresse e-mail de"
msgid "To use the advanced search, combine phrases and labels as described in the search tips below."
msgstr "Pour utiliser la recherche avancée, associez les termes et les étiquettes comme indiqué dans les conseils ci-dessous."
msgid "To view the email address that we use to send FOI requests to {{public_body_name}}, please enter these words."
-msgstr ""
+msgstr "Pour afficher l'adresse email que nous utilisons pour envoyer des demandes d'accès à l'information {{public_body_name}}, veuillez saisir ces mots."
msgid "To view the response, click on the link below."
-msgstr ""
+msgstr "Pour voir la réponse, cliquez sur le lien ci-dessous."
msgid "To {{public_body_link_absolute}}"
-msgstr ""
+msgstr "à {{public_body_link_absolute}}"
msgid "To:"
-msgstr ""
+msgstr "à:"
msgid "Today"
msgstr "Aujourd'hui"
msgid "Too many requests"
-msgstr ""
+msgstr "Trop de demandes "
msgid "Top search results:"
msgstr "Résultats les plus pertinents :"
msgid "Track thing"
-msgstr ""
+msgstr "Suivre chose"
msgid "Track this person"
-msgstr ""
+msgstr "Suivre cette personne"
msgid "Track this search"
-msgstr ""
+msgstr "Suivre cette recherche"
msgid "TrackThing|Track medium"
-msgstr ""
+msgstr "TrackThing|Track medium"
msgid "TrackThing|Track query"
-msgstr ""
+msgstr "TrackThing|Track query"
msgid "TrackThing|Track type"
-msgstr ""
+msgstr "TrackThing|Track type"
msgid "Turn off email alerts"
-msgstr ""
+msgstr "Désactiver les alertes e-mail"
msgid "Tweet this request"
msgstr "Partager cette demande d'information sur Twitter"
@@ -2558,43 +2564,43 @@ msgid "URL name can't be blank"
msgstr "Le champs URL ne peut être vide"
msgid "Unable to change email address on {{site_name}}"
-msgstr ""
+msgstr "Impossible de changer l'adresse email sur {{site_name}}"
msgid "Unable to send a reply to {{username}}"
-msgstr ""
+msgstr "Impossible d'envoyer une réponse à {{username}}"
msgid "Unable to send follow up message to {{username}}"
-msgstr ""
+msgstr "Impossible d'envoyer un message de suivi à {{username}}"
msgid "Unexpected search result type"
-msgstr ""
+msgstr "Type de résultat de recherche inattendu"
msgid "Unexpected search result type "
-msgstr ""
+msgstr "Type de résultat de recherche inattendu"
msgid "Unfortunately we don't know the FOI\\nemail address for that authority, so we can't validate this.\\nPlease <a href=\"{{url}}\">contact us</a> to sort it out."
-msgstr ""
+msgstr "Malheureusement, nous ne connaissons pas l'adresse email pour cette autorité, nous ne pouvons pas valider ça. \\n Veuillez {{url}}\">Nous contacter</a> pour règler ça."
msgid "Unfortunately, we do not have a working {{info_request_law_used_full}}\\naddress for"
-msgstr ""
+msgstr "Malheureusement, nous n'avons pas d'adresse {{info_request_law_used_full}} pour"
msgid "Unknown"
-msgstr ""
+msgstr "Inconnu"
msgid "Unsubscribe"
-msgstr ""
+msgstr "désabonner"
msgid "Unusual response."
-msgstr ""
+msgstr "Réponse intattendue"
msgid "Update the status of this request"
-msgstr ""
+msgstr "Mettre à jour l'état de cette demande"
msgid "Update the status of your request to "
-msgstr ""
+msgstr "Mettre à jour l'état de cette demande à"
msgid "Upload FOI response"
-msgstr ""
+msgstr "Uploader une réponse"
msgid "Use OR (in capital letters) where you don't mind which word, e.g. <strong><code>commons OR lords</code></strong>"
msgstr "Utilisez OR (en majuscules) pour indiquer que l'ordre des mots n'importe pas, \\n\\n par exemple, <code><strong>sénat OR assemblée</strong></code>"
@@ -2603,82 +2609,82 @@ msgid "Use quotes when you want to find an exact phrase, e.g. <strong><code>\"Li
msgstr "Utilisez les guillemets pour une expression exacte, par exemple, <code><strong>\"Conseil de l'europe\"</strong></code>"
msgid "User"
-msgstr ""
+msgstr "Utilisateur"
msgid "User info request sent alert"
-msgstr ""
+msgstr "Alerte envoyée"
msgid "User – {{name}}"
-msgstr ""
+msgstr "Utilisateur– {{name}}"
msgid "UserInfoRequestSentAlert|Alert type"
-msgstr ""
+msgstr "UserInfoRequestSentAlert|Alert type"
msgid "User|About me"
-msgstr ""
+msgstr "User|About me"
msgid "User|Address"
-msgstr ""
+msgstr "User|Address"
msgid "User|Admin level"
-msgstr ""
+msgstr "User|Admin level"
msgid "User|Ban text"
-msgstr ""
+msgstr "User|Ban text"
msgid "User|Dob"
-msgstr ""
+msgstr "User|Dob"
msgid "User|Email"
-msgstr ""
+msgstr "User|Email"
msgid "User|Email bounce message"
-msgstr ""
+msgstr "User|Email bounce message"
msgid "User|Email bounced at"
-msgstr ""
+msgstr "User|Email bounced at"
msgid "User|Email confirmed"
-msgstr ""
+msgstr "User|Email confirmed"
msgid "User|Hashed password"
-msgstr ""
+msgstr "User|Hashed password"
msgid "User|Last daily track email"
-msgstr ""
+msgstr "User|Last daily track email"
msgid "User|Locale"
-msgstr ""
+msgstr "User|Locale"
msgid "User|Name"
-msgstr ""
+msgstr "User|Name"
msgid "User|No limit"
-msgstr ""
+msgstr "User|No limit"
msgid "User|Receive email alerts"
-msgstr ""
+msgstr "User|Receive email alerts"
msgid "User|Salt"
-msgstr ""
+msgstr "User|Salt"
msgid "User|Url name"
-msgstr ""
+msgstr "User|Url name"
msgid "Version {{version}}"
-msgstr ""
+msgstr "Version {{version}}"
msgid "View FOI email address"
-msgstr ""
+msgstr "Voir les adresses mail "
msgid "View FOI email address for '{{public_body_name}}'"
-msgstr ""
+msgstr "Voir l'adresse mail pour '{{public_body_name}}'"
msgid "View FOI email address for {{public_body_name}}"
-msgstr ""
+msgstr "voir l'adresse mail pour {{public_body_name}}"
msgid "View Freedom of Information requests made by {{user_name}}:"
-msgstr ""
+msgstr "Voir les demandes faites par {{user_name}}:"
msgid "View and search requests"
msgstr "Visualiser et parcourir les demandes d'information"
@@ -2687,313 +2693,326 @@ msgid "View authorities"
msgstr "Voir institutions publiques"
msgid "View email"
-msgstr ""
+msgstr "Voir mail :"
msgid "View requests"
msgstr "Voir requêtes"
msgid "Waiting clarification."
-msgstr ""
+msgstr "En attente de clarification"
msgid "Waiting for an <strong>internal review</strong> by {{public_body_link}} of their handling of this request."
-msgstr ""
+msgstr "En attente <strong>d'une révision interne</strong> par {{public_body_link}} a propos de leur gestion de la demande."
msgid "Waiting for the public authority to complete an internal review of their handling of the request"
-msgstr ""
+msgstr "En attente de l'autorité administrative pour compléter une révision interne de leur gestion de la demande"
msgid "Waiting for the public authority to reply"
-msgstr ""
+msgstr "En attente de la réponse de l'autorité administrative"
msgid "Was the response you got to your FOI request any good?"
+msgstr "Est ce que vous êtes satisfait de la réponse que vous avez eu ?"
+
+msgid "We consider it is not a valid FOI request, and have therefore hidden it from other users."
msgstr ""
-msgid "We do not have a working request email address for this authority."
+msgid "We consider it to be vexatious, and have therefore hidden it from other users."
msgstr ""
+msgid "We do not have a working request email address for this authority."
+msgstr "Nous n'avons pas d'adresse email valide pour cette autorité."
+
msgid "We do not have a working {{law_used_full}} address for {{public_body_name}}."
-msgstr ""
+msgstr "Nous ne disposons pas d'adresse {{law_used_full}} pour {{public_body_name}}."
msgid "We don't know whether the most recent response to this request contains\\n information or not\\n &ndash;\\n\tif you are {{user_link}} please <a href=\"{{url}}\">sign in</a> and let everyone know."
-msgstr ""
+msgstr "Nous ne savons pas si la réponse la plus récente à cette demande contient l'information \\n ou non \\n &ndash;\\n\tsi vous etes {{user_link}} veuillez <a href=\"{{url}}\">vous connecter</a> et laisser nous savoir."
msgid "We will not reveal your email address to anybody unless you or\\n the law tell us to (<a href=\"{{url}}\">details</a>). "
-msgstr ""
-"Nous ne communiquerons pas votre adresse e-mail sauf si vous nous y \n"
-" autorisez ou si la loi nous y oblige (<a href=\"{{url}}\">détails</a>). "
+msgstr "Nous ne communiquerons pas votre adresse e-mail sauf si vous nous y autorisez ou si la loi nous y oblige (<a href=\"{{url}}\">détails</a>). "
msgid "We will not reveal your email address to anybody unless you\\nor the law tell us to."
-msgstr ""
+msgstr "Nous ne communiquerons pas votre adresse e-mail sauf si vous nous y autorisez ou si la loi nous y oblige."
msgid "We will not reveal your email addresses to anybody unless you\\nor the law tell us to."
-msgstr ""
+msgstr "Nous ne communiquerons pas vos adresses e-mail sauf si vous nous y autorisez ou si la loi nous y oblige"
msgid "We're waiting for"
-msgstr ""
+msgstr "Nous attendons"
msgid "We're waiting for someone to read"
-msgstr ""
+msgstr "Nous attendons qu'une personne lise"
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."
-msgstr ""
+msgstr "Nous avons envoyé un email à votre nouvelle adresse email. Vous devez cliquer sur le lien là dedans \\n avant que votre adresse e-mail sera changé."
msgid "We've sent you an email, and you'll need to click the link in it before you can\\ncontinue."
-msgstr ""
+msgstr "Nous avons envoyé un email . Vous devez cliquer sur le lien dans \\n pour pouvoir continuer."
msgid "We've sent you an email, click the link in it, then you can change your password."
-msgstr ""
+msgstr "Nous vous avons envoyé un email , cliquez sur le lien qu'il contient pour changer votre mot de passe"
msgid "What are you doing?"
-msgstr ""
+msgstr "Qu'est ce que vous faites?"
msgid "What best describes the status of this request now?"
-msgstr ""
+msgstr "Quelle est la meilleure description de l'état de votre demande ?"
msgid "What information has been released?"
msgstr "Quelles informations ont été rendues publiques ?"
msgid "What information has been requested?"
-msgstr ""
+msgstr "Quelles sont les informations qui ont été demandées?"
msgid "When you get there, please update the status to say if the response \\ncontains any useful information."
-msgstr ""
+msgstr "Quand vous y arrivez, veuillez mettre à jour le statut et dire si la réponse \\n contient une information utile."
msgid "When you receive the paper response, please help\\n others find out what it says:"
-msgstr ""
+msgstr "Lorsque vous recevez la réponse sur papier, s'il vous plaît aidez \\n les autres à découvrir ce qu'elle contient:"
msgid "When you're done, <strong>come back here</strong>, <a href=\"{{url}}\">reload this page</a> and file your new request."
-msgstr ""
+msgstr "Lorsque vous aurez terminé, <strong> Revenez ici </ strong>, <a href=\"{{url}}\"> actualisez cette page </a> et déposez votre nouvelle demande."
msgid "Which of these is happening?"
-msgstr ""
+msgstr "Lequel se passe "
msgid "Who can I request information from?"
msgstr "A qui puis-je faire une demande d'information ?"
msgid "Withdrawn by the requester."
-msgstr ""
+msgstr "retirée par le demandeur "
msgid "Wk"
-msgstr ""
+msgstr "Wk"
msgid "Would you like to see a website like this in your country?"
msgstr "Soutenez-vous la création d'un site similaire dans votre pays ?"
msgid "Write a reply"
-msgstr ""
+msgstr "écrire une réponse "
msgid "Write a reply to "
-msgstr ""
+msgstr "écrire une réponse à"
msgid "Write your FOI follow up message to "
-msgstr ""
+msgstr "Ecrire votre message de suivi à"
msgid "Write your request in <strong>simple, precise language</strong>."
-msgstr ""
+msgstr "Formulez votre demande en langage <strong>simple et precis </strong>."
msgid "You"
-msgstr ""
+msgstr "Vous"
msgid "You are already following new requests"
-msgstr ""
+msgstr "Vous suivez déjà de nouvelles demandes"
msgid "You are already following requests to {{public_body_name}}"
-msgstr ""
+msgstr "Vous suivez déjà les demandes à {{public_body_name}}"
msgid "You are already following things matching this search"
-msgstr ""
+msgstr "Vous suivez déjà ce qui correspond à cette recherche"
msgid "You are already following this person"
-msgstr ""
+msgstr "Vous suivez déjà cette personne"
msgid "You are already following this request"
-msgstr ""
+msgstr "Vous suivez déjà cette demande"
msgid "You are already following updates about {{track_description}}"
-msgstr ""
+msgstr "Vous suivez déjà mises à jour sur {{track_description}}"
msgid "You are currently receiving notification of new activity on your wall by email."
-msgstr ""
+msgstr "Vous suivez actuellement des notifications a propos des nouvelles activités sur votre mur par email."
msgid "You are following all new successful responses"
-msgstr ""
+msgstr "vous suivez toutes les nouvelles réponses réussies"
msgid "You are no longer following {{track_description}}."
-msgstr ""
+msgstr "Vous ne suivez plus {{track_description}}."
msgid "You are now <a href=\"{{wall_url_user}}\">following</a> updates about {{track_description}}"
-msgstr ""
+msgstr "vous <a href=\"{{wall_url_user}}\">suivez </a>maintenant les mises à jour concernant {{track_description}}"
msgid "You can <strong>complain</strong> by"
-msgstr ""
+msgstr "Vous pouvez <strong>vous plaindre</strong> en "
msgid "You can change the requests and users you are following on <a href=\"{{profile_url}}\">your profile page</a>."
-msgstr ""
+msgstr "Vous pouvez modifier les demandes et les utilisateurs que vous suivez sur <a href=\"{{profile_url}}\">votre profil</a>."
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>."
-msgstr ""
+msgstr "Vous pouvez avoir cette page dans un format electronique en tant que partie du fichier JSON principal . Voir <a href=\"{{api_path}}\">API documentation</a>."
msgid "You can only request information about the environment from this authority."
msgstr "Vous ne pouvez demander des informations concernant l'environnement pour cette institution."
msgid "You have a new response to the {{law_used_full}} request "
-msgstr ""
+msgstr "Vous avez une nouvelle réponse à la demande {{law_used_full}} "
msgid "You have found a bug. Please <a href=\"{{contact_url}}\">contact us</a> to tell us about the problem"
msgstr "Vous avez identifié un bogue. Merci de <a href=\"{{contact_url}}\">nous contacter</a> pour nous signaler ce problème"
msgid "You have hit the rate limit on new requests. Users are ordinarily limited to {{max_requests_per_user_per_day}} requests in any rolling 24-hour period. You will be able to make another request in {{can_make_another_request}}."
-msgstr ""
+msgstr "Vous avez atteint la limite du nombre des nouvelles demandes. Les utilisateurs sont normalement limités à {max_requests_per_user_per_day}} demandes par jour . Vous serez en mesure de faire une autre demande dans {{can_make_another_request}}."
msgid "You have made no Freedom of Information requests using this site."
-msgstr ""
+msgstr "Vous n'avez jamais effectué de demandes d'accès à l'information en utilisant ce site"
msgid "You have now changed the text about you on your profile."
-msgstr ""
+msgstr "Vous avez changé votre description personnelle "
msgid "You have now changed your email address used on {{site_name}}"
-msgstr ""
+msgstr "Vous avez changé votre adresse mail utilisée dans {{site_name}}"
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."
-msgstr ""
+msgstr "Vous avez essayé de vous inscrire sur {{site_name}}, alors que vous avez \\n déjà un compte. Votre nom et mot de passe ont été \\n laissés comme ils étaient auparavant. \\n\\n S'il vous plaît cliquer sur le lien ci-dessous."
msgid "You know what caused the error, and can <strong>suggest a solution</strong>, such as a working email address."
-msgstr ""
+msgstr "Vous savez ce qui a causé l'erreur et pouvez <strong>recommender une solution </strong> , une adresse mail valide par exemple."
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 ""
+msgstr "Vous pouvez <strong> inclure des pièces jointes </ strong>. Si vous souhaitez joindre un fichier \\n trop volumineux pour le courrier électronique, utiliser le formulaire ci-dessous."
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=\"{{url}}\">send it to us</a>."
-msgstr ""
+msgstr "Vous pourrez peut-être trouver \\n un sur leur site Web ou en leur téléphonant et demander. Si vous parvenez \\n en trouver un, alors s'il vous plaît <a href=\"{{help_url}}\">contactez nous </a>."
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>."
-msgstr ""
+msgstr "Vous pourrez peut-être trouver \\n un sur leur site Web ou en leur téléphonant et demander. Si vous parvenez \\n en trouver un, alors s'il vous plaît <a href=\"{{help_url}}\">contactez nous </a>."
msgid "You need to be logged in to change the text about you on your profile."
-msgstr ""
+msgstr "Vous devez être connectés pour changer votre description personnelle"
msgid "You need to be logged in to change your profile photo."
-msgstr ""
+msgstr "Vous devez être connectés pour changer votre photo de profil "
msgid "You need to be logged in to clear your profile photo."
-msgstr ""
+msgstr "Vous devez être connectés pour supprimer votre photo de profil"
msgid "You need to be logged in to edit your profile."
-msgstr ""
+msgstr "Vous devez être connectés pour modifier votre profil"
msgid "You previously submitted that exact follow up message for this request."
-msgstr ""
+msgstr "Vous avez dejà utilisé le même commentaire pour cette demande ."
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 ""
+msgstr "Vous devriez avoir reçu une copie de la demande par e-mail, et vous pouvez répondre \\n en <strong> répondant simplement </ strong> à cet email. Pour plus de facilité voici l'adresse:"
msgid "You want to <strong>give your postal address</strong> to the authority in private."
-msgstr ""
+msgstr "Vous voulez <strong>donner votre adresse postale </strong>en privé à l'autorité administrative."
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."
-msgstr ""
+msgstr "Vous serez incapable de faire de nouvelles demandes, envoyer des suivis, ajouter des annotations ou \\n envoyer des messages à d'autres utilisateurs. Vous pouvez continuer à voir d'autres demandes, et recevoir \\n \\n des alertes e-mail."
msgid "You will no longer be emailed updates for those alerts"
-msgstr ""
+msgstr "Vous ne recevrez plus des mises à jour pour ces alertes "
msgid "You will now be emailed updates about {{track_description}}. <a href=\"{{change_email_alerts_url}}\">Prefer not to receive emails?</a>"
-msgstr ""
+msgstr "Vous allez recevoir des mails de mise à jour concernant {{track_description}}. <a href=\"{{change_email_alerts_url}}\"> vous préférez ne pas recevoir de emails?</a>"
msgid "You will only get an answer to your request if you follow up\\nwith the clarification."
+msgstr "Vous ne pourrez obtenir une réponse à votre demande que si vous envoyer une \\n clarification."
+
+msgid "You will still be able to view it while logged in to the site. Please reply to this email if you would like to discuss this decision further."
msgstr ""
msgid "You're in. <a href=\"#\" id=\"send-request\">Continue sending your request</a>"
-msgstr ""
+msgstr "Vous y etes . <a href=\"#\" id=\"send-request\">Continuer l'evoi de votre demande </a>"
msgid "You're long overdue a response to your FOI request - "
-msgstr ""
+msgstr "Vous attendez depuis longtemps une réponse à votre demande d'accès à l'information -"
msgid "You're not following anything."
-msgstr ""
+msgstr "Vous ne suivez rien ."
msgid "You've now cleared your profile photo"
-msgstr ""
+msgstr "Vous avez supprimé votre photo de profil"
msgid "Your <strong>name will appear publicly</strong>\\n (<a href=\"{{why_url}}\">why?</a>)\\n on this website and in search engines. If you\\n are thinking of using a pseudonym, please\\n <a href=\"{{help_url}}\">read this first</a>."
-msgstr ""
+msgstr "Votre <strong>nom va apparaître publiquement</strong>\\n (<a href=\"{{why_url}}\">pourqoi?</a>)\\n dans ce site et les moteurs de recherche . Si vous \\n vous pensez à utiliser un pseudo veuillez \\n <a href=\"{{help_url}}\">Lire ça </a>."
msgid "Your annotations"
-msgstr ""
+msgstr "Vos commentaires "
msgid "Your details, including your email address, have not been given to anyone."
-msgstr ""
+msgstr "Vos coordonnées, y compris votre adresse e-mail, n'ont été données à personne."
msgid "Your e-mail:"
-msgstr ""
+msgstr "Votre e-mail:"
msgid "Your follow up has not been sent because this request has been stopped to prevent spam. Please <a href=\"{{url}}\">contact us</a> if you really want to send a follow up message."
-msgstr ""
+msgstr "Votre suivi n'a pas été envoyé parce que cette demande a été arrêté afin de prévenir le spam. Veuillez <a href=\"{{url}}\">nous contacter</a>si vous voulez vraiment envoyer un message de suivi."
msgid "Your follow up message has been sent on its way."
-msgstr ""
+msgstr "Votre message de suivi à été envoyé ."
msgid "Your internal review request has been sent on its way."
-msgstr ""
+msgstr "Votre demande de révision interne a été envoyée "
msgid "Your message has been sent. Thank you for getting in touch! We'll get back to you soon."
-msgstr ""
+msgstr "Votre message a été envoyé . Merci de prendre contact! Nous reviendrons vers avec bientôt"
msgid "Your message to {{recipient_user_name}} has been sent"
-msgstr ""
+msgstr "Votre message à {{recipient_user_name}} a été envoyé"
msgid "Your message to {{recipient_user_name}} has been sent!"
-msgstr ""
+msgstr "Votre message à {{recipient_user_name}} a été envoyé!"
msgid "Your message will appear in <strong>search engines</strong>"
-msgstr ""
+msgstr "Votre message va apparaitre dans les <strong>Moteurs de recherche</strong>"
msgid "Your name and annotation will appear in <strong>search engines</strong>."
-msgstr ""
+msgstr "Votre nom et remarque vont apparaitre dans <strong>les moteurs de recherche</strong>."
msgid "Your name, request and any responses will appear in <strong>search engines</strong>\\n (<a href=\"{{url}}\">details</a>)."
-msgstr ""
+msgstr "Votre nom , demande et toute réponse vont apparaître dans les <strong>moteurs de recherche </strong>\\n (<a href=\"{{url}}\">details</a>)."
msgid "Your name:"
-msgstr ""
+msgstr "Votre nom:"
msgid "Your original message is attached."
-msgstr ""
+msgstr "Votre message original est attaché"
msgid "Your password has been changed."
-msgstr ""
+msgstr "Votre mot de passe a été changé"
msgid "Your password:"
-msgstr ""
+msgstr "Votre mot de passe :"
msgid "Your photo will be shown in public <strong>on the Internet</strong>,\\n wherever you do something on {{site_name}}."
+msgstr "Votre photo va apparaitre publiquement <strong> sur internet </strong> ,\\n a chaque fois que vous changez quelque chose sur {{site_name}}."
+
+msgid "Your request '{{request}}' at {{url}} has been reviewed by moderators."
msgstr ""
-msgid "Your request was called {{info_request}}. Letting everyone know whether you got the information will help us keep tabs on"
+msgid "Your request on {{site_name}} hidden"
msgstr ""
+msgid "Your request was called {{info_request}}. Letting everyone know whether you got the information will help us keep tabs on"
+msgstr "Votre demande est appelée {{info_request}} . En laissant tout le monde savoir si vous avez obtenu l'information nous aidera a suivre "
+
msgid "Your request:"
-msgstr ""
+msgstr "Votre demande:"
msgid "Your response to an FOI request was not delivered"
-msgstr ""
+msgstr "Votre réponse n'a pas été délivrée"
msgid "Your response will <strong>appear on the Internet</strong>, <a href=\"{{url}}\">read why</a> and answers to other questions."
-msgstr ""
+msgstr "Votre réponse va <strong>apparaître sur l'internet </strong>, <a href=\"{{url}}\">lire pourquoi</a> et répondre aux autres questions."
msgid "Your thoughts on what the {{site_name}} <strong>administrators</strong> should do about the request."
-msgstr ""
+msgstr "Vos idées sur ce que les <strong>administrateurs</strong> de {{site_name}} devraient faire a propos de la demande."
msgid "Your {{count}} Freedom of Information request"
msgid_plural "Your {{count}} Freedom of Information requests"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "Votre {{count}} demande d'accès à l'information"
+msgstr[1] "Vos {{count}} demandes d'accès à l'information"
msgid "Your {{count}} annotation"
msgid_plural "Your {{count}} annotations"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "Votre {{count}} remarque"
+msgstr[1] "Vos {{count}} remarques"
msgid "Your {{site_name}} email alert"
-msgstr ""
+msgstr "Votre alerte mail de {{site_name}}"
msgid "Yours faithfully,"
msgstr "Je vous prie de croire, Monsieur/Madame, à l'assurance de mes salutations distinguées,"
@@ -3001,26 +3020,29 @@ msgstr "Je vous prie de croire, Monsieur/Madame, à l'assurance de mes salutatio
msgid "Yours sincerely,"
msgstr "Je vous prie de croire, Monsieur/Madame, à l'assurance de mes salutations distinguées,"
-msgid "[FOI #{{request}} email]"
+msgid "Yours,"
msgstr ""
+msgid "[FOI #{{request}} email]"
+msgstr "[FOI #{{request}} email]"
+
msgid "[{{public_body}} request email]"
-msgstr ""
+msgstr "[{{public_body}} request email]"
msgid "[{{site_name}} contact email]"
-msgstr ""
+msgstr "[{{site_name}} contact email]"
msgid "\\n\\n[ {{site_name}} note: The above text was badly encoded, and has had strange characters removed. ]"
-msgstr ""
+msgstr "\\n\\n[ {{site_name}} Remarque: Le texte ci-dessus a été mal codé, et les caractères étranges sont supprimés ]"
msgid "a one line summary of the information you are requesting, \\n\t\t\te.g."
-msgstr ""
+msgstr "un résumé d'une ligne de l'information que vous demandez, \\n\t\t\te.g."
msgid "admin"
msgstr "admin"
msgid "alaveteli_foi:The software that runs {{site_name}}"
-msgstr ""
+msgstr "alaveteli_foi:The software that runs {{site_name}}"
msgid "all requests"
msgstr "toutes les demandes"
@@ -3029,34 +3051,34 @@ msgid "also called {{public_body_short_name}}"
msgstr "aussi appelé {{public_body_short_name}}"
msgid "an anonymous user"
-msgstr ""
+msgstr "un utilisateur anonyme"
msgid "and"
msgstr "et"
msgid "and update the status accordingly. Perhaps <strong>you</strong> might like to help out by doing that?"
-msgstr ""
+msgstr "Et mettre à jour par conséquent. Peut être <strong>vous</strong> voudriez nous aider en faisant ça?"
msgid "and update the status."
-msgstr ""
+msgstr "et mettre à jour l'état"
msgid "and we'll suggest <strong>what to do next</strong>"
-msgstr ""
+msgstr "Et on va suggérer <strong>quoi faire après</strong>"
msgid "any <a href=\"/list\">new requests</a>"
-msgstr ""
+msgstr "Toutes <a href=\"/list\">les nouvelles demandes</a>"
msgid "any <a href=\"/list/successful\">successful requests</a>"
-msgstr ""
+msgstr "toutes <a href=\"/list/successful\">les demandes réussies</a>"
msgid "anything"
-msgstr ""
+msgstr "tout"
msgid "are long overdue."
-msgstr ""
+msgstr "sont en retard"
msgid "at"
-msgstr ""
+msgstr "à"
msgid "authorities"
msgstr "institutions"
@@ -3065,88 +3087,88 @@ msgid "awaiting a response"
msgstr "en attente d'une réponse"
msgid "beginning with ‘{{first_letter}}’"
-msgstr ""
+msgstr "Commençant par ‘{{first_letter}}’"
msgid "between two dates"
msgstr "entre deux dates"
msgid "but followupable"
-msgstr ""
+msgstr "Mais suivable"
msgid "by"
-msgstr ""
+msgstr "par"
msgid "by <strong>{{date}}</strong>"
-msgstr ""
+msgstr "par <strong>{{date}}</strong>"
msgid "by {{public_body_name}} to {{info_request_user}} on {{date}}."
-msgstr ""
+msgstr "par {{public_body_name}} à {{info_request_user}} le {{date}}."
msgid "by {{user_link_absolute}}"
-msgstr ""
+msgstr "par {{user_link_absolute}}"
msgid "comments"
msgstr "commentaires"
msgid "containing your postal address, and asking them to reply to this request.\\n Or you could phone them."
-msgstr ""
+msgstr "contenant votre adresse postale, et en leur demandant de répondre à cette demande. \\n Ou vous pouvez leur téléphoner."
msgid "details"
msgstr "détails"
msgid "display_status only works for incoming and outgoing messages right now"
-msgstr ""
+msgstr "display_status n'est valide que pour les messages entrant et sortant pour le moment"
msgid "during term time"
-msgstr ""
+msgstr "pendant l'année scolaire"
msgid "edit text about you"
-msgstr ""
+msgstr "modifier votre description personnelle"
msgid "even during holidays"
-msgstr ""
+msgstr "même pendant les vacances"
msgid "everything"
msgstr "tout"
msgid "external"
-msgstr ""
+msgstr "Externe"
msgid "has reported an"
-msgstr ""
+msgstr "à reporté un "
msgid "have delayed."
-msgstr ""
+msgstr "ont retardé"
msgid "hide quoted sections"
-msgstr ""
+msgstr "cacher les sections citées"
msgid "in term time"
-msgstr ""
+msgstr "en période scolaire"
msgid "in the category ‘{{category_name}}’"
-msgstr ""
+msgstr "dans la catégorie ‘{{category_name}}’"
msgid "internal error"
-msgstr ""
+msgstr "Erreur interne"
msgid "internal reviews"
msgstr "révisions internes"
msgid "is <strong>waiting for your clarification</strong>."
-msgstr ""
+msgstr "est <strong>en attente de votre clarification </strong>."
msgid "just to see how it works"
-msgstr ""
+msgstr "Juste pour voir comment ça marche"
msgid "left an annotation"
-msgstr ""
+msgstr "a laissé une remarque"
msgid "made."
-msgstr ""
+msgstr "faites."
msgid "matching the tag ‘{{tag_name}}’"
-msgstr ""
+msgstr "correspondant au tag ‘{{tag_name}}’"
msgid "messages from authorities"
msgstr "messages des institutions"
@@ -3155,25 +3177,25 @@ msgid "messages from users"
msgstr "messages des utilisateurs"
msgid "move..."
-msgstr ""
+msgstr "déplacer"
msgid "no later than"
-msgstr ""
+msgstr "au plus tard"
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=\"{{url}}\">send it to us</a>."
-msgstr ""
+msgstr "n'existe plus . Si vous essayer de faire ça a partir de la page de demande , essayer de répondre un un message en particulier plutôt que d'envoyer \\n un suivi général. Si vous avez besoin de faire un suivi général, et vous saviez \\ n quel e-mail ira à la bonne place, s'il vous plaît <a href=\"{{url}}\">Envoyez le nous </a>."
msgid "normally"
-msgstr ""
+msgstr "normalement"
msgid "not requestable due to: {{reason}}"
-msgstr ""
+msgstr "non demandable en raison de: {{reason}}"
msgid "please sign in as "
-msgstr ""
+msgstr "veuillez vous connecter en tant que "
msgid "requesting an internal review"
-msgstr ""
+msgstr "Solliciter une révision interne "
msgid "requests"
msgstr "demandes"
@@ -3182,25 +3204,25 @@ msgid "requests which are {{list_of_statuses}}"
msgstr "demandes qui sont"
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."
-msgstr ""
+msgstr "réponse ayant besoin d'attention de l'administrateur. Jetez un oeil, et répondez à cet \\n email pour leur faire savoir ce que vous allez faire à ce sujet."
msgid "send a follow up message"
-msgstr ""
+msgstr "Envoyer un message de suivi "
msgid "sent to {{public_body_name}} by {{info_request_user}} on {{date}}."
-msgstr ""
+msgstr "Envoyée à {{public_body_name}} par {{info_request_user}} Le {{date}}."
msgid "set to <strong>blank</strong> (empty string) if can't find an address; these emails are <strong>public</strong> as anyone can view with a CAPTCHA"
-msgstr ""
+msgstr "set to <strong>blank</strong> (empty string) if can't find an address; these emails are <strong>public</strong> as anyone can view with a CAPTCHA"
msgid "show quoted sections"
-msgstr ""
+msgstr "Afficher les sections citées"
msgid "sign in"
-msgstr ""
+msgstr "Connexion"
msgid "simple_date_format"
-msgstr ""
+msgstr "simple_date_format"
msgid "successful"
msgstr "fructueux/se"
@@ -3209,10 +3231,10 @@ msgid "successful requests"
msgstr "demandes qui ont abouti"
msgid "that you made to"
-msgstr ""
+msgstr "Que vous avez fait à "
msgid "the main FOI contact address for {{public_body}}"
-msgstr ""
+msgstr "l'adresse principale de l'agent d'accès a l'information au sein de {{public_body}}"
#. This phrase completes the following sentences:
#. Request an internal review from...
@@ -3220,40 +3242,40 @@ msgstr ""
#. Send a public reply to...
#. Don't want to address your message to... ?
msgid "the main FOI contact at {{public_body}}"
-msgstr ""
+msgstr "L'agent d'acces l'information au sein de {{public_body}}"
msgid "the requester"
-msgstr ""
+msgstr "Le demandeur"
msgid "the {{site_name}} team"
-msgstr ""
+msgstr "L'équipe {{site_name}}"
msgid "to read"
-msgstr ""
+msgstr "à lire "
msgid "to send a follow up message."
-msgstr ""
+msgstr "Pour envoyer un message de suivi ."
msgid "to {{public_body}}"
-msgstr ""
+msgstr "à {{public_body}}"
msgid "unexpected prominence on request event"
-msgstr ""
+msgstr "Importance inattendue de la demande "
msgid "unknown reason "
-msgstr ""
+msgstr "raison inconnue"
msgid "unknown status "
-msgstr ""
+msgstr "état inconnu"
msgid "unresolved requests"
msgstr "demandes qui n'ont pas encore abouti"
msgid "unsubscribe"
-msgstr ""
+msgstr "se désabonner"
msgid "unsubscribe all"
-msgstr ""
+msgstr "désabonner tout "
msgid "unsuccessful"
msgstr "infructueux/se"
@@ -3262,7 +3284,7 @@ msgid "unsuccessful requests"
msgstr "demandes qui n'ont pas abouti"
msgid "useful information."
-msgstr ""
+msgstr "information utile"
msgid "users"
msgstr "utilisateurs"
@@ -3280,8 +3302,8 @@ msgstr[1] "{{count}} Liberté de pouvoir faire des demandes d'informations sur {
msgid "{{count}} person is following this authority"
msgid_plural "{{count}} people are following this authority"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "{{count}} personne suit cette autorité administrative"
+msgstr[1] "{{count}} personnes suivent cette autorité administrative "
msgid "{{count}} request"
msgid_plural "{{count}} requests"
@@ -3294,19 +3316,19 @@ msgstr[0] "{{count}} demande réalisée."
msgstr[1] "{{count}} demandes réalisées."
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 ""
+msgstr "{{existing_request_user}} a dejà effectué la même demande le {{date}}. Vous pouvez soit voir la <a href=\"{{existing_request}}\">demande existante </a>,\\n ou modifier les details ci dessous pour faire une nouvelle demande similaire ."
msgid "{{info_request_user_name}} only:"
-msgstr ""
+msgstr "{{info_request_user_name}} uniquement:"
msgid "{{law_used_full}} request - {{title}}"
-msgstr ""
+msgstr "{{law_used_full}} demande - {{title}}"
msgid "{{law_used_full}} request GQ - {{title}}"
-msgstr ""
+msgstr "{{law_used_full}} demande - {{title}}"
msgid "{{law_used}} requests at {{public_body}}"
-msgstr ""
+msgstr "{{law_used}} demandes à {{public_body}}"
msgid "{{length_of_time}} ago"
msgstr "depuis {{length_of_time}}"
@@ -3315,64 +3337,64 @@ msgid "{{list_of_things}} matching text '{{search_query}}'"
msgstr "{{list_of_things}} correspondant au texte '{{search_query}}'"
msgid "{{number_of_comments}} comments"
-msgstr ""
+msgstr "{{number_of_comments}} commentaires"
msgid "{{public_body_link}} answered a request about"
-msgstr ""
+msgstr "{{public_body_link}} a répondu à une demande sur"
msgid "{{public_body_link}} was sent a request about"
-msgstr ""
+msgstr "{{public_body_link}} a reçu une demande sur "
msgid "{{public_body_name}} only:"
-msgstr ""
+msgstr "{{public_body_name}} uniquement:"
msgid "{{public_body}} has asked you to explain part of your {{law_used}} request."
-msgstr ""
+msgstr "{{public_body}} vous a demandé de clarifier une partie de votre {{law_used}} demande."
msgid "{{public_body}} sent a response to {{user_name}}"
msgstr "{{public_body}} a répondu à {{user_name}}"
msgid "{{reason}}, please sign in or make a new account."
-msgstr ""
+msgstr "{{reason}}, Veuillez vous connecter ou créer un nouveau compte."
msgid "{{search_results}} matching '{{query}}'"
msgstr "{{search_results}} correspondant à '{{query}}'"
msgid "{{site_name}} blog and tweets"
-msgstr ""
+msgstr "{{site_name}} blog et tweets"
msgid "{{site_name}} covers requests to {{number_of_authorities}} authorities, including:"
msgstr "{{site_name}} gère les demandes adressées à {{number_of_authorities}} institutions, dont :"
msgid "{{site_name}} sends new requests to <strong>{{request_email}}</strong> for this authority."
-msgstr ""
+msgstr "{{site_name}} Envoi de nouvelles demandes <strong>{{request_email}}</strong> pour cette autorité."
msgid "{{site_name}} users have made {{number_of_requests}} requests, including:"
msgstr "Les utilisateurs de {{site_name}} ont envoyé {{number_of_requests}} demandes, dont :"
msgid "{{thing_changed}} was changed from <code>{{from_value}}</code> to <code>{{to_value}}</code>"
-msgstr ""
+msgstr "{{thing_changed}} was changed from <code>{{from_value}}</code> to <code>{{to_value}}</code>"
msgid "{{title}} - a Freedom of Information request to {{public_body}}"
-msgstr ""
+msgstr "{{title}} - Une demande d'accès à l'information à {{public_body}}"
msgid "{{user_name}} (Account suspended)"
-msgstr ""
+msgstr "{{user_name}} (Compte suspondu)"
msgid "{{user_name}} - Freedom of Information requests"
-msgstr ""
+msgstr "{{user_name}} - Demandes d'accès à l'information"
msgid "{{user_name}} - user profile"
-msgstr ""
+msgstr "{{user_name}} - profil de l'utilisateur"
msgid "{{user_name}} added an annotation"
msgstr "{{user_name}} a ajouté une annotation"
msgid "{{user_name}} has annotated your {{law_used_short}} \\nrequest. Follow this link to see what they wrote."
-msgstr ""
+msgstr "{{user_name}} a commenté votre {{law_used_short}} \\ndemande. Suivez ce lien pour voir ce qu'il a ecrit "
msgid "{{user_name}} has used {{site_name}} to send you the message below."
-msgstr ""
+msgstr "{{user_name}} a utilisé {{site_name}} pour vous envoyer le message ci-dessous."
msgid "{{user_name}} sent a follow up message to {{public_body}}"
msgstr "{{user_name}} a envoyé un message de relance à {{public_body}}"
@@ -3381,10 +3403,10 @@ msgid "{{user_name}} sent a request to {{public_body}}"
msgstr "{{user_name}} a envoyé une demande à {{public_body}}"
msgid "{{username}} left an annotation:"
-msgstr ""
+msgstr "{{username}} a laissé une remarque:"
msgid "{{user}} ({{user_admin_link}}) 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 ""
+msgstr "{{user}} ({{user_admin_link}}) a fait cette {{law_used_full}} demande (<a href=\"{{request_admin_url}}\">admin</a>) à {{public_body_link}} (<a href=\"{{public_body_admin_url}}\">admin</a>)"
msgid "{{user}} made this {{law_used_full}} request"
-msgstr ""
+msgstr "{{user}} a fait cette {{law_used_full}} demande"
diff --git a/locale/gl/app.po b/locale/gl/app.po
index e127b5a97..7da3fbaa7 100644
--- a/locale/gl/app.po
+++ b/locale/gl/app.po
@@ -8,10 +8,10 @@ msgid ""
msgstr ""
"Project-Id-Version: alaveteli\n"
"Report-Msgid-Bugs-To: http://github.com/sebbacon/alaveteli/issues\n"
-"POT-Creation-Date: 2013-04-23 16:34+0100\n"
-"PO-Revision-Date: 2013-04-23 15:42+0000\n"
+"POT-Creation-Date: 2013-05-30 09:46+0100\n"
+"PO-Revision-Date: 2013-05-30 08:54+0000\n"
"Last-Translator: louisecrow <louise@mysociety.org>\n"
-"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language-Team: Galician (http://www.transifex.com/projects/p/alaveteli/language/gl/)\n"
"Language: gl\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -340,6 +340,15 @@ msgstr "Sobre mí:"
msgid "Act on what you've learnt"
msgstr "Utilice esta información"
+msgid "Acts as xapian/acts as xapian job"
+msgstr ""
+
+msgid "ActsAsXapian::ActsAsXapianJob|Action"
+msgstr ""
+
+msgid "ActsAsXapian::ActsAsXapianJob|Model"
+msgstr ""
+
msgid "Add an annotation"
msgstr "Añada un comentario"
@@ -651,6 +660,9 @@ msgstr "Actualmente <strong>esperando la respuesta</strong> de {{public_body_lin
msgid "Date:"
msgstr "Fecha:"
+msgid "Dear {{name}},"
+msgstr ""
+
msgid "Dear {{public_body_name}},"
msgstr "Estimado {{public_body_name}},"
@@ -928,6 +940,18 @@ msgstr "DETALLA TU QUEJA AQUÍ"
msgid "Handled by post."
msgstr "Resuelta por correo ordinario"
+msgid "Has tag string/has tag string tag"
+msgstr ""
+
+msgid "HasTagString::HasTagStringTag|Model"
+msgstr ""
+
+msgid "HasTagString::HasTagStringTag|Name"
+msgstr ""
+
+msgid "HasTagString::HasTagStringTag|Value"
+msgstr ""
+
msgid "Hello! You can make Freedom of Information requests within {{country_name}} at {{link_to_website}}"
msgstr "¡Hola! Puede hacer solicitudes de información en {{country_name}} usando {{link_to_website}}"
@@ -1792,9 +1816,6 @@ msgstr ""
msgid "Public body"
msgstr ""
-msgid "Public body/translation"
-msgstr ""
-
msgid "Public notes"
msgstr ""
@@ -1804,33 +1825,6 @@ msgstr ""
msgid "Public page not available"
msgstr ""
-msgid "PublicBody::Translation|Disclosure log"
-msgstr ""
-
-msgid "PublicBody::Translation|First letter"
-msgstr ""
-
-msgid "PublicBody::Translation|Locale"
-msgstr ""
-
-msgid "PublicBody::Translation|Name"
-msgstr ""
-
-msgid "PublicBody::Translation|Notes"
-msgstr ""
-
-msgid "PublicBody::Translation|Publication scheme"
-msgstr ""
-
-msgid "PublicBody::Translation|Request email"
-msgstr ""
-
-msgid "PublicBody::Translation|Short name"
-msgstr ""
-
-msgid "PublicBody::Translation|Url name"
-msgstr ""
-
msgid "PublicBody|Api key"
msgstr ""
@@ -2346,6 +2340,9 @@ msgstr "El motor de búsqueda no está accesible en estos momentos: no podemos m
msgid "The search index is currently offline, so we can't show the Freedom of Information requests this person has made."
msgstr "El motor de búsqueda no está accesible en estos momentos: no podemos mostrar las solicitudes de información que ha hecho esta persona"
+msgid "The {{site_name}} team."
+msgstr ""
+
msgid "Then you can cancel the alert."
msgstr "Entonces podrás cancelar tu alerta."
@@ -2887,6 +2884,12 @@ msgstr "Esperando que el organismo responda"
msgid "Was the response you got to your FOI request any good?"
msgstr "¿Fue la respuesta a tu solicitud satisfactoria?"
+msgid "We consider it is not a valid FOI request, and have therefore hidden it from other users."
+msgstr ""
+
+msgid "We consider it to be vexatious, and have therefore hidden it from other users."
+msgstr ""
+
msgid "We do not have a working request email address for this authority."
msgstr "No tenemos una dirección de correo válida para este organismo."
@@ -3115,6 +3118,9 @@ msgstr ""
"Sólo recibirás una respuesta a tu solicitud si continúas\n"
"con la aclaración."
+msgid "You will still be able to view it while logged in to the site. Please reply to this email if you would like to discuss this decision further."
+msgstr ""
+
msgid "You're in. <a href=\"#\" id=\"send-request\">Continue sending your request</a>"
msgstr ""
@@ -3188,6 +3194,12 @@ msgstr "Tu contraseña:"
msgid "Your photo will be shown in public <strong>on the Internet</strong>,\\n wherever you do something on {{site_name}}."
msgstr ""
+msgid "Your request '{{request}}' at {{url}} has been reviewed by moderators."
+msgstr ""
+
+msgid "Your request on {{site_name}} hidden"
+msgstr ""
+
msgid "Your request was called {{info_request}}. Letting everyone know whether you got the information will help us keep tabs on"
msgstr "Tu solicitud se llamaba {{info_request}}. Haznos saber si has recibido la información para ayudarnos a controlar a"
@@ -3222,6 +3234,9 @@ msgstr "Un saludo,"
msgid "Yours sincerely,"
msgstr "Un saludo,"
+msgid "Yours,"
+msgstr ""
+
msgid "[FOI #{{request}} email]"
msgstr ""
diff --git a/locale/he_IL/app.po b/locale/he_IL/app.po
index 2b01a2c1b..908be330d 100644
--- a/locale/he_IL/app.po
+++ b/locale/he_IL/app.po
@@ -20,10 +20,10 @@ msgid ""
msgstr ""
"Project-Id-Version: alaveteli\n"
"Report-Msgid-Bugs-To: http://github.com/sebbacon/alaveteli/issues\n"
-"POT-Creation-Date: 2013-04-23 16:34+0100\n"
-"PO-Revision-Date: 2013-04-23 15:56+0000\n"
+"POT-Creation-Date: 2013-05-30 09:46+0100\n"
+"PO-Revision-Date: 2013-05-30 08:54+0000\n"
"Last-Translator: louisecrow <louise@mysociety.org>\n"
-"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language-Team: Hebrew (Israel) (http://www.transifex.com/projects/p/alaveteli/language/he_IL/)\n"
"Language: he_IL\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -37,13 +37,13 @@ msgid " (<strong>no ranty</strong> politics, read our <a href=\"{{url}}\">modera
msgstr " (<strong>בלי פוליטיקה מפלגתית!</strong> קראו את<a href=\"{{url}}\">מדיניות הניהול</a>) שלנו"
msgid " (<strong>patience</strong>, especially for large files, it may take a while!)"
-msgstr " (<strong>הורדת קבצים גדולים עלולה לארוך מספר דקות</strong>)"
+msgstr " (<strong>נא המתינו, הורדת קבצים גדולים עלולה לארוך מספר דקות</strong>)"
msgid " (you)"
msgstr "(אתם)"
msgid " - view and make Freedom of Information requests"
-msgstr "– צפו ומלאו בקשות למידע"
+msgstr "– צפו והגישו בקשות למידע"
msgid " - wall"
msgstr " - קיר"
@@ -52,10 +52,10 @@ msgid " <strong>Note:</strong>\\n We will send you an email. Follow the instr
msgstr " <strong>הערה:<strong/> בקרוב יישלח אליכם דואר אלקטרוני. עקוב אחר ההוראות המצויות בו על מנת לשנות את הסיסמא."
msgid " <strong>Privacy note:</strong> Your email address will be given to"
-msgstr " <strong>הערת פרטיות:</strong> כתובת הדוא\"ל שלכם תימסר ל"
+msgstr " <strong>הערת פרטיות:</strong> כתובת הדוא\"ל שלכם תימסר ל- "
msgid " <strong>Summarise</strong> the content of any information returned. "
-msgstr " <strong>סיכום</strong> תוכן כל מידע מוחזר. "
+msgstr " <strong>סכמו</strong> תוכן של כל מידע מוחזר"
msgid " Advise on how to <strong>best clarify</strong> the request."
msgstr "הסברים כיצד <strong>לנסח בצורה בהירה</strong> את הבקשה."
@@ -160,7 +160,7 @@ msgid "<p>Thank you! Hopefully your wait isn't too long.</p><p>You should get a
msgstr "<p>תודה לכם! אנו מקווים שלא המתנתם זמן רב. </p><p>התגובה אמורה להגיע תוך {{late_number_of_days}} ימים, או שתקבלו הודעה על דחיית מועד קבלת התשובה (<a href=\"{{review_url}}\">פרטים</a>).</p>"
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 "<p>תודה לכם! בקשתכם היתה צריכה להענותת כבר לפני {{very_late_number_of_days}} ימי עבודה. רוב הבקשות נענות תוך {{late_number_of_days}} ימי עבודה. ייתכן ותרצו להגיש תלונה באמצעות הטופס למטה.</p>"
+msgstr "<p>תודה לכם! בקשתכם היתה צריכה להענות כבר לפני {{very_late_number_of_days}} ימי עבודה. רוב הבקשות נענות תוך {{late_number_of_days}} ימי עבודה. ייתכן ותרצו להגיש תלונה באמצעות הטופס למטה.</p>"
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>תודה על שינוי הפרטים.</p><p><strong>ועכשיו...</strong> תוכלו להוסיף גם תמונת פרופיל.</p>"
@@ -305,6 +305,15 @@ msgstr "אודותיך:"
msgid "Act on what you've learnt"
msgstr "פעלו לפי מה שלמדתם"
+msgid "Acts as xapian/acts as xapian job"
+msgstr ""
+
+msgid "ActsAsXapian::ActsAsXapianJob|Action"
+msgstr ""
+
+msgid "ActsAsXapian::ActsAsXapianJob|Model"
+msgstr ""
+
msgid "Add an annotation"
msgstr "הוסיפו הערה"
@@ -414,7 +423,7 @@ msgid "Awaiting response."
msgstr "ממתין לתשובה."
msgid "Beginning with"
-msgstr "מתחיל עם"
+msgstr "חיפוש על-פי אות ראשונה"
msgid "Browse <a href='{{url}}'>other requests</a> for examples of how to word your request."
msgstr "הקליקו על <a href='{{url}}'>בקשות אחרות</a> לצפות בדוגמאות לניסוח הבקשה."
@@ -426,10 +435,10 @@ msgid "Browse all authorities..."
msgstr "עיון בכל הרשויות..."
msgid "By law, under all circumstances, {{public_body_link}} should have responded by now"
-msgstr "לפי החוק, בכפוף לנסיבות, {{public_body_link}} היה צריך להשיב עד עתה"
+msgstr "לפי החוק, בכפוף לנסיבות, {{public_body_link}} היו צרכים להשיב עד עתה"
msgid "By law, {{public_body_link}} should normally have responded <strong>promptly</strong> and"
-msgstr "על-פי החוק, {{קישור_גוף_ציבורי}} היה/היתה צריך/צריכה להגיב כבר"
+msgstr "על-פי החוק, {{public_body_link}} היה/היתה צריך/צריכה להגיב כבר"
msgid "Calculated home page"
msgstr "דף בית מחושב"
@@ -474,7 +483,7 @@ msgid "Change profile photo"
msgstr "שנה תמונת פרופיל"
msgid "Change the text about you on your profile at {{site_name}}"
-msgstr "ערכו את הפרופיל שלכם ב- {{שם_אתר}}"
+msgstr "ערכו את הפרופיל שלכם ב- {{site_name}}"
msgid "Change your email"
msgstr "שינוי כתובת מייל"
@@ -540,7 +549,7 @@ msgid "Comment|Visible"
msgstr "הערה|גלוי"
msgid "Confirm you want to follow all successful FOI requests"
-msgstr "אשרו שאתם רוצים לעקוב אחר כל בקשות המידע המוצלחות"
+msgstr "אשרו שאתם רוצים לעקוב אחר כל בקשות המידע שנענו"
msgid "Confirm you want to follow new requests"
msgstr "אשרו שאתם רוצים לעקוב אחר בקשות חדשות"
@@ -579,10 +588,10 @@ msgid "Considered by administrators as vexatious and hidden from site."
msgstr "נחשב על ידי מנהלים כמרגיז ומוסתר מהאתר."
msgid "Contact {{recipient}}"
-msgstr "צור קשר עם {{recipient}}"
+msgstr "צרו קשר עם {{recipient}}"
msgid "Contact {{site_name}}"
-msgstr "צור קשר עם {{site_name}}"
+msgstr "צרו קשר עם {{site_name}}"
msgid "Could not identify the request from the email address"
msgstr "לא ניתן היה לזהות את הבקשה מכתובת הדואר האלקטרוני"
@@ -602,6 +611,9 @@ msgstr "כרגע <strong>ממתין לתגובה</strong> מ{{public_body_link}}
msgid "Date:"
msgstr "תאריך:"
+msgid "Dear {{name}},"
+msgstr ""
+
msgid "Dear {{public_body_name}},"
msgstr "{{public_body_name}} נכבד, "
@@ -636,7 +648,7 @@ msgid "Disclosure log URL"
msgstr "כתובת יומן גילוי נאות"
msgid "Don't want to address your message to {{person_or_body}}? You can also write to:"
-msgstr "לא מעוניינים להפנות את ההודעה ל- {{אדם_או_גוף}}? תוכלו לכתוב ל:"
+msgstr "לא מעוניינים להפנות את ההודעה ל- {{person_or_body}}? תוכלו לכתוב ל:"
msgid "Done"
msgstr "הסתיים"
@@ -732,13 +744,13 @@ msgid "Failed to convert image to a PNG"
msgstr "המרת הקובץ לפורמט PNG נכשלה"
msgid "Failed to convert image to the correct size: at {{cols}}x{{rows}}, need {{width}}x{{height}}"
-msgstr "המרת התמונה לגודל המתאים נכשלה: ל- {{עמודות}}x{{שורות}}, נדרש {{רוחב}}x{{גובה}}"
+msgstr "המרת התמונה לגודל המתאים נכשלה: ל- {{cols}}x{{rows}}, נדרש {{width}}x{{height}}"
msgid "Filter"
msgstr "סינון"
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=\"{{url}}\">why?</a>)."
-msgstr "ראשית, הקלידו את <strong>שם הגוף הממשלתי </strong> שממנו ברצונכם לקבל מידע.\\n <strong>לפי חוק, עליהם להגיב</strong> (<a href=\"{{url}}\">למה?</a>)."
+msgstr "ראשית, הקלידו את <strong>שם הגוף הממשלתי </strong>, ממנו ברצונכם לקבל מידע.\\n <strong>לפי חוק, עליהם למסור תגובה</strong> (<a href=\"{{url}}\">מדוע?</a>)."
msgid "Foi attachment"
msgstr "מסמף מצורף עבור חוק חופש המידע"
@@ -765,7 +777,7 @@ msgid "FoiAttachment|Within rfc822 subject"
msgstr "בקשהמצורפת|במסגרת סעיף XXX"
msgid "Follow"
-msgstr "עקוב"
+msgstr "עקבו"
msgid "Follow all new requests"
msgstr "עקבו אחר הבקשות החדשות"
@@ -804,10 +816,10 @@ msgid "Follow up messages to existing requests are sent to "
msgstr "הודעות מעקב לבקשות קיימות נשלחות ל- "
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 "הודעות תגובה והודעות חדשות לבקשה זו נחסמו מחשש לדואר זבל. נא <a href=\"{{url}}\">צרו קשר</a> אם את/ה {{משתמש_קישור}} וצריך לשלוח הודעת המשך."
+msgstr "הודעות תגובה והודעות חדשות לבקשה זו נחסמו מחשש לדואר זבל. נא <a href=\"{{url}}\">צרו קשר</a> אם את/ה {{user_link}} וצריך לשלוח הודעת המשך."
msgid "Follow us on twitter"
-msgstr "עקוב אחרינו בטוויטר"
+msgstr "עקבו אחרינו בטוויטר"
msgid "Followups cannot be sent for this request, as it was made externally, and published here by {{public_body_name}} on the requester's behalf."
msgstr "מצטערים, איננו יכולים לשלוח הודעות מעקב עבור בקשה זו, מכיוון שהיא בוצעה מחוץ לאתר, ופורסמה כאן ע\"י {{public_body_name}} בשמו של המבקש."
@@ -839,7 +851,7 @@ msgid "Freedom of Information law no longer applies to this authority.Follow up
msgstr "חוק חופש המידע לא תקף לרשות זו. הודעות המשך לבקשה קיימת נשלחות ל- "
msgid "Freedom of Information requests made"
-msgstr "בקשות לפי חוק חופש המידע שהתבצעו"
+msgstr "בקשות לפי חוק חופש המידע שנוצרו"
msgid "Freedom of Information requests made by this person"
msgstr "בקשות על-פי חוק חופש המידע שנוצרו על-ידי אדם זה."
@@ -868,6 +880,18 @@ msgstr "ספקו פרטים על התלונה שלכם כאן"
msgid "Handled by post."
msgstr "טופל בפוסט."
+msgid "Has tag string/has tag string tag"
+msgstr ""
+
+msgid "HasTagString::HasTagStringTag|Model"
+msgstr ""
+
+msgid "HasTagString::HasTagStringTag|Name"
+msgstr ""
+
+msgid "HasTagString::HasTagStringTag|Value"
+msgstr ""
+
msgid "Hello! You can make Freedom of Information requests within {{country_name}} at {{link_to_website}}"
msgstr "שלום! אתם יכולים להגיש בקשות על-פי חוק חופש המידע ב{{country_name}} באתר {{link_to_website}}"
@@ -899,7 +923,7 @@ msgid "Holiday|Description"
msgstr "Holiday|Description"
msgid "Home"
-msgstr "בית"
+msgstr "עמוד הבית"
msgid "Home page"
msgstr "עמוד הבית"
@@ -995,7 +1019,7 @@ msgid "If you find this service useful as an FOI officer, please ask your web ma
msgstr "אם אתם מוצאים שירות זה כמתאים להגשת בקשות על-פי חוק חופש המידע, בקשו ממנהל הרשת שלכם לשים קישור בדף הגשת הבקשות באתר שלכם."
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."
-msgstr "אם קילתם את ההודעה במייל <strong>לפני יותר משישה חודשים</strong>, אז הקישור הזה לא יעבוד יותר. /n נסו לעשות את התהליך מההתחלה."
+msgstr "אם קיבלתם את הדוא\"ל <strong>לפני יותר משישה חודשים</strong>, הקישור לא יעבוד יותר. /n נסו להתחיל את התהליך מההתחלה."
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 "אם טרם עשיתם זאת, נא רשמו למטה פניה לרשות המתאימה ובה הסבר על ביטול הבקשה שלכם, אחרת לא ידעו שהבקשה בוטלה."
@@ -1127,7 +1151,7 @@ msgid "Internal review request"
msgstr "בקשת בדיקה פנימית"
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 "האם הכתובת {{email_address}} היא הנכונה לסוג של {{בקשות type_of_request}} requests to {{public_body_name}}? אם לא, נא צרו איתנו קשר באמצעות טופס זה:"
+msgstr "האם הכתובת {{email_address}} היא הנכונה לבקשת {{type_of_request}} אל {{public_body_name}}? אם לא, נא צרו איתנו קשר באמצעות טופס זה:"
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."
msgstr "ייתכן והדפדפן שלכם מוגדר שלא לקבל \"עוגיות\" (\"cookies\") ,\\nאו לא מצליח לעשות כן. בדקו את הגדרות הדפדפן שלכם או השתמשו בדפדפן\\nאחר. לאחר מכן נסו שוב."
@@ -1196,7 +1220,7 @@ msgid "Long overdue."
msgstr "עברה ממזמן."
msgid "Made between"
-msgstr "נעשתה בין"
+msgstr "הוגשה בין"
msgid "Mail server log"
msgstr "יומן אירועים שרת דואר"
@@ -1259,7 +1283,7 @@ msgid "More similar requests"
msgstr "בקשות דומות נוספות"
msgid "More successful requests..."
-msgstr "בקשות מוצלחות נוספות..."
+msgstr "בקשות נוספות שנענו..."
msgid "My profile"
msgstr "הפרופיל שלי"
@@ -1574,7 +1598,7 @@ msgid "Please sign at the bottom with your name, or alter the \"{{signoff}}\" si
msgstr "חתמו למטה בשמכם, או שנו את \"{{signoff}}\" החתימה"
msgid "Please sign in as "
-msgstr "בבקשה התחברו כ"
+msgstr "נא התחברו כ"
msgid "Please sign in or make a new account."
msgstr "תוכלו להתחבר או ליצור חשבון חדש."
@@ -1678,9 +1702,6 @@ msgstr "רשות ציבורית – {{name}}"
msgid "Public body"
msgstr "גוף ציבורי"
-msgid "Public body/translation"
-msgstr "גוף/תרגום ציבורי"
-
msgid "Public notes"
msgstr "רשימות ציבוריות"
@@ -1690,33 +1711,6 @@ msgstr "דף ציבורי"
msgid "Public page not available"
msgstr "הדף הציבורי לא זמין"
-msgid "PublicBody::Translation|Disclosure log"
-msgstr "PublicBody::Translation|Disclosure log"
-
-msgid "PublicBody::Translation|First letter"
-msgstr "PublicBody::Translation|מכתב ראשון"
-
-msgid "PublicBody::Translation|Locale"
-msgstr "PublicBody::Translation|Locale"
-
-msgid "PublicBody::Translation|Name"
-msgstr "PublicBody::Translation|Name"
-
-msgid "PublicBody::Translation|Notes"
-msgstr "PublicBody::Translation|Notes"
-
-msgid "PublicBody::Translation|Publication scheme"
-msgstr "PublicBody::Translation|Publication scheme"
-
-msgid "PublicBody::Translation|Request email"
-msgstr "PublicBody::Translation|Request email"
-
-msgid "PublicBody::Translation|Short name"
-msgstr "PublicBody::Translation|Short name"
-
-msgid "PublicBody::Translation|Url name"
-msgstr "PublicBody::Translation|Url name"
-
msgid "PublicBody|Api key"
msgstr "PublicBody|Api key"
@@ -1790,7 +1784,7 @@ msgid "Read about <a href=\"{{advanced_search_url}}\">advanced search operators<
msgstr "קרא על <a href=\"{{advanced_search_url}}\">אופרטורים לחיפוש מתקדם</a>, כקרבה וסימנים כלליים (Wildcards)."
msgid "Read blog"
-msgstr "קראו את הבלוג"
+msgstr "בלוג"
msgid "Received an error message, such as delivery failure."
msgstr "התקבלה הודעת שגיאה, כגון, שגיאת מסירה"
@@ -1917,8 +1911,8 @@ msgstr "חפש באתר"
msgid "Search within the {{count}} Freedom of Information requests to {{public_body_name}}"
msgid_plural "Search within the {{count}} Freedom of Information requests made to {{public_body_name}}"
-msgstr[0] "חפש בקשות מידע מ- {{count}} עד {{public_body_name}}"
-msgstr[1] "חפש בקשות מידע מ- {{count}} שנעשו עד {{public_body_name}}"
+msgstr[0] "חפש בקשות מידע מבין {{count}} שנמסרה אל {{public_body_name}}"
+msgstr[1] "חפש בקשות מידע מבין {{count}} שנמסרו אל {{public_body_name}}"
msgid "Search your contributions"
msgstr "חפש בין התוספות שלך"
@@ -1972,16 +1966,16 @@ msgid "Show only..."
msgstr "הצג רק..."
msgid "Showing"
-msgstr "בחרו תצוגה:"
+msgstr "תצוגה"
msgid "Sign in"
-msgstr "התחבר"
+msgstr "התחברו"
msgid "Sign in or make a new account"
-msgstr "התחבר או צור חשבון חדש"
+msgstr "התחברו או צרו חשבון חדש"
msgid "Sign in or sign up"
-msgstr "התחבר או הירשם"
+msgstr "היכנסו או הירשמו"
msgid "Sign out"
msgstr "התנתק"
@@ -2029,13 +2023,13 @@ msgid "Special note for this authority!"
msgstr "הערה מיוחדת לרשות זו"
msgid "Start"
-msgstr "התחל"
+msgstr "התחילו"
msgid "Start now &raquo;"
-msgstr "התחל עכשיו &raquo;"
+msgstr "התחילו עכשיו &raquo;"
msgid "Start your own blog"
-msgstr "התחל את הבלוג שלך"
+msgstr "צרו את הבלוג שלכם"
msgid "Stay up to date"
msgstr "הישאר מעודכן"
@@ -2059,7 +2053,7 @@ msgid "Submit status and send message"
msgstr "רשמו מצב ושלחו הודעה"
msgid "Subscribe to blog"
-msgstr "הירשם לבלוג"
+msgstr "הירשמו לבלוג"
msgid "Successful Freedom of Information requests"
msgstr "בקשות מידע שנענו"
@@ -2113,7 +2107,7 @@ msgid "Thank you! We'll look into what happened and try and fix it up."
msgstr "תודה רבה! נבדוק מה קרה וננסה לתקן זאת"
msgid "Thanks for helping - your work will make it easier for everyone to find successful\\nresponses, and maybe even let us make league tables..."
-msgstr "תודה על העזרה - העזרה שלך תסייע לכולם למצוא בקשות מוצלחות."
+msgstr "תודה על העזרה - העזרה שלך תסייע לכולם למצוא בקשות שנענו."
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 "תודה רבה, זה יעזור לאחרים למצוא מידע בצורה יעילה יותר.\\n נוכל גם לתת לכם טיפים, מה לעשות בשלב הבא של הגשת הבקשות\\n שלכם."
@@ -2199,6 +2193,9 @@ msgstr "מנוע החיפוש לא זמין כרגע, לכן לא תוכלו ל
msgid "The search index is currently offline, so we can't show the Freedom of Information requests this person has made."
msgstr "מנוע החיפוש לא זמין כרגע, לכן לא תוכלו לצפות בבקשות מידע של אדם זה."
+msgid "The {{site_name}} team."
+msgstr ""
+
msgid "Then you can cancel the alert."
msgstr "אתם יכולים לבטל את האתרעה."
@@ -2282,7 +2279,7 @@ msgstr "מספר הבקשות שניתן להגיש ביום מוגבל, כי א
msgid "There is {{count}} person following this request"
msgid_plural "There are {{count}} people following this request"
-msgstr[0] "עוקבים אחר הבקשה הזו {{count}} אנשים"
+msgstr[0] "עוקב אחר הבקשה הזו אדם {{count}}"
msgstr[1] "עוקבים אחר הבקשה הזו {{count}} אנשים"
msgid "There was a <strong>delivery error</strong> or similar, which needs fixing by the {{site_name}} team."
@@ -2359,13 +2356,13 @@ msgstr "הערות של אדם זה"
msgid "This person's {{count}} Freedom of Information request"
msgid_plural "This person's {{count}} Freedom of Information requests"
-msgstr[0] "בקשת מידע מס' {{count}} של אדם זה"
+msgstr[0] "בקשת מידע {{count}} של אדם זה"
msgstr[1] "{{count}} בקשות מידע של אדם זה"
msgid "This person's {{count}} annotation"
msgid_plural "This person's {{count}} annotations"
-msgstr[0] "הערה מס' {{count}} של אדם זה"
-msgstr[1] "{{count}} בקשות מידע של אדם זה"
+msgstr[0] "הערה {{count}} של אדם זה"
+msgstr[1] "{{count}} הערות של אדם זה"
msgid "This request <strong>requires administrator attention</strong>"
msgstr "בקשה זו <strong>מצריכה טיפול מנהל</strong>"
@@ -2455,7 +2452,7 @@ msgid "To follow all successful requests"
msgstr "למעקב אחר כל הבקשות שהצליחו"
msgid "To follow new requests"
-msgstr "עקבו אחר כל הבקשות החדשות"
+msgstr "למעקב אחר בקשות החדשות"
msgid "To follow requests and responses matching your search"
msgstr "כדי לעקוב אחר בקשות מידע ותגובות המתאימות לחיפוש שלכם"
@@ -2686,13 +2683,13 @@ msgid "View and search requests"
msgstr "צפו וחפשו בקשות מידע"
msgid "View authorities"
-msgstr "צפו ברשויות"
+msgstr "רשויות"
msgid "View email"
msgstr "צפו בדואר האלקטרוני"
msgid "View requests"
-msgstr "צפו בבקשות"
+msgstr "בקשות מידע"
msgid "Waiting clarification."
msgstr "ממתין להבהרות"
@@ -2709,6 +2706,12 @@ msgstr "בהמתנה לתשובה של רשות ציבורית"
msgid "Was the response you got to your FOI request any good?"
msgstr "האם קיבלתם תגובה מספקת על בקשת המידע שלכם?"
+msgid "We consider it is not a valid FOI request, and have therefore hidden it from other users."
+msgstr ""
+
+msgid "We consider it to be vexatious, and have therefore hidden it from other users."
+msgstr ""
+
msgid "We do not have a working request email address for this authority."
msgstr "אין ברשותנו כתובת דוא\"ל פעילה להגשת בקשות מידע לרשות זו."
@@ -2815,7 +2818,7 @@ msgid "You are currently receiving notification of new activity on your wall by
msgstr "נשלחות אליהם התראות במייל בנוגע לפעילות חדשה על הקיר שלכם."
msgid "You are following all new successful responses"
-msgstr "אתם עוקבים אחר כל הבקשות החדשות שהצליחו"
+msgstr "אתם עוקבים אחר כל הבקשות החדשות שנענו"
msgid "You are no longer following {{track_description}}."
msgstr "אתה לא עוקב יותר אחרי {{track_description}}"
@@ -2901,6 +2904,9 @@ msgstr "כעת תקבלו עדכונים באימייל אודות t {{track_des
msgid "You will only get an answer to your request if you follow up\\nwith the clarification."
msgstr "תוכלו לקבל תשובה לבקשה זו רק עם תגיבו \\nעם הבהרה."
+msgid "You will still be able to view it while logged in to the site. Please reply to this email if you would like to discuss this decision further."
+msgstr ""
+
msgid "You're in. <a href=\"#\" id=\"send-request\">Continue sending your request</a>"
msgstr "אתם בפנים. <a href=\"#\" id=\"send-request\">המשיכו בשליחת הבקשה</a>"
@@ -2969,6 +2975,12 @@ msgstr "הסיסמה שלכם:"
msgid "Your photo will be shown in public <strong>on the Internet</strong>,\\n wherever you do something on {{site_name}}."
msgstr "התמונה שלכם תוצג באופן פומבי באינטרנט,\\n בכל פעם שתעשו משהו באתר {{site_name}}."
+msgid "Your request '{{request}}' at {{url}} has been reviewed by moderators."
+msgstr ""
+
+msgid "Your request on {{site_name}} hidden"
+msgstr ""
+
msgid "Your request was called {{info_request}}. Letting everyone know whether you got the information will help us keep tabs on"
msgstr "הבקשה שלכם נקראת {{info_request}}. אם תודיעו זאת לאחרים נוכל לעדכן את התווית"
@@ -2986,12 +2998,12 @@ msgstr "דעתכם על מה {{site_name}} <strong>שמנהלי האתר</strong
msgid "Your {{count}} Freedom of Information request"
msgid_plural "Your {{count}} Freedom of Information requests"
-msgstr[0] "בקשת המידע מס' {{count}} שלכם"
+msgstr[0] "בקשת המידע {{count}} שלכם"
msgstr[1] " {{count}} בקשות המידע שלכם"
msgid "Your {{count}} annotation"
msgid_plural "Your {{count}} annotations"
-msgstr[0] "הערה מס' {{count}} שלכם"
+msgstr[0] "הערה {{count}} שלכם"
msgstr[1] "{{count}} ההערות שלכם"
msgid "Your {{site_name}} email alert"
@@ -3003,6 +3015,9 @@ msgstr "שלכם במסירות,"
msgid "Yours sincerely,"
msgstr "שלכם בכנות,"
+msgid "Yours,"
+msgstr ""
+
msgid "[FOI #{{request}} email]"
msgstr "[FOI #{{request}} email]"
@@ -3076,7 +3091,7 @@ msgid "but followupable"
msgstr "אבל ניתן לעקוב אחריהם"
msgid "by"
-msgstr "מאת"
+msgstr "עד תאריך"
msgid "by <strong>{{date}}</strong>"
msgstr "עד תאריך <strong>{{date}}</strong>"
@@ -3208,7 +3223,7 @@ msgid "successful"
msgstr "עבר בהצלחה"
msgid "successful requests"
-msgstr "בקשות מוצלחות"
+msgstr "בקשות שנענו"
msgid "that you made to"
msgstr "שביצעתם כדי"
@@ -3261,7 +3276,7 @@ msgid "unsuccessful"
msgstr "לא הצליח"
msgid "unsuccessful requests"
-msgstr "בקשה לא מוצלחת"
+msgstr "בקשות שנדחו"
msgid "useful information."
msgstr "מידע שימושי."
@@ -3273,7 +3288,7 @@ msgid "what's that?"
msgstr "מה זה?"
msgid "{{count}} FOI requests found"
-msgstr "{{count}} בקשות מידע נמצאו"
+msgstr "נמצאו {{count}} בקשות מידע "
msgid "{{count}} Freedom of Information request to {{public_body_name}}"
msgid_plural "{{count}} Freedom of Information requests to {{public_body_name}}"
@@ -3282,18 +3297,18 @@ msgstr[1] "{{count}} בקשות מידע עבור {{public_body_name}}"
msgid "{{count}} person is following this authority"
msgid_plural "{{count}} people are following this authority"
-msgstr[0] "{{count}} אנשים עוקבים אחר רשות זו"
+msgstr[0] "אדם {{count}} עוקב/ת אחר רשות זו"
msgstr[1] "{{count}} אנשים עוקבים אחר רשות זו"
msgid "{{count}} request"
msgid_plural "{{count}} requests"
-msgstr[0] "{{count}} בקשה"
+msgstr[0] "בקשה {{count}}"
msgstr[1] "{{count}} בקשות"
msgid "{{count}} request made."
msgid_plural "{{count}} requests made."
-msgstr[0] "{{count}} הבקשה נמסרה."
-msgstr[1] "{{count}} הבקשות נמסרו."
+msgstr[0] "בקשה {{count}} נמסרה."
+msgstr[1] "{{count}} בקשות נמסרו."
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}} יצר/ה בקשה זהה בתאריך {{date}}. אתם יכולים לצפות <a href=\"{{existing_request}}\">בבקשה הקיימת</a>, או לערוך את פרטי הבקשה למטה כדי ליצור בקשה שונה במעט."
diff --git a/locale/hu_HU/app.po b/locale/hu_HU/app.po
index 74e55c6b6..cba0f0446 100644
--- a/locale/hu_HU/app.po
+++ b/locale/hu_HU/app.po
@@ -4,14 +4,15 @@
#
# Translators:
# alaveteli_hu <alaveteli@atlatszo.hu>, 2012
+# Ebatta <orsibatta@gmail.com>, 2013
msgid ""
msgstr ""
"Project-Id-Version: alaveteli\n"
"Report-Msgid-Bugs-To: http://github.com/sebbacon/alaveteli/issues\n"
-"POT-Creation-Date: 2013-04-23 16:34+0100\n"
-"PO-Revision-Date: 2013-04-23 15:59+0000\n"
+"POT-Creation-Date: 2013-05-30 09:46+0100\n"
+"PO-Revision-Date: 2013-05-30 08:54+0000\n"
"Last-Translator: louisecrow <louise@mysociety.org>\n"
-"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language-Team: Hungarian (Hungary) (http://www.transifex.com/projects/p/alaveteli/language/hu_HU/)\n"
"Language: hu_HU\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -34,7 +35,7 @@ msgid " - view and make Freedom of Information requests"
msgstr " - közérdekű adat igénylések megtekintése és benyújtása"
msgid " - wall"
-msgstr ""
+msgstr " - fal"
msgid " <strong>Note:</strong>\\n We will send you an email. Follow the instructions in it to change\\n your password."
msgstr ""
@@ -94,7 +95,7 @@ msgid " when you send this message."
msgstr " részére, így a címzett megismerheti azt."
msgid "\"Hello! We have an <a href=\\\"/help/alaveteli?country_name=#{CGI.escape(current_country)}\\\">important message</a> for visitors outside {{country_name}}\""
-msgstr ""
+msgstr "\"Üdvözöljük! <a href=\\\"/help/alaveteli?country_name=#{CGI.escape(current_country)}\\\">Fontos üzenet</a> nem {{country_name}}\" országból való látogatók számára"
msgid "'Crime statistics by ward level for Wales'"
msgstr "'A kiskereki oktatási intézmények 2010-es évi ételszállítási szerződései'."
@@ -112,7 +113,7 @@ msgid "'{{link_to_user}}', a person"
msgstr "'{{link_to_user}}', személy "
msgid "*unknown*"
-msgstr ""
+msgstr "*ismeretlen*"
msgid ",\\n\\n\\n\\nYours,\\n\\n{{user_name}}"
msgstr ""
@@ -149,7 +150,7 @@ msgid "<p>All done! Thank you very much for your help.</p><p>There are <a href=\
msgstr "<p>Kész! Köszönjük segítségét.</p><p>Különféle <a href=\"{{helpus_url}}\">módokon tud</a> segítséget nyújtani a {{site_name}} számára.</p> "
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 ""
+msgstr "<p>Köszönjük! Néhány javaslat a következő lépést illetően:</p>\\n <ul>\\n <li>Ha igénylését egy másik adatgazdának is el szeretné küldeni, először másolja be alulra igénylésének szövegét, majd <a href=\"{{find_authority_url}}\">keresse ki a másik adatgazdát</a>.</li>\\n <li>Amennyiben meg kívánja támadni a közintézmény azon állítását, miszerint nem rendelkeznek a kért információval, itt ismerheti meg a\\n <a href=\"{{complain_url}}\">panasz benyújtásának menetét</a>.\\n </li>\\n <li>Van <a href=\"{{other_means_url}}\">javaslatunk</a>\\n arra vonatkozóan, hogy kérdésére hogyan lehetne választ kapni.n </li>\\n </ul>"
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 "<p>Köszönjük! Reméljük, nem kell már sokáig várakoznia.</p> <p>A jogszabályi előírások szerint azonnal választ kellett volna kapnia, de legkésőbb <strong>{{date_response_required_by}}</strong>-ig.</p> "
@@ -196,7 +197,7 @@ msgid "<p>Your request contains a <strong>postcode</strong>. Unless it directly
msgstr "<p>Igénylésében szerepel <strong>irányítószám</strong>. Amennyiben az nem kapcsolódik közvetlenül az igénylés tárgyához, kérjük, címének adatait távolítsa el, mivel az <strong>nyilvánosan is megjelenik az interneten</strong>.</p> "
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 ""
+msgstr "<p>{{law_used_full}} igénylését <strong>elküldtük</strong>.</p>\\nA válasz érkeztéről <p><strong>e-mailben értesítjük önt</strong>. Ha az adatgazda {{late_number_of_days}} munkanap elteltével sem válaszol, a határidő lejártakor emlékeztetőt\\n küldünk önnek.</p>\\n <p>Amennyiben adatigénylését máshol is megemlíti (például: internetes fórumon vagy blogbejegyzésben), kérjük, helyezzen el ott egy erre a KiMitTud oldalra mutató hivatkozást.\\n Az ilyen megosztásokról tegyen itt is említést hozzászólás formájában.</p>"
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 "<p>A {{site_name}} jelenleg karbantartás alatt áll. Csak a meglevő igényléseket tudja megtekinteni. Nem vehet fel új igénylést, fejleményt, hozzászólást és egyéb módon sem módosíthatja az adatbázist.</p> <p>{{read_only}}</p> "
@@ -264,10 +265,10 @@ msgstr ""
" <small>(előfordulhat, hogy csak visszaigazolás érkezett)</small> "
msgid "<strong>Note:</strong> Because we're testing, requests are being sent to {{email}} rather than to the actual authority."
-msgstr ""
+msgstr "<strong>Megjegyzés:</strong> Mivel egyelőre a tesztelést végezzük, az igényléseket az adott adatgazda helyett a(z) {{email}} e-mail címre küldjük."
msgid "<strong>Note:</strong> You're sending a message to yourself, presumably\\n to try out how it works."
-msgstr ""
+msgstr "<strong>Megjegyzés:</strong> Ezzel saját magának küldhet próbaüzenetet."
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 ""
@@ -281,7 +282,7 @@ msgstr ""
" jellegű információt igényelni, <a href=\"{{url}}\">kattintson ide</a>. "
msgid "<strong>Privacy note:</strong> Your photo will be shown in public on the Internet,\\n wherever you do something on {{site_name}}."
-msgstr ""
+msgstr "<strong>Adatvédelmi nyilatkozat:</strong> Profilképe a {{site_name}} weboldalon\\n nyilvánosan megjelenik."
msgid "<strong>Privacy warning:</strong> Your message, and any response\\n to it, will be displayed publicly on this website."
msgstr ""
@@ -298,10 +299,10 @@ msgid "<strong>did not have</strong> the information requested."
msgstr "<strong>nem kapta meg</strong> a kért információt. "
msgid "A <a href=\"{{request_url}}\">follow up</a> to <em>{{request_title}}</em> was sent to {{public_body_name}} by {{info_request_user}} on {{date}}."
-msgstr ""
+msgstr "A(z) <em>{{request_title}}</em> adatigénylésre vonatkozóan {{info_request_user}} <a href=\"{{request_url}}\">emlékeztetőt</a> küldött a(z) {{public_body_name}} részére {{date}} napon."
msgid "A <a href=\"{{request_url}}\">response</a> to <em>{{request_title}}</em> was sent by {{public_body_name}} to {{info_request_user}} on {{date}}. The request status is: {{request_status}}"
-msgstr ""
+msgstr "A(z) {{public_body_name}} <a href=\"{{request_url}}\">választ küldött</a> a(z) <em>{{request_title}}</em> adatigénylésre vonatkozóan {{info_request_user}} részére {{date}} napon. Az adatigénylés állapota: {{request_status}}."
msgid "A <strong>summary</strong> of the response if you have received it by post. "
msgstr "A válasz <strong>összefoglalása</strong>, amennyiben azt postán kapta meg. "
@@ -310,7 +311,7 @@ msgid "A Freedom of Information request"
msgstr "Közérdekűadat-igénylés "
msgid "A new request, <em><a href=\"{{request_url}}\">{{request_title}}</a></em>, was sent to {{public_body_name}} by {{info_request_user}} on {{date}}."
-msgstr ""
+msgstr "{{info_request_user}} új adatigénylést <em><a href=\"{{request_url}}\">{{request_title}}</a></em> küldött a(z) {{public_body_name}} részére {{date}} napon."
msgid "A public authority"
msgstr "Egy adatgazda"
@@ -322,7 +323,7 @@ msgid "A strange reponse, required attention by the {{site_name}} team"
msgstr "Furcsa válasz, amelyre felfigyelt a {{site_name}} csapata "
msgid "A vexatious request"
-msgstr ""
+msgstr "Zaklató jellegű igénylés"
msgid "A {{site_name}} user"
msgstr "{{site_name}} felhasználó "
@@ -333,6 +334,15 @@ msgstr "Magamról: "
msgid "Act on what you've learnt"
msgstr "Tegyen lépéseket a megismert tények alapján "
+msgid "Acts as xapian/acts as xapian job"
+msgstr ""
+
+msgid "ActsAsXapian::ActsAsXapianJob|Action"
+msgstr ""
+
+msgid "ActsAsXapian::ActsAsXapianJob|Model"
+msgstr ""
+
msgid "Add an annotation"
msgstr "Hozzászólás"
@@ -375,7 +385,7 @@ msgid "Also called {{other_name}}."
msgstr "Más néven: {{other_name}}."
msgid "Also send me alerts by email"
-msgstr ""
+msgstr "E-mailben is kérek értesítőt"
msgid "Alter your subscription"
msgstr "Feliratkozások módosítása "
@@ -384,7 +394,7 @@ msgid "Although all responses are automatically published, we depend on\\nyou, t
msgstr " Minden választ automatikusan közzéteszünk, de azokat az eredeti igénylő/n - jelen esetben Ön - értékelheti."
msgid "An <a href=\"{{request_url}}\">annotation</a> to <em>{{request_title}}</em> was made by {{event_comment_user}} on {{date}}"
-msgstr ""
+msgstr "{{event_comment_user}} <a href=\"{{request_url}}\">hozzászólást</a> küldött a(z) <em>{{request_title}}</em> adatigénylésre vonatkozóan {{date}} napon."
msgid "An <strong>error message</strong> has been received"
msgstr "<strong>Hibaüzenet</strong> érkezett "
@@ -393,7 +403,7 @@ msgid "An Environmental Information Regulations request"
msgstr "Környezeti információ igénylése "
msgid "An anonymous user"
-msgstr ""
+msgstr "Névtelen felhasználó"
msgid "Annotation added to request"
msgstr "Hozzászólás készült az igényléshez"
@@ -410,13 +420,13 @@ msgstr ""
" <strong>nem</strong> küldjük el a(z) {{public_body_name}} részére. "
msgid "Anonymous user"
-msgstr ""
+msgstr "Névtelen felhasználó"
msgid "Anyone:"
msgstr "Bárki:"
msgid "Applies to"
-msgstr ""
+msgstr "A következőre vonatkozik:"
msgid "Are we missing a public authority?"
msgstr ""
@@ -481,7 +491,7 @@ msgid "Cancel, return to your profile page"
msgstr "Mégse, visszatérés a profiloldalra "
msgid "Censor rule"
-msgstr ""
+msgstr "Cenzúrára vonatkozó szabály "
msgid "CensorRule|Last edit comment"
msgstr "CensorRule|Last edit comment"
@@ -490,7 +500,7 @@ msgid "CensorRule|Last edit editor"
msgstr "CensorRule|Last edit editor"
msgid "CensorRule|Regexp"
-msgstr ""
+msgstr "CensorRule|Regexp"
msgid "CensorRule|Replacement"
msgstr "CensorRule|Replacement"
@@ -541,13 +551,13 @@ msgid "Clarification"
msgstr "Pontosítás"
msgid "Clarify your FOI request - "
-msgstr ""
+msgstr "A közérdekűadat-igénylés pontosítása"
msgid "Classify an FOI response from "
msgstr "-tól/-től származó közérdekű adat igénylésére érkező válasz besorolása "
msgid "Clear photo"
-msgstr ""
+msgstr "Jó minőségű fénykép"
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."
msgstr ""
@@ -558,10 +568,10 @@ msgid "Click on the link below to send a message to {{public_body}} reminding th
msgstr "Az alábbi hivatkozásra kattintva üzenetet küldhet a(z) {{public_body}} részére, amelyben emlékezteti őket, hogy az igénylésre válaszoljanak. "
msgid "Close"
-msgstr ""
+msgstr "Bezárás"
msgid "Comment"
-msgstr ""
+msgstr "Megjegyzés"
msgid "Comment|Body"
msgstr "Comment|Body"
@@ -576,22 +586,22 @@ msgid "Comment|Visible"
msgstr "Comment|Visible"
msgid "Confirm you want to follow all successful FOI requests"
-msgstr ""
+msgstr "Erősítse meg, hogy követni kívánja az összes közérdekűadat-igénylést"
msgid "Confirm you want to follow new requests"
-msgstr ""
+msgstr "Erősítse meg, hogy követni kívánja az új adatigényléseket"
msgid "Confirm you want to follow new requests or responses matching your search"
-msgstr ""
+msgstr "Erősítse meg, hogy követni kívánja az új adatigényléseket vagy a keresési feltételeknek megfelelő válaszokat"
msgid "Confirm you want to follow requests by '{{user_name}}'"
-msgstr ""
+msgstr "Erősítse meg, hogy követni kívánja '{{user_name}}' adatigényléseit"
msgid "Confirm you want to follow requests to '{{public_body_name}}'"
-msgstr ""
+msgstr "Erősítse meg, hogy követni kívánja a(z) '{{public_body_name}}' részére küldött adatigényléseket"
msgid "Confirm you want to follow the request '{{request_title}}'"
-msgstr ""
+msgstr "Erősítse meg, hogy követni kívánja a(z) '{{request_title}}' adatigénylést"
msgid "Confirm your FOI request to "
msgstr "{{public_body_name}} számára küldött közérdekűadat-igénylés megerősítése. "
@@ -609,13 +619,13 @@ msgid "Confirm your new email address on {{site_name}}"
msgstr "Új e-mail címének megerősítése a {{site_name}} weboldalon "
msgid "Considered by administrators as not an FOI request and hidden from site."
-msgstr ""
+msgstr "Az adminisztrátorok szerint az adatigénylés nem közérdekű, és ezért nem jelenik meg."
msgid "Considered by administrators as vexatious and hidden from site."
-msgstr ""
+msgstr "Az adminisztrátorok szerint az adatigénylés zaklató jellegű, és ezért nem jelenik meg."
msgid "Contact {{recipient}}"
-msgstr ""
+msgstr "Kapcsolatfelvétel a(z) {{recipient}} képviselőjével"
msgid "Contact {{site_name}}"
msgstr "Kapcsolatfelvétel a {{site_name}} üzemeltetőjével"
@@ -640,6 +650,9 @@ msgstr "Jelenleg a(z) {{public_body_link}} <strong>válaszát</strong> várjuk.
msgid "Date:"
msgstr "Dátum: "
+msgid "Dear {{name}},"
+msgstr ""
+
msgid "Dear {{public_body_name}},"
msgstr "Tisztelt {{public_body_name}}! "
@@ -668,7 +681,7 @@ msgid "Disclaimer: This message and any reply that you make will be published on
msgstr "Jognyilatkozat: Ezt az üzenetet és az ön válaszát is közzétesszük az interneten. Az adatvédelemre és szerzői jogokra vonatkozó politikánk: "
msgid "Disclosure log"
-msgstr ""
+msgstr "Közzétételi napló"
msgid "Disclosure log URL"
msgstr ""
@@ -680,7 +693,7 @@ msgid "Done"
msgstr "Kész. "
msgid "Done &gt;&gt;"
-msgstr ""
+msgstr "Kész &gt;&gt;"
msgid "Download a zip file of all correspondence"
msgstr "Az adatigényléssel kapcsolatos eddigi teljes levelezés letöltése <i>zip</i> formátumban"
@@ -772,7 +785,7 @@ msgid "FOI requests {{start_count}} to {{end_count}} of {{total_count}}"
msgstr "közérdekűadat-igénylések: {{start_count}} - {{end_count}}, összesen: {{total_count}} "
msgid "FOI response requires admin ({{reason}}) - {{title}}"
-msgstr ""
+msgstr "A közérdekűadat-igénylés megválaszolásához adminisztrátori beavatkozás szükséges ({{reason}}) - {{title}}"
msgid "Failed to convert image to a PNG"
msgstr "Nem sikerült a kép PNG formátumba való átalakítása "
@@ -790,7 +803,7 @@ msgstr ""
" <a href=\"{{url}}\">... Miért?</a><br/>Írja be a keresett adatgazda nevét, vagy nevének (ismert) részletét az alábbi mezőbe!"
msgid "Foi attachment"
-msgstr ""
+msgstr "Közérdekűadat-igénylés melléklete"
msgid "FoiAttachment|Charset"
msgstr "FoiAttachment|Charset"
@@ -814,22 +827,22 @@ msgid "FoiAttachment|Within rfc822 subject"
msgstr "FoiAttachment|Within rfc822 subject"
msgid "Follow"
-msgstr ""
+msgstr "Követés"
msgid "Follow all new requests"
-msgstr ""
+msgstr "Minden új igénylés követése"
msgid "Follow new successful responses"
-msgstr ""
+msgstr "Új sikeres válaszok követése"
msgid "Follow requests to {{public_body_name}}"
-msgstr ""
+msgstr "{{public_body_name}} részére küldött adatigénylések követése"
msgid "Follow these requests"
msgstr "Értesítő igénylése az adatigénylésekkel kapcsolatos fejlemények vonatkozásában."
msgid "Follow things matching this search"
-msgstr ""
+msgstr "Keresési feltételnek megfelelő elemek követése"
msgid "Follow this authority"
msgstr "Kísérje figyelemmel ezt az adatgazdát!"
@@ -838,7 +851,7 @@ msgid "Follow this link to see the request:"
msgstr "Ezen a hivatkozáson tekinthető meg az igénylés:"
msgid "Follow this person"
-msgstr ""
+msgstr "Ezen felhasználó követése"
msgid "Follow this request"
msgstr "Értesítő igénylése az adatigényléssel kapcsolatos fejlemények vonatkozásában."
@@ -859,7 +872,7 @@ msgid "Follow us on twitter"
msgstr "Kövessen bennünket a twitteren "
msgid "Followups cannot be sent for this request, as it was made externally, and published here by {{public_body_name}} on the requester's behalf."
-msgstr ""
+msgstr "Ehhez az igényléshez nem küldhető emlékeztető üzenet, mivel az adatigénylést máshol nyújtották be, és itt az igénylő kérésére a(z) {{public_body_name}} tette közzé."
msgid "For an unknown reason, it is not possible to make a request to this authority."
msgstr "Ismeretlen okból kifolyólag ennek a közintézménynek nem lehet igénylést küldeni. "
@@ -905,7 +918,7 @@ msgid "Freedom of information requests to"
msgstr "Közérdekű adatok, melyeket a ettől az adatgazdától igényeltek: "
msgid "From"
-msgstr ""
+msgstr "Feladó"
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=\"{{url}}\">send it to us</a>."
msgstr ""
@@ -922,6 +935,18 @@ msgstr "ITT ÍRJA LE PANASZÁNAK RÉSZLETEIT "
msgid "Handled by post."
msgstr "Postai úton kézbesítve"
+msgid "Has tag string/has tag string tag"
+msgstr ""
+
+msgid "HasTagString::HasTagStringTag|Model"
+msgstr ""
+
+msgid "HasTagString::HasTagStringTag|Name"
+msgstr ""
+
+msgid "HasTagString::HasTagStringTag|Value"
+msgstr ""
+
msgid "Hello! You can make Freedom of Information requests within {{country_name}} at {{link_to_website}}"
msgstr "Üdvözöljük. {{country_name}} területén illetékes adatgazdáktól a {{link_to_website}} weboldalon igényelhet közérdekű adatokat. "
@@ -952,7 +977,7 @@ msgid "Hide request"
msgstr ""
msgid "Holiday"
-msgstr ""
+msgstr "Ünnepnap"
msgid "Holiday|Day"
msgstr "Holiday|Day"
@@ -990,7 +1015,7 @@ msgid "I don't want to do any more tidying now!"
msgstr "Nem szeretnék többet rendet rakni most! "
msgid "I like this request"
-msgstr ""
+msgstr "Kedvelem ezt az igénylést"
msgid "I would like to <strong>withdraw this request</strong>"
msgstr "<strong>Vissza szeretném vonni az igénylést</strong> "
@@ -1057,7 +1082,7 @@ msgid "If you are {{user_link}}, please"
msgstr "Ha ön {{user_link}}, kérjük, "
msgid "If you believe this request is not suitable, you can report it for attention by the site administrators"
-msgstr ""
+msgstr "Ha úgy gondolja, hogy az igénylés nem elfogadható, jelentheti az adminisztrátorok részére"
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."
msgstr ""
@@ -1082,7 +1107,7 @@ msgid "If you have not done so already, please write a message below telling the
msgstr "Ha még nem tette meg eddig, írjon alább üzenetet, amelyben tájékoztatja a közintézményt, hogy igénylését visszavonta. Máskülönben nem fogják tudni, hogy az igénylés vissza lett vonva. "
msgid "If you reply to this message it will go directly to {{user_name}}, who will\\nlearn your email address. Only reply if that is okay."
-msgstr ""
+msgstr "Ha válaszol erre az üzenetre, válaszát közvetlenül {{user_name}} fogja\\nmegkapni, aki látni fogja az ön e-mail címét. Csak akkor válaszoljon, ha ezzel egyetért."
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."
msgstr ""
@@ -1109,7 +1134,7 @@ msgid "Incoming email address"
msgstr ""
msgid "Incoming message"
-msgstr ""
+msgstr "Beérkező üzenet"
msgid "IncomingMessage|Cached attachment text clipped"
msgstr "IncomingMessage|Cached attachment text clipped"
@@ -1139,13 +1164,13 @@ msgid "IncomingMessage|Valid to reply to"
msgstr "IncomingMessage|Valid to reply to"
msgid "Individual requests"
-msgstr ""
+msgstr "Egyéni igénylések"
msgid "Info request"
-msgstr ""
+msgstr "Információ kérése "
msgid "Info request event"
-msgstr ""
+msgstr "Információkérési esemény "
msgid "InfoRequestEvent|Calculated state"
msgstr "InfoRequestEvent|Calculated state"
@@ -1169,22 +1194,22 @@ msgid "InfoRequest|Allow new responses from"
msgstr "InfoRequest|Allow new responses from"
msgid "InfoRequest|Attention requested"
-msgstr ""
+msgstr "InfoRequest|Attention requested"
msgid "InfoRequest|Awaiting description"
msgstr "InfoRequest|Awaiting description"
msgid "InfoRequest|Comments allowed"
-msgstr ""
+msgstr "InfoRequest|Comments allowed"
msgid "InfoRequest|Described state"
msgstr "InfoRequest|Described state"
msgid "InfoRequest|External url"
-msgstr ""
+msgstr "InfoRequest|External url"
msgid "InfoRequest|External user name"
-msgstr ""
+msgstr "InfoRequest|External user name"
msgid "InfoRequest|Handle rejected responses"
msgstr "InfoRequest|Handle rejected responses"
@@ -1225,7 +1250,7 @@ msgstr ""
"böngészőt használni. Nyomja meg a frissítés gombot, ha újra szeretne próbálkozni."
msgid "Items matching the following conditions are currently displayed on your wall."
-msgstr ""
+msgstr "Az alábbi feltételeknek megfelelő elemek az üzenőfalán láthatók."
msgid "Items sent in last month"
msgstr ""
@@ -1284,7 +1309,7 @@ msgid "Log in to download a zip file of {{info_request_title}}"
msgstr "Jelentkezzen be, hogy a {{info_request_title}} tárgyú adatigénylési zip-fájlként letölthesse"
msgid "Log into the admin interface"
-msgstr ""
+msgstr "Bejelentkezés az adminisztrátori interfészre"
msgid "Long overdue."
msgstr "Régóta lejárt"
@@ -1293,22 +1318,22 @@ msgid "Made between"
msgstr "Készült:"
msgid "Mail server log"
-msgstr ""
+msgstr "Levelezőkiszolgáló napló"
msgid "Mail server log done"
-msgstr ""
+msgstr "Levelezőkiszolgáló napló elkészült"
msgid "MailServerLogDone|Filename"
-msgstr ""
+msgstr "MailServerLogDone|Filename"
msgid "MailServerLogDone|Last stat"
-msgstr ""
+msgstr "MailServerLogDone|Last stat"
msgid "MailServerLog|Line"
-msgstr ""
+msgstr "MailServerLog|Line"
msgid "MailServerLog|Order"
-msgstr ""
+msgstr "MailServerLog|Order"
msgid "Make a new <strong>Environmental Information</strong> request"
msgstr "Új <strong>környezeti információ</strong> igénylés "
@@ -1337,10 +1362,10 @@ msgid "Make your own request"
msgstr "Adatigénylés létrehozása "
msgid "Many requests"
-msgstr ""
+msgstr "Sok igénylés"
msgid "Message"
-msgstr ""
+msgstr "Üzenet"
msgid "Message sent using {{site_name}} contact form, "
msgstr "Üzenet elküldve a {{site_name}} kapcsolatfelvételi űrlapján, "
@@ -1352,7 +1377,7 @@ msgid "More about this authority"
msgstr "További információ erről az adatgazdáról"
msgid "More requests..."
-msgstr ""
+msgstr "Több igénylés..."
msgid "More similar requests"
msgstr "Több hasonló igénylés "
@@ -1370,7 +1395,7 @@ msgid "My requests"
msgstr " Adatigényléseim "
msgid "My wall"
-msgstr ""
+msgstr "Saját üzenőfal"
msgid "Name can't be blank"
msgstr "Név nem lehet üres "
@@ -1397,7 +1422,7 @@ msgid "New password: (again)"
msgstr "Új jelszó: (újból) "
msgid "New response to '{{title}}'"
-msgstr ""
+msgstr "Új válasz a(z) '{{title}}' igénylésre"
msgid "New response to your FOI request - "
msgstr "Új válasz közérdekű adatok igénylésére - "
@@ -1445,7 +1470,7 @@ msgid "Not a valid FOI request"
msgstr ""
msgid "Note that the requester will not be notified about your annotation, because the request was published by {{public_body_name}} on their behalf."
-msgstr ""
+msgstr "Az adatigénylő nem kap értesítést a hozzászólásról, mert az igénylést maga a(z) {{public_body_name}} hozta nyilvánosságra."
msgid "Now check your email!"
msgstr "Kérjük, ellenőrizze postafiókját! "
@@ -1463,7 +1488,7 @@ msgid "OR remove the existing photo"
msgstr "VAGY meglevő fénykép eltávolítása "
msgid "Offensive? Unsuitable?"
-msgstr ""
+msgstr "Sértő? Nem alkalmas?"
msgid "Oh no! Sorry to hear that your request was refused. Here is what to do now."
msgstr "Sajnáljuk, hogy igénylését elutasították. A következőket teheti: "
@@ -1511,7 +1536,7 @@ msgid "Other:"
msgstr "Egyéb: "
msgid "Outgoing message"
-msgstr ""
+msgstr "Kimenő üzenet"
msgid "OutgoingMessage|Body"
msgstr "OutgoingMessage|Body"
@@ -1544,7 +1569,7 @@ msgid "Paste this link into emails, tweets, and anywhere else:"
msgstr "Másolja be ezt a hivatkozást e-mailbe, tweetbe és máshova: "
msgid "People"
-msgstr ""
+msgstr "Személyek"
msgid "People {{start_count}} to {{end_count}} of {{total_count}}"
msgstr "Személyek: {{start_count}} - {{end_count}}, összesen: {{total_count}} "
@@ -1689,7 +1714,7 @@ msgid "Please sign in as "
msgstr "Jelentkezzen be mint "
msgid "Please sign in or make a new account."
-msgstr ""
+msgstr "Jelentkezzen be vagy hozzon létre új fiókot."
msgid "Please type a message and/or choose a file containing your response."
msgstr "Írja be üzenetét és/vagy válassza ki a válaszát tartalmazó fájlt. "
@@ -1722,7 +1747,7 @@ msgid "Post annotation"
msgstr "Hozzászólás beküldése "
msgid "Post redirect"
-msgstr ""
+msgstr "Feladás átirányítása"
msgid "PostRedirect|Circumstance"
msgstr "PostRedirect|Circumstance"
@@ -1767,7 +1792,7 @@ msgid "Preview your public request"
msgstr "Adatigénylése előnézetének megtekintése "
msgid "Profile photo"
-msgstr ""
+msgstr "Profilkép"
msgid "ProfilePhoto|Data"
msgstr "ProfilePhoto|Data"
@@ -1788,10 +1813,7 @@ msgid "Public authority – {{name}}"
msgstr ""
msgid "Public body"
-msgstr ""
-
-msgid "Public body/translation"
-msgstr ""
+msgstr "Adatgazda"
msgid "Public notes"
msgstr ""
@@ -1802,38 +1824,11 @@ msgstr ""
msgid "Public page not available"
msgstr ""
-msgid "PublicBody::Translation|Disclosure log"
-msgstr ""
-
-msgid "PublicBody::Translation|First letter"
-msgstr ""
-
-msgid "PublicBody::Translation|Locale"
-msgstr ""
-
-msgid "PublicBody::Translation|Name"
-msgstr ""
-
-msgid "PublicBody::Translation|Notes"
-msgstr ""
-
-msgid "PublicBody::Translation|Publication scheme"
-msgstr ""
-
-msgid "PublicBody::Translation|Request email"
-msgstr ""
-
-msgid "PublicBody::Translation|Short name"
-msgstr ""
-
-msgid "PublicBody::Translation|Url name"
-msgstr ""
-
msgid "PublicBody|Api key"
-msgstr ""
+msgstr "PublicBody|Api key"
msgid "PublicBody|Disclosure log"
-msgstr ""
+msgstr "PublicBody|Disclosure log"
msgid "PublicBody|First letter"
msgstr "PublicBody|First letter"
@@ -1842,7 +1837,7 @@ msgid "PublicBody|Home page"
msgstr "PublicBody|Home page"
msgid "PublicBody|Info requests count"
-msgstr ""
+msgstr "PublicBody|Info requests count"
msgid "PublicBody|Last edit comment"
msgstr "PublicBody|Last edit comment"
@@ -1878,13 +1873,13 @@ msgid "Publication scheme URL"
msgstr ""
msgid "Purge request"
-msgstr ""
+msgstr "Igénylés tisztítása"
msgid "PurgeRequest|Model"
-msgstr ""
+msgstr "PurgeRequest|Model"
msgid "PurgeRequest|Url"
-msgstr ""
+msgstr "PurgeRequest|Url"
msgid "RSS feed"
msgstr "RSS feed"
@@ -1922,13 +1917,13 @@ msgid "Report abuse"
msgstr "Visszaélés jelentése"
msgid "Report an offensive or unsuitable request"
-msgstr ""
+msgstr "Sértő vagy nem alkalmas igénylés jelentése"
msgid "Report this request"
-msgstr ""
+msgstr "Igénylés jelentése"
msgid "Reported for administrator attention."
-msgstr ""
+msgstr "Bejelentve az adminisztrátornak."
msgid "Request an internal review"
msgstr "Belső felülvizsgálat kérése"
@@ -1955,7 +1950,7 @@ msgid "Requested on {{date}}"
msgstr "Igénylés benyújtva {{date}} napon "
msgid "Requests for personal information and vexatious requests are not considered valid for FOI purposes (<a href=\"/help/about\">read more</a>)."
-msgstr ""
+msgstr "Személyes információk kérése vagy zaklatásnak minősülő igénylés nem tekinthetők érvényes közérdekűadat-igénylésnek (<a href=\"/help/about\">További részletek</a>)."
msgid "Requests or responses matching your saved search"
msgstr "Az ön által beállított keresési feltételeknek megfelelő igénylések vagy válaszok "
@@ -1979,7 +1974,7 @@ msgid "Response from a public authority"
msgstr "Válasz érkezett a közintézménytől "
msgid "Response to '{{title}}'"
-msgstr ""
+msgstr "Válasz a(z) '{{title}}' igénylésre"
msgid "Response to this request is <strong>delayed</strong>."
msgstr "Az igénylés megválaszolása <strong>késik</strong>. "
@@ -2024,7 +2019,7 @@ msgstr ""
" <strong>{{number_of_authorities}} adatgazda</strong> között böngészhet pillanatnyilag a rendszerünkben."
msgid "Search queries"
-msgstr ""
+msgstr "Keresési lekérdezések"
msgid "Search results"
msgstr "A keresés eredménye"
@@ -2062,7 +2057,7 @@ msgid "Send a public reply to {{person_or_body}}"
msgstr "Nyilvános válasz küldése {{person_or_body}} részére "
msgid "Send follow up to '{{title}}'"
-msgstr ""
+msgstr "Emlékeztető üzenet küldése a(z) '{{title}}' igényléshez"
msgid "Send message"
msgstr "Üzenet küldése "
@@ -2129,7 +2124,7 @@ msgid "Somebody added a note to your FOI request - "
msgstr "Közérdekűadat-igényléséhez valaki hozzászólt - "
msgid "Someone has updated the status of your request"
-msgstr ""
+msgstr "Valaki módosította az igénylés állapotát"
msgid "Someone, perhaps you, just tried to change their email address on\\n{{site_name}} from {{old_email}} to {{new_email}}."
msgstr ""
@@ -2137,7 +2132,7 @@ msgstr ""
"{{site_name}} weboldalon a következőről: {{old_email}} a következőre: {{new_email}}. "
msgid "Sorry - you cannot respond to this request via {{site_name}}, because this is a copy of the request originally at {{link_to_original_request}}."
-msgstr ""
+msgstr "Az igénylésre sajnos nem tud a {{site_name}} weboldalon választ adni, mert ez a(z) {{link_to_original_request}} eredeti igénylés másolata."
msgid "Sorry, but only {{user_name}} is allowed to do that."
msgstr "Erre csak {{user_name}} jogosult. "
@@ -2167,7 +2162,7 @@ msgid "Still awaiting an <strong>internal review</strong>"
msgstr "Továbbra is <strong>belső felülvizsgálatra</strong> várva "
msgid "Subject"
-msgstr ""
+msgstr "Tárgy"
msgid "Subject:"
msgstr "Tárgy: "
@@ -2344,6 +2339,9 @@ msgstr "A kereső jelenleg nem működik, így nem tudjuk megjeleníteni azokat
msgid "The search index is currently offline, so we can't show the Freedom of Information requests this person has made."
msgstr "A kereső jelenleg nem működik, így nem tudjuk megjeleníteni azokat a közérdekűadat-igényléseket, amelyeket ez a személy nyújtott be. "
+msgid "The {{site_name}} team."
+msgstr ""
+
msgid "Then you can cancel the alert."
msgstr "Ezután törölheti az értesítőt. "
@@ -2363,13 +2361,13 @@ msgid "Then you can download a zip file of {{info_request_title}}."
msgstr "Ezután letöltheti a(z) {{info_request_title}} igénylést zip-fájlban. "
msgid "Then you can log into the administrative interface"
-msgstr ""
+msgstr "Ezután bejelentkezhet az adminisztrátori interfészre"
msgid "Then you can play the request categorisation game."
msgstr "Ezután elvégezheti az igénylés besorolását. "
msgid "Then you can report the request '{{title}}'"
-msgstr ""
+msgstr "Ezután jelentheti a(z) '{{title}}' igénylést"
msgid "Then you can send a message to "
msgstr "Ezután üzenetet küldhet a következőnek: "
@@ -2390,22 +2388,22 @@ msgid "Then you can write your reply to "
msgstr "Ezután válaszolhat a következőnek: "
msgid "Then you will be following all new FOI requests."
-msgstr ""
+msgstr "Ezután az összes új közérdekűadat-igénylést követni fogja."
msgid "Then you will be notified whenever '{{user_name}}' requests something or gets a response."
-msgstr ""
+msgstr "Ezután értesítést kap, amint '{{user_name}}' igénylést nyújt be, vagy választ kap. "
msgid "Then you will be notified whenever a new request or response matches your search."
-msgstr ""
+msgstr "Ezután értesítést kap, ha keresésének megfelelő új igénylés vagy válasz érkezik. "
msgid "Then you will be notified whenever an FOI request succeeds."
-msgstr ""
+msgstr "Ezután értesítést kap, ha egy közérdekűadat-igénylés sikeresen lezárul. "
msgid "Then you will be notified whenever someone requests something or gets a response from '{{public_body_name}}'."
-msgstr ""
+msgstr "Ezután értesítést kap, ha valaki igénylést nyújt be, vagy választ kap a(z) '{{public_body_name}}' adatgazdától. "
msgid "Then you will be updated whenever the request '{{request_title}}' is updated."
-msgstr ""
+msgstr "Ezután értesítést kap, ha a(z) '{{request_title}}' igénylést frissítik. "
msgid "Then you'll be allowed to send FOI requests."
msgstr "Ezután önnek lehetősége van közérdekűadat-igénylést benyújtani. "
@@ -2420,7 +2418,7 @@ msgid "There are {{count}} new annotations on your {{info_request}} request. Fol
msgstr "{{count}} új hozzászólás érkezett a(z) {{info_request}} igényléséhez. A hivatkozásra kattintva elolvashatja ezeket. "
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 ""
+msgstr "A weboldal felhasználói között <strong>több</strong> ilyen nevű személy is van.\\n Egyiküket láthatja alább, de előfordulhat, hogy ez nem ön. "
msgid "There is a limit on the number of requests you can make in a day, because we don’t want public authorities to be bombarded with large numbers of inappropriate requests. If you feel you have a good reason to ask for the limit to be lifted in your case, please <a href='{{help_contact_path}}'>get in touch</a>."
msgstr "Ennek a korlátozásnak az az oka hogy nem szeretnénk ha nagy mennyiségű inadekvát adatigényléssel árasztaná el az adatgazdákat valaki. Ha úgy érzi hogy nyomós oka van ennél több adatigénylést kezdeményezni rövid időn belül, kérjük, <a href='{{help_contact_path}}'>lépjen kapcsolatba</a> velünk."
@@ -2463,7 +2461,7 @@ msgid "Things to do with this request"
msgstr "Az adatigényléssel kapcsolatosan az alábbi lehetőségek közül választhat:"
msgid "Things you're following"
-msgstr ""
+msgstr "Követett elemek:"
msgid "This authority no longer exists, so you cannot make a request to it."
msgstr "Ez az adatgazda már nem létezik, ezért nem tud adatigényléseket fogadni. "
@@ -2479,7 +2477,7 @@ msgstr ""
" a<strong>természeti és épített környezetre</strong> vonatkozóan, mint például: "
msgid "This external request has been hidden"
-msgstr ""
+msgstr "A külső igénylés el van rejtve"
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 "Ez a közérdekűadat-igénylés egyszerű szöveges változata \"{{request_title}}\". A legutóbbi, teljes változatot itt találja: {{full_url}} "
@@ -2526,19 +2524,19 @@ msgid "This request <strong>requires administrator attention</strong>"
msgstr "Ezt az igénylést <strong>meg kell vizsgálnia az adminisztrátornak</strong> "
msgid "This request has already been reported for administrator attention"
-msgstr ""
+msgstr "Ezt az igénylést már jelentették az adminisztrátornak"
msgid "This request has an <strong>unknown status</strong>."
msgstr "Ennek az igénylésnek <strong>ismeretlen az állapota</strong>. "
msgid "This request has been <strong>hidden</strong> from the site, because an administrator considers it not to be an FOI request"
-msgstr ""
+msgstr "Ez az igénylés <strong>nem jelenik meg</strong> a weboldalon, mert az adminisztrátor nem közérdekűadat-igénylésnek minősítette"
msgid "This request has been <strong>hidden</strong> from the site, because an administrator considers it vexatious"
-msgstr ""
+msgstr "Ez az igénylés <strong>nem jelenik meg</strong> a weboldalon, mert az adminisztrátor zaklató jellegűnek minősítette"
msgid "This request has been <strong>reported</strong> as needing administrator attention (perhaps because it is vexatious, or a request for personal information)"
-msgstr ""
+msgstr "Ezt az igénylést <strong>jelentették</strong> az adminisztrátornak (valószínűleg azért, mert zaklató jellegű vagy személyes információra irányult)"
msgid "This request has been <strong>withdrawn</strong> by the person who made it.\\n There may be an explanation in the correspondence below."
msgstr ""
@@ -2549,7 +2547,7 @@ msgid "This request has been marked for review by the site administrators, who h
msgstr ""
msgid "This request has been reported for administrator attention"
-msgstr ""
+msgstr "Ezt az igénylést már jelentették az adminisztrátornak"
msgid "This request has been set by an administrator to \"allow new responses from nobody\""
msgstr "Az adminisztrátor erre az igénylésre \"új választ senki sem küldhet\" beállítást adott meg "
@@ -2574,7 +2572,7 @@ msgid "This request requires administrator attention"
msgstr ""
msgid "This request was not made via {{site_name}}"
-msgstr ""
+msgstr "Az igénylést nem a(z) {{site_name}} weboldalon keresztül nyújtották be"
msgid "This response has been hidden. See annotations to find out why.\\n If you are the requester, then you may <a href=\"{{url}}\">sign in</a> to view the response."
msgstr ""
@@ -2623,22 +2621,22 @@ msgid "To download the zip file"
msgstr "Ha le szeretné tölteni a zip-fájlt "
msgid "To follow all successful requests"
-msgstr ""
+msgstr "Sikeres igénylések követése"
msgid "To follow new requests"
-msgstr ""
+msgstr "Új igénylések követése"
msgid "To follow requests and responses matching your search"
msgstr "Ha követni szeretné a keresésének megfelelő igényléseket és válaszokat "
msgid "To follow requests by '{{user_name}}'"
-msgstr ""
+msgstr "'{{user_name}}' igényléseinek követése"
msgid "To follow requests made using {{site_name}} to the public authority '{{public_body_name}}'"
-msgstr ""
+msgstr "{{site_name}} weboldalon a(z) '{{public_body_name}}' részére küldött adatigénylések követése"
msgid "To follow the request '{{request_title}}'"
-msgstr ""
+msgstr "A(z) '{{request_title}}' igénylés követése"
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 ""
@@ -2646,10 +2644,10 @@ msgstr ""
"{{law_used_full}} {{title}} című igénylést. A frissítés következtében ennek állapota: \"{{display_status}}\". Ha nem ért egyet ezzel a besorolással, frissítse ön is az állapotot olyan értékre, amely ön szerint pontosabb. "
msgid "To let everyone know, follow this link and then select the appropriate box."
-msgstr ""
+msgstr "Ha tájékoztatni szeretne mindenkit, kattintson a hivatkozásra, majd jelölje be a megfelelő négyzetet. "
msgid "To log into the administrative interface"
-msgstr ""
+msgstr "Bejelentkezés az adminisztrátori interfészre"
msgid "To play the request categorisation game"
msgstr "Ha osztályozni szeretné az igénylést "
@@ -2661,7 +2659,7 @@ msgid "To reply to "
msgstr "Ha válaszolni kíván a következőnek:"
msgid "To report this FOI request"
-msgstr ""
+msgstr "Közérdekűadat-igénylés jelentése"
msgid "To send a follow up message to "
msgstr "Ha emlékeztető üzenetet szeretne küldeni a(z) "
@@ -2697,13 +2695,13 @@ msgid "Today"
msgstr "Ma "
msgid "Too many requests"
-msgstr ""
+msgstr "Túl sok igénylés"
msgid "Top search results:"
msgstr "Találatok: "
msgid "Track thing"
-msgstr ""
+msgstr "Elem nyomon követése "
msgid "Track this person"
msgstr "Feliratkozás a felhasználó tevékenyégéről beszámoló hírlevélre"
@@ -2721,7 +2719,7 @@ msgid "TrackThing|Track type"
msgstr "TrackThing|Track type"
msgid "Turn off email alerts"
-msgstr ""
+msgstr "Értesítő e-mailben kikapcsolása"
msgid "Tweet this request"
msgstr "Az igénylés elküldése tweetben"
@@ -2762,7 +2760,7 @@ msgid "Unknown"
msgstr "Ismeretlen"
msgid "Unsubscribe"
-msgstr ""
+msgstr "Leiratkozás"
msgid "Unusual response."
msgstr "Szokatlan válasz"
@@ -2774,7 +2772,7 @@ msgid "Update the status of your request to "
msgstr "Igénylése állapotának frissítése a következőre: "
msgid "Upload FOI response"
-msgstr ""
+msgstr "Közérdekűadat-igénylésre kapott válasz"
msgid "Use OR (in capital letters) where you don't mind which word, e.g. <strong><code>commons OR lords</code></strong>"
msgstr "Használja az OR kifejezést (nagybetűkkel), ha mindegy, hogy melyik szó, pl. <strong><code>alsóház OR felsőház</code></strong> "
@@ -2783,7 +2781,7 @@ msgid "Use quotes when you want to find an exact phrase, e.g. <strong><code>\"Li
msgstr "Ha egy adott kifejezést keres, használjon idézőjeleket; például: <strong><code>\"Liverpool City Council\"</code></strong> "
msgid "User"
-msgstr ""
+msgstr "Felhasználó"
msgid "User info request sent alert"
msgstr ""
@@ -2798,7 +2796,7 @@ msgid "User|About me"
msgstr "User|About me"
msgid "User|Address"
-msgstr ""
+msgstr "User|Address"
msgid "User|Admin level"
msgstr "User|Admin level"
@@ -2807,7 +2805,7 @@ msgid "User|Ban text"
msgstr "User|Ban text"
msgid "User|Dob"
-msgstr ""
+msgstr "User|Dob"
msgid "User|Email"
msgstr "User|Email"
@@ -2837,7 +2835,7 @@ msgid "User|No limit"
msgstr "User|No limit"
msgid "User|Receive email alerts"
-msgstr ""
+msgstr "User|Receive email alerts"
msgid "User|Salt"
msgstr "User|Salt"
@@ -2887,6 +2885,12 @@ msgstr "Az adatgazda válaszára várakozik "
msgid "Was the response you got to your FOI request any good?"
msgstr "A közérdekűadat-igénylésére kielégítő választ kapott? "
+msgid "We consider it is not a valid FOI request, and have therefore hidden it from other users."
+msgstr ""
+
+msgid "We consider it to be vexatious, and have therefore hidden it from other users."
+msgstr ""
+
msgid "We do not have a working request email address for this authority."
msgstr "Nem rendelkezünk az adatgazda működő e-mail címével. "
@@ -2942,7 +2946,7 @@ msgid "What information has been released?"
msgstr "Mire voltak kíváncsiak mások? "
msgid "What information has been requested?"
-msgstr ""
+msgstr "Milyen adatot igényeltek?"
msgid "When you get there, please update the status to say if the response \\ncontains any useful information."
msgstr ""
@@ -2988,28 +2992,28 @@ msgid "You"
msgstr "ön"
msgid "You are already following new requests"
-msgstr ""
+msgstr "Ön már követi az új igényléseket"
msgid "You are already following requests to {{public_body_name}}"
-msgstr ""
+msgstr "Ön már követi a(z) {{public_body_name}} részére küldött adatigényléseket"
msgid "You are already following things matching this search"
-msgstr ""
+msgstr "Ön már követi a keresési feltételeknek megfelelő elemeket"
msgid "You are already following this person"
-msgstr ""
+msgstr "Ön már követi ezt a személyt"
msgid "You are already following this request"
-msgstr ""
+msgstr "Ön már követi ezt az igénylést"
msgid "You are already following updates about {{track_description}}"
msgstr ""
msgid "You are currently receiving notification of new activity on your wall by email."
-msgstr ""
+msgstr "Az új tevékenységekről értesítést kap e-mailben az üzenőfalára."
msgid "You are following all new successful responses"
-msgstr ""
+msgstr "Követi az összes sikeres választ"
msgid "You are no longer following {{track_description}}."
msgstr ""
@@ -3021,7 +3025,7 @@ msgid "You can <strong>complain</strong> by"
msgstr "<strong>Panaszt nyújthat be</strong> a következő időpontig:"
msgid "You can change the requests and users you are following on <a href=\"{{profile_url}}\">your profile page</a>."
-msgstr ""
+msgstr "Módosíthatja a <a href=\"{{profile_url}}\">profiloldalon</a> követett igényléseket és felhasználókat."
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>."
msgstr ""
@@ -3061,7 +3065,7 @@ msgid "You know what caused the error, and can <strong>suggest a solution</stron
msgstr "ön tudja, hogy mi okozta a hibát, és tud <strong>megoldást javasolni</strong>, mint például egy ténylegesen működő e-mail címet. "
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 ""
+msgstr "<strong>Mellékleteket is csatolhat</strong>. Ha olyan fájlt szeretne csatolni, amely\\n e-mailben történő küldéshez túl nagy, használja az alábbi űrlapot. "
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=\"{{url}}\">send it to us</a>."
msgstr ""
@@ -3085,13 +3089,13 @@ msgid "You need to be logged in to clear your profile photo."
msgstr "A profilkép törléséhez először be kell jelentkeznie. "
msgid "You need to be logged in to edit your profile."
-msgstr ""
+msgstr "Profiljának módosításához be kell jelentkeznie."
msgid "You previously submitted that exact follow up message for this request."
msgstr "Korábban már beküldte ugyanezt a nyomon követési üzenetet erre az igénylésre vonatkozóan. "
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 ""
+msgstr "E-mailben meg kellett volna kapnia az igénylést, és a válaszadáshoz\\n <strong>egyszerűen válaszolnia</strong> kell erre az e-mailre. A kényelem kedvéért, íme a cím: "
msgid "You want to <strong>give your postal address</strong> to the authority in private."
msgstr "<strong>Postai címét megadhatja</strong> a közintézménynek bizalmasan. "
@@ -3114,14 +3118,17 @@ msgstr ""
"Igénylésére csak akkor fog választ kapni, ha végrehajtja a\n"
"pontosítást."
-msgid "You're in. <a href=\"#\" id=\"send-request\">Continue sending your request</a>"
+msgid "You will still be able to view it while logged in to the site. Please reply to this email if you would like to discuss this decision further."
msgstr ""
+msgid "You're in. <a href=\"#\" id=\"send-request\">Continue sending your request</a>"
+msgstr "Bejelentkezett. <a href=\"#\" id=\"send-request\">Igénylés elküldésének folytatása</a>"
+
msgid "You're long overdue a response to your FOI request - "
msgstr "Közérdekűadat-igénylésére már rég választ kellett volna kapnia - "
msgid "You're not following anything."
-msgstr ""
+msgstr "Ön nem követ semmit."
msgid "You've now cleared your profile photo"
msgstr "Eltávolította profilképét "
@@ -3135,7 +3142,7 @@ msgid "Your annotations"
msgstr "Hozzászólásaim"
msgid "Your details, including your email address, have not been given to anyone."
-msgstr ""
+msgstr "Adatait (beleértve az e-mail címét) senkinek nem továbítottuk."
msgid "Your e-mail:"
msgstr "Az ön e-mail címe: "
@@ -3153,7 +3160,7 @@ msgid "Your message has been sent. Thank you for getting in touch! We'll get bac
msgstr "Üzenetét elküldtük. Köszönjük, hogy kapcsolatba lépett velünk! Hamarosan jelentkezünk. "
msgid "Your message to {{recipient_user_name}} has been sent"
-msgstr ""
+msgstr "{{recipient_user_name}} részére írt üzenetét a rendszer elküldte"
msgid "Your message to {{recipient_user_name}} has been sent!"
msgstr "Üzenetét elküldtük {{recipient_user_name}} részére. "
@@ -3182,6 +3189,12 @@ msgid "Your password:"
msgstr "Az ön jelszava: "
msgid "Your photo will be shown in public <strong>on the Internet</strong>,\\n wherever you do something on {{site_name}}."
+msgstr "Profilképe az <strong>interneten</strong> nyilvánosan megjelenik, ha a {{site_name}} weboldalon valamilyen műveletet hajt végre."
+
+msgid "Your request '{{request}}' at {{url}} has been reviewed by moderators."
+msgstr ""
+
+msgid "Your request on {{site_name}} hidden"
msgstr ""
msgid "Your request was called {{info_request}}. Letting everyone know whether you got the information will help us keep tabs on"
@@ -3191,7 +3204,7 @@ msgid "Your request:"
msgstr "Az ön igénylése: "
msgid "Your response to an FOI request was not delivered"
-msgstr ""
+msgstr "Közérdekűadat-igénylésre adott válaszát nem lehet továbbítani"
msgid "Your response will <strong>appear on the Internet</strong>, <a href=\"{{url}}\">read why</a> and answers to other questions."
msgstr "Válasza <strong>megjelenik az interneten</strong>, <a href=\"{{url}}\">olvassa el, miért</a> az egyéb kérdésekre adott válaszokhoz hasonlóan. "
@@ -3218,6 +3231,9 @@ msgstr "Üdvözlettel: "
msgid "Yours sincerely,"
msgstr "Üdvözlettel: "
+msgid "Yours,"
+msgstr ""
+
msgid "[FOI #{{request}} email]"
msgstr ""
@@ -3246,7 +3262,7 @@ msgid "also called {{public_body_short_name}}"
msgstr "más néven {{public_body_short_name}} "
msgid "an anonymous user"
-msgstr ""
+msgstr "névtelen felhasználó"
msgid "and"
msgstr "és"
@@ -3329,7 +3345,7 @@ msgid "everything"
msgstr "minden"
msgid "external"
-msgstr ""
+msgstr "külső"
msgid "has reported an"
msgstr "bejelentett"
@@ -3338,7 +3354,7 @@ msgid "have delayed."
msgstr "késedelmes. "
msgid "hide quoted sections"
-msgstr ""
+msgstr "idézett részek elrejtése"
msgid "in term time"
msgstr "szorgalmi időszakban "
@@ -3419,13 +3435,13 @@ msgid "set to <strong>blank</strong> (empty string) if can't find an address; th
msgstr ""
msgid "show quoted sections"
-msgstr ""
+msgstr "idézett részek megjelenítése"
msgid "sign in"
msgstr "bejelentkezés"
msgid "simple_date_format"
-msgstr ""
+msgstr "simple_date_format"
msgid "successful"
msgstr "sikeres"
@@ -3448,7 +3464,7 @@ msgid "the main FOI contact at {{public_body}}"
msgstr "{{public_body}} közérdekűadat-igénylésekkel foglalkozó elsődleges kapcsolattartója "
msgid "the requester"
-msgstr ""
+msgstr "igénylő"
msgid "the {{site_name}} team"
msgstr "a {{site_name}} csapata "
@@ -3534,7 +3550,7 @@ msgid "{{law_used_full}} request GQ - {{title}}"
msgstr "{{law_used_full}} igénylés GQ - {{title}} "
msgid "{{law_used}} requests at {{public_body}}"
-msgstr ""
+msgstr "{{law_used}} igénylések {{public_body}} adatgazdánál"
msgid "{{length_of_time}} ago"
msgstr "Azóta {{length_of_time}} telt el."
@@ -3546,22 +3562,22 @@ msgid "{{number_of_comments}} comments"
msgstr "{{number_of_comments}} hozzászólás"
msgid "{{public_body_link}} answered a request about"
-msgstr ""
+msgstr "{{public_body_link}} válaszolt a következőre irányuló adatigénylésre:"
msgid "{{public_body_link}} was sent a request about"
-msgstr ""
+msgstr "{{public_body_link}} a következőre irányuló adatigénylést kapott:"
msgid "{{public_body_name}} only:"
msgstr "Csak a(z) {{public_body_name}} munkatársa:"
msgid "{{public_body}} has asked you to explain part of your {{law_used}} request."
-msgstr ""
+msgstr "{{public_body}} kéri, hogy {{law_used}} igénylésének egy részét magyarázza meg."
msgid "{{public_body}} sent a response to {{user_name}}"
msgstr "{{public_body}} választ küldött {{user_name}} részére "
msgid "{{reason}}, please sign in or make a new account."
-msgstr ""
+msgstr "{{reason}}, jelentkezzen be vagy hozzon létre új fiókot"
msgid "{{search_results}} matching '{{query}}'"
msgstr "{{search_results}}, amelyek megfelelnek a(z) '{{query}}' lekérdezésnek "
@@ -3582,16 +3598,16 @@ msgid "{{thing_changed}} was changed from <code>{{from_value}}</code> to <code>{
msgstr ""
msgid "{{title}} - a Freedom of Information request to {{public_body}}"
-msgstr ""
+msgstr "{{title}} - közérdekűadat-igénylés {{public_body}} részére"
msgid "{{user_name}} (Account suspended)"
msgstr "{{user_name}} (Fiók felfüggesztve) "
msgid "{{user_name}} - Freedom of Information requests"
-msgstr ""
+msgstr "{{user_name}} - Közérdekűadat-igénylések "
msgid "{{user_name}} - user profile"
-msgstr ""
+msgstr "{{user_name}} - felhasználói profil"
msgid "{{user_name}} added an annotation"
msgstr "{{user_name}} hozzászólt"
diff --git a/locale/id/app.po b/locale/id/app.po
index 9a98fd1d2..2dd368b4c 100644
--- a/locale/id/app.po
+++ b/locale/id/app.po
@@ -14,10 +14,10 @@ msgid ""
msgstr ""
"Project-Id-Version: alaveteli\n"
"Report-Msgid-Bugs-To: http://github.com/sebbacon/alaveteli/issues\n"
-"POT-Creation-Date: 2013-04-23 16:34+0100\n"
-"PO-Revision-Date: 2013-04-23 15:50+0000\n"
+"POT-Creation-Date: 2013-05-30 09:46+0100\n"
+"PO-Revision-Date: 2013-05-30 08:54+0000\n"
"Last-Translator: louisecrow <louise@mysociety.org>\n"
-"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language-Team: Indonesian (http://www.transifex.com/projects/p/alaveteli/language/id/)\n"
"Language: id\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -360,6 +360,15 @@ msgstr "Tentang Anda:"
msgid "Act on what you've learnt"
msgstr "Bertindak atas apa yang telah Anda pelajari"
+msgid "Acts as xapian/acts as xapian job"
+msgstr ""
+
+msgid "ActsAsXapian::ActsAsXapianJob|Action"
+msgstr ""
+
+msgid "ActsAsXapian::ActsAsXapianJob|Model"
+msgstr ""
+
msgid "Add an annotation"
msgstr "Tambahkan anotasi"
@@ -671,6 +680,9 @@ msgstr "Saat ini<strong>sedang menunggu respon</strong> dari{{public_body_link}}
msgid "Date:"
msgstr "Tanggal:"
+msgid "Dear {{name}},"
+msgstr ""
+
msgid "Dear {{public_body_name}},"
msgstr "Yang terhormat {{public_body_name}},"
@@ -952,6 +964,18 @@ msgstr "BERIKAN RINCIAN TENTANG KEBERATAN ANDA DI SINI"
msgid "Handled by post."
msgstr "Ditangani oleh pos."
+msgid "Has tag string/has tag string tag"
+msgstr ""
+
+msgid "HasTagString::HasTagStringTag|Model"
+msgstr ""
+
+msgid "HasTagString::HasTagStringTag|Name"
+msgstr ""
+
+msgid "HasTagString::HasTagStringTag|Value"
+msgstr ""
+
msgid "Hello! You can make Freedom of Information requests within {{country_name}} at {{link_to_website}}"
msgstr "Halo! Anda dapat membuat permintaan Freedom of Information di {{country_name}} pada{{link_to_website}}"
@@ -1816,9 +1840,6 @@ msgstr "Otoritas publik - {{name}}"
msgid "Public body"
msgstr "Badan publik"
-msgid "Public body/translation"
-msgstr "Public body/translation"
-
msgid "Public notes"
msgstr "Catatan publik"
@@ -1828,33 +1849,6 @@ msgstr "Halaman publik"
msgid "Public page not available"
msgstr "Halaman publik tidak ada"
-msgid "PublicBody::Translation|Disclosure log"
-msgstr "PublicBody::Translation | Disclosure log"
-
-msgid "PublicBody::Translation|First letter"
-msgstr "PublicBody::Translation|First letter"
-
-msgid "PublicBody::Translation|Locale"
-msgstr "PublicBody::Translation|Locale"
-
-msgid "PublicBody::Translation|Name"
-msgstr "PublicBody::Translation|Name"
-
-msgid "PublicBody::Translation|Notes"
-msgstr "PublicBody::Translation|Notes"
-
-msgid "PublicBody::Translation|Publication scheme"
-msgstr "PublicBody::Translation|Publication scheme"
-
-msgid "PublicBody::Translation|Request email"
-msgstr "PublicBody::Translation|Request email"
-
-msgid "PublicBody::Translation|Short name"
-msgstr "PublicBody::Translation|Short name"
-
-msgid "PublicBody::Translation|Url name"
-msgstr "PublicBody::Translation|Url name"
-
msgid "PublicBody|Api key"
msgstr "PublicBody | Api key"
@@ -2369,6 +2363,9 @@ msgstr "Indeks pencarian saat ini sedang offline, sehingga kami tidak dapat mena
msgid "The search index is currently offline, so we can't show the Freedom of Information requests this person has made."
msgstr "Indeks pencarian saat ini sedang offline, sehingga kami tidak dapat menampilkan permintaan Freedom of Information yang telah dibuat oleh orang ini."
+msgid "The {{site_name}} team."
+msgstr ""
+
msgid "Then you can cancel the alert."
msgstr "Maka Anda dapat membatalkan tanda notifikasi."
@@ -2909,6 +2906,12 @@ msgstr "Menunggu otoritas publik untuk membalas"
msgid "Was the response you got to your FOI request any good?"
msgstr "Apakah respon yang Anda terima atas permintaa FOI Anda berguna?"
+msgid "We consider it is not a valid FOI request, and have therefore hidden it from other users."
+msgstr ""
+
+msgid "We consider it to be vexatious, and have therefore hidden it from other users."
+msgstr ""
+
msgid "We do not have a working request email address for this authority."
msgstr "Kami tidak memiliki alamat email permintaan yang bekerja untuk otoritas ini."
@@ -3137,6 +3140,9 @@ msgstr ""
"Anda hanya akan menerima jawaban atas permintaan Anda jika Anda menindaklanjuti\n"
"dengan klarifikasi."
+msgid "You will still be able to view it while logged in to the site. Please reply to this email if you would like to discuss this decision further."
+msgstr ""
+
msgid "You're in. <a href=\"#\" id=\"send-request\">Continue sending your request</a>"
msgstr "Anda telah masuk. <a href=\"#\" id=\"send-request\">Lanjut mengirim permintaan Anda</a>"
@@ -3210,6 +3216,12 @@ msgstr "kode sandi aAnda:"
msgid "Your photo will be shown in public <strong>on the Internet</strong>,\\n wherever you do something on {{site_name}}."
msgstr "Foto Anda akan ditampilkan secara terbuka <strong>di Internet</strong>,\\n di mana pun Anda melakukan sesuatu pada {{site_name}}."
+msgid "Your request '{{request}}' at {{url}} has been reviewed by moderators."
+msgstr ""
+
+msgid "Your request on {{site_name}} hidden"
+msgstr ""
+
msgid "Your request was called {{info_request}}. Letting everyone know whether you got the information will help us keep tabs on"
msgstr "Permintaan Anda disebut {{info_request}}. Memberitahukan semua orang apakah Anda memperoleh informasi tersebut akan membantu kami mengawasi"
@@ -3242,6 +3254,9 @@ msgstr "Hormat saya,"
msgid "Yours sincerely,"
msgstr "Hormat saya,"
+msgid "Yours,"
+msgstr ""
+
msgid "[FOI #{{request}} email]"
msgstr "[FOI #{{request}} email]"
diff --git a/locale/it/app.po b/locale/it/app.po
index ac99b8533..302f1c6d9 100644
--- a/locale/it/app.po
+++ b/locale/it/app.po
@@ -9,10 +9,10 @@ msgid ""
msgstr ""
"Project-Id-Version: alaveteli\n"
"Report-Msgid-Bugs-To: http://github.com/sebbacon/alaveteli/issues\n"
-"POT-Creation-Date: 2013-04-23 16:34+0100\n"
-"PO-Revision-Date: 2013-04-23 15:40+0000\n"
+"POT-Creation-Date: 2013-05-30 09:46+0100\n"
+"PO-Revision-Date: 2013-05-30 08:54+0000\n"
"Last-Translator: louisecrow <louise@mysociety.org>\n"
-"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language-Team: Italian (http://www.transifex.com/projects/p/alaveteli/language/it/)\n"
"Language: it\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -292,6 +292,15 @@ msgstr ""
msgid "Act on what you've learnt"
msgstr ""
+msgid "Acts as xapian/acts as xapian job"
+msgstr ""
+
+msgid "ActsAsXapian::ActsAsXapianJob|Action"
+msgstr ""
+
+msgid "ActsAsXapian::ActsAsXapianJob|Model"
+msgstr ""
+
msgid "Add an annotation"
msgstr ""
@@ -589,6 +598,9 @@ msgstr ""
msgid "Date:"
msgstr ""
+msgid "Dear {{name}},"
+msgstr ""
+
msgid "Dear {{public_body_name}},"
msgstr ""
@@ -855,6 +867,18 @@ msgstr ""
msgid "Handled by post."
msgstr ""
+msgid "Has tag string/has tag string tag"
+msgstr ""
+
+msgid "HasTagString::HasTagStringTag|Model"
+msgstr ""
+
+msgid "HasTagString::HasTagStringTag|Name"
+msgstr ""
+
+msgid "HasTagString::HasTagStringTag|Value"
+msgstr ""
+
msgid "Hello! You can make Freedom of Information requests within {{country_name}} at {{link_to_website}}"
msgstr ""
@@ -1665,9 +1689,6 @@ msgstr ""
msgid "Public body"
msgstr ""
-msgid "Public body/translation"
-msgstr ""
-
msgid "Public notes"
msgstr ""
@@ -1677,33 +1698,6 @@ msgstr ""
msgid "Public page not available"
msgstr ""
-msgid "PublicBody::Translation|Disclosure log"
-msgstr ""
-
-msgid "PublicBody::Translation|First letter"
-msgstr ""
-
-msgid "PublicBody::Translation|Locale"
-msgstr ""
-
-msgid "PublicBody::Translation|Name"
-msgstr ""
-
-msgid "PublicBody::Translation|Notes"
-msgstr ""
-
-msgid "PublicBody::Translation|Publication scheme"
-msgstr ""
-
-msgid "PublicBody::Translation|Request email"
-msgstr ""
-
-msgid "PublicBody::Translation|Short name"
-msgstr ""
-
-msgid "PublicBody::Translation|Url name"
-msgstr ""
-
msgid "PublicBody|Api key"
msgstr ""
@@ -2186,6 +2180,9 @@ msgstr ""
msgid "The search index is currently offline, so we can't show the Freedom of Information requests this person has made."
msgstr ""
+msgid "The {{site_name}} team."
+msgstr ""
+
msgid "Then you can cancel the alert."
msgstr ""
@@ -2696,6 +2693,12 @@ msgstr ""
msgid "Was the response you got to your FOI request any good?"
msgstr ""
+msgid "We consider it is not a valid FOI request, and have therefore hidden it from other users."
+msgstr ""
+
+msgid "We consider it to be vexatious, and have therefore hidden it from other users."
+msgstr ""
+
msgid "We do not have a working request email address for this authority."
msgstr ""
@@ -2888,6 +2891,9 @@ msgstr ""
msgid "You will only get an answer to your request if you follow up\\nwith the clarification."
msgstr ""
+msgid "You will still be able to view it while logged in to the site. Please reply to this email if you would like to discuss this decision further."
+msgstr ""
+
msgid "You're in. <a href=\"#\" id=\"send-request\">Continue sending your request</a>"
msgstr ""
@@ -2954,6 +2960,12 @@ msgstr ""
msgid "Your photo will be shown in public <strong>on the Internet</strong>,\\n wherever you do something on {{site_name}}."
msgstr ""
+msgid "Your request '{{request}}' at {{url}} has been reviewed by moderators."
+msgstr ""
+
+msgid "Your request on {{site_name}} hidden"
+msgstr ""
+
msgid "Your request was called {{info_request}}. Letting everyone know whether you got the information will help us keep tabs on"
msgstr ""
@@ -2988,6 +3000,9 @@ msgstr ""
msgid "Yours sincerely,"
msgstr ""
+msgid "Yours,"
+msgstr ""
+
msgid "[FOI #{{request}} email]"
msgstr ""
diff --git a/locale/model_attributes.rb b/locale/model_attributes.rb
index 27925cd02..ba3a60c90 100644
--- a/locale/model_attributes.rb
+++ b/locale/model_attributes.rb
@@ -1,4 +1,7 @@
#DO NOT MODIFY! AUTOMATICALLY GENERATED FILE!
+_('Acts as xapian/acts as xapian job')
+_('ActsAsXapian::ActsAsXapianJob|Action')
+_('ActsAsXapian::ActsAsXapianJob|Model')
_('Censor rule')
_('CensorRule|Last edit comment')
_('CensorRule|Last edit editor')
@@ -18,6 +21,10 @@ _('FoiAttachment|Filename')
_('FoiAttachment|Hexdigest')
_('FoiAttachment|Url part number')
_('FoiAttachment|Within rfc822 subject')
+_('Has tag string/has tag string tag')
+_('HasTagString::HasTagStringTag|Model')
+_('HasTagString::HasTagStringTag|Name')
+_('HasTagString::HasTagStringTag|Value')
_('Holiday')
_('Holiday|Day')
_('Holiday|Description')
@@ -89,16 +96,6 @@ _('PublicBody|Request email')
_('PublicBody|Short name')
_('PublicBody|Url name')
_('PublicBody|Version')
-_('Public body/translation')
-_('PublicBody::Translation|Disclosure log')
-_('PublicBody::Translation|First letter')
-_('PublicBody::Translation|Locale')
-_('PublicBody::Translation|Name')
-_('PublicBody::Translation|Notes')
-_('PublicBody::Translation|Publication scheme')
-_('PublicBody::Translation|Request email')
-_('PublicBody::Translation|Short name')
-_('PublicBody::Translation|Url name')
_('Purge request')
_('PurgeRequest|Model')
_('PurgeRequest|Url')
diff --git a/locale/nb_NO/app.po b/locale/nb_NO/app.po
index 16528a908..68d32c8c0 100644
--- a/locale/nb_NO/app.po
+++ b/locale/nb_NO/app.po
@@ -6,16 +6,16 @@
msgid ""
msgstr ""
"Project-Id-Version: alaveteli\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2013-04-23 16:34+0100\n"
-"PO-Revision-Date: 2011-03-09 17:48+0000\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: LANGUAGE <LL@li.org>\n"
+"Report-Msgid-Bugs-To: http://github.com/sebbacon/alaveteli/issues\n"
+"POT-Creation-Date: 2013-05-30 09:46+0100\n"
+"PO-Revision-Date: 2013-05-30 09:01+0000\n"
+"Last-Translator: louisecrow <louise@mysociety.org>\n"
+"Language-Team: Norwegian Bokmål (Norway) (http://www.transifex.com/projects/p/alaveteli/language/nb_NO/)\n"
"Language: nb_NO\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: nplurals=2; plural=(n != 1)\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
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 ""
@@ -290,6 +290,15 @@ msgstr ""
msgid "Act on what you've learnt"
msgstr ""
+msgid "Acts as xapian/acts as xapian job"
+msgstr ""
+
+msgid "ActsAsXapian::ActsAsXapianJob|Action"
+msgstr ""
+
+msgid "ActsAsXapian::ActsAsXapianJob|Model"
+msgstr ""
+
msgid "Add an annotation"
msgstr ""
@@ -587,6 +596,9 @@ msgstr ""
msgid "Date:"
msgstr ""
+msgid "Dear {{name}},"
+msgstr ""
+
msgid "Dear {{public_body_name}},"
msgstr ""
@@ -853,6 +865,18 @@ msgstr ""
msgid "Handled by post."
msgstr ""
+msgid "Has tag string/has tag string tag"
+msgstr ""
+
+msgid "HasTagString::HasTagStringTag|Model"
+msgstr ""
+
+msgid "HasTagString::HasTagStringTag|Name"
+msgstr ""
+
+msgid "HasTagString::HasTagStringTag|Value"
+msgstr ""
+
msgid "Hello! You can make Freedom of Information requests within {{country_name}} at {{link_to_website}}"
msgstr ""
@@ -1663,9 +1687,6 @@ msgstr ""
msgid "Public body"
msgstr ""
-msgid "Public body/translation"
-msgstr ""
-
msgid "Public notes"
msgstr ""
@@ -1675,33 +1696,6 @@ msgstr ""
msgid "Public page not available"
msgstr ""
-msgid "PublicBody::Translation|Disclosure log"
-msgstr ""
-
-msgid "PublicBody::Translation|First letter"
-msgstr ""
-
-msgid "PublicBody::Translation|Locale"
-msgstr ""
-
-msgid "PublicBody::Translation|Name"
-msgstr ""
-
-msgid "PublicBody::Translation|Notes"
-msgstr ""
-
-msgid "PublicBody::Translation|Publication scheme"
-msgstr ""
-
-msgid "PublicBody::Translation|Request email"
-msgstr ""
-
-msgid "PublicBody::Translation|Short name"
-msgstr ""
-
-msgid "PublicBody::Translation|Url name"
-msgstr ""
-
msgid "PublicBody|Api key"
msgstr ""
@@ -2184,6 +2178,9 @@ msgstr ""
msgid "The search index is currently offline, so we can't show the Freedom of Information requests this person has made."
msgstr ""
+msgid "The {{site_name}} team."
+msgstr ""
+
msgid "Then you can cancel the alert."
msgstr ""
@@ -2694,6 +2691,12 @@ msgstr ""
msgid "Was the response you got to your FOI request any good?"
msgstr ""
+msgid "We consider it is not a valid FOI request, and have therefore hidden it from other users."
+msgstr ""
+
+msgid "We consider it to be vexatious, and have therefore hidden it from other users."
+msgstr ""
+
msgid "We do not have a working request email address for this authority."
msgstr ""
@@ -2886,6 +2889,9 @@ msgstr ""
msgid "You will only get an answer to your request if you follow up\\nwith the clarification."
msgstr ""
+msgid "You will still be able to view it while logged in to the site. Please reply to this email if you would like to discuss this decision further."
+msgstr ""
+
msgid "You're in. <a href=\"#\" id=\"send-request\">Continue sending your request</a>"
msgstr ""
@@ -2952,6 +2958,12 @@ msgstr ""
msgid "Your photo will be shown in public <strong>on the Internet</strong>,\\n wherever you do something on {{site_name}}."
msgstr ""
+msgid "Your request '{{request}}' at {{url}} has been reviewed by moderators."
+msgstr ""
+
+msgid "Your request on {{site_name}} hidden"
+msgstr ""
+
msgid "Your request was called {{info_request}}. Letting everyone know whether you got the information will help us keep tabs on"
msgstr ""
@@ -2986,6 +2998,9 @@ msgstr ""
msgid "Yours sincerely,"
msgstr ""
+msgid "Yours,"
+msgstr ""
+
msgid "[FOI #{{request}} email]"
msgstr ""
diff --git a/locale/pt_BR/app.po b/locale/pt_BR/app.po
index 56537a970..44bba74f4 100644
--- a/locale/pt_BR/app.po
+++ b/locale/pt_BR/app.po
@@ -27,10 +27,10 @@ msgid ""
msgstr ""
"Project-Id-Version: alaveteli\n"
"Report-Msgid-Bugs-To: http://github.com/sebbacon/alaveteli/issues\n"
-"POT-Creation-Date: 2013-04-23 16:34+0100\n"
-"PO-Revision-Date: 2013-04-23 15:40+0000\n"
+"POT-Creation-Date: 2013-05-30 09:46+0100\n"
+"PO-Revision-Date: 2013-05-30 08:54+0000\n"
"Last-Translator: louisecrow <louise@mysociety.org>\n"
-"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language-Team: Portuguese (Brazil) (http://www.transifex.com/projects/p/alaveteli/language/pt_BR/)\n"
"Language: pt_BR\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -328,6 +328,15 @@ msgstr "Sobre você:"
msgid "Act on what you've learnt"
msgstr "Faça algo com o que você aprendeu"
+msgid "Acts as xapian/acts as xapian job"
+msgstr ""
+
+msgid "ActsAsXapian::ActsAsXapianJob|Action"
+msgstr ""
+
+msgid "ActsAsXapian::ActsAsXapianJob|Model"
+msgstr ""
+
msgid "Add an annotation"
msgstr "Adicionar um comentário"
@@ -625,6 +634,9 @@ msgstr "Atualmente <strong>aguardando uma resposta</strong> de {{public_body_lin
msgid "Date:"
msgstr "Data:"
+msgid "Dear {{name}},"
+msgstr ""
+
msgid "Dear {{public_body_name}},"
msgstr "Prezado(a) {{public_body_name}},"
@@ -650,7 +662,7 @@ msgid "Did you mean: {{correction}}"
msgstr "Você quis dizer: {{correction}}"
msgid "Disclaimer: This message and any reply that you make will be published on the internet. Our privacy and copyright policies:"
-msgstr "Aviso: Esta mensagem e todas as respostas enviadas serão publicadas na Internet, por meio da plataforma Queremos Saber <http://queremossaber.org.br/>. Leia algumas questões sobre acesso a informação para agentes públicos <http://queremossaber.org.br/help/officers/>."
+msgstr "Aviso: Esta mensagem e todas as respostas enviadas serão publicadas na Internet, por meio da plataforma Queremos Saber http://queremossaber.org.br/. Leia algumas questões sobre acesso a informação para agentes públicos http://queremossaber.org.br/help/officers/."
msgid "Disclosure log"
msgstr ""
@@ -893,6 +905,18 @@ msgstr "DÊ DETALHES SOBRE SUA QUEIXA AQUI"
msgid "Handled by post."
msgstr "Encaminhado por correio."
+msgid "Has tag string/has tag string tag"
+msgstr ""
+
+msgid "HasTagString::HasTagStringTag|Model"
+msgstr ""
+
+msgid "HasTagString::HasTagStringTag|Name"
+msgstr ""
+
+msgid "HasTagString::HasTagStringTag|Value"
+msgstr ""
+
msgid "Hello! You can make Freedom of Information requests within {{country_name}} at {{link_to_website}}"
msgstr "Olá! Você pode fazer pedidos de informação no {{country_name}} em {{link_to_website}}"
@@ -1712,9 +1736,6 @@ msgstr ""
msgid "Public body"
msgstr "Órgão público"
-msgid "Public body/translation"
-msgstr "Public body/translation"
-
msgid "Public notes"
msgstr ""
@@ -1724,33 +1745,6 @@ msgstr ""
msgid "Public page not available"
msgstr ""
-msgid "PublicBody::Translation|Disclosure log"
-msgstr ""
-
-msgid "PublicBody::Translation|First letter"
-msgstr ""
-
-msgid "PublicBody::Translation|Locale"
-msgstr ""
-
-msgid "PublicBody::Translation|Name"
-msgstr ""
-
-msgid "PublicBody::Translation|Notes"
-msgstr ""
-
-msgid "PublicBody::Translation|Publication scheme"
-msgstr ""
-
-msgid "PublicBody::Translation|Request email"
-msgstr "PublicBody::Translation|Solicitar email"
-
-msgid "PublicBody::Translation|Short name"
-msgstr ""
-
-msgid "PublicBody::Translation|Url name"
-msgstr ""
-
msgid "PublicBody|Api key"
msgstr ""
@@ -2237,6 +2231,9 @@ msgstr "O index de busca está temporariamente offline, então não podemos exib
msgid "The search index is currently offline, so we can't show the Freedom of Information requests this person has made."
msgstr "A busca não esta funcionando, então nós não podemos mostrar os pedidos de acesso a informação que essa pessoa fez."
+msgid "The {{site_name}} team."
+msgstr ""
+
msgid "Then you can cancel the alert."
msgstr "Então você pode cancelar o alerta."
@@ -2755,6 +2752,12 @@ msgstr "Aguardando resposta do órgão público"
msgid "Was the response you got to your FOI request any good?"
msgstr "A resposta ao seu pedido de acesso à informação foi satisfatória?"
+msgid "We consider it is not a valid FOI request, and have therefore hidden it from other users."
+msgstr ""
+
+msgid "We consider it to be vexatious, and have therefore hidden it from other users."
+msgstr ""
+
msgid "We do not have a working request email address for this authority."
msgstr "Nós não temos um email válido desse orgão."
@@ -2950,6 +2953,9 @@ msgstr "Você irá receber atualizações por email sobre {{track_description}}.
msgid "You will only get an answer to your request if you follow up\\nwith the clarification."
msgstr "Você só vai receber uma resposta para o seu pedido se enviar uma mensagem com as explicações adicionais."
+msgid "You will still be able to view it while logged in to the site. Please reply to this email if you would like to discuss this decision further."
+msgstr ""
+
msgid "You're in. <a href=\"#\" id=\"send-request\">Continue sending your request</a>"
msgstr "Você está dentro. <a href=\"#\" id=\"send-request\">Continue enviando seu pedido</a>"
@@ -3023,6 +3029,12 @@ msgstr ""
"Sua foto será exibida em público <strong>na internet</strong>,\\n \n"
"em qualquer ação que fizer no {{site_name}}."
+msgid "Your request '{{request}}' at {{url}} has been reviewed by moderators."
+msgstr ""
+
+msgid "Your request on {{site_name}} hidden"
+msgstr ""
+
msgid "Your request was called {{info_request}}. Letting everyone know whether you got the information will help us keep tabs on"
msgstr "Sua requisição foi nomeada {{info_request}}. Permitir que todos saibam onde você obteve a informação irá nos ajudar a manter as abas"
@@ -3057,6 +3069,9 @@ msgstr "Atenciosamente,"
msgid "Yours sincerely,"
msgstr "Grato(a),"
+msgid "Yours,"
+msgstr ""
+
msgid "[FOI #{{request}} email]"
msgstr ""
diff --git a/locale/ro_RO/app.po b/locale/ro_RO/app.po
index 889dd7684..e5c45e3d3 100644
--- a/locale/ro_RO/app.po
+++ b/locale/ro_RO/app.po
@@ -21,10 +21,10 @@ msgid ""
msgstr ""
"Project-Id-Version: alaveteli\n"
"Report-Msgid-Bugs-To: http://github.com/sebbacon/alaveteli/issues\n"
-"POT-Creation-Date: 2013-04-23 16:34+0100\n"
-"PO-Revision-Date: 2013-04-23 16:07+0000\n"
+"POT-Creation-Date: 2013-05-30 09:46+0100\n"
+"PO-Revision-Date: 2013-05-30 08:54+0000\n"
"Last-Translator: louisecrow <louise@mysociety.org>\n"
-"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language-Team: Romanian (Romania) (http://www.transifex.com/projects/p/alaveteli/language/ro_RO/)\n"
"Language: ro_RO\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -304,6 +304,15 @@ msgstr "Despre dvs:"
msgid "Act on what you've learnt"
msgstr "Actţonează conform a ceea ce ai învăţat."
+msgid "Acts as xapian/acts as xapian job"
+msgstr ""
+
+msgid "ActsAsXapian::ActsAsXapianJob|Action"
+msgstr ""
+
+msgid "ActsAsXapian::ActsAsXapianJob|Model"
+msgstr ""
+
msgid "Add an annotation"
msgstr "Adaugă o adnotare."
@@ -601,6 +610,9 @@ msgstr "În acest moment <strong>asteptăm un răspuns</strong> de la {{public_b
msgid "Date:"
msgstr "Data:"
+msgid "Dear {{name}},"
+msgstr ""
+
msgid "Dear {{public_body_name}},"
msgstr "Stimate {{public_body_name}},"
@@ -868,6 +880,18 @@ msgstr "DAŢI DETALII DESPRE PLÂNGEREA DVS. AICI"
msgid "Handled by post."
msgstr "Înmânat prin poştă"
+msgid "Has tag string/has tag string tag"
+msgstr ""
+
+msgid "HasTagString::HasTagStringTag|Model"
+msgstr ""
+
+msgid "HasTagString::HasTagStringTag|Name"
+msgstr ""
+
+msgid "HasTagString::HasTagStringTag|Value"
+msgstr ""
+
msgid "Hello! You can make Freedom of Information requests within {{country_name}} at {{link_to_website}}"
msgstr "Hello! Puteţi face cereri \"Libertatea de informare\" în {{country_name}} la {{link_to_website}}"
@@ -1680,9 +1704,6 @@ msgstr "Autoritatea publică – {{name}}"
msgid "Public body"
msgstr "Autoritate publică"
-msgid "Public body/translation"
-msgstr "Autoritate publică/traducere"
-
msgid "Public notes"
msgstr "Note publice"
@@ -1692,33 +1713,6 @@ msgstr "Pagina publică"
msgid "Public page not available"
msgstr "Pagină publica indisponibilă"
-msgid "PublicBody::Translation|Disclosure log"
-msgstr "PublicBody::Translation|Disclosure log"
-
-msgid "PublicBody::Translation|First letter"
-msgstr "AutoritatePublică::Traducere|Prima literă"
-
-msgid "PublicBody::Translation|Locale"
-msgstr "AutoritatePublică::Traducere|Local"
-
-msgid "PublicBody::Translation|Name"
-msgstr "AutoritatePublică::Traducere|Nume"
-
-msgid "PublicBody::Translation|Notes"
-msgstr "AutoritatePublică::Traducere|Note"
-
-msgid "PublicBody::Translation|Publication scheme"
-msgstr "AutoritatePublică::Traducere|Schema publicaţiei"
-
-msgid "PublicBody::Translation|Request email"
-msgstr "AutoritatePublică::Traducere|Cerere email"
-
-msgid "PublicBody::Translation|Short name"
-msgstr "AutoritatePublică::Traducere|Nume scurt"
-
-msgid "PublicBody::Translation|Url name"
-msgstr "AutoritatePublică::Traducere| Nume URL"
-
msgid "PublicBody|Api key"
msgstr "InstituţiePublică|Api key"
@@ -2202,6 +2196,9 @@ msgstr "Acest index de căutare este în acest moment off-line, aşa ca nu putem
msgid "The search index is currently offline, so we can't show the Freedom of Information requests this person has made."
msgstr "Acest index de căutare este în acest moment off-line, aşa ca nu putem afişa cererile FOI pe care această persoană le-a făcut."
+msgid "The {{site_name}} team."
+msgstr ""
+
msgid "Then you can cancel the alert."
msgstr "Apoi puteţi anula alerta."
@@ -2715,6 +2712,12 @@ msgstr "Aşteaptă răspunsul autorităţii publice"
msgid "Was the response you got to your FOI request any good?"
msgstr "Răspunsul pe care l-aţi primit la cererea dvs. FOI vi-a fost de folos?"
+msgid "We consider it is not a valid FOI request, and have therefore hidden it from other users."
+msgstr ""
+
+msgid "We consider it to be vexatious, and have therefore hidden it from other users."
+msgstr ""
+
msgid "We do not have a working request email address for this authority."
msgstr "Nu avem o adresă de email valabilă pentru cererile adresate acestei autoritate."
@@ -2907,6 +2910,9 @@ msgstr "Acum veţi fi primi prin email actualizări referitoare la {{track_descr
msgid "You will only get an answer to your request if you follow up\\nwith the clarification."
msgstr "Vei primi un răspuns la solicitarea ta numai dacă revii\\ncu clarificări."
+msgid "You will still be able to view it while logged in to the site. Please reply to this email if you would like to discuss this decision further."
+msgstr ""
+
msgid "You're in. <a href=\"#\" id=\"send-request\">Continue sending your request</a>"
msgstr "Ești autentificat.<a href=\"#\" id=\"send-request\">Continuă pentru transmiterea solicitării tale</a>"
@@ -2973,6 +2979,12 @@ msgstr "Parola dvs.:"
msgid "Your photo will be shown in public <strong>on the Internet</strong>,\\n wherever you do something on {{site_name}}."
msgstr "Fotografia ta va fi făcută publică <strong>pe Internet</strong>,\\n oriunde faci ceva pe {{site_name}}."
+msgid "Your request '{{request}}' at {{url}} has been reviewed by moderators."
+msgstr ""
+
+msgid "Your request on {{site_name}} hidden"
+msgstr ""
+
msgid "Your request was called {{info_request}}. Letting everyone know whether you got the information will help us keep tabs on"
msgstr "Cererea dvs. a fost numită {{info_request}}. Permiţând tuturor să afle dacă aţi obţinut informaţiile, ne ajutaţi să menţinem o evidenţă"
@@ -3009,6 +3021,9 @@ msgstr "Cu respect,"
msgid "Yours sincerely,"
msgstr "Cu stimă,"
+msgid "Yours,"
+msgstr ""
+
msgid "[FOI #{{request}} email]"
msgstr "[FOI #{{request}} email]"
diff --git a/locale/sl/app.po b/locale/sl/app.po
index 51f5d9f87..8a49de3f4 100644
--- a/locale/sl/app.po
+++ b/locale/sl/app.po
@@ -6,11 +6,11 @@
msgid ""
msgstr ""
"Project-Id-Version: alaveteli\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2013-04-23 16:34+0100\n"
+"Report-Msgid-Bugs-To: http://github.com/sebbacon/alaveteli/issues\n"
+"POT-Creation-Date: 2013-05-30 09:46+0100\n"
"PO-Revision-Date: 2011-03-09 17:48+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language-Team: Slovenian (http://www.transifex.com/projects/p/alaveteli/language/sl/)\n"
"Language: sl\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -290,6 +290,15 @@ msgstr ""
msgid "Act on what you've learnt"
msgstr ""
+msgid "Acts as xapian/acts as xapian job"
+msgstr ""
+
+msgid "ActsAsXapian::ActsAsXapianJob|Action"
+msgstr ""
+
+msgid "ActsAsXapian::ActsAsXapianJob|Model"
+msgstr ""
+
msgid "Add an annotation"
msgstr ""
@@ -587,6 +596,9 @@ msgstr ""
msgid "Date:"
msgstr ""
+msgid "Dear {{name}},"
+msgstr ""
+
msgid "Dear {{public_body_name}},"
msgstr ""
@@ -855,6 +867,18 @@ msgstr ""
msgid "Handled by post."
msgstr ""
+msgid "Has tag string/has tag string tag"
+msgstr ""
+
+msgid "HasTagString::HasTagStringTag|Model"
+msgstr ""
+
+msgid "HasTagString::HasTagStringTag|Name"
+msgstr ""
+
+msgid "HasTagString::HasTagStringTag|Value"
+msgstr ""
+
msgid "Hello! You can make Freedom of Information requests within {{country_name}} at {{link_to_website}}"
msgstr ""
@@ -1665,9 +1689,6 @@ msgstr ""
msgid "Public body"
msgstr ""
-msgid "Public body/translation"
-msgstr ""
-
msgid "Public notes"
msgstr ""
@@ -1677,33 +1698,6 @@ msgstr ""
msgid "Public page not available"
msgstr ""
-msgid "PublicBody::Translation|Disclosure log"
-msgstr ""
-
-msgid "PublicBody::Translation|First letter"
-msgstr ""
-
-msgid "PublicBody::Translation|Locale"
-msgstr ""
-
-msgid "PublicBody::Translation|Name"
-msgstr ""
-
-msgid "PublicBody::Translation|Notes"
-msgstr ""
-
-msgid "PublicBody::Translation|Publication scheme"
-msgstr ""
-
-msgid "PublicBody::Translation|Request email"
-msgstr ""
-
-msgid "PublicBody::Translation|Short name"
-msgstr ""
-
-msgid "PublicBody::Translation|Url name"
-msgstr ""
-
msgid "PublicBody|Api key"
msgstr ""
@@ -2188,6 +2182,9 @@ msgstr ""
msgid "The search index is currently offline, so we can't show the Freedom of Information requests this person has made."
msgstr ""
+msgid "The {{site_name}} team."
+msgstr ""
+
msgid "Then you can cancel the alert."
msgstr ""
@@ -2704,6 +2701,12 @@ msgstr ""
msgid "Was the response you got to your FOI request any good?"
msgstr ""
+msgid "We consider it is not a valid FOI request, and have therefore hidden it from other users."
+msgstr ""
+
+msgid "We consider it to be vexatious, and have therefore hidden it from other users."
+msgstr ""
+
msgid "We do not have a working request email address for this authority."
msgstr ""
@@ -2896,6 +2899,9 @@ msgstr ""
msgid "You will only get an answer to your request if you follow up\\nwith the clarification."
msgstr ""
+msgid "You will still be able to view it while logged in to the site. Please reply to this email if you would like to discuss this decision further."
+msgstr ""
+
msgid "You're in. <a href=\"#\" id=\"send-request\">Continue sending your request</a>"
msgstr ""
@@ -2962,6 +2968,12 @@ msgstr ""
msgid "Your photo will be shown in public <strong>on the Internet</strong>,\\n wherever you do something on {{site_name}}."
msgstr ""
+msgid "Your request '{{request}}' at {{url}} has been reviewed by moderators."
+msgstr ""
+
+msgid "Your request on {{site_name}} hidden"
+msgstr ""
+
msgid "Your request was called {{info_request}}. Letting everyone know whether you got the information will help us keep tabs on"
msgstr ""
@@ -3000,6 +3012,9 @@ msgstr ""
msgid "Yours sincerely,"
msgstr ""
+msgid "Yours,"
+msgstr ""
+
msgid "[FOI #{{request}} email]"
msgstr ""
diff --git a/locale/sq/app.po b/locale/sq/app.po
index adf9d3001..e2a01666d 100644
--- a/locale/sq/app.po
+++ b/locale/sq/app.po
@@ -14,10 +14,10 @@ msgid ""
msgstr ""
"Project-Id-Version: alaveteli\n"
"Report-Msgid-Bugs-To: http://github.com/sebbacon/alaveteli/issues\n"
-"POT-Creation-Date: 2013-04-23 16:34+0100\n"
-"PO-Revision-Date: 2013-04-23 16:09+0000\n"
+"POT-Creation-Date: 2013-05-30 09:46+0100\n"
+"PO-Revision-Date: 2013-05-30 08:54+0000\n"
"Last-Translator: louisecrow <louise@mysociety.org>\n"
-"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language-Team: Albanian (http://www.transifex.com/projects/p/alaveteli/language/sq/)\n"
"Language: sq\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -335,6 +335,15 @@ msgstr "Për ty:"
msgid "Act on what you've learnt"
msgstr "Vepro sipas asaj që ke marrë vesh"
+msgid "Acts as xapian/acts as xapian job"
+msgstr ""
+
+msgid "ActsAsXapian::ActsAsXapianJob|Action"
+msgstr ""
+
+msgid "ActsAsXapian::ActsAsXapianJob|Model"
+msgstr ""
+
msgid "Add an annotation"
msgstr "Shto një shënim"
@@ -640,6 +649,9 @@ msgstr "Momentalisht <strong>duke pritur përgjigje</strong> nga {{public_body_l
msgid "Date:"
msgstr "Data:"
+msgid "Dear {{name}},"
+msgstr ""
+
msgid "Dear {{public_body_name}},"
msgstr "Të nderuar {{public_body_name}},"
@@ -922,6 +934,18 @@ msgstr "JEPI DETAJET PËR ANKESËN TËNDE KËTU"
msgid "Handled by post."
msgstr "Do të trajtohet me postë."
+msgid "Has tag string/has tag string tag"
+msgstr ""
+
+msgid "HasTagString::HasTagStringTag|Model"
+msgstr ""
+
+msgid "HasTagString::HasTagStringTag|Name"
+msgstr ""
+
+msgid "HasTagString::HasTagStringTag|Value"
+msgstr ""
+
msgid "Hello! You can make Freedom of Information requests within {{country_name}} at {{link_to_website}}"
msgstr "Përshëndetje! Ti mund të bën kërkesa për informata zyrtare për autoritetet e {{country_name}} në {{link_to_website}}"
@@ -1765,9 +1789,6 @@ msgstr ""
msgid "Public body"
msgstr "Institucion publik"
-msgid "Public body/translation"
-msgstr ""
-
msgid "Public notes"
msgstr ""
@@ -1777,33 +1798,6 @@ msgstr ""
msgid "Public page not available"
msgstr ""
-msgid "PublicBody::Translation|Disclosure log"
-msgstr ""
-
-msgid "PublicBody::Translation|First letter"
-msgstr ""
-
-msgid "PublicBody::Translation|Locale"
-msgstr ""
-
-msgid "PublicBody::Translation|Name"
-msgstr ""
-
-msgid "PublicBody::Translation|Notes"
-msgstr ""
-
-msgid "PublicBody::Translation|Publication scheme"
-msgstr ""
-
-msgid "PublicBody::Translation|Request email"
-msgstr ""
-
-msgid "PublicBody::Translation|Short name"
-msgstr ""
-
-msgid "PublicBody::Translation|Url name"
-msgstr ""
-
msgid "PublicBody|Api key"
msgstr ""
@@ -2303,6 +2297,9 @@ msgstr "Indeksi i kërkimit aktualisht është i shkëputur, kështu që nuk mun
msgid "The search index is currently offline, so we can't show the Freedom of Information requests this person has made."
msgstr "Indeksi i kërkimit është jashtë funksioni, kështu që ne nuk mund t'i tregojmë kërkesat për informata zyrtare që ky person ka bërë."
+msgid "The {{site_name}} team."
+msgstr ""
+
msgid "Then you can cancel the alert."
msgstr "Pastaj ti mund të anulon njoftimin."
@@ -2825,6 +2822,12 @@ msgstr "Duke pritur që autoriteti publik të përgjigjet"
msgid "Was the response you got to your FOI request any good?"
msgstr "A ishte kërkesa e juaj për QDP e mirë?"
+msgid "We consider it is not a valid FOI request, and have therefore hidden it from other users."
+msgstr ""
+
+msgid "We consider it to be vexatious, and have therefore hidden it from other users."
+msgstr ""
+
msgid "We do not have a working request email address for this authority."
msgstr "Për fat të keq, ne nuk kemi një email adresë funksionale për këtë autoritet"
@@ -3039,6 +3042,9 @@ msgstr ""
msgid "You will only get an answer to your request if you follow up\\nwith the clarification."
msgstr "Ti do të merr përgjigje në kërkesën tënde vetëm në qoftë se e sqaroni atë."
+msgid "You will still be able to view it while logged in to the site. Please reply to this email if you would like to discuss this decision further."
+msgstr ""
+
msgid "You're in. <a href=\"#\" id=\"send-request\">Continue sending your request</a>"
msgstr ""
@@ -3112,6 +3118,12 @@ msgstr "Fjalëkalimi yt:"
msgid "Your photo will be shown in public <strong>on the Internet</strong>,\\n wherever you do something on {{site_name}}."
msgstr ""
+msgid "Your request '{{request}}' at {{url}} has been reviewed by moderators."
+msgstr ""
+
+msgid "Your request on {{site_name}} hidden"
+msgstr ""
+
msgid "Your request was called {{info_request}}. Letting everyone know whether you got the information will help us keep tabs on"
msgstr "Kërkesa yte qe emëruar {{info_request}}. Nëse i lejoni të tjerër ta dijnë a i keni marrë informatat në pergjigje, do të na mundësoni ta mbikqyrim "
@@ -3148,6 +3160,9 @@ msgstr "Me nderime,"
msgid "Yours sincerely,"
msgstr "Sinqerisht,"
+msgid "Yours,"
+msgstr ""
+
msgid "[FOI #{{request}} email]"
msgstr ""
diff --git a/locale/sr@latin/app.po b/locale/sr@latin/app.po
index 4a1891332..8b9022d83 100644
--- a/locale/sr@latin/app.po
+++ b/locale/sr@latin/app.po
@@ -10,10 +10,10 @@ msgid ""
msgstr ""
"Project-Id-Version: alaveteli\n"
"Report-Msgid-Bugs-To: http://github.com/sebbacon/alaveteli/issues\n"
-"POT-Creation-Date: 2013-04-23 16:34+0100\n"
-"PO-Revision-Date: 2013-04-23 15:41+0000\n"
+"POT-Creation-Date: 2013-05-30 09:46+0100\n"
+"PO-Revision-Date: 2013-05-30 08:54+0000\n"
"Last-Translator: louisecrow <louise@mysociety.org>\n"
-"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language-Team: Serbian (Latin) (http://www.transifex.com/projects/p/alaveteli/language/sr@latin/)\n"
"Language: sr@latin\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -323,6 +323,15 @@ msgstr "O Vama:"
msgid "Act on what you've learnt"
msgstr "Radite na osnovu onoga što ste naučili"
+msgid "Acts as xapian/acts as xapian job"
+msgstr ""
+
+msgid "ActsAsXapian::ActsAsXapianJob|Action"
+msgstr ""
+
+msgid "ActsAsXapian::ActsAsXapianJob|Model"
+msgstr ""
+
msgid "Add an annotation"
msgstr "Dodati napomenu"
@@ -632,6 +641,9 @@ msgstr "Trenutno <strong>čeka odgovor</strong> od {{public_body_link}}, moraju
msgid "Date:"
msgstr "Datum:"
+msgid "Dear {{name}},"
+msgstr ""
+
msgid "Dear {{public_body_name}},"
msgstr "Poštovani {{public_body_name}},"
@@ -907,6 +919,18 @@ msgstr "OVDE IZNESITE DETALJE VAŠE ŽALBE"
msgid "Handled by post."
msgstr ""
+msgid "Has tag string/has tag string tag"
+msgstr ""
+
+msgid "HasTagString::HasTagStringTag|Model"
+msgstr ""
+
+msgid "HasTagString::HasTagStringTag|Name"
+msgstr ""
+
+msgid "HasTagString::HasTagStringTag|Value"
+msgstr ""
+
msgid "Hello! You can make Freedom of Information requests within {{country_name}} at {{link_to_website}}"
msgstr "Dobrodošli! Možete podnositi Zahteve za slobodan pristup informacijama u {{country_name}} na ovom linku: {{link_to_website}}"
@@ -1768,9 +1792,6 @@ msgstr ""
msgid "Public body"
msgstr ""
-msgid "Public body/translation"
-msgstr ""
-
msgid "Public notes"
msgstr ""
@@ -1780,33 +1801,6 @@ msgstr ""
msgid "Public page not available"
msgstr ""
-msgid "PublicBody::Translation|Disclosure log"
-msgstr ""
-
-msgid "PublicBody::Translation|First letter"
-msgstr ""
-
-msgid "PublicBody::Translation|Locale"
-msgstr ""
-
-msgid "PublicBody::Translation|Name"
-msgstr ""
-
-msgid "PublicBody::Translation|Notes"
-msgstr ""
-
-msgid "PublicBody::Translation|Publication scheme"
-msgstr ""
-
-msgid "PublicBody::Translation|Request email"
-msgstr ""
-
-msgid "PublicBody::Translation|Short name"
-msgstr ""
-
-msgid "PublicBody::Translation|Url name"
-msgstr ""
-
msgid "PublicBody|Api key"
msgstr ""
@@ -2320,6 +2314,9 @@ msgstr "Indeks za pretragu je trenutno isključen, ne možemo prikazati Zahteve
msgid "The search index is currently offline, so we can't show the Freedom of Information requests this person has made."
msgstr "Indeks za pretragu je trenutno isključen, radi toga ne možemo prikazati Zahteve za slobodan pristup informacijama koje je ova osoba napravila."
+msgid "The {{site_name}} team."
+msgstr ""
+
msgid "Then you can cancel the alert."
msgstr "Tada možete poništiti upozorenje."
@@ -2850,6 +2847,12 @@ msgstr "Čekamo na odgovor javne ustanove"
msgid "Was the response you got to your FOI request any good?"
msgstr "Da li je odgovor koji ste dobili na Vaš Zahtev o slobodnom pristupu informacijama bio od ikakve koristi?"
+msgid "We consider it is not a valid FOI request, and have therefore hidden it from other users."
+msgstr ""
+
+msgid "We consider it to be vexatious, and have therefore hidden it from other users."
+msgstr ""
+
msgid "We do not have a working request email address for this authority."
msgstr "Ne posedujemo ispravnu e-mail adresu za zahteve ove ustanove."
@@ -3069,6 +3072,9 @@ msgstr ""
msgid "You will only get an answer to your request if you follow up\\nwith the clarification."
msgstr ""
+msgid "You will still be able to view it while logged in to the site. Please reply to this email if you would like to discuss this decision further."
+msgstr ""
+
msgid "You're in. <a href=\"#\" id=\"send-request\">Continue sending your request</a>"
msgstr ""
@@ -3137,6 +3143,12 @@ msgstr "Vaš password:"
msgid "Your photo will be shown in public <strong>on the Internet</strong>,\\n wherever you do something on {{site_name}}."
msgstr ""
+msgid "Your request '{{request}}' at {{url}} has been reviewed by moderators."
+msgstr ""
+
+msgid "Your request on {{site_name}} hidden"
+msgstr ""
+
msgid "Your request was called {{info_request}}. Letting everyone know whether you got the information will help us keep tabs on"
msgstr "Naziv Vašeg zahteva je {{info_request}}. Obavest o tome da li ste dobili odgovor će nam pomoći da bolje pratimo."
@@ -3173,6 +3185,9 @@ msgstr "S poštovanjem,"
msgid "Yours sincerely,"
msgstr "S poštovanjem,"
+msgid "Yours,"
+msgstr ""
+
msgid "[FOI #{{request}} email]"
msgstr ""
diff --git a/locale/tr/app.po b/locale/tr/app.po
index e38f290d1..83eca28b7 100644
--- a/locale/tr/app.po
+++ b/locale/tr/app.po
@@ -8,10 +8,10 @@ msgid ""
msgstr ""
"Project-Id-Version: alaveteli\n"
"Report-Msgid-Bugs-To: http://github.com/sebbacon/alaveteli/issues\n"
-"POT-Creation-Date: 2013-04-23 16:34+0100\n"
-"PO-Revision-Date: 2013-04-23 16:09+0000\n"
+"POT-Creation-Date: 2013-05-30 09:46+0100\n"
+"PO-Revision-Date: 2013-05-30 08:54+0000\n"
"Last-Translator: louisecrow <louise@mysociety.org>\n"
-"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language-Team: Turkish (http://www.transifex.com/projects/p/alaveteli/language/tr/)\n"
"Language: tr\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -291,6 +291,15 @@ msgstr ""
msgid "Act on what you've learnt"
msgstr ""
+msgid "Acts as xapian/acts as xapian job"
+msgstr ""
+
+msgid "ActsAsXapian::ActsAsXapianJob|Action"
+msgstr ""
+
+msgid "ActsAsXapian::ActsAsXapianJob|Model"
+msgstr ""
+
msgid "Add an annotation"
msgstr ""
@@ -588,6 +597,9 @@ msgstr ""
msgid "Date:"
msgstr ""
+msgid "Dear {{name}},"
+msgstr ""
+
msgid "Dear {{public_body_name}},"
msgstr ""
@@ -854,6 +866,18 @@ msgstr ""
msgid "Handled by post."
msgstr ""
+msgid "Has tag string/has tag string tag"
+msgstr ""
+
+msgid "HasTagString::HasTagStringTag|Model"
+msgstr ""
+
+msgid "HasTagString::HasTagStringTag|Name"
+msgstr ""
+
+msgid "HasTagString::HasTagStringTag|Value"
+msgstr ""
+
msgid "Hello! You can make Freedom of Information requests within {{country_name}} at {{link_to_website}}"
msgstr ""
@@ -1664,9 +1688,6 @@ msgstr ""
msgid "Public body"
msgstr ""
-msgid "Public body/translation"
-msgstr ""
-
msgid "Public notes"
msgstr ""
@@ -1676,33 +1697,6 @@ msgstr ""
msgid "Public page not available"
msgstr ""
-msgid "PublicBody::Translation|Disclosure log"
-msgstr ""
-
-msgid "PublicBody::Translation|First letter"
-msgstr ""
-
-msgid "PublicBody::Translation|Locale"
-msgstr ""
-
-msgid "PublicBody::Translation|Name"
-msgstr ""
-
-msgid "PublicBody::Translation|Notes"
-msgstr ""
-
-msgid "PublicBody::Translation|Publication scheme"
-msgstr ""
-
-msgid "PublicBody::Translation|Request email"
-msgstr ""
-
-msgid "PublicBody::Translation|Short name"
-msgstr ""
-
-msgid "PublicBody::Translation|Url name"
-msgstr ""
-
msgid "PublicBody|Api key"
msgstr ""
@@ -2185,6 +2179,9 @@ msgstr ""
msgid "The search index is currently offline, so we can't show the Freedom of Information requests this person has made."
msgstr ""
+msgid "The {{site_name}} team."
+msgstr ""
+
msgid "Then you can cancel the alert."
msgstr ""
@@ -2695,6 +2692,12 @@ msgstr ""
msgid "Was the response you got to your FOI request any good?"
msgstr ""
+msgid "We consider it is not a valid FOI request, and have therefore hidden it from other users."
+msgstr ""
+
+msgid "We consider it to be vexatious, and have therefore hidden it from other users."
+msgstr ""
+
msgid "We do not have a working request email address for this authority."
msgstr ""
@@ -2887,6 +2890,9 @@ msgstr ""
msgid "You will only get an answer to your request if you follow up\\nwith the clarification."
msgstr ""
+msgid "You will still be able to view it while logged in to the site. Please reply to this email if you would like to discuss this decision further."
+msgstr ""
+
msgid "You're in. <a href=\"#\" id=\"send-request\">Continue sending your request</a>"
msgstr ""
@@ -2953,6 +2959,12 @@ msgstr ""
msgid "Your photo will be shown in public <strong>on the Internet</strong>,\\n wherever you do something on {{site_name}}."
msgstr ""
+msgid "Your request '{{request}}' at {{url}} has been reviewed by moderators."
+msgstr ""
+
+msgid "Your request on {{site_name}} hidden"
+msgstr ""
+
msgid "Your request was called {{info_request}}. Letting everyone know whether you got the information will help us keep tabs on"
msgstr ""
@@ -2987,6 +2999,9 @@ msgstr ""
msgid "Yours sincerely,"
msgstr ""
+msgid "Yours,"
+msgstr ""
+
msgid "[FOI #{{request}} email]"
msgstr ""
diff --git a/locale/uk/app.po b/locale/uk/app.po
index 76a21a27a..50a66ce7a 100644
--- a/locale/uk/app.po
+++ b/locale/uk/app.po
@@ -4,16 +4,17 @@
#
# Translators:
# hiiri <murahoid@gmail.com>, 2012
+# louisecrow <louise@mysociety.org>, 2013
# hiiri <murahoid@gmail.com>, 2012
# hiiri <murahoid@gmail.com>, 2012
msgid ""
msgstr ""
"Project-Id-Version: alaveteli\n"
"Report-Msgid-Bugs-To: http://github.com/sebbacon/alaveteli/issues\n"
-"POT-Creation-Date: 2013-04-23 16:34+0100\n"
-"PO-Revision-Date: 2013-04-23 16:10+0000\n"
+"POT-Creation-Date: 2013-05-30 09:46+0100\n"
+"PO-Revision-Date: 2013-05-30 08:54+0000\n"
"Last-Translator: louisecrow <louise@mysociety.org>\n"
-"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language-Team: Ukrainian (http://www.transifex.com/projects/p/alaveteli/language/uk/)\n"
"Language: uk\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -205,7 +206,7 @@ msgstr "<p>Ваша адреса містить <strong>поштовий інд
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 ""
-"<p>Ваш {{law_used_full}} запит <strong>було відправлено</strong>!</p>\n"
+"<p>Ваш запит <strong>було відправлено</strong>!</p>\n"
"<p><strong>Ми повідомимо вам</strong> коли з’явиться відповідь або якщо розпорядник інформації не надасть її в межах {{late_number_of_days}} робочих днів.</p>\n"
"<p>Якщо ви збираєтесь написати про цей запит (наприклад, у форумі або в блозі), будь ласка, дайте посилання на цю сторінку та додайте коментар про це внизу.</p>"
@@ -341,6 +342,15 @@ msgstr "Про вас:"
msgid "Act on what you've learnt"
msgstr "Дійте, спираючись на отриману інформацію"
+msgid "Acts as xapian/acts as xapian job"
+msgstr ""
+
+msgid "ActsAsXapian::ActsAsXapianJob|Action"
+msgstr ""
+
+msgid "ActsAsXapian::ActsAsXapianJob|Model"
+msgstr ""
+
msgid "Add an annotation"
msgstr "Додайте коментар"
@@ -646,6 +656,9 @@ msgstr "На даний момент відповідь від {{public_body_lin
msgid "Date:"
msgstr "Дата:"
+msgid "Dear {{name}},"
+msgstr ""
+
msgid "Dear {{public_body_name}},"
msgstr "Шановний {{public_body_name}},"
@@ -928,6 +941,18 @@ msgstr "НАДАЙТЕ ДЕТАЛІ ЩОДО ВАШОЇ СКАРГИ ТУТ"
msgid "Handled by post."
msgstr "Надіслано звичайною поштою"
+msgid "Has tag string/has tag string tag"
+msgstr ""
+
+msgid "HasTagString::HasTagStringTag|Model"
+msgstr ""
+
+msgid "HasTagString::HasTagStringTag|Name"
+msgstr ""
+
+msgid "HasTagString::HasTagStringTag|Value"
+msgstr ""
+
msgid "Hello! You can make Freedom of Information requests within {{country_name}} at {{link_to_website}}"
msgstr ""
@@ -1739,7 +1764,7 @@ msgid "Preview follow up to '"
msgstr "Попередній перегляд уточнення щодо запиту '"
msgid "Preview new annotation on '{{info_request_title}}'"
-msgstr ""
+msgstr "Попередній перегляд коментаря на запит '{{info_request_title}}'"
msgid "Preview your annotation"
msgstr "Попередній перегляд коментаря"
@@ -1774,9 +1799,6 @@ msgstr "Розпорядник інформації – {{name}}"
msgid "Public body"
msgstr ""
-msgid "Public body/translation"
-msgstr ""
-
msgid "Public notes"
msgstr ""
@@ -1786,33 +1808,6 @@ msgstr ""
msgid "Public page not available"
msgstr ""
-msgid "PublicBody::Translation|Disclosure log"
-msgstr ""
-
-msgid "PublicBody::Translation|First letter"
-msgstr ""
-
-msgid "PublicBody::Translation|Locale"
-msgstr ""
-
-msgid "PublicBody::Translation|Name"
-msgstr ""
-
-msgid "PublicBody::Translation|Notes"
-msgstr ""
-
-msgid "PublicBody::Translation|Publication scheme"
-msgstr ""
-
-msgid "PublicBody::Translation|Request email"
-msgstr ""
-
-msgid "PublicBody::Translation|Short name"
-msgstr ""
-
-msgid "PublicBody::Translation|Url name"
-msgstr ""
-
msgid "PublicBody|Api key"
msgstr ""
@@ -2300,6 +2295,9 @@ msgstr ""
msgid "The search index is currently offline, so we can't show the Freedom of Information requests this person has made."
msgstr ""
+msgid "The {{site_name}} team."
+msgstr ""
+
msgid "Then you can cancel the alert."
msgstr ""
@@ -2379,7 +2377,7 @@ msgid "There is <strong>more than one person</strong> who uses this site and has
msgstr ""
msgid "There is a limit on the number of requests you can make in a day, because we don’t want public authorities to be bombarded with large numbers of inappropriate requests. If you feel you have a good reason to ask for the limit to be lifted in your case, please <a href='{{help_contact_path}}'>get in touch</a>."
-msgstr "Ми встановили обмеження на кількість запитів, які можна відправитипротягом одного дня. Ви можете попросити про зняття цього обмеження, <a href='{{help_contact_path}}'>написавши нам</a>. Ваше прохання має бутиобґрунтованим"
+msgstr "Ми встановили обмеження на кількість запитів, які можна відправитипротягом одного дня. Ви можете попросити про зняття цього обмеження, <a href='{{help_contact_path}}'>написавши нам</a>. Ваше прохання має бути обґрунтованим"
msgid "There is {{count}} person following this request"
msgid_plural "There are {{count}} people following this request"
@@ -2821,6 +2819,12 @@ msgstr "В очікуванні відповіді від розпорядник
msgid "Was the response you got to your FOI request any good?"
msgstr "Чи була відповідь на ваш запит корисною для вас?"
+msgid "We consider it is not a valid FOI request, and have therefore hidden it from other users."
+msgstr ""
+
+msgid "We consider it to be vexatious, and have therefore hidden it from other users."
+msgstr ""
+
msgid "We do not have a working request email address for this authority."
msgstr "У нас нема електронної адреси цього органу."
@@ -2962,7 +2966,7 @@ msgid "You have found a bug. Please <a href=\"{{contact_url}}\">contact us</a>
msgstr "Ви натрапили на баг. Будь ласка, <a href=\"{{contact_url}}\">напишіть нам</a> про цю проблему"
msgid "You have hit the rate limit on new requests. Users are ordinarily limited to {{max_requests_per_user_per_day}} requests in any rolling 24-hour period. You will be able to make another request in {{can_make_another_request}}."
-msgstr ""
+msgstr "Ви перевищили кількість дозволених запитів. Користувачі не можуть надсилати більш ніж{{max_requests_per_user_per_day}} запитів протягом 24 годин."
msgid "You have made no Freedom of Information requests using this site."
msgstr "Ви не зробили жодного запиту через цей сайт."
@@ -2993,7 +2997,7 @@ msgid "You may be able to find\\n one on their website, or by phoning them up
msgstr "Якщо вона вам відома, <a href=\"{{url}}\">повідомте її нам</a>, будь ласка."
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>."
-msgstr ""
+msgstr "Якщо вона вам відома, <a href=\"%s\">повідомте її нам</a>, будь ласка."
msgid "You need to be logged in to change the text about you on your profile."
msgstr "Ви маєте увійти в систему, щоб мати можливість змінити інформацію про себе в профілі."
@@ -3036,6 +3040,9 @@ msgstr ""
"Ви отримаєте відповідь на свій запит, тільки якщо надішлете\n"
"уточнення щодо нього."
+msgid "You will still be able to view it while logged in to the site. Please reply to this email if you would like to discuss this decision further."
+msgstr ""
+
msgid "You're in. <a href=\"#\" id=\"send-request\">Continue sending your request</a>"
msgstr ""
@@ -3109,6 +3116,12 @@ msgstr "Ваш пароль:"
msgid "Your photo will be shown in public <strong>on the Internet</strong>,\\n wherever you do something on {{site_name}}."
msgstr "Ваше фото з’явиться в загальному доступі в інтернеті."
+msgid "Your request '{{request}}' at {{url}} has been reviewed by moderators."
+msgstr ""
+
+msgid "Your request on {{site_name}} hidden"
+msgstr ""
+
msgid "Your request was called {{info_request}}. Letting everyone know whether you got the information will help us keep tabs on"
msgstr ""
@@ -3145,6 +3158,9 @@ msgstr "З повагою,"
msgid "Yours sincerely,"
msgstr "З повагою,"
+msgid "Yours,"
+msgstr ""
+
msgid "[FOI #{{request}} email]"
msgstr ""
@@ -3444,7 +3460,7 @@ msgstr[1] "{{count}} запити зроблено"
msgstr[2] "{{count}} запитів зроблено"
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 ""
+msgstr "Точно такий самий запит вже створено ({{date}}). Ви можете <a href=\"{{existing_request}}\">переглянути його</a> або створити подібний."
msgid "{{info_request_user_name}} only:"
msgstr "Тільки {{info_request_user_name}}:"
diff --git a/public/404.html b/public/404.html
index eff660b90..9a48320a5 100644
--- a/public/404.html
+++ b/public/404.html
@@ -1,23 +1,19 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-
+<!DOCTYPE html>
+<html>
<head>
- <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
<title>The page you were looking for doesn't exist (404)</title>
- <style type="text/css">
- body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
- div.dialog {
- width: 25em;
- padding: 0 4em;
- margin: 4em auto 0 auto;
- border: 1px solid #ccc;
- border-right-color: #999;
- border-bottom-color: #999;
- }
- h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
- </style>
+ <style type="text/css">
+ body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
+ div.dialog {
+ width: 25em;
+ padding: 0 4em;
+ margin: 4em auto 0 auto;
+ border: 1px solid #ccc;
+ border-right-color: #999;
+ border-bottom-color: #999;
+ }
+ h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
+ </style>
</head>
<body>
@@ -27,4 +23,4 @@
<p>You may have mistyped the address or the page may have moved.</p>
</div>
</body>
-</html> \ No newline at end of file
+</html>
diff --git a/public/422.html b/public/422.html
new file mode 100644
index 000000000..83660ab18
--- /dev/null
+++ b/public/422.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>The change you wanted was rejected (422)</title>
+ <style type="text/css">
+ body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
+ div.dialog {
+ width: 25em;
+ padding: 0 4em;
+ margin: 4em auto 0 auto;
+ border: 1px solid #ccc;
+ border-right-color: #999;
+ border-bottom-color: #999;
+ }
+ h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
+ </style>
+</head>
+
+<body>
+ <!-- This file lives in public/422.html -->
+ <div class="dialog">
+ <h1>The change you wanted was rejected.</h1>
+ <p>Maybe you tried to change something you didn't have access to.</p>
+ </div>
+</body>
+</html>
diff --git a/public/500.html b/public/500.html
index f0aee0e9f..b80307fc1 100644
--- a/public/500.html
+++ b/public/500.html
@@ -1,23 +1,19 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-
+<!DOCTYPE html>
+<html>
<head>
- <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
- <title>We're sorry, but something went wrong</title>
- <style type="text/css">
- body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
- div.dialog {
- width: 25em;
- padding: 0 4em;
- margin: 4em auto 0 auto;
- border: 1px solid #ccc;
- border-right-color: #999;
- border-bottom-color: #999;
- }
- h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
- </style>
+ <title>We're sorry, but something went wrong (500)</title>
+ <style type="text/css">
+ body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
+ div.dialog {
+ width: 25em;
+ padding: 0 4em;
+ margin: 4em auto 0 auto;
+ border: 1px solid #ccc;
+ border-right-color: #999;
+ border-bottom-color: #999;
+ }
+ h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
+ </style>
</head>
<body>
@@ -27,4 +23,4 @@
<p>We've been notified about this issue and we'll take a look at it shortly.</p>
</div>
</body>
-</html> \ No newline at end of file
+</html>
diff --git a/public/dispatch.cgi b/public/dispatch.cgi
deleted file mode 100755
index 3848806db..000000000
--- a/public/dispatch.cgi
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/usr/bin/ruby1.8
-
-require File.dirname(__FILE__) + "/../config/environment" unless defined?(RAILS_ROOT)
-
-# If you're using RubyGems and mod_ruby, this require should be changed to an absolute path one, like:
-# "/usr/local/lib/ruby/gems/1.8/gems/rails-0.8.0/lib/dispatcher" -- otherwise performance is severely impaired
-require "dispatcher"
-
-ADDITIONAL_LOAD_PATHS.reverse.each { |dir| $:.unshift(dir) if File.directory?(dir) } if defined?(Apache::RubyRun)
-Dispatcher.dispatch \ No newline at end of file
diff --git a/public/dispatch.fcgi b/public/dispatch.fcgi
deleted file mode 100755
index ad34d90e4..000000000
--- a/public/dispatch.fcgi
+++ /dev/null
@@ -1,24 +0,0 @@
-#!/usr/bin/ruby1.8
-#
-# You may specify the path to the FastCGI crash log (a log of unhandled
-# exceptions which forced the FastCGI instance to exit, great for debugging)
-# and the number of requests to process before running garbage collection.
-#
-# By default, the FastCGI crash log is Rails.root/log/fastcgi.crash.log
-# and the GC period is nil (turned off). A reasonable number of requests
-# could range from 10-100 depending on the memory footprint of your app.
-#
-# Example:
-# # Default log path, normal GC behavior.
-# RailsFCGIHandler.process!
-#
-# # Default log path, 50 requests between GC.
-# RailsFCGIHandler.process! nil, 50
-#
-# # Custom log path, normal GC behavior.
-# RailsFCGIHandler.process! '/var/log/myapp_fcgi_crash.log'
-#
-require File.dirname(__FILE__) + "/../config/environment"
-require 'fcgi_handler'
-
-RailsFCGIHandler.process!
diff --git a/public/dispatch.rb b/public/dispatch.rb
deleted file mode 100755
index 3848806db..000000000
--- a/public/dispatch.rb
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/usr/bin/ruby1.8
-
-require File.dirname(__FILE__) + "/../config/environment" unless defined?(RAILS_ROOT)
-
-# If you're using RubyGems and mod_ruby, this require should be changed to an absolute path one, like:
-# "/usr/local/lib/ruby/gems/1.8/gems/rails-0.8.0/lib/dispatcher" -- otherwise performance is severely impaired
-require "dispatcher"
-
-ADDITIONAL_LOAD_PATHS.reverse.each { |dir| $:.unshift(dir) if File.directory?(dir) } if defined?(Apache::RubyRun)
-Dispatcher.dispatch \ No newline at end of file
diff --git a/public/javascripts/controls.js b/public/javascripts/controls.js
index 5aaf0bb2b..7392fb664 100644
--- a/public/javascripts/controls.js
+++ b/public/javascripts/controls.js
@@ -1,22 +1,24 @@
-// Copyright (c) 2005-2008 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
-// (c) 2005-2007 Ivan Krstic (http://blogs.law.harvard.edu/ivan)
-// (c) 2005-2007 Jon Tirsen (http://www.tirsen.com)
+// script.aculo.us controls.js v1.8.3, Thu Oct 08 11:23:33 +0200 2009
+
+// Copyright (c) 2005-2009 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
+// (c) 2005-2009 Ivan Krstic (http://blogs.law.harvard.edu/ivan)
+// (c) 2005-2009 Jon Tirsen (http://www.tirsen.com)
// Contributors:
// Richard Livsey
// Rahul Bhargava
// Rob Wills
-//
+//
// script.aculo.us is freely distributable under the terms of an MIT-style license.
// For details, see the script.aculo.us web site: http://script.aculo.us/
-// Autocompleter.Base handles all the autocompletion functionality
+// Autocompleter.Base handles all the autocompletion functionality
// that's independent of the data source for autocompletion. This
// includes drawing the autocompletion menu, observing keyboard
// and mouse events, and similar.
//
-// Specific autocompleters need to provide, at the very least,
+// Specific autocompleters need to provide, at the very least,
// a getUpdatedChoices function that will be invoked every time
-// the text inside the monitored textbox changes. This method
+// the text inside the monitored textbox changes. This method
// should get the text for which to provide autocompletion by
// invoking this.getToken(), NOT by directly accessing
// this.element.value. This is to allow incremental tokenized
@@ -30,23 +32,23 @@
// will incrementally autocomplete with a comma as the token.
// Additionally, ',' in the above example can be replaced with
// a token array, e.g. { tokens: [',', '\n'] } which
-// enables autocompletion on multiple tokens. This is most
-// useful when one of the tokens is \n (a newline), as it
+// enables autocompletion on multiple tokens. This is most
+// useful when one of the tokens is \n (a newline), as it
// allows smart autocompletion after linebreaks.
if(typeof Effect == 'undefined')
throw("controls.js requires including script.aculo.us' effects.js library");
-var Autocompleter = { }
+var Autocompleter = { };
Autocompleter.Base = Class.create({
baseInitialize: function(element, update, options) {
- element = $(element)
- this.element = element;
- this.update = $(update);
- this.hasFocus = false;
- this.changed = false;
- this.active = false;
- this.index = 0;
+ element = $(element);
+ this.element = element;
+ this.update = $(update);
+ this.hasFocus = false;
+ this.changed = false;
+ this.active = false;
+ this.index = 0;
this.entryCount = 0;
this.oldElementValue = this.element.value;
@@ -59,28 +61,28 @@ Autocompleter.Base = Class.create({
this.options.tokens = this.options.tokens || [];
this.options.frequency = this.options.frequency || 0.4;
this.options.minChars = this.options.minChars || 1;
- this.options.onShow = this.options.onShow ||
- function(element, update){
+ this.options.onShow = this.options.onShow ||
+ function(element, update){
if(!update.style.position || update.style.position=='absolute') {
update.style.position = 'absolute';
Position.clone(element, update, {
- setHeight: false,
+ setHeight: false,
offsetTop: element.offsetHeight
});
}
Effect.Appear(update,{duration:0.15});
};
- this.options.onHide = this.options.onHide ||
+ this.options.onHide = this.options.onHide ||
function(element, update){ new Effect.Fade(update,{duration:0.15}) };
- if(typeof(this.options.tokens) == 'string')
+ if(typeof(this.options.tokens) == 'string')
this.options.tokens = new Array(this.options.tokens);
// Force carriage returns as token delimiters anyway
if (!this.options.tokens.include('\n'))
this.options.tokens.push('\n');
this.observer = null;
-
+
this.element.setAttribute('autocomplete','off');
Element.hide(this.update);
@@ -91,10 +93,10 @@ Autocompleter.Base = Class.create({
show: function() {
if(Element.getStyle(this.update, 'display')=='none') this.options.onShow(this.element, this.update);
- if(!this.iefix &&
+ if(!this.iefix &&
(Prototype.Browser.IE) &&
(Element.getStyle(this.update, 'position')=='absolute')) {
- new Insertion.After(this.update,
+ new Insertion.After(this.update,
'<iframe id="' + this.update.id + '_iefix" '+
'style="display:none;position:absolute;filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);" ' +
'src="javascript:false;" frameborder="0" scrolling="no"></iframe>');
@@ -102,7 +104,7 @@ Autocompleter.Base = Class.create({
}
if(this.iefix) setTimeout(this.fixIEOverlapping.bind(this), 50);
},
-
+
fixIEOverlapping: function() {
Position.clone(this.update, this.iefix, {setTop:(!this.update.style.height)});
this.iefix.style.zIndex = 1;
@@ -150,15 +152,15 @@ Autocompleter.Base = Class.create({
Event.stop(event);
return;
}
- else
- if(event.keyCode==Event.KEY_TAB || event.keyCode==Event.KEY_RETURN ||
+ else
+ if(event.keyCode==Event.KEY_TAB || event.keyCode==Event.KEY_RETURN ||
(Prototype.Browser.WebKit > 0 && event.keyCode == 0)) return;
this.changed = true;
this.hasFocus = true;
if(this.observer) clearTimeout(this.observer);
- this.observer =
+ this.observer =
setTimeout(this.onObserverEvent.bind(this), this.options.frequency*1000);
},
@@ -170,35 +172,35 @@ Autocompleter.Base = Class.create({
onHover: function(event) {
var element = Event.findElement(event, 'LI');
- if(this.index != element.autocompleteIndex)
+ if(this.index != element.autocompleteIndex)
{
this.index = element.autocompleteIndex;
this.render();
}
Event.stop(event);
},
-
+
onClick: function(event) {
var element = Event.findElement(event, 'LI');
this.index = element.autocompleteIndex;
this.selectEntry();
this.hide();
},
-
+
onBlur: function(event) {
// needed to make click events working
setTimeout(this.hide.bind(this), 250);
this.hasFocus = false;
- this.active = false;
- },
-
+ this.active = false;
+ },
+
render: function() {
if(this.entryCount > 0) {
for (var i = 0; i < this.entryCount; i++)
- this.index==i ?
- Element.addClassName(this.getEntry(i),"selected") :
+ this.index==i ?
+ Element.addClassName(this.getEntry(i),"selected") :
Element.removeClassName(this.getEntry(i),"selected");
- if(this.hasFocus) {
+ if(this.hasFocus) {
this.show();
this.active = true;
}
@@ -207,27 +209,27 @@ Autocompleter.Base = Class.create({
this.hide();
}
},
-
+
markPrevious: function() {
- if(this.index > 0) this.index--
+ if(this.index > 0) this.index--;
else this.index = this.entryCount-1;
this.getEntry(this.index).scrollIntoView(true);
},
-
+
markNext: function() {
- if(this.index < this.entryCount-1) this.index++
+ if(this.index < this.entryCount-1) this.index++;
else this.index = 0;
this.getEntry(this.index).scrollIntoView(false);
},
-
+
getEntry: function(index) {
return this.update.firstChild.childNodes[index];
},
-
+
getCurrentEntry: function() {
return this.getEntry(this.index);
},
-
+
selectEntry: function() {
this.active = false;
this.updateElement(this.getCurrentEntry());
@@ -244,7 +246,7 @@ Autocompleter.Base = Class.create({
if(nodes.length>0) value = Element.collectTextNodes(nodes[0], this.options.select);
} else
value = Element.collectTextNodesIgnoreClass(selectedElement, 'informal');
-
+
var bounds = this.getTokenBounds();
if (bounds[0] != -1) {
var newValue = this.element.value.substr(0, bounds[0]);
@@ -257,7 +259,7 @@ Autocompleter.Base = Class.create({
}
this.oldElementValue = this.element.value;
this.element.focus();
-
+
if (this.options.afterUpdateElement)
this.options.afterUpdateElement(this.element, selectedElement);
},
@@ -269,20 +271,20 @@ Autocompleter.Base = Class.create({
Element.cleanWhitespace(this.update.down());
if(this.update.firstChild && this.update.down().childNodes) {
- this.entryCount =
+ this.entryCount =
this.update.down().childNodes.length;
for (var i = 0; i < this.entryCount; i++) {
var entry = this.getEntry(i);
entry.autocompleteIndex = i;
this.addObservers(entry);
}
- } else {
+ } else {
this.entryCount = 0;
}
this.stopIndicator();
this.index = 0;
-
+
if(this.entryCount==1 && this.options.autoSelect) {
this.selectEntry();
this.hide();
@@ -298,7 +300,7 @@ Autocompleter.Base = Class.create({
},
onObserverEvent: function() {
- this.changed = false;
+ this.changed = false;
this.tokenBounds = null;
if(this.getToken().length>=this.options.minChars) {
this.getUpdatedChoices();
@@ -351,16 +353,16 @@ Ajax.Autocompleter = Class.create(Autocompleter.Base, {
getUpdatedChoices: function() {
this.startIndicator();
-
- var entry = encodeURIComponent(this.options.paramName) + '=' +
+
+ var entry = encodeURIComponent(this.options.paramName) + '=' +
encodeURIComponent(this.getToken());
this.options.parameters = this.options.callback ?
this.options.callback(this.element, entry) : entry;
- if(this.options.defaultParams)
+ if(this.options.defaultParams)
this.options.parameters += '&' + this.options.defaultParams;
-
+
new Ajax.Request(this.url, this.options);
},
@@ -382,7 +384,7 @@ Ajax.Autocompleter = Class.create(Autocompleter.Base, {
// - choices - How many autocompletion choices to offer
//
// - partialSearch - If false, the autocompleter will match entered
-// text only at the beginning of strings in the
+// text only at the beginning of strings in the
// autocomplete array. Defaults to true, which will
// match text at the beginning of any *word* in the
// strings in the autocomplete array. If you want to
@@ -399,7 +401,7 @@ Ajax.Autocompleter = Class.create(Autocompleter.Base, {
// - ignoreCase - Whether to ignore case when autocompleting.
// Defaults to true.
//
-// It's possible to pass in a custom function as the 'selector'
+// It's possible to pass in a custom function as the 'selector'
// option, if you prefer to write your own autocompletion logic.
// In that case, the other options above will not apply unless
// you support them.
@@ -427,20 +429,20 @@ Autocompleter.Local = Class.create(Autocompleter.Base, {
var entry = instance.getToken();
var count = 0;
- for (var i = 0; i < instance.options.array.length &&
- ret.length < instance.options.choices ; i++) {
+ for (var i = 0; i < instance.options.array.length &&
+ ret.length < instance.options.choices ; i++) {
var elem = instance.options.array[i];
- var foundPos = instance.options.ignoreCase ?
- elem.toLowerCase().indexOf(entry.toLowerCase()) :
+ var foundPos = instance.options.ignoreCase ?
+ elem.toLowerCase().indexOf(entry.toLowerCase()) :
elem.indexOf(entry);
while (foundPos != -1) {
- if (foundPos == 0 && elem.length != entry.length) {
- ret.push("<li><strong>" + elem.substr(0, entry.length) + "</strong>" +
+ if (foundPos == 0 && elem.length != entry.length) {
+ ret.push("<li><strong>" + elem.substr(0, entry.length) + "</strong>" +
elem.substr(entry.length) + "</li>");
break;
- } else if (entry.length >= instance.options.partialChars &&
+ } else if (entry.length >= instance.options.partialChars &&
instance.options.partialSearch && foundPos != -1) {
if (instance.options.fullSearch || /\s/.test(elem.substr(foundPos-1,1))) {
partial.push("<li>" + elem.substr(0, foundPos) + "<strong>" +
@@ -450,14 +452,14 @@ Autocompleter.Local = Class.create(Autocompleter.Base, {
}
}
- foundPos = instance.options.ignoreCase ?
- elem.toLowerCase().indexOf(entry.toLowerCase(), foundPos + 1) :
+ foundPos = instance.options.ignoreCase ?
+ elem.toLowerCase().indexOf(entry.toLowerCase(), foundPos + 1) :
elem.indexOf(entry, foundPos + 1);
}
}
if (partial.length)
- ret = ret.concat(partial.slice(0, instance.options.choices - ret.length))
+ ret = ret.concat(partial.slice(0, instance.options.choices - ret.length));
return "<ul>" + ret.join('') + "</ul>";
}
}, options || { });
@@ -474,7 +476,7 @@ Field.scrollFreeActivate = function(field) {
setTimeout(function() {
Field.activate(field);
}, 1);
-}
+};
Ajax.InPlaceEditor = Class.create({
initialize: function(element, url, options) {
@@ -604,7 +606,7 @@ Ajax.InPlaceEditor = Class.create({
this.triggerCallback('onEnterHover');
},
getText: function() {
- return this.element.innerHTML;
+ return this.element.innerHTML.unescapeHTML();
},
handleAJAXFailure: function(transport) {
this.triggerCallback('onFailure', transport);
@@ -780,7 +782,7 @@ Ajax.InPlaceCollectionEditor = Class.create(Ajax.InPlaceEditor, {
onSuccess: function(transport) {
var js = transport.responseText.strip();
if (!/^\[.*\]$/.test(js)) // TODO: improve sanity check
- throw 'Server returned an invalid collection representation.';
+ throw('Server returned an invalid collection representation.');
this._collection = eval(js);
this.checkForExternalText();
}.bind(this),
@@ -937,7 +939,7 @@ Ajax.InPlaceCollectionEditor.DefaultOptions = {
loadingCollectionText: 'Loading options...'
};
-// Delayed observer, like Form.Element.Observer,
+// Delayed observer, like Form.Element.Observer,
// but waits for delay after last key input
// Ideal for live-search fields
@@ -947,7 +949,7 @@ Form.Element.DelayedObserver = Class.create({
this.element = $(element);
this.callback = callback;
this.timer = null;
- this.lastValue = $F(this.element);
+ this.lastValue = $F(this.element);
Event.observe(this.element,'keyup',this.delayedListener.bindAsEventListener(this));
},
delayedListener: function(event) {
@@ -960,4 +962,4 @@ Form.Element.DelayedObserver = Class.create({
this.timer = null;
this.callback(this.element, $F(this.element));
}
-});
+}); \ No newline at end of file
diff --git a/public/javascripts/dragdrop.js b/public/javascripts/dragdrop.js
index bf5cfea66..15c6dbca6 100644
--- a/public/javascripts/dragdrop.js
+++ b/public/javascripts/dragdrop.js
@@ -1,6 +1,7 @@
-// Copyright (c) 2005-2008 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
-// (c) 2005-2007 Sammi Williams (http://www.oriontransfer.co.nz, sammi@oriontransfer.co.nz)
-//
+// script.aculo.us dragdrop.js v1.8.3, Thu Oct 08 11:23:33 +0200 2009
+
+// Copyright (c) 2005-2009 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
+//
// script.aculo.us is freely distributable under the terms of an MIT-style license.
// For details, see the script.aculo.us web site: http://script.aculo.us/
@@ -32,7 +33,7 @@ var Droppables = {
options._containers.push($(containment));
}
}
-
+
if(options.accept) options.accept = [options.accept].flatten();
Element.makePositioned(element); // fix IE
@@ -40,34 +41,34 @@ var Droppables = {
this.drops.push(options);
},
-
+
findDeepestChild: function(drops) {
deepest = drops[0];
-
+
for (i = 1; i < drops.length; ++i)
if (Element.isParent(drops[i].element, deepest.element))
deepest = drops[i];
-
+
return deepest;
},
isContained: function(element, drop) {
var containmentNode;
if(drop.tree) {
- containmentNode = element.treeNode;
+ containmentNode = element.treeNode;
} else {
containmentNode = element.parentNode;
}
return drop._containers.detect(function(c) { return containmentNode == c });
},
-
+
isAffected: function(point, element, drop) {
return (
(drop.element!=element) &&
((!drop._containers) ||
this.isContained(element, drop)) &&
((!drop.accept) ||
- (Element.classNames(element).detect(
+ (Element.classNames(element).detect(
function(v) { return drop.accept.include(v) } ) )) &&
Position.within(drop.element, point[0], point[1]) );
},
@@ -87,12 +88,12 @@ var Droppables = {
show: function(point, element) {
if(!this.drops.length) return;
var drop, affected = [];
-
+
this.drops.each( function(drop) {
if(Droppables.isAffected(point, element, drop))
affected.push(drop);
});
-
+
if(affected.length>0)
drop = Droppables.findDeepestChild(affected);
@@ -101,7 +102,7 @@ var Droppables = {
Position.within(drop.element, point[0], point[1]);
if(drop.onHover)
drop.onHover(element, drop.element, Position.overlap(drop.overlap, drop.element));
-
+
if (drop != this.last_active) Droppables.activate(drop);
}
},
@@ -112,8 +113,8 @@ var Droppables = {
if (this.isAffected([Event.pointerX(event), Event.pointerY(event)], element, this.last_active))
if (this.last_active.onDrop) {
- this.last_active.onDrop(element, this.last_active.element, event);
- return true;
+ this.last_active.onDrop(element, this.last_active.element, event);
+ return true;
}
},
@@ -121,25 +122,25 @@ var Droppables = {
if(this.last_active)
this.deactivate(this.last_active);
}
-}
+};
var Draggables = {
drags: [],
observers: [],
-
+
register: function(draggable) {
if(this.drags.length == 0) {
this.eventMouseUp = this.endDrag.bindAsEventListener(this);
this.eventMouseMove = this.updateDrag.bindAsEventListener(this);
this.eventKeypress = this.keyPress.bindAsEventListener(this);
-
+
Event.observe(document, "mouseup", this.eventMouseUp);
Event.observe(document, "mousemove", this.eventMouseMove);
Event.observe(document, "keypress", this.eventKeypress);
}
this.drags.push(draggable);
},
-
+
unregister: function(draggable) {
this.drags = this.drags.reject(function(d) { return d==draggable });
if(this.drags.length == 0) {
@@ -148,24 +149,24 @@ var Draggables = {
Event.stopObserving(document, "keypress", this.eventKeypress);
}
},
-
+
activate: function(draggable) {
- if(draggable.options.delay) {
- this._timeout = setTimeout(function() {
- Draggables._timeout = null;
- window.focus();
- Draggables.activeDraggable = draggable;
- }.bind(this), draggable.options.delay);
+ if(draggable.options.delay) {
+ this._timeout = setTimeout(function() {
+ Draggables._timeout = null;
+ window.focus();
+ Draggables.activeDraggable = draggable;
+ }.bind(this), draggable.options.delay);
} else {
window.focus(); // allows keypress events if window isn't currently focused, fails for Safari
this.activeDraggable = draggable;
}
},
-
+
deactivate: function() {
this.activeDraggable = null;
},
-
+
updateDrag: function(event) {
if(!this.activeDraggable) return;
var pointer = [Event.pointerX(event), Event.pointerY(event)];
@@ -173,36 +174,36 @@ var Draggables = {
// the same coordinates, prevent needless redrawing (moz bug?)
if(this._lastPointer && (this._lastPointer.inspect() == pointer.inspect())) return;
this._lastPointer = pointer;
-
+
this.activeDraggable.updateDrag(event, pointer);
},
-
+
endDrag: function(event) {
- if(this._timeout) {
- clearTimeout(this._timeout);
- this._timeout = null;
+ if(this._timeout) {
+ clearTimeout(this._timeout);
+ this._timeout = null;
}
if(!this.activeDraggable) return;
this._lastPointer = null;
this.activeDraggable.endDrag(event);
this.activeDraggable = null;
},
-
+
keyPress: function(event) {
if(this.activeDraggable)
this.activeDraggable.keyPress(event);
},
-
+
addObserver: function(observer) {
this.observers.push(observer);
this._cacheObserverCallbacks();
},
-
+
removeObserver: function(element) { // element instead of observer fixes mem leaks
this.observers = this.observers.reject( function(o) { return o.element==element });
this._cacheObserverCallbacks();
},
-
+
notify: function(eventName, draggable, event) { // 'onStart', 'onEnd', 'onDrag'
if(this[eventName+'Count'] > 0)
this.observers.each( function(o) {
@@ -210,7 +211,7 @@ var Draggables = {
});
if(draggable.options[eventName]) draggable.options[eventName](draggable, event);
},
-
+
_cacheObserverCallbacks: function() {
['onStart','onEnd','onDrag'].each( function(eventName) {
Draggables[eventName+'Count'] = Draggables.observers.select(
@@ -218,7 +219,7 @@ var Draggables = {
).length;
});
}
-}
+};
/*--------------------------------------------------------------------------*/
@@ -234,12 +235,12 @@ var Draggable = Class.create({
},
endeffect: function(element) {
var toOpacity = Object.isNumber(element._opacity) ? element._opacity : 1.0;
- new Effect.Opacity(element, {duration:0.2, from:0.7, to:toOpacity,
+ new Effect.Opacity(element, {duration:0.2, from:0.7, to:toOpacity,
queue: {scope:'_draggable', position:'end'},
- afterFinish: function(){
- Draggable._dragging[element] = false
+ afterFinish: function(){
+ Draggable._dragging[element] = false
}
- });
+ });
},
zindex: 1000,
revert: false,
@@ -250,57 +251,57 @@ var Draggable = Class.create({
snap: false, // false, or xy or [x,y] or function(x,y){ return [x,y] }
delay: 0
};
-
+
if(!arguments[1] || Object.isUndefined(arguments[1].endeffect))
Object.extend(defaults, {
starteffect: function(element) {
element._opacity = Element.getOpacity(element);
Draggable._dragging[element] = true;
- new Effect.Opacity(element, {duration:0.2, from:element._opacity, to:0.7});
+ new Effect.Opacity(element, {duration:0.2, from:element._opacity, to:0.7});
}
});
-
+
var options = Object.extend(defaults, arguments[1] || { });
this.element = $(element);
-
+
if(options.handle && Object.isString(options.handle))
this.handle = this.element.down('.'+options.handle, 0);
-
+
if(!this.handle) this.handle = $(options.handle);
if(!this.handle) this.handle = this.element;
-
+
if(options.scroll && !options.scroll.scrollTo && !options.scroll.outerHTML) {
options.scroll = $(options.scroll);
this._isScrollChild = Element.childOf(this.element, options.scroll);
}
- Element.makePositioned(this.element); // fix IE
+ Element.makePositioned(this.element); // fix IE
this.options = options;
- this.dragging = false;
+ this.dragging = false;
this.eventMouseDown = this.initDrag.bindAsEventListener(this);
Event.observe(this.handle, "mousedown", this.eventMouseDown);
-
+
Draggables.register(this);
},
-
+
destroy: function() {
Event.stopObserving(this.handle, "mousedown", this.eventMouseDown);
Draggables.unregister(this);
},
-
+
currentDelta: function() {
return([
parseInt(Element.getStyle(this.element,'left') || '0'),
parseInt(Element.getStyle(this.element,'top') || '0')]);
},
-
+
initDrag: function(event) {
if(!Object.isUndefined(Draggable._dragging[this.element]) &&
Draggable._dragging[this.element]) return;
- if(Event.isLeftClick(event)) {
+ if(Event.isLeftClick(event)) {
// abort on form elements, fixes a Firefox issue
var src = Event.element(event);
if((tag_name = src.tagName.toUpperCase()) && (
@@ -309,34 +310,34 @@ var Draggable = Class.create({
tag_name=='OPTION' ||
tag_name=='BUTTON' ||
tag_name=='TEXTAREA')) return;
-
+
var pointer = [Event.pointerX(event), Event.pointerY(event)];
- var pos = Position.cumulativeOffset(this.element);
+ var pos = this.element.cumulativeOffset();
this.offset = [0,1].map( function(i) { return (pointer[i] - pos[i]) });
-
+
Draggables.activate(this);
Event.stop(event);
}
},
-
+
startDrag: function(event) {
this.dragging = true;
if(!this.delta)
this.delta = this.currentDelta();
-
+
if(this.options.zindex) {
this.originalZ = parseInt(Element.getStyle(this.element,'z-index') || 0);
this.element.style.zIndex = this.options.zindex;
}
-
+
if(this.options.ghosting) {
this._clone = this.element.cloneNode(true);
- this.element._originallyAbsolute = (this.element.getStyle('position') == 'absolute');
- if (!this.element._originallyAbsolute)
+ this._originallyAbsolute = (this.element.getStyle('position') == 'absolute');
+ if (!this._originallyAbsolute)
Position.absolutize(this.element);
this.element.parentNode.insertBefore(this._clone, this.element);
}
-
+
if(this.options.scroll) {
if (this.options.scroll == window) {
var where = this._getWindowScroll(this.options.scroll);
@@ -347,28 +348,28 @@ var Draggable = Class.create({
this.originalScrollTop = this.options.scroll.scrollTop;
}
}
-
+
Draggables.notify('onStart', this, event);
-
+
if(this.options.starteffect) this.options.starteffect(this.element);
},
-
+
updateDrag: function(event, pointer) {
if(!this.dragging) this.startDrag(event);
-
+
if(!this.options.quiet){
Position.prepare();
Droppables.show(pointer, this.element);
}
-
+
Draggables.notify('onDrag', this, event);
-
+
this.draw(pointer);
if(this.options.change) this.options.change(this);
-
+
if(this.options.scroll) {
this.stopScrolling();
-
+
var p;
if (this.options.scroll == window) {
with(this._getWindowScroll(this.options.scroll)) { p = [ left, top, left+width, top+height ]; }
@@ -386,16 +387,16 @@ var Draggable = Class.create({
if(pointer[1] > (p[3]-this.options.scrollSensitivity)) speed[1] = pointer[1]-(p[3]-this.options.scrollSensitivity);
this.startScrolling(speed);
}
-
+
// fix AppleWebKit rendering
if(Prototype.Browser.WebKit) window.scrollBy(0,0);
-
+
Event.stop(event);
},
-
+
finishDrag: function(event, success) {
this.dragging = false;
-
+
if(this.options.quiet){
Position.prepare();
var pointer = [Event.pointerX(event), Event.pointerY(event)];
@@ -403,24 +404,24 @@ var Draggable = Class.create({
}
if(this.options.ghosting) {
- if (!this.element._originallyAbsolute)
+ if (!this._originallyAbsolute)
Position.relativize(this.element);
- delete this.element._originallyAbsolute;
+ delete this._originallyAbsolute;
Element.remove(this._clone);
this._clone = null;
}
- var dropped = false;
- if(success) {
- dropped = Droppables.fire(event, this.element);
- if (!dropped) dropped = false;
+ var dropped = false;
+ if(success) {
+ dropped = Droppables.fire(event, this.element);
+ if (!dropped) dropped = false;
}
if(dropped && this.options.onDropped) this.options.onDropped(this.element);
Draggables.notify('onEnd', this, event);
var revert = this.options.revert;
if(revert && Object.isFunction(revert)) revert = revert(this.element);
-
+
var d = this.currentDelta();
if(revert && this.options.reverteffect) {
if (dropped == 0 || revert != 'failure')
@@ -433,67 +434,67 @@ var Draggable = Class.create({
if(this.options.zindex)
this.element.style.zIndex = this.originalZ;
- if(this.options.endeffect)
+ if(this.options.endeffect)
this.options.endeffect(this.element);
-
+
Draggables.deactivate(this);
Droppables.reset();
},
-
+
keyPress: function(event) {
if(event.keyCode!=Event.KEY_ESC) return;
this.finishDrag(event, false);
Event.stop(event);
},
-
+
endDrag: function(event) {
if(!this.dragging) return;
this.stopScrolling();
this.finishDrag(event, true);
Event.stop(event);
},
-
+
draw: function(point) {
- var pos = Position.cumulativeOffset(this.element);
+ var pos = this.element.cumulativeOffset();
if(this.options.ghosting) {
var r = Position.realOffset(this.element);
pos[0] += r[0] - Position.deltaX; pos[1] += r[1] - Position.deltaY;
}
-
+
var d = this.currentDelta();
pos[0] -= d[0]; pos[1] -= d[1];
-
+
if(this.options.scroll && (this.options.scroll != window && this._isScrollChild)) {
pos[0] -= this.options.scroll.scrollLeft-this.originalScrollLeft;
pos[1] -= this.options.scroll.scrollTop-this.originalScrollTop;
}
-
- var p = [0,1].map(function(i){
- return (point[i]-pos[i]-this.offset[i])
+
+ var p = [0,1].map(function(i){
+ return (point[i]-pos[i]-this.offset[i])
}.bind(this));
-
+
if(this.options.snap) {
if(Object.isFunction(this.options.snap)) {
p = this.options.snap(p[0],p[1],this);
} else {
if(Object.isArray(this.options.snap)) {
p = p.map( function(v, i) {
- return (v/this.options.snap[i]).round()*this.options.snap[i] }.bind(this))
+ return (v/this.options.snap[i]).round()*this.options.snap[i] }.bind(this));
} else {
p = p.map( function(v) {
- return (v/this.options.snap).round()*this.options.snap }.bind(this))
+ return (v/this.options.snap).round()*this.options.snap }.bind(this));
}
}}
-
+
var style = this.element.style;
if((!this.options.constraint) || (this.options.constraint=='horizontal'))
style.left = p[0] + "px";
if((!this.options.constraint) || (this.options.constraint=='vertical'))
style.top = p[1] + "px";
-
+
if(style.visibility=="hidden") style.visibility = ""; // fix gecko rendering
},
-
+
stopScrolling: function() {
if(this.scrollInterval) {
clearInterval(this.scrollInterval);
@@ -501,14 +502,14 @@ var Draggable = Class.create({
Draggables._lastScrollPointer = null;
}
},
-
+
startScrolling: function(speed) {
if(!(speed[0] || speed[1])) return;
this.scrollSpeed = [speed[0]*this.options.scrollSpeed,speed[1]*this.options.scrollSpeed];
this.lastScrolled = new Date();
this.scrollInterval = setInterval(this.scroll.bind(this), 10);
},
-
+
scroll: function() {
var current = new Date();
var delta = current - this.lastScrolled;
@@ -524,7 +525,7 @@ var Draggable = Class.create({
this.options.scroll.scrollLeft += this.scrollSpeed[0] * delta / 1000;
this.options.scroll.scrollTop += this.scrollSpeed[1] * delta / 1000;
}
-
+
Position.prepare();
Droppables.show(Draggables._lastPointer, this.element);
Draggables.notify('onDrag', this);
@@ -538,10 +539,10 @@ var Draggable = Class.create({
Draggables._lastScrollPointer[1] = 0;
this.draw(Draggables._lastScrollPointer);
}
-
+
if(this.options.change) this.options.change(this);
},
-
+
_getWindowScroll: function(w) {
var T, L, W, H;
with (w.document) {
@@ -560,7 +561,7 @@ var Draggable = Class.create({
H = documentElement.clientHeight;
} else {
W = body.offsetWidth;
- H = body.offsetHeight
+ H = body.offsetHeight;
}
}
return { top: T, left: L, width: W, height: H };
@@ -577,11 +578,11 @@ var SortableObserver = Class.create({
this.observer = observer;
this.lastValue = Sortable.serialize(this.element);
},
-
+
onStart: function() {
this.lastValue = Sortable.serialize(this.element);
},
-
+
onEnd: function() {
Sortable.unmark();
if(this.lastValue != Sortable.serialize(this.element))
@@ -591,11 +592,11 @@ var SortableObserver = Class.create({
var Sortable = {
SERIALIZE_RULE: /^[^_\-](?:[A-Za-z0-9\-\_]*)[_](.*)$/,
-
+
sortables: { },
-
+
_findRootElement: function(element) {
- while (element.tagName.toUpperCase() != "BODY") {
+ while (element.tagName.toUpperCase() != "BODY") {
if(element.id && Sortable.sortables[element.id]) return element;
element = element.parentNode;
}
@@ -606,22 +607,23 @@ var Sortable = {
if(!element) return;
return Sortable.sortables[element.id];
},
-
+
destroy: function(element){
- var s = Sortable.options(element);
-
+ element = $(element);
+ var s = Sortable.sortables[element.id];
+
if(s) {
Draggables.removeObserver(s.element);
s.droppables.each(function(d){ Droppables.remove(d) });
s.draggables.invoke('destroy');
-
+
delete Sortable.sortables[s.element.id];
}
},
create: function(element) {
element = $(element);
- var options = Object.extend({
+ var options = Object.extend({
element: element,
tag: 'li', // assumes li children, override with tag: 'tagname'
dropOnEmpty: false,
@@ -635,17 +637,17 @@ var Sortable = {
delay: 0,
hoverclass: null,
ghosting: false,
- quiet: false,
+ quiet: false,
scroll: false,
scrollSensitivity: 20,
scrollSpeed: 15,
format: this.SERIALIZE_RULE,
-
- // these take arrays of elements or ids and can be
+
+ // these take arrays of elements or ids and can be
// used for better initialization performance
elements: false,
handles: false,
-
+
onChange: Prototype.emptyFunction,
onUpdate: Prototype.emptyFunction
}, arguments[1] || { });
@@ -682,24 +684,24 @@ var Sortable = {
if(options.zindex)
options_for_draggable.zindex = options.zindex;
- // build options for the droppables
+ // build options for the droppables
var options_for_droppable = {
overlap: options.overlap,
containment: options.containment,
tree: options.tree,
hoverclass: options.hoverclass,
onHover: Sortable.onHover
- }
-
+ };
+
var options_for_tree = {
onHover: Sortable.onEmptyHover,
overlap: options.overlap,
containment: options.containment,
hoverclass: options.hoverclass
- }
+ };
// fix for gecko engine
- Element.cleanWhitespace(element);
+ Element.cleanWhitespace(element);
options.draggables = [];
options.droppables = [];
@@ -712,14 +714,14 @@ var Sortable = {
(options.elements || this.findElements(element, options) || []).each( function(e,i) {
var handle = options.handles ? $(options.handles[i]) :
- (options.handle ? $(e).select('.' + options.handle)[0] : e);
+ (options.handle ? $(e).select('.' + options.handle)[0] : e);
options.draggables.push(
new Draggable(e, Object.extend(options_for_draggable, { handle: handle })));
Droppables.add(e, options_for_droppable);
if(options.tree) e.treeNode = element;
- options.droppables.push(e);
+ options.droppables.push(e);
});
-
+
if(options.tree) {
(Sortable.findTreeElements(element, options) || []).each( function(e) {
Droppables.add(e, options_for_tree);
@@ -729,7 +731,7 @@ var Sortable = {
}
// keep reference
- this.sortables[element.id] = options;
+ this.sortables[element.identify()] = options;
// for onupdate
Draggables.addObserver(new SortableObserver(element, options.onUpdate));
@@ -741,7 +743,7 @@ var Sortable = {
return Element.findChildren(
element, options.only, options.tree ? true : false, options.tag);
},
-
+
findTreeElements: function(element, options) {
return Element.findChildren(
element, options.only, options.tree ? true : false, options.treeTag);
@@ -758,7 +760,7 @@ var Sortable = {
var oldParentNode = element.parentNode;
element.style.visibility = "hidden"; // fix gecko rendering
dropon.parentNode.insertBefore(element, dropon);
- if(dropon.parentNode!=oldParentNode)
+ if(dropon.parentNode!=oldParentNode)
Sortable.options(oldParentNode).onChange(element);
Sortable.options(dropon.parentNode).onChange(element);
}
@@ -769,26 +771,26 @@ var Sortable = {
var oldParentNode = element.parentNode;
element.style.visibility = "hidden"; // fix gecko rendering
dropon.parentNode.insertBefore(element, nextElement);
- if(dropon.parentNode!=oldParentNode)
+ if(dropon.parentNode!=oldParentNode)
Sortable.options(oldParentNode).onChange(element);
Sortable.options(dropon.parentNode).onChange(element);
}
}
},
-
+
onEmptyHover: function(element, dropon, overlap) {
var oldParentNode = element.parentNode;
var droponOptions = Sortable.options(dropon);
-
+
if(!Element.isParent(dropon, element)) {
var index;
-
+
var children = Sortable.findElements(dropon, {tag: droponOptions.tag, only: droponOptions.only});
var child = null;
-
+
if(children) {
var offset = Element.offsetSize(dropon, droponOptions.overlap) * (1.0 - overlap);
-
+
for (index = 0; index < children.length; index += 1) {
if (offset - Element.offsetSize (children[index], droponOptions.overlap) >= 0) {
offset -= Element.offsetSize (children[index], droponOptions.overlap);
@@ -801,9 +803,9 @@ var Sortable = {
}
}
}
-
+
dropon.insertBefore(element, child);
-
+
Sortable.options(oldParentNode).onChange(element);
droponOptions.onChange(element);
}
@@ -816,34 +818,34 @@ var Sortable = {
mark: function(dropon, position) {
// mark on ghosting only
var sortable = Sortable.options(dropon.parentNode);
- if(sortable && !sortable.ghosting) return;
+ if(sortable && !sortable.ghosting) return;
if(!Sortable._marker) {
- Sortable._marker =
+ Sortable._marker =
($('dropmarker') || Element.extend(document.createElement('DIV'))).
hide().addClassName('dropmarker').setStyle({position:'absolute'});
document.getElementsByTagName("body").item(0).appendChild(Sortable._marker);
- }
- var offsets = Position.cumulativeOffset(dropon);
+ }
+ var offsets = dropon.cumulativeOffset();
Sortable._marker.setStyle({left: offsets[0]+'px', top: offsets[1] + 'px'});
-
+
if(position=='after')
- if(sortable.overlap == 'horizontal')
+ if(sortable.overlap == 'horizontal')
Sortable._marker.setStyle({left: (offsets[0]+dropon.clientWidth) + 'px'});
else
Sortable._marker.setStyle({top: (offsets[1]+dropon.clientHeight) + 'px'});
-
+
Sortable._marker.show();
},
-
+
_tree: function(element, options, parent) {
var children = Sortable.findElements(element, options) || [];
-
+
for (var i = 0; i < children.length; ++i) {
var match = children[i].id.match(options.format);
if (!match) continue;
-
+
var child = {
id: encodeURIComponent(match ? match[1] : null),
element: element,
@@ -851,16 +853,16 @@ var Sortable = {
children: [],
position: parent.children.length,
container: $(children[i]).down(options.treeTag)
- }
-
+ };
+
/* Get the element containing the children and recurse over it */
if (child.container)
- this._tree(child.container, options, child)
-
+ this._tree(child.container, options, child);
+
parent.children.push (child);
}
- return parent;
+ return parent;
},
tree: function(element) {
@@ -873,15 +875,15 @@ var Sortable = {
name: element.id,
format: sortableOptions.format
}, arguments[1] || { });
-
+
var root = {
id: null,
parent: null,
children: [],
container: element,
position: 0
- }
-
+ };
+
return Sortable._tree(element, options, root);
},
@@ -897,7 +899,7 @@ var Sortable = {
sequence: function(element) {
element = $(element);
var options = Object.extend(this.options(element), arguments[1] || { });
-
+
return $(this.findElements(element, options) || []).map( function(item) {
return item.id.match(options.format) ? item.id.match(options.format)[1] : '';
});
@@ -906,14 +908,14 @@ var Sortable = {
setSequence: function(element, new_sequence) {
element = $(element);
var options = Object.extend(this.options(element), arguments[2] || { });
-
+
var nodeMap = { };
this.findElements(element, options).each( function(n) {
if (n.id.match(options.format))
nodeMap[n.id.match(options.format)[1]] = [n, n.parentNode];
n.parentNode.removeChild(n);
});
-
+
new_sequence.each(function(ident) {
var n = nodeMap[ident];
if (n) {
@@ -922,16 +924,16 @@ var Sortable = {
}
});
},
-
+
serialize: function(element) {
element = $(element);
var options = Object.extend(Sortable.options(element), arguments[1] || { });
var name = encodeURIComponent(
(arguments[1] && arguments[1].name) ? arguments[1].name : element.id);
-
+
if (options.tree) {
return Sortable.tree(element, arguments[1]).children.map( function (item) {
- return [name + Sortable._constructIndex(item) + "[id]=" +
+ return [name + Sortable._constructIndex(item) + "[id]=" +
encodeURIComponent(item.id)].concat(item.children.map(arguments.callee));
}).flatten().join('&');
} else {
@@ -940,16 +942,16 @@ var Sortable = {
}).join('&');
}
}
-}
+};
// Returns true if child is contained within element
Element.isParent = function(child, element) {
if (!child.parentNode || child == element) return false;
if (child.parentNode == element) return true;
return Element.isParent(child.parentNode, element);
-}
+};
-Element.findChildren = function(element, only, recursive, tagName) {
+Element.findChildren = function(element, only, recursive, tagName) {
if(!element.hasChildNodes()) return null;
tagName = tagName.toUpperCase();
if(only) only = [only].flatten();
@@ -965,8 +967,8 @@ Element.findChildren = function(element, only, recursive, tagName) {
});
return (elements.length>0 ? elements.flatten() : []);
-}
+};
Element.offsetSize = function (element, type) {
return element['offset' + ((type=='vertical' || type=='height') ? 'Height' : 'Width')];
-}
+}; \ No newline at end of file
diff --git a/public/javascripts/effects.js b/public/javascripts/effects.js
index f030b5dbe..c81e6c7d5 100644
--- a/public/javascripts/effects.js
+++ b/public/javascripts/effects.js
@@ -1,48 +1,50 @@
-// Copyright (c) 2005-2008 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
+// script.aculo.us effects.js v1.8.3, Thu Oct 08 11:23:33 +0200 2009
+
+// Copyright (c) 2005-2009 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
// Contributors:
// Justin Palmer (http://encytemedia.com/)
// Mark Pilgrim (http://diveintomark.org/)
// Martin Bialasinki
-//
+//
// script.aculo.us is freely distributable under the terms of an MIT-style license.
-// For details, see the script.aculo.us web site: http://script.aculo.us/
+// For details, see the script.aculo.us web site: http://script.aculo.us/
-// converts rgb() and #xxx to #xxxxxx format,
-// returns self (or first argument) if not convertable
-String.prototype.parseColor = function() {
+// converts rgb() and #xxx to #xxxxxx format,
+// returns self (or first argument) if not convertable
+String.prototype.parseColor = function() {
var color = '#';
- if (this.slice(0,4) == 'rgb(') {
- var cols = this.slice(4,this.length-1).split(',');
- var i=0; do { color += parseInt(cols[i]).toColorPart() } while (++i<3);
- } else {
- if (this.slice(0,1) == '#') {
- if (this.length==4) for(var i=1;i<4;i++) color += (this.charAt(i) + this.charAt(i)).toLowerCase();
- if (this.length==7) color = this.toLowerCase();
- }
- }
- return (color.length==7 ? color : (arguments[0] || this));
+ if (this.slice(0,4) == 'rgb(') {
+ var cols = this.slice(4,this.length-1).split(',');
+ var i=0; do { color += parseInt(cols[i]).toColorPart() } while (++i<3);
+ } else {
+ if (this.slice(0,1) == '#') {
+ if (this.length==4) for(var i=1;i<4;i++) color += (this.charAt(i) + this.charAt(i)).toLowerCase();
+ if (this.length==7) color = this.toLowerCase();
+ }
+ }
+ return (color.length==7 ? color : (arguments[0] || this));
};
/*--------------------------------------------------------------------------*/
-Element.collectTextNodes = function(element) {
+Element.collectTextNodes = function(element) {
return $A($(element).childNodes).collect( function(node) {
- return (node.nodeType==3 ? node.nodeValue :
+ return (node.nodeType==3 ? node.nodeValue :
(node.hasChildNodes() ? Element.collectTextNodes(node) : ''));
}).flatten().join('');
};
-Element.collectTextNodesIgnoreClass = function(element, className) {
+Element.collectTextNodesIgnoreClass = function(element, className) {
return $A($(element).childNodes).collect( function(node) {
- return (node.nodeType==3 ? node.nodeValue :
- ((node.hasChildNodes() && !Element.hasClassName(node,className)) ?
+ return (node.nodeType==3 ? node.nodeValue :
+ ((node.hasChildNodes() && !Element.hasClassName(node,className)) ?
Element.collectTextNodesIgnoreClass(node, className) : ''));
}).flatten().join('');
};
Element.setContentZoom = function(element, percent) {
- element = $(element);
- element.setStyle({fontSize: (percent/100) + 'em'});
+ element = $(element);
+ element.setStyle({fontSize: (percent/100) + 'em'});
if (Prototype.Browser.WebKit) window.scrollBy(0,0);
return element;
};
@@ -70,28 +72,23 @@ var Effect = {
Transitions: {
linear: Prototype.K,
sinoidal: function(pos) {
- return (-Math.cos(pos*Math.PI)/2) + 0.5;
+ return (-Math.cos(pos*Math.PI)/2) + .5;
},
reverse: function(pos) {
return 1-pos;
},
flicker: function(pos) {
- var pos = ((-Math.cos(pos*Math.PI)/4) + 0.75) + Math.random()/4;
+ var pos = ((-Math.cos(pos*Math.PI)/4) + .75) + Math.random()/4;
return pos > 1 ? 1 : pos;
},
wobble: function(pos) {
- return (-Math.cos(pos*Math.PI*(9*pos))/2) + 0.5;
+ return (-Math.cos(pos*Math.PI*(9*pos))/2) + .5;
},
- pulse: function(pos, pulses) {
- pulses = pulses || 5;
- return (
- ((pos % (1/pulses)) * pulses).round() == 0 ?
- ((pos * pulses * 2) - (pos * pulses * 2).floor()) :
- 1 - ((pos * pulses * 2) - (pos * pulses * 2).floor())
- );
+ pulse: function(pos, pulses) {
+ return (-Math.cos((pos*((pulses||5)-.5)*2)*Math.PI)/2) + .5;
},
- spring: function(pos) {
- return 1 - (Math.cos(pos * 4.5 * Math.PI) * Math.exp(-pos * 6));
+ spring: function(pos) {
+ return 1 - (Math.cos(pos * 4.5 * Math.PI) * Math.exp(-pos * 6));
},
none: function(pos) {
return 0;
@@ -112,14 +109,14 @@ var Effect = {
tagifyText: function(element) {
var tagifyStyle = 'position:relative';
if (Prototype.Browser.IE) tagifyStyle += ';zoom:1';
-
+
element = $(element);
$A(element.childNodes).each( function(child) {
if (child.nodeType==3) {
child.nodeValue.toArray().each( function(character) {
element.insertBefore(
new Element('span', {style: tagifyStyle}).update(
- character == ' ' ? String.fromCharCode(160) : character),
+ character == ' ' ? String.fromCharCode(160) : character),
child);
});
Element.remove(child);
@@ -128,13 +125,13 @@ var Effect = {
},
multiple: function(element, effect) {
var elements;
- if (((typeof element == 'object') ||
- Object.isFunction(element)) &&
+ if (((typeof element == 'object') ||
+ Object.isFunction(element)) &&
(element.length))
elements = element;
else
elements = $(element).childNodes;
-
+
var options = Object.extend({
speed: 0.1,
delay: 0.0
@@ -150,14 +147,13 @@ var Effect = {
'blind': ['BlindDown','BlindUp'],
'appear': ['Appear','Fade']
},
- toggle: function(element, effect) {
+ toggle: function(element, effect, options) {
element = $(element);
- effect = (effect || 'appear').toLowerCase();
- var options = Object.extend({
+ effect = (effect || 'appear').toLowerCase();
+
+ return Effect[ Effect.PAIRS[ effect ][ element.visible() ? 1 : 0 ] ](element, Object.extend({
queue: { position:'end', scope:(element.id || 'global'), limit: 1 }
- }, arguments[2] || { });
- Effect[element.visible() ?
- Effect.PAIRS[effect][1] : Effect.PAIRS[effect][0]](element, options);
+ }, options || {}));
}
};
@@ -168,20 +164,20 @@ Effect.DefaultOptions.transition = Effect.Transitions.sinoidal;
Effect.ScopedQueue = Class.create(Enumerable, {
initialize: function() {
this.effects = [];
- this.interval = null;
+ this.interval = null;
},
_each: function(iterator) {
this.effects._each(iterator);
},
add: function(effect) {
var timestamp = new Date().getTime();
-
- var position = Object.isString(effect.options.queue) ?
+
+ var position = Object.isString(effect.options.queue) ?
effect.options.queue : effect.options.queue.position;
-
+
switch(position) {
case 'front':
- // move unstarted effects after this effect
+ // move unstarted effects after this effect
this.effects.findAll(function(e){ return e.state=='idle' }).each( function(e) {
e.startOn += effect.finishOn;
e.finishOn += effect.finishOn;
@@ -195,13 +191,13 @@ Effect.ScopedQueue = Class.create(Enumerable, {
timestamp = this.effects.pluck('finishOn').max() || timestamp;
break;
}
-
+
effect.startOn += timestamp;
effect.finishOn += timestamp;
if (!effect.options.queue.limit || (this.effects.length < effect.options.queue.limit))
this.effects.push(effect);
-
+
if (!this.interval)
this.interval = setInterval(this.loop.bind(this), 15);
},
@@ -214,7 +210,7 @@ Effect.ScopedQueue = Class.create(Enumerable, {
},
loop: function() {
var timePos = new Date().getTime();
- for(var i=0, len=this.effects.length;i<len;i++)
+ for(var i=0, len=this.effects.length;i<len;i++)
this.effects[i] && this.effects[i].loop(timePos);
}
});
@@ -223,7 +219,7 @@ Effect.Queues = {
instances: $H(),
get: function(queueName) {
if (!Object.isString(queueName)) return queueName;
-
+
return this.instances.get(queueName) ||
this.instances.set(queueName, new Effect.ScopedQueue());
}
@@ -233,12 +229,6 @@ Effect.Queue = Effect.Queues.get('global');
Effect.Base = Class.create({
position: null,
start: function(options) {
- function codeForEvent(options,eventName){
- return (
- (options[eventName+'Internal'] ? 'this.options.'+eventName+'Internal(this);' : '') +
- (options[eventName] ? 'this.options.'+eventName+'(this);' : '')
- );
- }
if (options && options.transition === false) options.transition = Effect.Transitions.linear;
this.options = Object.extend(Object.extend({ },Effect.DefaultOptions), options || { });
this.currentFrame = 0;
@@ -248,23 +238,35 @@ Effect.Base = Class.create({
this.fromToDelta = this.options.to-this.options.from;
this.totalTime = this.finishOn-this.startOn;
this.totalFrames = this.options.fps*this.options.duration;
-
- eval('this.render = function(pos){ '+
- 'if (this.state=="idle"){this.state="running";'+
- codeForEvent(this.options,'beforeSetup')+
- (this.setup ? 'this.setup();':'')+
- codeForEvent(this.options,'afterSetup')+
- '};if (this.state=="running"){'+
- 'pos=this.options.transition(pos)*'+this.fromToDelta+'+'+this.options.from+';'+
- 'this.position=pos;'+
- codeForEvent(this.options,'beforeUpdate')+
- (this.update ? 'this.update(pos);':'')+
- codeForEvent(this.options,'afterUpdate')+
- '}}');
-
+
+ this.render = (function() {
+ function dispatch(effect, eventName) {
+ if (effect.options[eventName + 'Internal'])
+ effect.options[eventName + 'Internal'](effect);
+ if (effect.options[eventName])
+ effect.options[eventName](effect);
+ }
+
+ return function(pos) {
+ if (this.state === "idle") {
+ this.state = "running";
+ dispatch(this, 'beforeSetup');
+ if (this.setup) this.setup();
+ dispatch(this, 'afterSetup');
+ }
+ if (this.state === "running") {
+ pos = (this.options.transition(pos) * this.fromToDelta) + this.options.from;
+ this.position = pos;
+ dispatch(this, 'beforeUpdate');
+ if (this.update) this.update(pos);
+ dispatch(this, 'afterUpdate');
+ }
+ };
+ })();
+
this.event('beforeStart');
if (!this.options.sync)
- Effect.Queues.get(Object.isString(this.options.queue) ?
+ Effect.Queues.get(Object.isString(this.options.queue) ?
'global' : this.options.queue.scope).add(this);
},
loop: function(timePos) {
@@ -273,9 +275,9 @@ Effect.Base = Class.create({
this.render(1.0);
this.cancel();
this.event('beforeFinish');
- if (this.finish) this.finish();
+ if (this.finish) this.finish();
this.event('afterFinish');
- return;
+ return;
}
var pos = (timePos - this.startOn) / this.totalTime,
frame = (pos * this.totalFrames).round();
@@ -287,7 +289,7 @@ Effect.Base = Class.create({
},
cancel: function() {
if (!this.options.sync)
- Effect.Queues.get(Object.isString(this.options.queue) ?
+ Effect.Queues.get(Object.isString(this.options.queue) ?
'global' : this.options.queue.scope).remove(this);
this.state = 'finished';
},
@@ -325,10 +327,10 @@ Effect.Parallel = Class.create(Effect.Base, {
Effect.Tween = Class.create(Effect.Base, {
initialize: function(object, from, to) {
object = Object.isString(object) ? $(object) : object;
- var args = $A(arguments), method = args.last(),
+ var args = $A(arguments), method = args.last(),
options = args.length == 5 ? args[3] : null;
this.method = Object.isFunction(method) ? method.bind(object) :
- Object.isFunction(object[method]) ? object[method].bind(object) :
+ Object.isFunction(object[method]) ? object[method].bind(object) :
function(value) { object[method] = value };
this.start(Object.extend({ from: from, to: to }, options || { }));
},
@@ -392,7 +394,7 @@ Effect.Move = Class.create(Effect.Base, {
// for backwards compatibility
Effect.MoveBy = function(element, toTop, toLeft) {
- return new Effect.Move(element,
+ return new Effect.Move(element,
Object.extend({ x: toLeft, y: toTop }, arguments[3] || { }));
};
@@ -414,15 +416,15 @@ Effect.Scale = Class.create(Effect.Base, {
setup: function() {
this.restoreAfterFinish = this.options.restoreAfterFinish || false;
this.elementPositioning = this.element.getStyle('position');
-
+
this.originalStyle = { };
['top','left','width','height','fontSize'].each( function(k) {
this.originalStyle[k] = this.element.style[k];
}.bind(this));
-
+
this.originalTop = this.element.offsetTop;
this.originalLeft = this.element.offsetLeft;
-
+
var fontSize = this.element.getStyle('font-size') || '100%';
['em','px','%','pt'].each( function(fontSizeType) {
if (fontSize.indexOf(fontSizeType)>0) {
@@ -430,9 +432,9 @@ Effect.Scale = Class.create(Effect.Base, {
this.fontSizeType = fontSizeType;
}
}.bind(this));
-
+
this.factor = (this.options.scaleTo - this.options.scaleFrom)/100;
-
+
this.dims = null;
if (this.options.scaleMode=='box')
this.dims = [this.element.offsetHeight, this.element.offsetWidth];
@@ -507,17 +509,16 @@ Effect.Highlight = Class.create(Effect.Base, {
Effect.ScrollTo = function(element) {
var options = arguments[1] || { },
- scrollOffsets = document.viewport.getScrollOffsets(),
- elementOffsets = $(element).cumulativeOffset(),
- max = (window.height || document.body.scrollHeight) - document.viewport.getHeight();
+ scrollOffsets = document.viewport.getScrollOffsets(),
+ elementOffsets = $(element).cumulativeOffset();
if (options.offset) elementOffsets[1] += options.offset;
return new Effect.Tween(null,
scrollOffsets.top,
- elementOffsets[1] > max ? max : elementOffsets[1],
+ elementOffsets[1],
options,
- function(p){ scrollTo(scrollOffsets.left, p.round()) }
+ function(p){ scrollTo(scrollOffsets.left, p.round()); }
);
};
@@ -529,9 +530,9 @@ Effect.Fade = function(element) {
var options = Object.extend({
from: element.getOpacity() || 1.0,
to: 0.0,
- afterFinishInternal: function(effect) {
+ afterFinishInternal: function(effect) {
if (effect.options.to!=0) return;
- effect.element.hide().setStyle({opacity: oldOpacity});
+ effect.element.hide().setStyle({opacity: oldOpacity});
}
}, arguments[1] || { });
return new Effect.Opacity(element,options);
@@ -547,15 +548,15 @@ Effect.Appear = function(element) {
effect.element.forceRerendering();
},
beforeSetup: function(effect) {
- effect.element.setOpacity(effect.options.from).show();
+ effect.element.setOpacity(effect.options.from).show();
}}, arguments[1] || { });
return new Effect.Opacity(element,options);
};
Effect.Puff = function(element) {
element = $(element);
- var oldStyle = {
- opacity: element.getInlineOpacity(),
+ var oldStyle = {
+ opacity: element.getInlineOpacity(),
position: element.getStyle('position'),
top: element.style.top,
left: element.style.left,
@@ -563,12 +564,12 @@ Effect.Puff = function(element) {
height: element.style.height
};
return new Effect.Parallel(
- [ new Effect.Scale(element, 200,
- { sync: true, scaleFromCenter: true, scaleContent: true, restoreAfterFinish: true }),
- new Effect.Opacity(element, { sync: true, to: 0.0 } ) ],
- Object.extend({ duration: 1.0,
+ [ new Effect.Scale(element, 200,
+ { sync: true, scaleFromCenter: true, scaleContent: true, restoreAfterFinish: true }),
+ new Effect.Opacity(element, { sync: true, to: 0.0 } ) ],
+ Object.extend({ duration: 1.0,
beforeSetupInternal: function(effect) {
- Position.absolutize(effect.effects[0].element)
+ Position.absolutize(effect.effects[0].element);
},
afterFinishInternal: function(effect) {
effect.effects[0].element.hide().setStyle(oldStyle); }
@@ -580,12 +581,12 @@ Effect.BlindUp = function(element) {
element = $(element);
element.makeClipping();
return new Effect.Scale(element, 0,
- Object.extend({ scaleContent: false,
- scaleX: false,
+ Object.extend({ scaleContent: false,
+ scaleX: false,
restoreAfterFinish: true,
afterFinishInternal: function(effect) {
effect.element.hide().undoClipping();
- }
+ }
}, arguments[1] || { })
);
};
@@ -593,15 +594,15 @@ Effect.BlindUp = function(element) {
Effect.BlindDown = function(element) {
element = $(element);
var elementDimensions = element.getDimensions();
- return new Effect.Scale(element, 100, Object.extend({
- scaleContent: false,
+ return new Effect.Scale(element, 100, Object.extend({
+ scaleContent: false,
scaleX: false,
scaleFrom: 0,
scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
restoreAfterFinish: true,
afterSetup: function(effect) {
- effect.element.makeClipping().setStyle({height: '0px'}).show();
- },
+ effect.element.makeClipping().setStyle({height: '0px'}).show();
+ },
afterFinishInternal: function(effect) {
effect.element.undoClipping();
}
@@ -616,16 +617,16 @@ Effect.SwitchOff = function(element) {
from: 0,
transition: Effect.Transitions.flicker,
afterFinishInternal: function(effect) {
- new Effect.Scale(effect.element, 1, {
+ new Effect.Scale(effect.element, 1, {
duration: 0.3, scaleFromCenter: true,
scaleX: false, scaleContent: false, restoreAfterFinish: true,
- beforeSetup: function(effect) {
+ beforeSetup: function(effect) {
effect.element.makePositioned().makeClipping();
},
afterFinishInternal: function(effect) {
effect.element.hide().undoClipping().undoPositioned().setStyle({opacity: oldOpacity});
}
- })
+ });
}
}, arguments[1] || { }));
};
@@ -637,16 +638,16 @@ Effect.DropOut = function(element) {
left: element.getStyle('left'),
opacity: element.getInlineOpacity() };
return new Effect.Parallel(
- [ new Effect.Move(element, {x: 0, y: 100, sync: true }),
+ [ new Effect.Move(element, {x: 0, y: 100, sync: true }),
new Effect.Opacity(element, { sync: true, to: 0.0 }) ],
Object.extend(
{ duration: 0.5,
beforeSetup: function(effect) {
- effect.effects[0].element.makePositioned();
+ effect.effects[0].element.makePositioned();
},
afterFinishInternal: function(effect) {
effect.effects[0].element.hide().undoPositioned().setStyle(oldStyle);
- }
+ }
}, arguments[1] || { }));
};
@@ -674,7 +675,7 @@ Effect.Shake = function(element) {
new Effect.Move(effect.element,
{ x: -distance, y: 0, duration: split, afterFinishInternal: function(effect) {
effect.element.undoPositioned().setStyle(oldStyle);
- }}) }}) }}) }}) }}) }});
+ }}); }}); }}); }}); }}); }});
};
Effect.SlideDown = function(element) {
@@ -682,9 +683,9 @@ Effect.SlideDown = function(element) {
// SlideDown need to have the content of the element wrapped in a container element with fixed height!
var oldInnerBottom = element.down().getStyle('bottom');
var elementDimensions = element.getDimensions();
- return new Effect.Scale(element, 100, Object.extend({
- scaleContent: false,
- scaleX: false,
+ return new Effect.Scale(element, 100, Object.extend({
+ scaleContent: false,
+ scaleX: false,
scaleFrom: window.opera ? 0 : 1,
scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
restoreAfterFinish: true,
@@ -692,11 +693,11 @@ Effect.SlideDown = function(element) {
effect.element.makePositioned();
effect.element.down().makePositioned();
if (window.opera) effect.element.setStyle({top: ''});
- effect.element.makeClipping().setStyle({height: '0px'}).show();
+ effect.element.makeClipping().setStyle({height: '0px'}).show();
},
afterUpdateInternal: function(effect) {
effect.element.down().setStyle({bottom:
- (effect.dims[0] - effect.element.clientHeight) + 'px' });
+ (effect.dims[0] - effect.element.clientHeight) + 'px' });
},
afterFinishInternal: function(effect) {
effect.element.undoClipping().undoPositioned();
@@ -710,8 +711,8 @@ Effect.SlideUp = function(element) {
var oldInnerBottom = element.down().getStyle('bottom');
var elementDimensions = element.getDimensions();
return new Effect.Scale(element, window.opera ? 0 : 1,
- Object.extend({ scaleContent: false,
- scaleX: false,
+ Object.extend({ scaleContent: false,
+ scaleX: false,
scaleMode: 'box',
scaleFrom: 100,
scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
@@ -721,7 +722,7 @@ Effect.SlideUp = function(element) {
effect.element.down().makePositioned();
if (window.opera) effect.element.setStyle({top: ''});
effect.element.makeClipping().show();
- },
+ },
afterUpdateInternal: function(effect) {
effect.element.down().setStyle({bottom:
(effect.dims[0] - effect.element.clientHeight) + 'px' });
@@ -734,15 +735,15 @@ Effect.SlideUp = function(element) {
);
};
-// Bug in opera makes the TD containing this element expand for a instance after finish
+// Bug in opera makes the TD containing this element expand for a instance after finish
Effect.Squish = function(element) {
- return new Effect.Scale(element, window.opera ? 1 : 0, {
+ return new Effect.Scale(element, window.opera ? 1 : 0, {
restoreAfterFinish: true,
beforeSetup: function(effect) {
- effect.element.makeClipping();
- },
+ effect.element.makeClipping();
+ },
afterFinishInternal: function(effect) {
- effect.element.hide().undoClipping();
+ effect.element.hide().undoClipping();
}
});
};
@@ -762,13 +763,13 @@ Effect.Grow = function(element) {
width: element.style.width,
opacity: element.getInlineOpacity() };
- var dims = element.getDimensions();
+ var dims = element.getDimensions();
var initialMoveX, initialMoveY;
var moveX, moveY;
-
+
switch (options.direction) {
case 'top-left':
- initialMoveX = initialMoveY = moveX = moveY = 0;
+ initialMoveX = initialMoveY = moveX = moveY = 0;
break;
case 'top-right':
initialMoveX = dims.width;
@@ -793,11 +794,11 @@ Effect.Grow = function(element) {
moveY = -dims.height / 2;
break;
}
-
+
return new Effect.Move(element, {
x: initialMoveX,
y: initialMoveY,
- duration: 0.01,
+ duration: 0.01,
beforeSetup: function(effect) {
effect.element.hide().makeClipping().makePositioned();
},
@@ -806,17 +807,17 @@ Effect.Grow = function(element) {
[ new Effect.Opacity(effect.element, { sync: true, to: 1.0, from: 0.0, transition: options.opacityTransition }),
new Effect.Move(effect.element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition }),
new Effect.Scale(effect.element, 100, {
- scaleMode: { originalHeight: dims.height, originalWidth: dims.width },
+ scaleMode: { originalHeight: dims.height, originalWidth: dims.width },
sync: true, scaleFrom: window.opera ? 1 : 0, transition: options.scaleTransition, restoreAfterFinish: true})
], Object.extend({
beforeSetup: function(effect) {
- effect.effects[0].element.setStyle({height: '0px'}).show();
+ effect.effects[0].element.setStyle({height: '0px'}).show();
},
afterFinishInternal: function(effect) {
- effect.effects[0].element.undoClipping().undoPositioned().setStyle(oldStyle);
+ effect.effects[0].element.undoClipping().undoPositioned().setStyle(oldStyle);
}
}, options)
- )
+ );
}
});
};
@@ -838,7 +839,7 @@ Effect.Shrink = function(element) {
var dims = element.getDimensions();
var moveX, moveY;
-
+
switch (options.direction) {
case 'top-left':
moveX = moveY = 0;
@@ -855,19 +856,19 @@ Effect.Shrink = function(element) {
moveX = dims.width;
moveY = dims.height;
break;
- case 'center':
+ case 'center':
moveX = dims.width / 2;
moveY = dims.height / 2;
break;
}
-
+
return new Effect.Parallel(
[ new Effect.Opacity(element, { sync: true, to: 0.0, from: 1.0, transition: options.opacityTransition }),
new Effect.Scale(element, window.opera ? 1 : 0, { sync: true, transition: options.scaleTransition, restoreAfterFinish: true}),
new Effect.Move(element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition })
- ], Object.extend({
+ ], Object.extend({
beforeStartInternal: function(effect) {
- effect.effects[0].element.makePositioned().makeClipping();
+ effect.effects[0].element.makePositioned().makeClipping();
},
afterFinishInternal: function(effect) {
effect.effects[0].element.hide().undoClipping().undoPositioned().setStyle(oldStyle); }
@@ -877,12 +878,14 @@ Effect.Shrink = function(element) {
Effect.Pulsate = function(element) {
element = $(element);
- var options = arguments[1] || { };
- var oldOpacity = element.getInlineOpacity();
- var transition = options.transition || Effect.Transitions.sinoidal;
- var reverser = function(pos){ return transition(1-Effect.Transitions.pulse(pos, options.pulses)) };
- reverser.bind(transition);
- return new Effect.Opacity(element,
+ var options = arguments[1] || { },
+ oldOpacity = element.getInlineOpacity(),
+ transition = options.transition || Effect.Transitions.linear,
+ reverser = function(pos){
+ return 1 - transition((-Math.cos((pos*(options.pulses||5)*2)*Math.PI)/2) + .5);
+ };
+
+ return new Effect.Opacity(element,
Object.extend(Object.extend({ duration: 2.0, from: 0,
afterFinishInternal: function(effect) { effect.element.setStyle({opacity: oldOpacity}); }
}, options), {transition: reverser}));
@@ -896,12 +899,12 @@ Effect.Fold = function(element) {
width: element.style.width,
height: element.style.height };
element.makeClipping();
- return new Effect.Scale(element, 5, Object.extend({
+ return new Effect.Scale(element, 5, Object.extend({
scaleContent: false,
scaleX: false,
afterFinishInternal: function(effect) {
- new Effect.Scale(element, 1, {
- scaleContent: false,
+ new Effect.Scale(element, 1, {
+ scaleContent: false,
scaleY: false,
afterFinishInternal: function(effect) {
effect.element.hide().undoClipping().setStyle(oldStyle);
@@ -916,7 +919,7 @@ Effect.Morph = Class.create(Effect.Base, {
var options = Object.extend({
style: { }
}, arguments[1] || { });
-
+
if (!Object.isString(options.style)) this.style = $H(options.style);
else {
if (options.style.include(':'))
@@ -934,18 +937,18 @@ Effect.Morph = Class.create(Effect.Base, {
effect.transforms.each(function(transform) {
effect.element.style[transform.style] = '';
});
- }
+ };
}
}
this.start(options);
},
-
+
setup: function(){
function parseColor(color){
if (!color || ['rgba(0, 0, 0, 0)','transparent'].include(color)) color = '#ffffff';
color = color.parseColor();
return $R(0,2).map(function(i){
- return parseInt( color.slice(i*2+1,i*2+3), 16 )
+ return parseInt( color.slice(i*2+1,i*2+3), 16 );
});
}
this.transforms = this.style.map(function(pair){
@@ -965,9 +968,9 @@ Effect.Morph = Class.create(Effect.Base, {
}
var originalValue = this.element.getStyle(property);
- return {
- style: property.camelize(),
- originalValue: unit=='color' ? parseColor(originalValue) : parseFloat(originalValue || 0),
+ return {
+ style: property.camelize(),
+ originalValue: unit=='color' ? parseColor(originalValue) : parseFloat(originalValue || 0),
targetValue: unit=='color' ? parseColor(value) : value,
unit: unit
};
@@ -978,13 +981,13 @@ Effect.Morph = Class.create(Effect.Base, {
transform.unit != 'color' &&
(isNaN(transform.originalValue) || isNaN(transform.targetValue))
)
- )
+ );
});
},
update: function(position) {
var style = { }, transform, i = this.transforms.length;
while(i--)
- style[(transform = this.transforms[i]).style] =
+ style[(transform = this.transforms[i]).style] =
transform.unit=='color' ? '#'+
(Math.round(transform.originalValue[0]+
(transform.targetValue[0]-transform.originalValue[0])*position)).toColorPart() +
@@ -993,7 +996,7 @@ Effect.Morph = Class.create(Effect.Base, {
(Math.round(transform.originalValue[2]+
(transform.targetValue[2]-transform.originalValue[2])*position)).toColorPart() :
(transform.originalValue +
- (transform.targetValue - transform.originalValue) * position).toFixed(3) +
+ (transform.targetValue - transform.originalValue) * position).toFixed(3) +
(transform.unit === null ? '' : transform.unit);
this.element.setStyle(style, true);
}
@@ -1030,7 +1033,7 @@ Effect.Transform = Class.create({
});
Element.CSS_PROPERTIES = $w(
- 'backgroundColor backgroundPosition borderBottomColor borderBottomStyle ' +
+ 'backgroundColor backgroundPosition borderBottomColor borderBottomStyle ' +
'borderBottomWidth borderLeftColor borderLeftStyle borderLeftWidth ' +
'borderRightColor borderRightStyle borderRightWidth borderSpacing ' +
'borderTopColor borderTopStyle borderTopWidth bottom clip color ' +
@@ -1039,7 +1042,7 @@ Element.CSS_PROPERTIES = $w(
'maxWidth minHeight minWidth opacity outlineColor outlineOffset ' +
'outlineWidth paddingBottom paddingLeft paddingRight paddingTop ' +
'right textIndent top width wordSpacing zIndex');
-
+
Element.CSS_LENGTH = /^(([\+\-]?[0-9\.]+)(em|ex|px|in|cm|mm|pt|pc|\%))|0$/;
String.__parseStyleElement = document.createElement('div');
@@ -1051,11 +1054,11 @@ String.prototype.parseStyle = function(){
String.__parseStyleElement.innerHTML = '<div style="' + this + '"></div>';
style = String.__parseStyleElement.childNodes[0].style;
}
-
+
Element.CSS_PROPERTIES.each(function(property){
- if (style[property]) styleRules.set(property, style[property]);
+ if (style[property]) styleRules.set(property, style[property]);
});
-
+
if (Prototype.Browser.IE && this.include('opacity'))
styleRules.set('opacity', this.match(/opacity:\s*((?:0|1)?(?:\.\d*)?)/)[1]);
@@ -1074,14 +1077,14 @@ if (document.defaultView && document.defaultView.getComputedStyle) {
Element.getStyles = function(element) {
element = $(element);
var css = element.currentStyle, styles;
- styles = Element.CSS_PROPERTIES.inject({ }, function(hash, property) {
- hash.set(property, css[property]);
- return hash;
+ styles = Element.CSS_PROPERTIES.inject({ }, function(results, property) {
+ results[property] = css[property];
+ return results;
});
- if (!styles.opacity) styles.set('opacity', element.getOpacity());
+ if (!styles.opacity) styles.opacity = element.getOpacity();
return styles;
};
-};
+}
Effect.Methods = {
morph: function(element, style) {
@@ -1090,7 +1093,7 @@ Effect.Methods = {
return element;
},
visualEffect: function(element, effect, options) {
- element = $(element)
+ element = $(element);
var s = effect.dasherize().camelize(), klass = s.charAt(0).toUpperCase() + s.substring(1);
new Effect[klass](element, options);
return element;
@@ -1104,17 +1107,17 @@ Effect.Methods = {
$w('fade appear grow shrink fold blindUp blindDown slideUp slideDown '+
'pulsate shake puff squish switchOff dropOut').each(
- function(effect) {
+ function(effect) {
Effect.Methods[effect] = function(element, options){
element = $(element);
Effect[effect.charAt(0).toUpperCase() + effect.substring(1)](element, options);
return element;
- }
+ };
}
);
-$w('getInlineOpacity forceRerendering setContentZoom collectTextNodes collectTextNodesIgnoreClass getStyles').each(
+$w('getInlineOpacity forceRerendering setContentZoom collectTextNodes collectTextNodesIgnoreClass getStyles').each(
function(f) { Effect.Methods[f] = Element[f]; }
);
-Element.addMethods(Effect.Methods);
+Element.addMethods(Effect.Methods); \ No newline at end of file
diff --git a/public/javascripts/prototype.js b/public/javascripts/prototype.js
index 546f9fe44..06249a6ae 100644
--- a/public/javascripts/prototype.js
+++ b/public/javascripts/prototype.js
@@ -1,5 +1,5 @@
-/* Prototype JavaScript framework, version 1.6.0.1
- * (c) 2005-2007 Sam Stephenson
+/* Prototype JavaScript framework, version 1.7_rc2
+ * (c) 2005-2010 Sam Stephenson
*
* Prototype is freely distributable under the terms of an MIT-style license.
* For details, see the Prototype web site: http://www.prototypejs.org/
@@ -7,29 +7,53 @@
*--------------------------------------------------------------------------*/
var Prototype = {
- Version: '1.6.0.1',
- Browser: {
- IE: !!(window.attachEvent && !window.opera),
- Opera: !!window.opera,
- WebKit: navigator.userAgent.indexOf('AppleWebKit/') > -1,
- Gecko: navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('KHTML') == -1,
- MobileSafari: !!navigator.userAgent.match(/Apple.*Mobile.*Safari/)
- },
+ Version: '1.7_rc2',
+
+ Browser: (function(){
+ var ua = navigator.userAgent;
+ var isOpera = Object.prototype.toString.call(window.opera) == '[object Opera]';
+ return {
+ IE: !!window.attachEvent && !isOpera,
+ Opera: isOpera,
+ WebKit: ua.indexOf('AppleWebKit/') > -1,
+ Gecko: ua.indexOf('Gecko') > -1 && ua.indexOf('KHTML') === -1,
+ MobileSafari: /Apple.*Mobile/.test(ua)
+ }
+ })(),
BrowserFeatures: {
XPath: !!document.evaluate,
- ElementExtensions: !!window.HTMLElement,
- SpecificElementExtensions:
- document.createElement('div').__proto__ &&
- document.createElement('div').__proto__ !==
- document.createElement('form').__proto__
+
+ SelectorsAPI: !!document.querySelector,
+
+ ElementExtensions: (function() {
+ var constructor = window.Element || window.HTMLElement;
+ return !!(constructor && constructor.prototype);
+ })(),
+ SpecificElementExtensions: (function() {
+ if (typeof window.HTMLDivElement !== 'undefined')
+ return true;
+
+ var div = document.createElement('div'),
+ form = document.createElement('form'),
+ isSupported = false;
+
+ if (div['__proto__'] && (div['__proto__'] !== form['__proto__'])) {
+ isSupported = true;
+ }
+
+ div = form = null;
+
+ return isSupported;
+ })()
},
ScriptFragment: '<script[^>]*>([\\S\\s]*?)<\/script>',
JSONFilter: /^\/\*-secure-([\s\S]*)\*\/\s*$/,
emptyFunction: function() { },
+
K: function(x) { return x }
};
@@ -37,9 +61,38 @@ if (Prototype.Browser.MobileSafari)
Prototype.BrowserFeatures.SpecificElementExtensions = false;
+var Abstract = { };
+
+
+var Try = {
+ these: function() {
+ var returnValue;
+
+ for (var i = 0, length = arguments.length; i < length; i++) {
+ var lambda = arguments[i];
+ try {
+ returnValue = lambda();
+ break;
+ } catch (e) { }
+ }
+
+ return returnValue;
+ }
+};
+
/* Based on Alex Arnell's inheritance implementation. */
-var Class = {
- create: function() {
+
+var Class = (function() {
+
+ var IS_DONTENUM_BUGGY = (function(){
+ for (var p in { toString: 1 }) {
+ if (p === 'toString') return false;
+ }
+ return true;
+ })();
+
+ function subclass() {};
+ function create() {
var parent = null, properties = $A(arguments);
if (Object.isFunction(properties[0]))
parent = properties.shift();
@@ -53,235 +106,374 @@ var Class = {
klass.subclasses = [];
if (parent) {
- var subclass = function() { };
subclass.prototype = parent.prototype;
klass.prototype = new subclass;
parent.subclasses.push(klass);
}
- for (var i = 0; i < properties.length; i++)
+ for (var i = 0, length = properties.length; i < length; i++)
klass.addMethods(properties[i]);
if (!klass.prototype.initialize)
klass.prototype.initialize = Prototype.emptyFunction;
klass.prototype.constructor = klass;
-
return klass;
}
-};
-Class.Methods = {
- addMethods: function(source) {
- var ancestor = this.superclass && this.superclass.prototype;
- var properties = Object.keys(source);
+ function addMethods(source) {
+ var ancestor = this.superclass && this.superclass.prototype,
+ properties = Object.keys(source);
- if (!Object.keys({ toString: true }).length)
- properties.push("toString", "valueOf");
+ if (IS_DONTENUM_BUGGY) {
+ if (source.toString != Object.prototype.toString)
+ properties.push("toString");
+ if (source.valueOf != Object.prototype.valueOf)
+ properties.push("valueOf");
+ }
for (var i = 0, length = properties.length; i < length; i++) {
var property = properties[i], value = source[property];
if (ancestor && Object.isFunction(value) &&
- value.argumentNames().first() == "$super") {
- var method = value, value = Object.extend((function(m) {
- return function() { return ancestor[m].apply(this, arguments) };
- })(property).wrap(method), {
- valueOf: function() { return method },
- toString: function() { return method.toString() }
- });
+ value.argumentNames()[0] == "$super") {
+ var method = value;
+ value = (function(m) {
+ return function() { return ancestor[m].apply(this, arguments); };
+ })(property).wrap(method);
+
+ value.valueOf = method.valueOf.bind(method);
+ value.toString = method.toString.bind(method);
}
this.prototype[property] = value;
}
return this;
}
-};
-var Abstract = { };
+ return {
+ create: create,
+ Methods: {
+ addMethods: addMethods
+ }
+ };
+})();
+(function() {
-Object.extend = function(destination, source) {
- for (var property in source)
- destination[property] = source[property];
- return destination;
-};
+ var _toString = Object.prototype.toString,
+ NULL_TYPE = 'Null',
+ UNDEFINED_TYPE = 'Undefined',
+ BOOLEAN_TYPE = 'Boolean',
+ NUMBER_TYPE = 'Number',
+ STRING_TYPE = 'String',
+ OBJECT_TYPE = 'Object',
+ BOOLEAN_CLASS = '[object Boolean]',
+ NUMBER_CLASS = '[object Number]',
+ STRING_CLASS = '[object String]',
+ ARRAY_CLASS = '[object Array]',
+ NATIVE_JSON_STRINGIFY_SUPPORT = window.JSON &&
+ typeof JSON.stringify === 'function' &&
+ JSON.stringify(0) === '0' &&
+ typeof JSON.stringify(Prototype.K) === 'undefined';
+
+ function Type(o) {
+ switch(o) {
+ case null: return NULL_TYPE;
+ case (void 0): return UNDEFINED_TYPE;
+ }
+ var type = typeof o;
+ switch(type) {
+ case 'boolean': return BOOLEAN_TYPE;
+ case 'number': return NUMBER_TYPE;
+ case 'string': return STRING_TYPE;
+ }
+ return OBJECT_TYPE;
+ }
-Object.extend(Object, {
- inspect: function(object) {
+ function extend(destination, source) {
+ for (var property in source)
+ destination[property] = source[property];
+ return destination;
+ }
+
+ function inspect(object) {
try {
- if (Object.isUndefined(object)) return 'undefined';
+ if (isUndefined(object)) return 'undefined';
if (object === null) return 'null';
- return object.inspect ? object.inspect() : object.toString();
+ return object.inspect ? object.inspect() : String(object);
} catch (e) {
if (e instanceof RangeError) return '...';
throw e;
}
- },
+ }
- toJSON: function(object) {
- var type = typeof object;
- switch (type) {
- case 'undefined':
- case 'function':
- case 'unknown': return;
- case 'boolean': return object.toString();
+ function toJSON(value) {
+ return Str('', { '': value }, []);
+ }
+
+ function Str(key, holder, stack) {
+ var value = holder[key],
+ type = typeof value;
+
+ if (Type(value) === OBJECT_TYPE && typeof value.toJSON === 'function') {
+ value = value.toJSON(key);
}
- if (object === null) return 'null';
- if (object.toJSON) return object.toJSON();
- if (Object.isElement(object)) return;
+ var _class = _toString.call(value);
- var results = [];
- for (var property in object) {
- var value = Object.toJSON(object[property]);
- if (!Object.isUndefined(value))
- results.push(property.toJSON() + ': ' + value);
+ switch (_class) {
+ case NUMBER_CLASS:
+ case BOOLEAN_CLASS:
+ case STRING_CLASS:
+ value = value.valueOf();
}
- return '{' + results.join(', ') + '}';
- },
+ switch (value) {
+ case null: return 'null';
+ case true: return 'true';
+ case false: return 'false';
+ }
+
+ type = typeof value;
+ switch (type) {
+ case 'string':
+ return value.inspect(true);
+ case 'number':
+ return isFinite(value) ? String(value) : 'null';
+ case 'object':
+
+ for (var i = 0, length = stack.length; i < length; i++) {
+ if (stack[i] === value) { throw new TypeError(); }
+ }
+ stack.push(value);
- toQueryString: function(object) {
+ var partial = [];
+ if (_class === ARRAY_CLASS) {
+ for (var i = 0, length = value.length; i < length; i++) {
+ var str = Str(i, value, stack);
+ partial.push(typeof str === 'undefined' ? 'null' : str);
+ }
+ partial = '[' + partial.join(',') + ']';
+ } else {
+ var keys = Object.keys(value);
+ for (var i = 0, length = keys.length; i < length; i++) {
+ var key = keys[i], str = Str(key, value, stack);
+ if (typeof str !== "undefined") {
+ partial.push(key.inspect(true)+ ':' + str);
+ }
+ }
+ partial = '{' + partial.join(',') + '}';
+ }
+ stack.pop();
+ return partial;
+ }
+ }
+
+ function stringify(object) {
+ return JSON.stringify(object);
+ }
+
+ function toQueryString(object) {
return $H(object).toQueryString();
- },
+ }
- toHTML: function(object) {
+ function toHTML(object) {
return object && object.toHTML ? object.toHTML() : String.interpret(object);
- },
+ }
- keys: function(object) {
- var keys = [];
- for (var property in object)
- keys.push(property);
- return keys;
- },
+ function keys(object) {
+ if (Type(object) !== OBJECT_TYPE) { throw new TypeError(); }
+ var results = [];
+ for (var property in object) {
+ if (object.hasOwnProperty(property)) {
+ results.push(property);
+ }
+ }
+ return results;
+ }
- values: function(object) {
- var values = [];
+ function values(object) {
+ var results = [];
for (var property in object)
- values.push(object[property]);
- return values;
- },
+ results.push(object[property]);
+ return results;
+ }
- clone: function(object) {
- return Object.extend({ }, object);
- },
+ function clone(object) {
+ return extend({ }, object);
+ }
- isElement: function(object) {
- return object && object.nodeType == 1;
- },
+ function isElement(object) {
+ return !!(object && object.nodeType == 1);
+ }
- isArray: function(object) {
- return object && object.constructor === Array;
- },
+ function isArray(object) {
+ return _toString.call(object) === ARRAY_CLASS;
+ }
+
+ var hasNativeIsArray = (typeof Array.isArray == 'function')
+ && Array.isArray([]) && !Array.isArray({});
- isHash: function(object) {
+ if (hasNativeIsArray) {
+ isArray = Array.isArray;
+ }
+
+ function isHash(object) {
return object instanceof Hash;
- },
+ }
- isFunction: function(object) {
- return typeof object == "function";
- },
+ function isFunction(object) {
+ return typeof object === "function";
+ }
- isString: function(object) {
- return typeof object == "string";
- },
+ function isString(object) {
+ return _toString.call(object) === STRING_CLASS;
+ }
- isNumber: function(object) {
- return typeof object == "number";
- },
+ function isNumber(object) {
+ return _toString.call(object) === NUMBER_CLASS;
+ }
- isUndefined: function(object) {
- return typeof object == "undefined";
+ function isUndefined(object) {
+ return typeof object === "undefined";
}
-});
-Object.extend(Function.prototype, {
- argumentNames: function() {
- var names = this.toString().match(/^[\s\(]*function[^(]*\((.*?)\)/)[1].split(",").invoke("strip");
+ extend(Object, {
+ extend: extend,
+ inspect: inspect,
+ toJSON: NATIVE_JSON_STRINGIFY_SUPPORT ? stringify : toJSON,
+ toQueryString: toQueryString,
+ toHTML: toHTML,
+ keys: Object.keys || keys,
+ values: values,
+ clone: clone,
+ isElement: isElement,
+ isArray: isArray,
+ isHash: isHash,
+ isFunction: isFunction,
+ isString: isString,
+ isNumber: isNumber,
+ isUndefined: isUndefined
+ });
+})();
+Object.extend(Function.prototype, (function() {
+ var slice = Array.prototype.slice;
+
+ function update(array, args) {
+ var arrayLength = array.length, length = args.length;
+ while (length--) array[arrayLength + length] = args[length];
+ return array;
+ }
+
+ function merge(array, args) {
+ array = slice.call(array, 0);
+ return update(array, args);
+ }
+
+ function argumentNames() {
+ var names = this.toString().match(/^[\s\(]*function[^(]*\(([^)]*)\)/)[1]
+ .replace(/\/\/.*?[\r\n]|\/\*(?:.|[\r\n])*?\*\//g, '')
+ .replace(/\s+/g, '').split(',');
return names.length == 1 && !names[0] ? [] : names;
- },
+ }
- bind: function() {
+ function bind(context) {
if (arguments.length < 2 && Object.isUndefined(arguments[0])) return this;
- var __method = this, args = $A(arguments), object = args.shift();
+ var __method = this, args = slice.call(arguments, 1);
return function() {
- return __method.apply(object, args.concat($A(arguments)));
+ var a = merge(args, arguments);
+ return __method.apply(context, a);
}
- },
+ }
- bindAsEventListener: function() {
- var __method = this, args = $A(arguments), object = args.shift();
+ function bindAsEventListener(context) {
+ var __method = this, args = slice.call(arguments, 1);
return function(event) {
- return __method.apply(object, [event || window.event].concat(args));
+ var a = update([event || window.event], args);
+ return __method.apply(context, a);
}
- },
+ }
- curry: function() {
+ function curry() {
if (!arguments.length) return this;
- var __method = this, args = $A(arguments);
+ var __method = this, args = slice.call(arguments, 0);
return function() {
- return __method.apply(this, args.concat($A(arguments)));
+ var a = merge(args, arguments);
+ return __method.apply(this, a);
}
- },
+ }
- delay: function() {
- var __method = this, args = $A(arguments), timeout = args.shift() * 1000;
+ function delay(timeout) {
+ var __method = this, args = slice.call(arguments, 1);
+ timeout = timeout * 1000;
return window.setTimeout(function() {
return __method.apply(__method, args);
}, timeout);
- },
+ }
+
+ function defer() {
+ var args = update([0.01], arguments);
+ return this.delay.apply(this, args);
+ }
- wrap: function(wrapper) {
+ function wrap(wrapper) {
var __method = this;
return function() {
- return wrapper.apply(this, [__method.bind(this)].concat($A(arguments)));
+ var a = update([__method.bind(this)], arguments);
+ return wrapper.apply(this, a);
}
- },
+ }
- methodize: function() {
+ function methodize() {
if (this._methodized) return this._methodized;
var __method = this;
return this._methodized = function() {
- return __method.apply(null, [this].concat($A(arguments)));
+ var a = update([this], arguments);
+ return __method.apply(null, a);
};
}
-});
-Function.prototype.defer = Function.prototype.delay.curry(0.01);
+ return {
+ argumentNames: argumentNames,
+ bind: bind,
+ bindAsEventListener: bindAsEventListener,
+ curry: curry,
+ delay: delay,
+ defer: defer,
+ wrap: wrap,
+ methodize: methodize
+ }
+})());
-Date.prototype.toJSON = function() {
- return '"' + this.getUTCFullYear() + '-' +
- (this.getUTCMonth() + 1).toPaddedString(2) + '-' +
- this.getUTCDate().toPaddedString(2) + 'T' +
- this.getUTCHours().toPaddedString(2) + ':' +
- this.getUTCMinutes().toPaddedString(2) + ':' +
- this.getUTCSeconds().toPaddedString(2) + 'Z"';
-};
-var Try = {
- these: function() {
- var returnValue;
- for (var i = 0, length = arguments.length; i < length; i++) {
- var lambda = arguments[i];
- try {
- returnValue = lambda();
- break;
- } catch (e) { }
- }
+(function(proto) {
- return returnValue;
+
+ function toISOString() {
+ return this.getUTCFullYear() + '-' +
+ (this.getUTCMonth() + 1).toPaddedString(2) + '-' +
+ this.getUTCDate().toPaddedString(2) + 'T' +
+ this.getUTCHours().toPaddedString(2) + ':' +
+ this.getUTCMinutes().toPaddedString(2) + ':' +
+ this.getUTCSeconds().toPaddedString(2) + 'Z';
}
-};
+
+
+ function toJSON() {
+ return this.toISOString();
+ }
+
+ if (!proto.toISOString) proto.toISOString = toISOString;
+ if (!proto.toJSON) proto.toJSON = toJSON;
+
+})(Date.prototype);
+
RegExp.prototype.match = RegExp.prototype.test;
RegExp.escape = function(str) {
return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1');
};
-
-/*--------------------------------------------------------------------------*/
-
var PeriodicalExecuter = Class.create({
initialize: function(callback, frequency) {
this.callback = callback;
@@ -310,8 +502,10 @@ var PeriodicalExecuter = Class.create({
try {
this.currentlyExecuting = true;
this.execute();
- } finally {
this.currentlyExecuting = false;
+ } catch(e) {
+ this.currentlyExecuting = false;
+ throw e;
}
}
}
@@ -330,10 +524,28 @@ Object.extend(String, {
}
});
-Object.extend(String.prototype, {
- gsub: function(pattern, replacement) {
+Object.extend(String.prototype, (function() {
+ var NATIVE_JSON_PARSE_SUPPORT = window.JSON &&
+ typeof JSON.parse === 'function' &&
+ JSON.parse('{"test": true}').test;
+
+ function prepareReplacement(replacement) {
+ if (Object.isFunction(replacement)) return replacement;
+ var template = new Template(replacement);
+ return function(match) { return template.evaluate(match) };
+ }
+
+ function gsub(pattern, replacement) {
var result = '', source = this, match;
- replacement = arguments.callee.prepareReplacement(replacement);
+ replacement = prepareReplacement(replacement);
+
+ if (Object.isString(pattern))
+ pattern = RegExp.escape(pattern);
+
+ if (!(pattern.length || pattern.source)) {
+ replacement = replacement('');
+ return replacement + source.split('').join(replacement) + replacement;
+ }
while (source.length > 0) {
if (match = source.match(pattern)) {
@@ -345,76 +557,72 @@ Object.extend(String.prototype, {
}
}
return result;
- },
+ }
- sub: function(pattern, replacement, count) {
- replacement = this.gsub.prepareReplacement(replacement);
+ function sub(pattern, replacement, count) {
+ replacement = prepareReplacement(replacement);
count = Object.isUndefined(count) ? 1 : count;
return this.gsub(pattern, function(match) {
if (--count < 0) return match[0];
return replacement(match);
});
- },
+ }
- scan: function(pattern, iterator) {
+ function scan(pattern, iterator) {
this.gsub(pattern, iterator);
return String(this);
- },
+ }
- truncate: function(length, truncation) {
+ function truncate(length, truncation) {
length = length || 30;
truncation = Object.isUndefined(truncation) ? '...' : truncation;
return this.length > length ?
this.slice(0, length - truncation.length) + truncation : String(this);
- },
+ }
- strip: function() {
+ function strip() {
return this.replace(/^\s+/, '').replace(/\s+$/, '');
- },
+ }
- stripTags: function() {
- return this.replace(/<\/?[^>]+>/gi, '');
- },
+ function stripTags() {
+ return this.replace(/<\w+(\s+("[^"]*"|'[^']*'|[^>])+)?>|<\/\w+>/gi, '');
+ }
- stripScripts: function() {
+ function stripScripts() {
return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), '');
- },
+ }
- extractScripts: function() {
- var matchAll = new RegExp(Prototype.ScriptFragment, 'img');
- var matchOne = new RegExp(Prototype.ScriptFragment, 'im');
+ function extractScripts() {
+ var matchAll = new RegExp(Prototype.ScriptFragment, 'img'),
+ matchOne = new RegExp(Prototype.ScriptFragment, 'im');
return (this.match(matchAll) || []).map(function(scriptTag) {
return (scriptTag.match(matchOne) || ['', ''])[1];
});
- },
+ }
- evalScripts: function() {
+ function evalScripts() {
return this.extractScripts().map(function(script) { return eval(script) });
- },
+ }
- escapeHTML: function() {
- var self = arguments.callee;
- self.text.data = this;
- return self.div.innerHTML;
- },
+ function escapeHTML() {
+ return this.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
+ }
+
+ function unescapeHTML() {
+ return this.stripTags().replace(/&lt;/g,'<').replace(/&gt;/g,'>').replace(/&amp;/g,'&');
+ }
- unescapeHTML: function() {
- var div = new Element('div');
- div.innerHTML = this.stripTags();
- return div.childNodes[0] ? (div.childNodes.length > 1 ?
- $A(div.childNodes).inject('', function(memo, node) { return memo+node.nodeValue }) :
- div.childNodes[0].nodeValue) : '';
- },
- toQueryParams: function(separator) {
+ function toQueryParams(separator) {
var match = this.strip().match(/([^?#]*)(#.*)?$/);
if (!match) return { };
return match[1].split(separator || '&').inject({ }, function(hash, pair) {
if ((pair = pair.split('='))[0]) {
- var key = decodeURIComponent(pair.shift());
- var value = pair.length > 1 ? pair.join('=') : pair[0];
+ var key = decodeURIComponent(pair.shift()),
+ value = pair.length > 1 ? pair.join('=') : pair[0];
+
if (value != undefined) value = decodeURIComponent(value);
if (key in hash) {
@@ -425,128 +633,144 @@ Object.extend(String.prototype, {
}
return hash;
});
- },
+ }
- toArray: function() {
+ function toArray() {
return this.split('');
- },
+ }
- succ: function() {
+ function succ() {
return this.slice(0, this.length - 1) +
String.fromCharCode(this.charCodeAt(this.length - 1) + 1);
- },
+ }
- times: function(count) {
+ function times(count) {
return count < 1 ? '' : new Array(count + 1).join(this);
- },
-
- camelize: function() {
- var parts = this.split('-'), len = parts.length;
- if (len == 1) return parts[0];
-
- var camelized = this.charAt(0) == '-'
- ? parts[0].charAt(0).toUpperCase() + parts[0].substring(1)
- : parts[0];
-
- for (var i = 1; i < len; i++)
- camelized += parts[i].charAt(0).toUpperCase() + parts[i].substring(1);
+ }
- return camelized;
- },
+ function camelize() {
+ return this.replace(/-+(.)?/g, function(match, chr) {
+ return chr ? chr.toUpperCase() : '';
+ });
+ }
- capitalize: function() {
+ function capitalize() {
return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase();
- },
+ }
- underscore: function() {
- return this.gsub(/::/, '/').gsub(/([A-Z]+)([A-Z][a-z])/,'#{1}_#{2}').gsub(/([a-z\d])([A-Z])/,'#{1}_#{2}').gsub(/-/,'_').toLowerCase();
- },
+ function underscore() {
+ return this.replace(/::/g, '/')
+ .replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2')
+ .replace(/([a-z\d])([A-Z])/g, '$1_$2')
+ .replace(/-/g, '_')
+ .toLowerCase();
+ }
- dasherize: function() {
- return this.gsub(/_/,'-');
- },
+ function dasherize() {
+ return this.replace(/_/g, '-');
+ }
- inspect: function(useDoubleQuotes) {
- var escapedString = this.gsub(/[\x00-\x1f\\]/, function(match) {
- var character = String.specialChar[match[0]];
- return character ? character : '\\u00' + match[0].charCodeAt().toPaddedString(2, 16);
+ function inspect(useDoubleQuotes) {
+ var escapedString = this.replace(/[\x00-\x1f\\]/g, function(character) {
+ if (character in String.specialChar) {
+ return String.specialChar[character];
+ }
+ return '\\u00' + character.charCodeAt().toPaddedString(2, 16);
});
if (useDoubleQuotes) return '"' + escapedString.replace(/"/g, '\\"') + '"';
return "'" + escapedString.replace(/'/g, '\\\'') + "'";
- },
-
- toJSON: function() {
- return this.inspect(true);
- },
+ }
- unfilterJSON: function(filter) {
- return this.sub(filter || Prototype.JSONFilter, '#{1}');
- },
+ function unfilterJSON(filter) {
+ return this.replace(filter || Prototype.JSONFilter, '$1');
+ }
- isJSON: function() {
+ function isJSON() {
var str = this;
if (str.blank()) return false;
- str = this.replace(/\\./g, '@').replace(/"[^"\\\n\r]*"/g, '');
- return (/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(str);
- },
+ str = str.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@');
+ str = str.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']');
+ str = str.replace(/(?:^|:|,)(?:\s*\[)+/g, '');
+ return (/^[\],:{}\s]*$/).test(str);
+ }
- evalJSON: function(sanitize) {
- var json = this.unfilterJSON();
+ function evalJSON(sanitize) {
+ var json = this.unfilterJSON(),
+ cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
+ if (cx.test(json)) {
+ json = json.replace(cx, function (a) {
+ return '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
+ });
+ }
try {
if (!sanitize || json.isJSON()) return eval('(' + json + ')');
} catch (e) { }
throw new SyntaxError('Badly formed JSON string: ' + this.inspect());
- },
+ }
- include: function(pattern) {
+ function parseJSON() {
+ var json = this.unfilterJSON();
+ return JSON.parse(json);
+ }
+
+ function include(pattern) {
return this.indexOf(pattern) > -1;
- },
+ }
- startsWith: function(pattern) {
- return this.indexOf(pattern) === 0;
- },
+ function startsWith(pattern) {
+ return this.lastIndexOf(pattern, 0) === 0;
+ }
- endsWith: function(pattern) {
+ function endsWith(pattern) {
var d = this.length - pattern.length;
- return d >= 0 && this.lastIndexOf(pattern) === d;
- },
+ return d >= 0 && this.indexOf(pattern, d) === d;
+ }
- empty: function() {
+ function empty() {
return this == '';
- },
+ }
- blank: function() {
+ function blank() {
return /^\s*$/.test(this);
- },
-
- interpolate: function(object, pattern) {
- return new Template(this, pattern).evaluate(object);
}
-});
-if (Prototype.Browser.WebKit || Prototype.Browser.IE) Object.extend(String.prototype, {
- escapeHTML: function() {
- return this.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
- },
- unescapeHTML: function() {
- return this.replace(/&amp;/g,'&').replace(/&lt;/g,'<').replace(/&gt;/g,'>');
+ function interpolate(object, pattern) {
+ return new Template(this, pattern).evaluate(object);
}
-});
-
-String.prototype.gsub.prepareReplacement = function(replacement) {
- if (Object.isFunction(replacement)) return replacement;
- var template = new Template(replacement);
- return function(match) { return template.evaluate(match) };
-};
-String.prototype.parseQuery = String.prototype.toQueryParams;
-
-Object.extend(String.prototype.escapeHTML, {
- div: document.createElement('div'),
- text: document.createTextNode('')
-});
-
-with (String.prototype.escapeHTML) div.appendChild(text);
+ return {
+ gsub: gsub,
+ sub: sub,
+ scan: scan,
+ truncate: truncate,
+ strip: String.prototype.trim || strip,
+ stripTags: stripTags,
+ stripScripts: stripScripts,
+ extractScripts: extractScripts,
+ evalScripts: evalScripts,
+ escapeHTML: escapeHTML,
+ unescapeHTML: unescapeHTML,
+ toQueryParams: toQueryParams,
+ parseQuery: toQueryParams,
+ toArray: toArray,
+ succ: succ,
+ times: times,
+ camelize: camelize,
+ capitalize: capitalize,
+ underscore: underscore,
+ dasherize: dasherize,
+ inspect: inspect,
+ unfilterJSON: unfilterJSON,
+ isJSON: isJSON,
+ evalJSON: NATIVE_JSON_PARSE_SUPPORT ? parseJSON : evalJSON,
+ include: include,
+ startsWith: startsWith,
+ endsWith: endsWith,
+ empty: empty,
+ blank: blank,
+ interpolate: interpolate
+ };
+})());
var Template = Class.create({
initialize: function(template, pattern) {
@@ -555,22 +779,23 @@ var Template = Class.create({
},
evaluate: function(object) {
- if (Object.isFunction(object.toTemplateReplacements))
+ if (object && Object.isFunction(object.toTemplateReplacements))
object = object.toTemplateReplacements();
return this.template.gsub(this.pattern, function(match) {
- if (object == null) return '';
+ if (object == null) return (match[1] + '');
var before = match[1] || '';
if (before == '\\') return match[2];
- var ctx = object, expr = match[3];
- var pattern = /^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/;
+ var ctx = object, expr = match[3],
+ pattern = /^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/;
+
match = pattern.exec(expr);
if (match == null) return before;
while (match != null) {
- var comp = match[1].startsWith('[') ? match[2].gsub('\\\\]', ']') : match[1];
+ var comp = match[1].startsWith('[') ? match[2].replace(/\\\\]/g, ']') : match[1];
ctx = ctx[comp];
if (null == ctx || '' == match[3]) break;
expr = expr.substring('[' == match[3] ? match[1].length : match[0].length);
@@ -578,101 +803,98 @@ var Template = Class.create({
}
return before + String.interpret(ctx);
- }.bind(this));
+ });
}
});
Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/;
var $break = { };
-var Enumerable = {
- each: function(iterator, context) {
+var Enumerable = (function() {
+ function each(iterator, context) {
var index = 0;
- iterator = iterator.bind(context);
try {
this._each(function(value) {
- iterator(value, index++);
+ iterator.call(context, value, index++);
});
} catch (e) {
if (e != $break) throw e;
}
return this;
- },
+ }
- eachSlice: function(number, iterator, context) {
- iterator = iterator ? iterator.bind(context) : Prototype.K;
+ function eachSlice(number, iterator, context) {
var index = -number, slices = [], array = this.toArray();
+ if (number < 1) return array;
while ((index += number) < array.length)
slices.push(array.slice(index, index+number));
return slices.collect(iterator, context);
- },
+ }
- all: function(iterator, context) {
- iterator = iterator ? iterator.bind(context) : Prototype.K;
+ function all(iterator, context) {
+ iterator = iterator || Prototype.K;
var result = true;
this.each(function(value, index) {
- result = result && !!iterator(value, index);
+ result = result && !!iterator.call(context, value, index);
if (!result) throw $break;
});
return result;
- },
+ }
- any: function(iterator, context) {
- iterator = iterator ? iterator.bind(context) : Prototype.K;
+ function any(iterator, context) {
+ iterator = iterator || Prototype.K;
var result = false;
this.each(function(value, index) {
- if (result = !!iterator(value, index))
+ if (result = !!iterator.call(context, value, index))
throw $break;
});
return result;
- },
+ }
- collect: function(iterator, context) {
- iterator = iterator ? iterator.bind(context) : Prototype.K;
+ function collect(iterator, context) {
+ iterator = iterator || Prototype.K;
var results = [];
this.each(function(value, index) {
- results.push(iterator(value, index));
+ results.push(iterator.call(context, value, index));
});
return results;
- },
+ }
- detect: function(iterator, context) {
- iterator = iterator.bind(context);
+ function detect(iterator, context) {
var result;
this.each(function(value, index) {
- if (iterator(value, index)) {
+ if (iterator.call(context, value, index)) {
result = value;
throw $break;
}
});
return result;
- },
+ }
- findAll: function(iterator, context) {
- iterator = iterator.bind(context);
+ function findAll(iterator, context) {
var results = [];
this.each(function(value, index) {
- if (iterator(value, index))
+ if (iterator.call(context, value, index))
results.push(value);
});
return results;
- },
+ }
- grep: function(filter, iterator, context) {
- iterator = iterator ? iterator.bind(context) : Prototype.K;
+ function grep(filter, iterator, context) {
+ iterator = iterator || Prototype.K;
var results = [];
if (Object.isString(filter))
- filter = new RegExp(filter);
+ filter = new RegExp(RegExp.escape(filter));
this.each(function(value, index) {
if (filter.match(value))
- results.push(iterator(value, index));
+ results.push(iterator.call(context, value, index));
});
return results;
- },
+ }
- include: function(object) {
+ function include(object) {
if (Object.isFunction(this.indexOf))
if (this.indexOf(object) != -1) return true;
@@ -684,96 +906,96 @@ var Enumerable = {
}
});
return found;
- },
+ }
- inGroupsOf: function(number, fillWith) {
+ function inGroupsOf(number, fillWith) {
fillWith = Object.isUndefined(fillWith) ? null : fillWith;
return this.eachSlice(number, function(slice) {
while(slice.length < number) slice.push(fillWith);
return slice;
});
- },
+ }
- inject: function(memo, iterator, context) {
- iterator = iterator.bind(context);
+ function inject(memo, iterator, context) {
this.each(function(value, index) {
- memo = iterator(memo, value, index);
+ memo = iterator.call(context, memo, value, index);
});
return memo;
- },
+ }
- invoke: function(method) {
+ function invoke(method) {
var args = $A(arguments).slice(1);
return this.map(function(value) {
return value[method].apply(value, args);
});
- },
+ }
- max: function(iterator, context) {
- iterator = iterator ? iterator.bind(context) : Prototype.K;
+ function max(iterator, context) {
+ iterator = iterator || Prototype.K;
var result;
this.each(function(value, index) {
- value = iterator(value, index);
+ value = iterator.call(context, value, index);
if (result == null || value >= result)
result = value;
});
return result;
- },
+ }
- min: function(iterator, context) {
- iterator = iterator ? iterator.bind(context) : Prototype.K;
+ function min(iterator, context) {
+ iterator = iterator || Prototype.K;
var result;
this.each(function(value, index) {
- value = iterator(value, index);
+ value = iterator.call(context, value, index);
if (result == null || value < result)
result = value;
});
return result;
- },
+ }
- partition: function(iterator, context) {
- iterator = iterator ? iterator.bind(context) : Prototype.K;
+ function partition(iterator, context) {
+ iterator = iterator || Prototype.K;
var trues = [], falses = [];
this.each(function(value, index) {
- (iterator(value, index) ?
+ (iterator.call(context, value, index) ?
trues : falses).push(value);
});
return [trues, falses];
- },
+ }
- pluck: function(property) {
+ function pluck(property) {
var results = [];
this.each(function(value) {
results.push(value[property]);
});
return results;
- },
+ }
- reject: function(iterator, context) {
- iterator = iterator.bind(context);
+ function reject(iterator, context) {
var results = [];
this.each(function(value, index) {
- if (!iterator(value, index))
+ if (!iterator.call(context, value, index))
results.push(value);
});
return results;
- },
+ }
- sortBy: function(iterator, context) {
- iterator = iterator.bind(context);
+ function sortBy(iterator, context) {
return this.map(function(value, index) {
- return {value: value, criteria: iterator(value, index)};
+ return {
+ value: value,
+ criteria: iterator.call(context, value, index)
+ };
}).sort(function(left, right) {
var a = left.criteria, b = right.criteria;
return a < b ? -1 : a > b ? 1 : 0;
}).pluck('value');
- },
+ }
- toArray: function() {
+ function toArray() {
return this.map();
- },
+ }
- zip: function() {
+ function zip() {
var iterator = Prototype.K, args = $A(arguments);
if (Object.isFunction(args.last()))
iterator = args.pop();
@@ -782,330 +1004,409 @@ var Enumerable = {
return this.map(function(value, index) {
return iterator(collections.pluck(index));
});
- },
+ }
- size: function() {
+ function size() {
return this.toArray().length;
- },
+ }
- inspect: function() {
+ function inspect() {
return '#<Enumerable:' + this.toArray().inspect() + '>';
}
-};
-Object.extend(Enumerable, {
- map: Enumerable.collect,
- find: Enumerable.detect,
- select: Enumerable.findAll,
- filter: Enumerable.findAll,
- member: Enumerable.include,
- entries: Enumerable.toArray,
- every: Enumerable.all,
- some: Enumerable.any
-});
+
+
+
+
+
+
+
+
+ return {
+ each: each,
+ eachSlice: eachSlice,
+ all: all,
+ every: all,
+ any: any,
+ some: any,
+ collect: collect,
+ map: collect,
+ detect: detect,
+ findAll: findAll,
+ select: findAll,
+ filter: findAll,
+ grep: grep,
+ include: include,
+ member: include,
+ inGroupsOf: inGroupsOf,
+ inject: inject,
+ invoke: invoke,
+ max: max,
+ min: min,
+ partition: partition,
+ pluck: pluck,
+ reject: reject,
+ sortBy: sortBy,
+ toArray: toArray,
+ entries: toArray,
+ zip: zip,
+ size: size,
+ inspect: inspect,
+ find: detect
+ };
+})();
+
function $A(iterable) {
if (!iterable) return [];
- if (iterable.toArray) return iterable.toArray();
- var length = iterable.length, results = new Array(length);
+ if ('toArray' in Object(iterable)) return iterable.toArray();
+ var length = iterable.length || 0, results = new Array(length);
while (length--) results[length] = iterable[length];
return results;
}
-if (Prototype.Browser.WebKit) {
- function $A(iterable) {
- if (!iterable) return [];
- if (!(Object.isFunction(iterable) && iterable == '[object NodeList]') &&
- iterable.toArray) return iterable.toArray();
- var length = iterable.length, results = new Array(length);
- while (length--) results[length] = iterable[length];
- return results;
- }
+
+function $w(string) {
+ if (!Object.isString(string)) return [];
+ string = string.strip();
+ return string ? string.split(/\s+/) : [];
}
Array.from = $A;
-Object.extend(Array.prototype, Enumerable);
-if (!Array.prototype._reverse) Array.prototype._reverse = Array.prototype.reverse;
+(function() {
+ var arrayProto = Array.prototype,
+ slice = arrayProto.slice,
+ _each = arrayProto.forEach; // use native browser JS 1.6 implementation if available
-Object.extend(Array.prototype, {
- _each: function(iterator) {
+ function each(iterator) {
for (var i = 0, length = this.length; i < length; i++)
iterator(this[i]);
- },
+ }
+ if (!_each) _each = each;
- clear: function() {
+ function clear() {
this.length = 0;
return this;
- },
+ }
- first: function() {
+ function first() {
return this[0];
- },
+ }
- last: function() {
+ function last() {
return this[this.length - 1];
- },
+ }
- compact: function() {
+ function compact() {
return this.select(function(value) {
return value != null;
});
- },
+ }
- flatten: function() {
+ function flatten() {
return this.inject([], function(array, value) {
- return array.concat(Object.isArray(value) ?
- value.flatten() : [value]);
+ if (Object.isArray(value))
+ return array.concat(value.flatten());
+ array.push(value);
+ return array;
});
- },
+ }
- without: function() {
- var values = $A(arguments);
+ function without() {
+ var values = slice.call(arguments, 0);
return this.select(function(value) {
return !values.include(value);
});
- },
-
- reverse: function(inline) {
- return (inline !== false ? this : this.toArray())._reverse();
- },
+ }
- reduce: function() {
- return this.length > 1 ? this : this[0];
- },
+ function reverse(inline) {
+ return (inline === false ? this.toArray() : this)._reverse();
+ }
- uniq: function(sorted) {
+ function uniq(sorted) {
return this.inject([], function(array, value, index) {
if (0 == index || (sorted ? array.last() != value : !array.include(value)))
array.push(value);
return array;
});
- },
+ }
- intersect: function(array) {
+ function intersect(array) {
return this.uniq().findAll(function(item) {
return array.detect(function(value) { return item === value });
});
- },
+ }
- clone: function() {
- return [].concat(this);
- },
- size: function() {
+ function clone() {
+ return slice.call(this, 0);
+ }
+
+ function size() {
return this.length;
- },
+ }
- inspect: function() {
+ function inspect() {
return '[' + this.map(Object.inspect).join(', ') + ']';
- },
-
- toJSON: function() {
- var results = [];
- this.each(function(object) {
- var value = Object.toJSON(object);
- if (!Object.isUndefined(value)) results.push(value);
- });
- return '[' + results.join(', ') + ']';
}
-});
-
-// use native browser JS 1.6 implementation if available
-if (Object.isFunction(Array.prototype.forEach))
- Array.prototype._each = Array.prototype.forEach;
-
-if (!Array.prototype.indexOf) Array.prototype.indexOf = function(item, i) {
- i || (i = 0);
- var length = this.length;
- if (i < 0) i = length + i;
- for (; i < length; i++)
- if (this[i] === item) return i;
- return -1;
-};
-
-if (!Array.prototype.lastIndexOf) Array.prototype.lastIndexOf = function(item, i) {
- i = isNaN(i) ? this.length : (i < 0 ? this.length + i : i) + 1;
- var n = this.slice(0, i).reverse().indexOf(item);
- return (n < 0) ? n : i - n - 1;
-};
-Array.prototype.toArray = Array.prototype.clone;
+ function indexOf(item, i) {
+ i || (i = 0);
+ var length = this.length;
+ if (i < 0) i = length + i;
+ for (; i < length; i++)
+ if (this[i] === item) return i;
+ return -1;
+ }
-function $w(string) {
- if (!Object.isString(string)) return [];
- string = string.strip();
- return string ? string.split(/\s+/) : [];
-}
+ function lastIndexOf(item, i) {
+ i = isNaN(i) ? this.length : (i < 0 ? this.length + i : i) + 1;
+ var n = this.slice(0, i).reverse().indexOf(item);
+ return (n < 0) ? n : i - n - 1;
+ }
-if (Prototype.Browser.Opera){
- Array.prototype.concat = function() {
- var array = [];
- for (var i = 0, length = this.length; i < length; i++) array.push(this[i]);
+ function concat() {
+ var array = slice.call(this, 0), item;
for (var i = 0, length = arguments.length; i < length; i++) {
- if (Object.isArray(arguments[i])) {
- for (var j = 0, arrayLength = arguments[i].length; j < arrayLength; j++)
- array.push(arguments[i][j]);
+ item = arguments[i];
+ if (Object.isArray(item) && !('callee' in item)) {
+ for (var j = 0, arrayLength = item.length; j < arrayLength; j++)
+ array.push(item[j]);
} else {
- array.push(arguments[i]);
+ array.push(item);
}
}
return array;
- };
-}
-Object.extend(Number.prototype, {
- toColorPart: function() {
- return this.toPaddedString(2, 16);
- },
-
- succ: function() {
- return this + 1;
- },
+ }
- times: function(iterator) {
- $R(0, this, true).each(iterator);
- return this;
- },
+ Object.extend(arrayProto, Enumerable);
+
+ if (!arrayProto._reverse)
+ arrayProto._reverse = arrayProto.reverse;
+
+ Object.extend(arrayProto, {
+ _each: _each,
+ clear: clear,
+ first: first,
+ last: last,
+ compact: compact,
+ flatten: flatten,
+ without: without,
+ reverse: reverse,
+ uniq: uniq,
+ intersect: intersect,
+ clone: clone,
+ toArray: clone,
+ size: size,
+ inspect: inspect
+ });
- toPaddedString: function(length, radix) {
- var string = this.toString(radix || 10);
- return '0'.times(length - string.length) + string;
- },
+ var CONCAT_ARGUMENTS_BUGGY = (function() {
+ return [].concat(arguments)[0][0] !== 1;
+ })(1,2)
- toJSON: function() {
- return isFinite(this) ? this.toString() : 'null';
- }
-});
+ if (CONCAT_ARGUMENTS_BUGGY) arrayProto.concat = concat;
-$w('abs round ceil floor').each(function(method){
- Number.prototype[method] = Math[method].methodize();
-});
+ if (!arrayProto.indexOf) arrayProto.indexOf = indexOf;
+ if (!arrayProto.lastIndexOf) arrayProto.lastIndexOf = lastIndexOf;
+})();
function $H(object) {
return new Hash(object);
};
var Hash = Class.create(Enumerable, (function() {
-
- function toQueryPair(key, value) {
- if (Object.isUndefined(value)) return key;
- return key + '=' + encodeURIComponent(String.interpret(value));
+ function initialize(object) {
+ this._object = Object.isHash(object) ? object.toObject() : Object.clone(object);
}
- return {
- initialize: function(object) {
- this._object = Object.isHash(object) ? object.toObject() : Object.clone(object);
- },
- _each: function(iterator) {
- for (var key in this._object) {
- var value = this._object[key], pair = [key, value];
- pair.key = key;
- pair.value = value;
- iterator(pair);
- }
- },
+ function _each(iterator) {
+ for (var key in this._object) {
+ var value = this._object[key], pair = [key, value];
+ pair.key = key;
+ pair.value = value;
+ iterator(pair);
+ }
+ }
- set: function(key, value) {
- return this._object[key] = value;
- },
+ function set(key, value) {
+ return this._object[key] = value;
+ }
- get: function(key) {
+ function get(key) {
+ if (this._object[key] !== Object.prototype[key])
return this._object[key];
- },
+ }
- unset: function(key) {
- var value = this._object[key];
- delete this._object[key];
- return value;
- },
+ function unset(key) {
+ var value = this._object[key];
+ delete this._object[key];
+ return value;
+ }
- toObject: function() {
- return Object.clone(this._object);
- },
+ function toObject() {
+ return Object.clone(this._object);
+ }
- keys: function() {
- return this.pluck('key');
- },
- values: function() {
- return this.pluck('value');
- },
- index: function(value) {
- var match = this.detect(function(pair) {
- return pair.value === value;
- });
- return match && match.key;
- },
+ function keys() {
+ return this.pluck('key');
+ }
- merge: function(object) {
- return this.clone().update(object);
- },
+ function values() {
+ return this.pluck('value');
+ }
- update: function(object) {
- return new Hash(object).inject(this, function(result, pair) {
- result.set(pair.key, pair.value);
- return result;
- });
- },
+ function index(value) {
+ var match = this.detect(function(pair) {
+ return pair.value === value;
+ });
+ return match && match.key;
+ }
- toQueryString: function() {
- return this.map(function(pair) {
- var key = encodeURIComponent(pair.key), values = pair.value;
+ function merge(object) {
+ return this.clone().update(object);
+ }
- if (values && typeof values == 'object') {
- if (Object.isArray(values))
- return values.map(toQueryPair.curry(key)).join('&');
- }
- return toQueryPair(key, values);
- }).join('&');
- },
+ function update(object) {
+ return new Hash(object).inject(this, function(result, pair) {
+ result.set(pair.key, pair.value);
+ return result;
+ });
+ }
- inspect: function() {
- return '#<Hash:{' + this.map(function(pair) {
- return pair.map(Object.inspect).join(': ');
- }).join(', ') + '}>';
- },
+ function toQueryPair(key, value) {
+ if (Object.isUndefined(value)) return key;
+ return key + '=' + encodeURIComponent(String.interpret(value));
+ }
- toJSON: function() {
- return Object.toJSON(this.toObject());
- },
+ function toQueryString() {
+ return this.inject([], function(results, pair) {
+ var key = encodeURIComponent(pair.key), values = pair.value;
- clone: function() {
- return new Hash(this);
- }
+ if (values && typeof values == 'object') {
+ if (Object.isArray(values))
+ return results.concat(values.map(toQueryPair.curry(key)));
+ } else results.push(toQueryPair(key, values));
+ return results;
+ }).join('&');
+ }
+
+ function inspect() {
+ return '#<Hash:{' + this.map(function(pair) {
+ return pair.map(Object.inspect).join(': ');
+ }).join(', ') + '}>';
+ }
+
+ function clone() {
+ return new Hash(this);
}
+
+ return {
+ initialize: initialize,
+ _each: _each,
+ set: set,
+ get: get,
+ unset: unset,
+ toObject: toObject,
+ toTemplateReplacements: toObject,
+ keys: keys,
+ values: values,
+ index: index,
+ merge: merge,
+ update: update,
+ toQueryString: toQueryString,
+ inspect: inspect,
+ toJSON: toObject,
+ clone: clone
+ };
})());
-Hash.prototype.toTemplateReplacements = Hash.prototype.toObject;
Hash.from = $H;
-var ObjectRange = Class.create(Enumerable, {
- initialize: function(start, end, exclusive) {
+Object.extend(Number.prototype, (function() {
+ function toColorPart() {
+ return this.toPaddedString(2, 16);
+ }
+
+ function succ() {
+ return this + 1;
+ }
+
+ function times(iterator, context) {
+ $R(0, this, true).each(iterator, context);
+ return this;
+ }
+
+ function toPaddedString(length, radix) {
+ var string = this.toString(radix || 10);
+ return '0'.times(length - string.length) + string;
+ }
+
+ function abs() {
+ return Math.abs(this);
+ }
+
+ function round() {
+ return Math.round(this);
+ }
+
+ function ceil() {
+ return Math.ceil(this);
+ }
+
+ function floor() {
+ return Math.floor(this);
+ }
+
+ return {
+ toColorPart: toColorPart,
+ succ: succ,
+ times: times,
+ toPaddedString: toPaddedString,
+ abs: abs,
+ round: round,
+ ceil: ceil,
+ floor: floor
+ };
+})());
+
+function $R(start, end, exclusive) {
+ return new ObjectRange(start, end, exclusive);
+}
+
+var ObjectRange = Class.create(Enumerable, (function() {
+ function initialize(start, end, exclusive) {
this.start = start;
this.end = end;
this.exclusive = exclusive;
- },
+ }
- _each: function(iterator) {
+ function _each(iterator) {
var value = this.start;
while (this.include(value)) {
iterator(value);
value = value.succ();
}
- },
+ }
- include: function(value) {
+ function include(value) {
if (value < this.start)
return false;
if (this.exclusive)
return value < this.end;
return value <= this.end;
}
-});
-var $R = function(start, end, exclusive) {
- return new ObjectRange(start, end, exclusive);
-};
+ return {
+ initialize: initialize,
+ _each: _each,
+ include: include
+ };
+})());
+
+
var Ajax = {
getTransport: function() {
@@ -1152,7 +1453,6 @@ Ajax.Responders.register({
onCreate: function() { Ajax.activeRequestCount++ },
onComplete: function() { Ajax.activeRequestCount-- }
});
-
Ajax.Base = Class.create({
initialize: function(options) {
this.options = {
@@ -1174,7 +1474,6 @@ Ajax.Base = Class.create({
this.options.parameters = this.options.parameters.toObject();
}
});
-
Ajax.Request = Class.create(Ajax.Base, {
_complete: false,
@@ -1190,7 +1489,6 @@ Ajax.Request = Class.create(Ajax.Base, {
var params = Object.clone(this.options.parameters);
if (!['get', 'post'].include(this.method)) {
- // simulate other verbs over post
params['_method'] = this.method;
this.method = 'post';
}
@@ -1198,7 +1496,6 @@ Ajax.Request = Class.create(Ajax.Base, {
this.parameters = params;
if (params = Object.toQueryString(params)) {
- // when GET, append parameters to URL
if (this.method == 'get')
this.url += (this.url.include('?') ? '&' : '?') + params;
else if (/Konqueror|Safari|KHTML/.test(navigator.userAgent))
@@ -1257,7 +1554,6 @@ Ajax.Request = Class.create(Ajax.Base, {
headers['Connection'] = 'close';
}
- // user-defined headers
if (typeof this.options.requestHeaders == 'object') {
var extras = this.options.requestHeaders;
@@ -1298,7 +1594,7 @@ Ajax.Request = Class.create(Ajax.Base, {
var contentType = response.getHeader('Content-type');
if (this.options.evalJS == 'force'
- || (this.options.evalJS && contentType
+ || (this.options.evalJS && this.isSameOrigin() && contentType
&& contentType.match(/^\s*(text|application)\/(x-)?(java|ecma)script(;.*)?\s*$/i)))
this.evalResponse();
}
@@ -1311,15 +1607,23 @@ Ajax.Request = Class.create(Ajax.Base, {
}
if (state == 'Complete') {
- // avoid memory leak in MSIE: clean up
this.transport.onreadystatechange = Prototype.emptyFunction;
}
},
+ isSameOrigin: function() {
+ var m = this.url.match(/^\s*https?:\/\/[^\/]*/);
+ return !m || (m[0] == '#{protocol}//#{domain}#{port}'.interpolate({
+ protocol: location.protocol,
+ domain: document.domain,
+ port: location.port ? ':' + location.port : ''
+ }));
+ },
+
getHeader: function(name) {
try {
- return this.transport.getResponseHeader(name);
- } catch (e) { return null }
+ return this.transport.getResponseHeader(name) || null;
+ } catch (e) { return null; }
},
evalResponse: function() {
@@ -1339,20 +1643,27 @@ Ajax.Request = Class.create(Ajax.Base, {
Ajax.Request.Events =
['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];
+
+
+
+
+
+
+
Ajax.Response = Class.create({
initialize: function(request){
this.request = request;
var transport = this.transport = request.transport,
readyState = this.readyState = transport.readyState;
- if((readyState > 2 && !Prototype.Browser.IE) || readyState == 4) {
+ if ((readyState > 2 && !Prototype.Browser.IE) || readyState == 4) {
this.status = this.getStatus();
this.statusText = this.getStatusText();
this.responseText = String.interpret(transport.responseText);
this.headerJSON = this._getHeaderJSON();
}
- if(readyState == 4) {
+ if (readyState == 4) {
var xml = transport.responseXML;
this.responseXML = Object.isUndefined(xml) ? null : xml;
this.responseJSON = this._getResponseJSON();
@@ -1360,6 +1671,7 @@ Ajax.Response = Class.create({
},
status: 0,
+
statusText: '',
getStatus: Ajax.Request.prototype.getStatus,
@@ -1391,7 +1703,8 @@ Ajax.Response = Class.create({
if (!json) return null;
json = decodeURIComponent(escape(json));
try {
- return json.evalJSON(this.request.options.sanitizeJSON);
+ return json.evalJSON(this.request.options.sanitizeJSON ||
+ !this.request.isSameOrigin());
} catch (e) {
this.request.dispatchException(e);
}
@@ -1404,7 +1717,8 @@ Ajax.Response = Class.create({
this.responseText.blank())
return null;
try {
- return this.responseText.evalJSON(options.sanitizeJSON);
+ return this.responseText.evalJSON(options.sanitizeJSON ||
+ !this.request.isSameOrigin());
} catch (e) {
this.request.dispatchException(e);
}
@@ -1487,6 +1801,8 @@ Ajax.PeriodicalUpdater = Class.create(Ajax.Base, {
this.updater = new Ajax.Updater(this.container, this.url, this.options);
}
});
+
+
function $(element) {
if (arguments.length > 1) {
for (var i = 0, elements = [], length = arguments.length; i < length; i++)
@@ -1511,10 +1827,9 @@ if (Prototype.BrowserFeatures.XPath) {
/*--------------------------------------------------------------------------*/
-if (!window.Node) var Node = { };
+if (!Node) var Node = { };
if (!Node.ELEMENT_NODE) {
- // DOM level 2 ECMAScript Language Binding
Object.extend(Node, {
ELEMENT_NODE: 1,
ATTRIBUTE_NODE: 2,
@@ -1531,13 +1846,27 @@ if (!Node.ELEMENT_NODE) {
});
}
-(function() {
- var element = this.Element;
- this.Element = function(tagName, attributes) {
+
+
+(function(global) {
+
+ var HAS_EXTENDED_CREATE_ELEMENT_SYNTAX = (function(){
+ try {
+ var el = document.createElement('<input name="x">');
+ return el.tagName.toLowerCase() === 'input' && el.name === 'x';
+ }
+ catch(err) {
+ return false;
+ }
+ })();
+
+ var element = global.Element;
+
+ global.Element = function(tagName, attributes) {
attributes = attributes || { };
tagName = tagName.toLowerCase();
var cache = Element.cache;
- if (Prototype.Browser.IE && attributes.name) {
+ if (HAS_EXTENDED_CREATE_ELEMENT_SYNTAX && attributes.name) {
tagName = '<' + tagName + ' name="' + attributes.name + '">';
delete attributes.name;
return Element.writeAttribute(document.createElement(tagName), attributes);
@@ -1545,11 +1874,24 @@ if (!Node.ELEMENT_NODE) {
if (!cache[tagName]) cache[tagName] = Element.extend(document.createElement(tagName));
return Element.writeAttribute(cache[tagName].cloneNode(false), attributes);
};
- Object.extend(this.Element, element || { });
-}).call(window);
+ Object.extend(global.Element, element || { });
+ if (element) global.Element.prototype = element.prototype;
+
+})(this);
+
+Element.idCounter = 1;
Element.cache = { };
+function purgeElement(element) {
+ var uid = element._prototypeUID;
+ if (uid) {
+ Element.stopObserving(element);
+ element._prototypeUID = void 0;
+ delete Element.Storage[uid];
+ }
+}
+
Element.Methods = {
visible: function(element) {
return $(element).style.display != 'none';
@@ -1562,12 +1904,14 @@ Element.Methods = {
},
hide: function(element) {
- $(element).style.display = 'none';
+ element = $(element);
+ element.style.display = 'none';
return element;
},
show: function(element) {
- $(element).style.display = '';
+ element = $(element);
+ element.style.display = '';
return element;
},
@@ -1577,15 +1921,93 @@ Element.Methods = {
return element;
},
- update: function(element, content) {
- element = $(element);
- if (content && content.toElement) content = content.toElement();
- if (Object.isElement(content)) return element.update().insert(content);
- content = Object.toHTML(content);
- element.innerHTML = content.stripScripts();
- content.evalScripts.bind(content).defer();
- return element;
- },
+ update: (function(){
+
+ var SELECT_ELEMENT_INNERHTML_BUGGY = (function(){
+ var el = document.createElement("select"),
+ isBuggy = true;
+ el.innerHTML = "<option value=\"test\">test</option>";
+ if (el.options && el.options[0]) {
+ isBuggy = el.options[0].nodeName.toUpperCase() !== "OPTION";
+ }
+ el = null;
+ return isBuggy;
+ })();
+
+ var TABLE_ELEMENT_INNERHTML_BUGGY = (function(){
+ try {
+ var el = document.createElement("table");
+ if (el && el.tBodies) {
+ el.innerHTML = "<tbody><tr><td>test</td></tr></tbody>";
+ var isBuggy = typeof el.tBodies[0] == "undefined";
+ el = null;
+ return isBuggy;
+ }
+ } catch (e) {
+ return true;
+ }
+ })();
+
+ var SCRIPT_ELEMENT_REJECTS_TEXTNODE_APPENDING = (function () {
+ var s = document.createElement("script"),
+ isBuggy = false;
+ try {
+ s.appendChild(document.createTextNode(""));
+ isBuggy = !s.firstChild ||
+ s.firstChild && s.firstChild.nodeType !== 3;
+ } catch (e) {
+ isBuggy = true;
+ }
+ s = null;
+ return isBuggy;
+ })();
+
+ function update(element, content) {
+ element = $(element);
+
+ var descendants = element.getElementsByTagName('*'),
+ i = descendants.length;
+ while (i--) purgeElement(descendants[i]);
+
+ if (content && content.toElement)
+ content = content.toElement();
+
+ if (Object.isElement(content))
+ return element.update().insert(content);
+
+ content = Object.toHTML(content);
+
+ var tagName = element.tagName.toUpperCase();
+
+ if (tagName === 'SCRIPT' && SCRIPT_ELEMENT_REJECTS_TEXTNODE_APPENDING) {
+ element.text = content;
+ return element;
+ }
+
+ if (SELECT_ELEMENT_INNERHTML_BUGGY || TABLE_ELEMENT_INNERHTML_BUGGY) {
+ if (tagName in Element._insertionTranslations.tags) {
+ while (element.firstChild) {
+ element.removeChild(element.firstChild);
+ }
+ Element._getContentFromAnonymousElement(tagName, content.stripScripts())
+ .each(function(node) {
+ element.appendChild(node)
+ });
+ }
+ else {
+ element.innerHTML = content.stripScripts();
+ }
+ }
+ else {
+ element.innerHTML = content.stripScripts();
+ }
+
+ content.evalScripts.bind(content).defer();
+ return element;
+ }
+
+ return update;
+ })(),
replace: function(element, content) {
element = $(element);
@@ -1608,24 +2030,28 @@ Element.Methods = {
Object.isElement(insertions) || (insertions && (insertions.toElement || insertions.toHTML)))
insertions = {bottom:insertions};
- var content, t, range;
+ var content, insert, tagName, childNodes;
- for (position in insertions) {
+ for (var position in insertions) {
content = insertions[position];
position = position.toLowerCase();
- t = Element._insertionTranslations[position];
+ insert = Element._insertionTranslations[position];
if (content && content.toElement) content = content.toElement();
if (Object.isElement(content)) {
- t.insert(element, content);
+ insert(element, content);
continue;
}
content = Object.toHTML(content);
- range = element.ownerDocument.createRange();
- t.initializeRange(element, range);
- t.insert(element, range.createContextualFragment(content.stripScripts()));
+ tagName = ((position == 'before' || position == 'after')
+ ? element.parentNode : element).tagName.toUpperCase();
+
+ childNodes = Element._getContentFromAnonymousElement(tagName, content.stripScripts());
+
+ if (position == 'top' || position == 'after') childNodes.reverse();
+ childNodes.each(insert.curry(element));
content.evalScripts.bind(content).defer();
}
@@ -1649,28 +2075,35 @@ Element.Methods = {
element = $(element);
var result = '<' + element.tagName.toLowerCase();
$H({'id': 'id', 'className': 'class'}).each(function(pair) {
- var property = pair.first(), attribute = pair.last();
- var value = (element[property] || '').toString();
+ var property = pair.first(),
+ attribute = pair.last(),
+ value = (element[property] || '').toString();
if (value) result += ' ' + attribute + '=' + value.inspect(true);
});
return result + '>';
},
- recursivelyCollect: function(element, property) {
+ recursivelyCollect: function(element, property, maximumLength) {
element = $(element);
+ maximumLength = maximumLength || -1;
var elements = [];
- while (element = element[property])
+
+ while (element = element[property]) {
if (element.nodeType == 1)
elements.push(Element.extend(element));
+ if (elements.length == maximumLength)
+ break;
+ }
+
return elements;
},
ancestors: function(element) {
- return $(element).recursivelyCollect('parentNode');
+ return Element.recursivelyCollect(element, 'parentNode');
},
descendants: function(element) {
- return $(element).getElementsBySelector("*");
+ return Element.select(element, "*");
},
firstDescendant: function(element) {
@@ -1680,79 +2113,96 @@ Element.Methods = {
},
immediateDescendants: function(element) {
- if (!(element = $(element).firstChild)) return [];
- while (element && element.nodeType != 1) element = element.nextSibling;
- if (element) return [element].concat($(element).nextSiblings());
- return [];
+ var results = [], child = $(element).firstChild;
+ while (child) {
+ if (child.nodeType === 1) {
+ results.push(Element.extend(child));
+ }
+ child = child.nextSibling;
+ }
+ return results;
},
- previousSiblings: function(element) {
- return $(element).recursivelyCollect('previousSibling');
+ previousSiblings: function(element, maximumLength) {
+ return Element.recursivelyCollect(element, 'previousSibling');
},
nextSiblings: function(element) {
- return $(element).recursivelyCollect('nextSibling');
+ return Element.recursivelyCollect(element, 'nextSibling');
},
siblings: function(element) {
element = $(element);
- return element.previousSiblings().reverse().concat(element.nextSiblings());
+ return Element.previousSiblings(element).reverse()
+ .concat(Element.nextSiblings(element));
},
match: function(element, selector) {
+ element = $(element);
if (Object.isString(selector))
- selector = new Selector(selector);
- return selector.match($(element));
+ return Prototype.Selector.match(element, selector);
+ return selector.match(element);
},
up: function(element, expression, index) {
element = $(element);
if (arguments.length == 1) return $(element.parentNode);
- var ancestors = element.ancestors();
- return expression ? Selector.findElement(ancestors, expression, index) :
- ancestors[index || 0];
+ var ancestors = Element.ancestors(element);
+ return Object.isNumber(expression) ? ancestors[expression] :
+ Prototype.Selector.find(ancestors, expression, index);
},
down: function(element, expression, index) {
element = $(element);
- if (arguments.length == 1) return element.firstDescendant();
- var descendants = element.descendants();
- return expression ? Selector.findElement(descendants, expression, index) :
- descendants[index || 0];
+ if (arguments.length == 1) return Element.firstDescendant(element);
+ return Object.isNumber(expression) ? Element.descendants(element)[expression] :
+ Element.select(element, expression)[index || 0];
},
previous: function(element, expression, index) {
element = $(element);
- if (arguments.length == 1) return $(Selector.handlers.previousElementSibling(element));
- var previousSiblings = element.previousSiblings();
- return expression ? Selector.findElement(previousSiblings, expression, index) :
- previousSiblings[index || 0];
+ if (Object.isNumber(expression)) index = expression, expression = false;
+ if (!Object.isNumber(index)) index = 0;
+
+ if (expression) {
+ return Prototype.Selector.find(element.previousSiblings(), expression, index);
+ } else {
+ return element.recursivelyCollect("previousSibling", index + 1)[index];
+ }
},
next: function(element, expression, index) {
element = $(element);
- if (arguments.length == 1) return $(Selector.handlers.nextElementSibling(element));
- var nextSiblings = element.nextSiblings();
- return expression ? Selector.findElement(nextSiblings, expression, index) :
- nextSiblings[index || 0];
+ if (Object.isNumber(expression)) index = expression, expression = false;
+ if (!Object.isNumber(index)) index = 0;
+
+ if (expression) {
+ return Prototype.Selector.find(element.nextSiblings(), expression, index);
+ } else {
+ var maximumLength = Object.isNumber(index) ? index + 1 : 1;
+ return element.recursivelyCollect("nextSibling", index + 1)[index];
+ }
},
- select: function() {
- var args = $A(arguments), element = $(args.shift());
- return Selector.findChildElements(element, args);
+
+ select: function(element) {
+ element = $(element);
+ var expressions = Array.prototype.slice.call(arguments, 1).join(', ');
+ return Prototype.Selector.select(expressions, element);
},
- adjacent: function() {
- var args = $A(arguments), element = $(args.shift());
- return Selector.findChildElements(element.parentNode, args).without(element);
+ adjacent: function(element) {
+ element = $(element);
+ var expressions = Array.prototype.slice.call(arguments, 1).join(', ');
+ return Prototype.Selector.select(expressions, element.parentNode).without(element);
},
identify: function(element) {
element = $(element);
- var id = element.readAttribute('id'), self = arguments.callee;
+ var id = Element.readAttribute(element, 'id');
if (id) return id;
- do { id = 'anonymous_element_' + self.counter++ } while ($(id));
- element.writeAttribute('id', id);
+ do { id = 'anonymous_element_' + Element.idCounter++ } while ($(id));
+ Element.writeAttribute(element, 'id', id);
return id;
},
@@ -1791,11 +2241,11 @@ Element.Methods = {
},
getHeight: function(element) {
- return $(element).getDimensions().height;
+ return Element.getDimensions(element).height;
},
getWidth: function(element) {
- return $(element).getDimensions().width;
+ return Element.getDimensions(element).width;
},
classNames: function(element) {
@@ -1811,7 +2261,7 @@ Element.Methods = {
addClassName: function(element, className) {
if (!(element = $(element))) return;
- if (!element.hasClassName(className))
+ if (!Element.hasClassName(element, className))
element.className += (element.className ? ' ' : '') + className;
return element;
},
@@ -1825,11 +2275,10 @@ Element.Methods = {
toggleClassName: function(element, className) {
if (!(element = $(element))) return;
- return element[element.hasClassName(className) ?
- 'removeClassName' : 'addClassName'](className);
+ return Element[Element.hasClassName(element, className) ?
+ 'removeClassName' : 'addClassName'](element, className);
},
- // removes whitespace-only text node children
cleanWhitespace: function(element) {
element = $(element);
var node = element.firstChild;
@@ -1848,29 +2297,22 @@ Element.Methods = {
descendantOf: function(element, ancestor) {
element = $(element), ancestor = $(ancestor);
- var originalAncestor = ancestor;
if (element.compareDocumentPosition)
return (element.compareDocumentPosition(ancestor) & 8) === 8;
- if (element.sourceIndex && !Prototype.Browser.Opera) {
- var e = element.sourceIndex, a = ancestor.sourceIndex,
- nextAncestor = ancestor.nextSibling;
- if (!nextAncestor) {
- do { ancestor = ancestor.parentNode; }
- while (!(nextAncestor = ancestor.nextSibling) && ancestor.parentNode);
- }
- if (nextAncestor) return (e > a && e < nextAncestor.sourceIndex);
- }
+ if (ancestor.contains)
+ return ancestor.contains(element) && ancestor !== element;
while (element = element.parentNode)
- if (element == originalAncestor) return true;
+ if (element == ancestor) return true;
+
return false;
},
scrollTo: function(element) {
element = $(element);
- var pos = element.cumulativeOffset();
+ var pos = Element.cumulativeOffset(element);
window.scrollTo(pos[0], pos[1]);
return element;
},
@@ -1879,7 +2321,7 @@ Element.Methods = {
element = $(element);
style = style == 'float' ? 'cssFloat' : style.camelize();
var value = element.style[style];
- if (!value) {
+ if (!value || value == 'auto') {
var css = document.defaultView.getComputedStyle(element, null);
value = css ? css[style] : null;
}
@@ -1916,38 +2358,13 @@ Element.Methods = {
return element;
},
- getDimensions: function(element) {
- element = $(element);
- var display = $(element).getStyle('display');
- if (display != 'none' && display != null) // Safari bug
- return {width: element.offsetWidth, height: element.offsetHeight};
-
- // All *Width and *Height properties give 0 on elements with display none,
- // so enable the element temporarily
- var els = element.style;
- var originalVisibility = els.visibility;
- var originalPosition = els.position;
- var originalDisplay = els.display;
- els.visibility = 'hidden';
- els.position = 'absolute';
- els.display = 'block';
- var originalWidth = element.clientWidth;
- var originalHeight = element.clientHeight;
- els.display = originalDisplay;
- els.position = originalPosition;
- els.visibility = originalVisibility;
- return {width: originalWidth, height: originalHeight};
- },
-
makePositioned: function(element) {
element = $(element);
var pos = Element.getStyle(element, 'position');
if (pos == 'static' || !pos) {
element._madePositioned = true;
element.style.position = 'relative';
- // Opera returns the offset relative to the positioning context, when an
- // element is position relative but top and left have not been defined
- if (window.opera) {
+ if (Prototype.Browser.Opera) {
element.style.top = 0;
element.style.left = 0;
}
@@ -1987,11 +2404,13 @@ Element.Methods = {
cumulativeOffset: function(element) {
var valueT = 0, valueL = 0;
- do {
- valueT += element.offsetTop || 0;
- valueL += element.offsetLeft || 0;
- element = element.offsetParent;
- } while (element);
+ if (element.parentNode) {
+ do {
+ valueT += element.offsetTop || 0;
+ valueL += element.offsetLeft || 0;
+ element = element.offsetParent;
+ } while (element);
+ }
return Element._returnOffset(valueL, valueT);
},
@@ -2002,9 +2421,9 @@ Element.Methods = {
valueL += element.offsetLeft || 0;
element = element.offsetParent;
if (element) {
- if (element.tagName == 'BODY') break;
+ if (element.tagName.toUpperCase() == 'BODY') break;
var p = Element.getStyle(element, 'position');
- if (p == 'relative' || p == 'absolute') break;
+ if (p !== 'static') break;
}
} while (element);
return Element._returnOffset(valueL, valueT);
@@ -2012,14 +2431,13 @@ Element.Methods = {
absolutize: function(element) {
element = $(element);
- if (element.getStyle('position') == 'absolute') return;
- // Position.prepare(); // To be done manually by Scripty when it needs it.
+ if (Element.getStyle(element, 'position') == 'absolute') return element;
- var offsets = element.positionedOffset();
- var top = offsets[1];
- var left = offsets[0];
- var width = element.clientWidth;
- var height = element.clientHeight;
+ var offsets = Element.positionedOffset(element),
+ top = offsets[1],
+ left = offsets[0],
+ width = element.clientWidth,
+ height = element.clientHeight;
element._originalLeft = left - parseFloat(element.style.left || 0);
element._originalTop = top - parseFloat(element.style.top || 0);
@@ -2036,12 +2454,11 @@ Element.Methods = {
relativize: function(element) {
element = $(element);
- if (element.getStyle('position') == 'relative') return;
- // Position.prepare(); // To be done manually by Scripty when it needs it.
+ if (Element.getStyle(element, 'position') == 'relative') return element;
element.style.position = 'relative';
- var top = parseFloat(element.style.top || 0) - (element._originalTop || 0);
- var left = parseFloat(element.style.left || 0) - (element._originalLeft || 0);
+ var top = parseFloat(element.style.top || 0) - (element._originalTop || 0),
+ left = parseFloat(element.style.left || 0) - (element._originalLeft || 0);
element.style.top = top + 'px';
element.style.left = left + 'px';
@@ -2072,14 +2489,14 @@ Element.Methods = {
},
viewportOffset: function(forElement) {
- var valueT = 0, valueL = 0;
+ var valueT = 0,
+ valueL = 0,
+ element = forElement;
- var element = forElement;
do {
valueT += element.offsetTop || 0;
valueL += element.offsetLeft || 0;
- // Safari fix
if (element.offsetParent == document.body &&
Element.getStyle(element, 'position') == 'absolute') break;
@@ -2087,7 +2504,7 @@ Element.Methods = {
element = forElement;
do {
- if (!Prototype.Browser.Opera || element.tagName == 'BODY') {
+ if (!Prototype.Browser.Opera || (element.tagName && (element.tagName.toUpperCase() == 'BODY'))) {
valueT -= element.scrollTop || 0;
valueL -= element.scrollLeft || 0;
}
@@ -2106,28 +2523,21 @@ Element.Methods = {
offsetLeft: 0
}, arguments[2] || { });
- // find page position of source
source = $(source);
- var p = source.viewportOffset();
+ var p = Element.viewportOffset(source), delta = [0, 0], parent = null;
- // find coordinate system to use
element = $(element);
- var delta = [0, 0];
- var parent = null;
- // delta [0,0] will do fine with position: fixed elements,
- // position:absolute needs offsetParent deltas
+
if (Element.getStyle(element, 'position') == 'absolute') {
- parent = element.getOffsetParent();
- delta = parent.viewportOffset();
+ parent = Element.getOffsetParent(element);
+ delta = Element.viewportOffset(parent);
}
- // correct by body offsets (fixes Safari)
if (parent == document.body) {
delta[0] -= document.body.offsetLeft;
delta[1] -= document.body.offsetTop;
}
- // set position
if (options.setLeft) element.style.left = (p[0] - delta[0] + options.offsetLeft) + 'px';
if (options.setTop) element.style.top = (p[1] - delta[1] + options.offsetTop) + 'px';
if (options.setWidth) element.style.width = source.offsetWidth + 'px';
@@ -2136,10 +2546,9 @@ Element.Methods = {
}
};
-Element.Methods.identify.counter = 1;
-
Object.extend(Element.Methods, {
getElementsBySelector: Element.Methods.select,
+
childElements: Element.Methods.immediateDescendants
});
@@ -2153,46 +2562,6 @@ Element._attributeTranslations = {
}
};
-
-if (!document.createRange || Prototype.Browser.Opera) {
- Element.Methods.insert = function(element, insertions) {
- element = $(element);
-
- if (Object.isString(insertions) || Object.isNumber(insertions) ||
- Object.isElement(insertions) || (insertions && (insertions.toElement || insertions.toHTML)))
- insertions = { bottom: insertions };
-
- var t = Element._insertionTranslations, content, position, pos, tagName;
-
- for (position in insertions) {
- content = insertions[position];
- position = position.toLowerCase();
- pos = t[position];
-
- if (content && content.toElement) content = content.toElement();
- if (Object.isElement(content)) {
- pos.insert(element, content);
- continue;
- }
-
- content = Object.toHTML(content);
- tagName = ((position == 'before' || position == 'after')
- ? element.parentNode : element).tagName.toUpperCase();
-
- if (t.tags[tagName]) {
- var fragments = Element._getContentFromAnonymousElement(tagName, content.stripScripts());
- if (position == 'top' || position == 'after') fragments.reverse();
- fragments.each(pos.insert.curry(element));
- }
- else element.insertAdjacentHTML(pos.adjacency, content.stripScripts());
-
- content.evalScripts.bind(content).defer();
- }
-
- return element;
- };
-}
-
if (Prototype.Browser.Opera) {
Element.Methods.getStyle = Element.Methods.getStyle.wrap(
function(proceed, element, style) {
@@ -2200,11 +2569,8 @@ if (Prototype.Browser.Opera) {
case 'left': case 'top': case 'right': case 'bottom':
if (proceed(element, 'position') === 'static') return null;
case 'height': case 'width':
- // returns '0px' for hidden elements; we want it to return null
if (!Element.visible(element)) return null;
- // returns the border-box dimensions rather than the content-box
- // dimensions, so we subtract padding and borders from the value
var dim = parseInt(proceed(element, style), 10);
if (dim !== element['offset' + style.capitalize()])
@@ -2237,12 +2603,29 @@ if (Prototype.Browser.Opera) {
}
else if (Prototype.Browser.IE) {
- $w('positionedOffset getOffsetParent viewportOffset').each(function(method) {
+ Element.Methods.getOffsetParent = Element.Methods.getOffsetParent.wrap(
+ function(proceed, element) {
+ element = $(element);
+ if (!element.parentNode) return $(document.body);
+ var position = element.getStyle('position');
+ if (position !== 'static') return proceed(element);
+ element.setStyle({ position: 'relative' });
+ var value = proceed(element);
+ element.setStyle({ position: position });
+ return value;
+ }
+ );
+
+ $w('positionedOffset viewportOffset').each(function(method) {
Element.Methods[method] = Element.Methods[method].wrap(
function(proceed, element) {
element = $(element);
+ if (!element.parentNode) return Element._returnOffset(0, 0);
var position = element.getStyle('position');
- if (position != 'static') return proceed(element);
+ if (position !== 'static') return proceed(element);
+ var offsetParent = element.getOffsetParent();
+ if (offsetParent && offsetParent.getStyle('position') === 'fixed')
+ offsetParent.setStyle({ zoom: 1 });
element.setStyle({ position: 'relative' });
var value = proceed(element);
element.setStyle({ position: position });
@@ -2292,39 +2675,96 @@ else if (Prototype.Browser.IE) {
return element;
};
- Element._attributeTranslations = {
- read: {
- names: {
- 'class': 'className',
- 'for': 'htmlFor'
- },
- values: {
- _getAttr: function(element, attribute) {
- return element.getAttribute(attribute, 2);
- },
- _getAttrNode: function(element, attribute) {
- var node = element.getAttributeNode(attribute);
- return node ? node.value : "";
- },
- _getEv: function(element, attribute) {
- attribute = element.getAttribute(attribute);
- return attribute ? attribute.toString().slice(23, -2) : null;
- },
- _flag: function(element, attribute) {
- return $(element).hasAttribute(attribute) ? attribute : null;
- },
- style: function(element) {
- return element.style.cssText.toLowerCase();
+ Element._attributeTranslations = (function(){
+
+ var classProp = 'className',
+ forProp = 'for',
+ el = document.createElement('div');
+
+ el.setAttribute(classProp, 'x');
+
+ if (el.className !== 'x') {
+ el.setAttribute('class', 'x');
+ if (el.className === 'x') {
+ classProp = 'class';
+ }
+ }
+ el = null;
+
+ el = document.createElement('label');
+ el.setAttribute(forProp, 'x');
+ if (el.htmlFor !== 'x') {
+ el.setAttribute('htmlFor', 'x');
+ if (el.htmlFor === 'x') {
+ forProp = 'htmlFor';
+ }
+ }
+ el = null;
+
+ return {
+ read: {
+ names: {
+ 'class': classProp,
+ 'className': classProp,
+ 'for': forProp,
+ 'htmlFor': forProp
},
- title: function(element) {
- return element.title;
+ values: {
+ _getAttr: function(element, attribute) {
+ return element.getAttribute(attribute);
+ },
+ _getAttr2: function(element, attribute) {
+ return element.getAttribute(attribute, 2);
+ },
+ _getAttrNode: function(element, attribute) {
+ var node = element.getAttributeNode(attribute);
+ return node ? node.value : "";
+ },
+ _getEv: (function(){
+
+ var el = document.createElement('div'), f;
+ el.onclick = Prototype.emptyFunction;
+ var value = el.getAttribute('onclick');
+
+ if (String(value).indexOf('{') > -1) {
+ f = function(element, attribute) {
+ attribute = element.getAttribute(attribute);
+ if (!attribute) return null;
+ attribute = attribute.toString();
+ attribute = attribute.split('{')[1];
+ attribute = attribute.split('}')[0];
+ return attribute.strip();
+ };
+ }
+ else if (value === '') {
+ f = function(element, attribute) {
+ attribute = element.getAttribute(attribute);
+ if (!attribute) return null;
+ return attribute.strip();
+ };
+ }
+ el = null;
+ return f;
+ })(),
+ _flag: function(element, attribute) {
+ return $(element).hasAttribute(attribute) ? attribute : null;
+ },
+ style: function(element) {
+ return element.style.cssText.toLowerCase();
+ },
+ title: function(element) {
+ return element.title;
+ }
}
}
}
- };
+ })();
Element._attributeTranslations.write = {
- names: Object.clone(Element._attributeTranslations.read.names),
+ names: Object.extend({
+ cellpadding: 'cellPadding',
+ cellspacing: 'cellSpacing'
+ }, Element._attributeTranslations.read.names),
values: {
checked: function(element, value) {
element.checked = !!value;
@@ -2339,15 +2779,15 @@ else if (Prototype.Browser.IE) {
Element._attributeTranslations.has = {};
$w('colSpan rowSpan vAlign dateTime accessKey tabIndex ' +
- 'encType maxLength readOnly longDesc').each(function(attr) {
+ 'encType maxLength readOnly longDesc frameBorder').each(function(attr) {
Element._attributeTranslations.write.names[attr.toLowerCase()] = attr;
Element._attributeTranslations.has[attr.toLowerCase()] = attr;
});
(function(v) {
Object.extend(v, {
- href: v._getAttr,
- src: v._getAttr,
+ href: v._getAttr2,
+ src: v._getAttr2,
type: v._getAttr,
action: v._getAttrNode,
disabled: v._flag,
@@ -2374,6 +2814,26 @@ else if (Prototype.Browser.IE) {
onchange: v._getEv
});
})(Element._attributeTranslations.read.values);
+
+ if (Prototype.BrowserFeatures.ElementExtensions) {
+ (function() {
+ function _descendants(element) {
+ var nodes = element.getElementsByTagName('*'), results = [];
+ for (var i = 0, node; node = nodes[i]; i++)
+ if (node.tagName !== "!") // Filter out comment nodes.
+ results.push(node);
+ return results;
+ }
+
+ Element.Methods.down = function(element, expression, index) {
+ element = $(element);
+ if (arguments.length == 1) return element.firstDescendant();
+ return Object.isNumber(expression) ? _descendants(element)[expression] :
+ Element.select(element, expression)[index || 0];
+ }
+ })();
+ }
+
}
else if (Prototype.Browser.Gecko && /rv:1\.8\.0/.test(navigator.userAgent)) {
@@ -2392,7 +2852,7 @@ else if (Prototype.Browser.WebKit) {
(value < 0.00001) ? 0 : value;
if (value == 1)
- if(element.tagName == 'IMG' && element.width) {
+ if (element.tagName.toUpperCase() == 'IMG' && element.width) {
element.width++; element.width--;
} else try {
var n = document.createTextNode(' ');
@@ -2403,9 +2863,6 @@ else if (Prototype.Browser.WebKit) {
return element;
};
- // Safari returns margins on body which is incorrect if the child is absolutely
- // positioned. For performance reasons, redefine Element#cumulativeOffset for
- // KHTML/WebKit only.
Element.Methods.cumulativeOffset = function(element) {
var valueT = 0, valueL = 0;
do {
@@ -2421,30 +2878,7 @@ else if (Prototype.Browser.WebKit) {
};
}
-if (Prototype.Browser.IE || Prototype.Browser.Opera) {
- // IE and Opera are missing .innerHTML support for TABLE-related and SELECT elements
- Element.Methods.update = function(element, content) {
- element = $(element);
-
- if (content && content.toElement) content = content.toElement();
- if (Object.isElement(content)) return element.update().insert(content);
-
- content = Object.toHTML(content);
- var tagName = element.tagName.toUpperCase();
-
- if (tagName in Element._insertionTranslations.tags) {
- $A(element.childNodes).each(function(node) { element.removeChild(node) });
- Element._getContentFromAnonymousElement(tagName, content.stripScripts())
- .each(function(node) { element.appendChild(node) });
- }
- else element.innerHTML = content.stripScripts();
-
- content.evalScripts.bind(content).defer();
- return element;
- };
-}
-
-if (document.createElement('div').outerHTML) {
+if ('outerHTML' in document.documentElement) {
Element.Methods.replace = function(element, content) {
element = $(element);
@@ -2458,8 +2892,8 @@ if (document.createElement('div').outerHTML) {
var parent = element.parentNode, tagName = parent.tagName.toUpperCase();
if (Element._insertionTranslations.tags[tagName]) {
- var nextSibling = element.next();
- var fragments = Element._getContentFromAnonymousElement(tagName, content.stripScripts());
+ var nextSibling = element.next(),
+ fragments = Element._getContentFromAnonymousElement(tagName, content.stripScripts());
parent.removeChild(element);
if (nextSibling)
fragments.each(function(node) { parent.insertBefore(node, nextSibling) });
@@ -2481,46 +2915,32 @@ Element._returnOffset = function(l, t) {
};
Element._getContentFromAnonymousElement = function(tagName, html) {
- var div = new Element('div'), t = Element._insertionTranslations.tags[tagName];
- div.innerHTML = t[0] + html + t[1];
- t[2].times(function() { div = div.firstChild });
+ var div = new Element('div'),
+ t = Element._insertionTranslations.tags[tagName];
+ if (t) {
+ div.innerHTML = t[0] + html + t[1];
+ for (var i = t[2]; i--; ) {
+ div = div.firstChild;
+ }
+ }
+ else {
+ div.innerHTML = html;
+ }
return $A(div.childNodes);
};
Element._insertionTranslations = {
- before: {
- adjacency: 'beforeBegin',
- insert: function(element, node) {
- element.parentNode.insertBefore(node, element);
- },
- initializeRange: function(element, range) {
- range.setStartBefore(element);
- }
+ before: function(element, node) {
+ element.parentNode.insertBefore(node, element);
},
- top: {
- adjacency: 'afterBegin',
- insert: function(element, node) {
- element.insertBefore(node, element.firstChild);
- },
- initializeRange: function(element, range) {
- range.selectNodeContents(element);
- range.collapse(true);
- }
+ top: function(element, node) {
+ element.insertBefore(node, element.firstChild);
},
- bottom: {
- adjacency: 'beforeEnd',
- insert: function(element, node) {
- element.appendChild(node);
- }
+ bottom: function(element, node) {
+ element.appendChild(node);
},
- after: {
- adjacency: 'afterEnd',
- insert: function(element, node) {
- element.parentNode.insertBefore(node, element.nextSibling);
- },
- initializeRange: function(element, range) {
- range.setStartAfter(element);
- }
+ after: function(element, node) {
+ element.parentNode.insertBefore(node, element.nextSibling);
},
tags: {
TABLE: ['<table>', '</table>', 1],
@@ -2532,19 +2952,19 @@ Element._insertionTranslations = {
};
(function() {
- this.bottom.initializeRange = this.top.initializeRange;
- Object.extend(this.tags, {
- THEAD: this.tags.TBODY,
- TFOOT: this.tags.TBODY,
- TH: this.tags.TD
+ var tags = Element._insertionTranslations.tags;
+ Object.extend(tags, {
+ THEAD: tags.TBODY,
+ TFOOT: tags.TBODY,
+ TH: tags.TD
});
-}).call(Element._insertionTranslations);
+})();
Element.Methods.Simulated = {
hasAttribute: function(element, attribute) {
attribute = Element._attributeTranslations.has[attribute] || attribute;
var node = $(element).getAttributeNode(attribute);
- return node && node.specified;
+ return !!(node && node.specified);
}
};
@@ -2552,41 +2972,81 @@ Element.Methods.ByTag = { };
Object.extend(Element, Element.Methods);
-if (!Prototype.BrowserFeatures.ElementExtensions &&
- document.createElement('div').__proto__) {
- window.HTMLElement = { };
- window.HTMLElement.prototype = document.createElement('div').__proto__;
- Prototype.BrowserFeatures.ElementExtensions = true;
-}
+(function(div) {
+
+ if (!Prototype.BrowserFeatures.ElementExtensions && div['__proto__']) {
+ window.HTMLElement = { };
+ window.HTMLElement.prototype = div['__proto__'];
+ Prototype.BrowserFeatures.ElementExtensions = true;
+ }
+
+ div = null;
+
+})(document.createElement('div'));
Element.extend = (function() {
- if (Prototype.BrowserFeatures.SpecificElementExtensions)
+
+ function checkDeficiency(tagName) {
+ if (typeof window.Element != 'undefined') {
+ var proto = window.Element.prototype;
+ if (proto) {
+ var id = '_' + (Math.random()+'').slice(2),
+ el = document.createElement(tagName);
+ proto[id] = 'x';
+ var isBuggy = (el[id] !== 'x');
+ delete proto[id];
+ el = null;
+ return isBuggy;
+ }
+ }
+ return false;
+ }
+
+ function extendElementWith(element, methods) {
+ for (var property in methods) {
+ var value = methods[property];
+ if (Object.isFunction(value) && !(property in element))
+ element[property] = value.methodize();
+ }
+ }
+
+ var HTMLOBJECTELEMENT_PROTOTYPE_BUGGY = checkDeficiency('object');
+
+ if (Prototype.BrowserFeatures.SpecificElementExtensions) {
+ if (HTMLOBJECTELEMENT_PROTOTYPE_BUGGY) {
+ return function(element) {
+ if (element && typeof element._extendedByPrototype == 'undefined') {
+ var t = element.tagName;
+ if (t && (/^(?:object|applet|embed)$/i.test(t))) {
+ extendElementWith(element, Element.Methods);
+ extendElementWith(element, Element.Methods.Simulated);
+ extendElementWith(element, Element.Methods.ByTag[t.toUpperCase()]);
+ }
+ }
+ return element;
+ }
+ }
return Prototype.K;
+ }
var Methods = { }, ByTag = Element.Methods.ByTag;
var extend = Object.extend(function(element) {
- if (!element || element._extendedByPrototype ||
+ if (!element || typeof element._extendedByPrototype != 'undefined' ||
element.nodeType != 1 || element == window) return element;
var methods = Object.clone(Methods),
- tagName = element.tagName, property, value;
+ tagName = element.tagName.toUpperCase();
- // extend methods for specific tags
if (ByTag[tagName]) Object.extend(methods, ByTag[tagName]);
- for (property in methods) {
- value = methods[property];
- if (Object.isFunction(value) && !(property in element))
- element[property] = value.methodize();
- }
+ extendElementWith(element, methods);
element._extendedByPrototype = Prototype.emptyFunction;
return element;
}, {
refresh: function() {
- // extend methods for all tags (Safari doesn't need this)
if (!Prototype.BrowserFeatures.ElementExtensions) {
Object.extend(Methods, Element.Methods);
Object.extend(Methods, Element.Methods.Simulated);
@@ -2598,10 +3058,14 @@ Element.extend = (function() {
return extend;
})();
-Element.hasAttribute = function(element, attribute) {
- if (element.hasAttribute) return element.hasAttribute(attribute);
- return Element.Methods.Simulated.hasAttribute(element, attribute);
-};
+if (document.documentElement.hasAttribute) {
+ Element.hasAttribute = function(element, attribute) {
+ return element.hasAttribute(attribute);
+ };
+}
+else {
+ Element.hasAttribute = Element.Methods.Simulated.hasAttribute;
+}
Element.addMethods = function(methods) {
var F = Prototype.BrowserFeatures, T = Element.Methods.ByTag;
@@ -2665,14 +3129,19 @@ Element.addMethods = function(methods) {
klass = 'HTML' + tagName.capitalize() + 'Element';
if (window[klass]) return window[klass];
- window[klass] = { };
- window[klass].prototype = document.createElement(tagName).__proto__;
- return window[klass];
+ var element = document.createElement(tagName),
+ proto = element['__proto__'] || element.constructor.prototype;
+
+ element = null;
+ return proto;
}
+ var elementPrototype = window.HTMLElement ? HTMLElement.prototype :
+ Element.prototype;
+
if (F.ElementExtensions) {
- copy(Element.Methods, HTMLElement.prototype);
- copy(Element.Methods.Simulated, HTMLElement.prototype, true);
+ copy(Element.Methods, elementPrototype);
+ copy(Element.Methods.Simulated, elementPrototype, true);
}
if (F.SpecificElementExtensions) {
@@ -2690,697 +3159,1803 @@ Element.addMethods = function(methods) {
Element.cache = { };
};
-document.viewport = {
- getDimensions: function() {
- var dimensions = { };
- var B = Prototype.Browser;
- $w('width height').each(function(d) {
- var D = d.capitalize();
- dimensions[d] = (B.WebKit && !document.evaluate) ? self['inner' + D] :
- (B.Opera) ? document.body['client' + D] : document.documentElement['client' + D];
- });
- return dimensions;
- },
- getWidth: function() {
- return this.getDimensions().width;
- },
+document.viewport = {
- getHeight: function() {
- return this.getDimensions().height;
+ getDimensions: function() {
+ return { width: this.getWidth(), height: this.getHeight() };
},
getScrollOffsets: function() {
return Element._returnOffset(
window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft,
- window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop);
+ window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop);
}
};
-/* Portions of the Selector class are derived from Jack Slocum’s DomQuery,
- * part of YUI-Ext version 0.40, distributed under the terms of an MIT-style
- * license. Please see http://www.yui-ext.com/ for more information. */
-var Selector = Class.create({
- initialize: function(expression) {
- this.expression = expression.strip();
- this.compileMatcher();
- },
+(function(viewport) {
+ var B = Prototype.Browser, doc = document, element, property = {};
- shouldUseXPath: function() {
- if (!Prototype.BrowserFeatures.XPath) return false;
+ function getRootElement() {
+ if (B.WebKit && !doc.evaluate)
+ return document;
- var e = this.expression;
+ if (B.Opera && window.parseFloat(window.opera.version()) < 9.5)
+ return document.body;
- // Safari 3 chokes on :*-of-type and :empty
- if (Prototype.Browser.WebKit &&
- (e.include("-of-type") || e.include(":empty")))
- return false;
+ return document.documentElement;
+ }
- // XPath can't do namespaced attributes, nor can it read
- // the "checked" property from DOM nodes
- if ((/(\[[\w-]*?:|:checked)/).test(this.expression))
- return false;
+ function define(D) {
+ if (!element) element = getRootElement();
- return true;
- },
+ property[D] = 'client' + D;
- compileMatcher: function() {
- if (this.shouldUseXPath())
- return this.compileXPathMatcher();
+ viewport['get' + D] = function() { return element[property[D]] };
+ return viewport['get' + D]();
+ }
- var e = this.expression, ps = Selector.patterns, h = Selector.handlers,
- c = Selector.criteria, le, p, m;
+ viewport.getWidth = define.curry('Width');
- if (Selector._cache[e]) {
- this.matcher = Selector._cache[e];
- return;
- }
+ viewport.getHeight = define.curry('Height');
+})(document.viewport);
- this.matcher = ["this.matcher = function(root) {",
- "var r = root, h = Selector.handlers, c = false, n;"];
- while (e && le != e && (/\S/).test(e)) {
- le = e;
- for (var i in ps) {
- p = ps[i];
- if (m = e.match(p)) {
- this.matcher.push(Object.isFunction(c[i]) ? c[i](m) :
- new Template(c[i]).evaluate(m));
- e = e.replace(m[0], '');
- break;
- }
- }
+Element.Storage = {
+ UID: 1
+};
+
+Element.addMethods({
+ getStorage: function(element) {
+ if (!(element = $(element))) return;
+
+ var uid;
+ if (element === window) {
+ uid = 0;
+ } else {
+ if (typeof element._prototypeUID === "undefined")
+ element._prototypeUID = Element.Storage.UID++;
+ uid = element._prototypeUID;
}
- this.matcher.push("return h.unique(n);\n}");
- eval(this.matcher.join('\n'));
- Selector._cache[this.expression] = this.matcher;
+ if (!Element.Storage[uid])
+ Element.Storage[uid] = $H();
+
+ return Element.Storage[uid];
},
- compileXPathMatcher: function() {
- var e = this.expression, ps = Selector.patterns,
- x = Selector.xpath, le, m;
+ store: function(element, key, value) {
+ if (!(element = $(element))) return;
- if (Selector._cache[e]) {
- this.xpath = Selector._cache[e]; return;
+ if (arguments.length === 2) {
+ Element.getStorage(element).update(key);
+ } else {
+ Element.getStorage(element).set(key, value);
}
- this.matcher = ['.//*'];
- while (e && le != e && (/\S/).test(e)) {
- le = e;
- for (var i in ps) {
- if (m = e.match(ps[i])) {
- this.matcher.push(Object.isFunction(x[i]) ? x[i](m) :
- new Template(x[i]).evaluate(m));
- e = e.replace(m[0], '');
- break;
- }
- }
+ return element;
+ },
+
+ retrieve: function(element, key, defaultValue) {
+ if (!(element = $(element))) return;
+ var hash = Element.getStorage(element), value = hash.get(key);
+
+ if (Object.isUndefined(value)) {
+ hash.set(key, defaultValue);
+ value = defaultValue;
}
- this.xpath = this.matcher.join('');
- Selector._cache[this.expression] = this.xpath;
+ return value;
},
- findElements: function(root) {
- root = root || document;
- if (this.xpath) return document._getElementsByXPath(this.xpath, root);
- return this.matcher(root);
+ clone: function(element, deep) {
+ if (!(element = $(element))) return;
+ var clone = element.cloneNode(deep);
+ clone._prototypeUID = void 0;
+ if (deep) {
+ var descendants = Element.select(clone, '*'),
+ i = descendants.length;
+ while (i--) {
+ descendants[i]._prototypeUID = void 0;
+ }
+ }
+ return Element.extend(clone);
},
- match: function(element) {
- this.tokens = [];
+ purge: function(element) {
+ if (!(element = $(element))) return;
+ purgeElement(element);
- var e = this.expression, ps = Selector.patterns, as = Selector.assertions;
- var le, p, m;
+ var descendants = element.getElementsByTagName('*'),
+ i = descendants.length;
- while (e && le !== e && (/\S/).test(e)) {
- le = e;
- for (var i in ps) {
- p = ps[i];
- if (m = e.match(p)) {
- // use the Selector.assertions methods unless the selector
- // is too complex.
- if (as[i]) {
- this.tokens.push([i, Object.clone(m)]);
- e = e.replace(m[0], '');
- } else {
- // reluctantly do a document-wide search
- // and look for a match in the array
- return this.findElements(document).include(element);
- }
- }
- }
+ while (i--) purgeElement(descendants[i]);
+
+ return null;
+ }
+});
+
+(function() {
+
+ function toDecimal(pctString) {
+ var match = pctString.match(/^(\d+)%?$/i);
+ if (!match) return null;
+ return (Number(match[1]) / 100);
+ }
+
+ function getPixelValue(value, property) {
+ if (Object.isElement(value)) {
+ element = value;
+ value = element.getStyle(property);
+ }
+ if (value === null) {
+ return null;
+ }
+
+ if ((/^(?:-)?\d+(\.\d+)?(px)?$/i).test(value)) {
+ return window.parseFloat(value);
}
- var match = true, name, matches;
- for (var i = 0, token; token = this.tokens[i]; i++) {
- name = token[0], matches = token[1];
- if (!Selector.assertions[name](element, matches)) {
- match = false; break;
+ if (/\d/.test(value) && element.runtimeStyle) {
+ var style = element.style.left, rStyle = element.runtimeStyle.left;
+ element.runtimeStyle.left = element.currentStyle.left;
+ element.style.left = value || 0;
+ value = element.style.pixelLeft;
+ element.style.left = style;
+ element.runtimeStyle.left = rStyle;
+
+ return value;
+ }
+
+ if (value.include('%')) {
+ var decimal = toDecimal(value);
+ var whole;
+ if (property.include('left') || property.include('right') ||
+ property.include('width')) {
+ whole = $(element.parentNode).measure('width');
+ } else if (property.include('top') || property.include('bottom') ||
+ property.include('height')) {
+ whole = $(element.parentNode).measure('height');
}
+
+ return whole * decimal;
}
- return match;
- },
+ return 0;
+ }
- toString: function() {
- return this.expression;
- },
+ function toCSSPixels(number) {
+ if (Object.isString(number) && number.endsWith('px')) {
+ return number;
+ }
+ return number + 'px';
+ }
- inspect: function() {
- return "#<Selector:" + this.expression.inspect() + ">";
+ function isDisplayed(element) {
+ var originalElement = element;
+ while (element && element.parentNode) {
+ var display = element.getStyle('display');
+ if (display === 'none') {
+ return false;
+ }
+ element = $(element.parentNode);
+ }
+ return true;
}
-});
-Object.extend(Selector, {
- _cache: { },
-
- xpath: {
- descendant: "//*",
- child: "/*",
- adjacent: "/following-sibling::*[1]",
- laterSibling: '/following-sibling::*',
- tagName: function(m) {
- if (m[1] == '*') return '';
- return "[local-name()='" + m[1].toLowerCase() +
- "' or local-name()='" + m[1].toUpperCase() + "']";
+ var hasLayout = Prototype.K;
+ if ('currentStyle' in document.documentElement) {
+ hasLayout = function(element) {
+ if (!element.currentStyle.hasLayout) {
+ element.style.zoom = 1;
+ }
+ return element;
+ };
+ }
+
+ function cssNameFor(key) {
+ if (key.include('border')) key = key + '-width';
+ return key.camelize();
+ }
+
+ Element.Layout = Class.create(Hash, {
+ initialize: function($super, element, preCompute) {
+ $super();
+ this.element = $(element);
+
+ Element.Layout.PROPERTIES.each( function(property) {
+ this._set(property, null);
+ }, this);
+
+ if (preCompute) {
+ this._preComputing = true;
+ this._begin();
+ Element.Layout.PROPERTIES.each( this._compute, this );
+ this._end();
+ this._preComputing = false;
+ }
+ },
+
+ _set: function(property, value) {
+ return Hash.prototype.set.call(this, property, value);
+ },
+
+ set: function(property, value) {
+ throw "Properties of Element.Layout are read-only.";
+ },
+
+ get: function($super, property) {
+ var value = $super(property);
+ return value === null ? this._compute(property) : value;
+ },
+
+ _begin: function() {
+ if (this._prepared) return;
+
+ var element = this.element;
+ if (isDisplayed(element)) {
+ this._prepared = true;
+ return;
+ }
+
+ var originalStyles = {
+ position: element.style.position || '',
+ width: element.style.width || '',
+ visibility: element.style.visibility || '',
+ display: element.style.display || ''
+ };
+
+ element.store('prototype_original_styles', originalStyles);
+
+ var position = element.getStyle('position'),
+ width = element.getStyle('width');
+
+ element.setStyle({
+ position: 'absolute',
+ visibility: 'hidden',
+ display: 'block'
+ });
+
+ var positionedWidth = element.getStyle('width');
+
+ var newWidth;
+ if (width && (positionedWidth === width)) {
+ newWidth = getPixelValue(width);
+ } else if (width && (position === 'absolute' || position === 'fixed')) {
+ newWidth = getPixelValue(width);
+ } else {
+ var parent = element.parentNode, pLayout = $(parent).getLayout();
+
+ newWidth = pLayout.get('width') -
+ this.get('margin-left') -
+ this.get('border-left') -
+ this.get('padding-left') -
+ this.get('padding-right') -
+ this.get('border-right') -
+ this.get('margin-right');
+ }
+
+ element.setStyle({ width: newWidth + 'px' });
+
+ this._prepared = true;
},
- className: "[contains(concat(' ', @class, ' '), ' #{1} ')]",
- id: "[@id='#{1}']",
- attrPresence: function(m) {
- m[1] = m[1].toLowerCase();
- return new Template("[@#{1}]").evaluate(m);
+
+ _end: function() {
+ var element = this.element;
+ var originalStyles = element.retrieve('prototype_original_styles');
+ element.store('prototype_original_styles', null);
+ element.setStyle(originalStyles);
+ this._prepared = false;
},
- attr: function(m) {
- m[1] = m[1].toLowerCase();
- m[3] = m[5] || m[6];
- return new Template(Selector.xpath.operators[m[2]]).evaluate(m);
+
+ _compute: function(property) {
+ var COMPUTATIONS = Element.Layout.COMPUTATIONS;
+ if (!(property in COMPUTATIONS)) {
+ throw "Property not found.";
+ }
+ return this._set(property, COMPUTATIONS[property].call(this, this.element));
},
- pseudo: function(m) {
- var h = Selector.xpath.pseudos[m[1]];
- if (!h) return '';
- if (Object.isFunction(h)) return h(m);
- return new Template(Selector.xpath.pseudos[m[1]]).evaluate(m);
+
+ toObject: function() {
+ var args = $A(arguments);
+ var keys = (args.length === 0) ? Element.Layout.PROPERTIES :
+ args.join(' ').split(' ');
+ var obj = {};
+ keys.each( function(key) {
+ if (!Element.Layout.PROPERTIES.include(key)) return;
+ var value = this.get(key);
+ if (value != null) obj[key] = value;
+ }, this);
+ return obj;
},
- operators: {
- '=': "[@#{1}='#{3}']",
- '!=': "[@#{1}!='#{3}']",
- '^=': "[starts-with(@#{1}, '#{3}')]",
- '$=': "[substring(@#{1}, (string-length(@#{1}) - string-length('#{3}') + 1))='#{3}']",
- '*=': "[contains(@#{1}, '#{3}')]",
- '~=': "[contains(concat(' ', @#{1}, ' '), ' #{3} ')]",
- '|=': "[contains(concat('-', @#{1}, '-'), '-#{3}-')]"
+
+ toHash: function() {
+ var obj = this.toObject.apply(this, arguments);
+ return new Hash(obj);
},
- pseudos: {
- 'first-child': '[not(preceding-sibling::*)]',
- 'last-child': '[not(following-sibling::*)]',
- 'only-child': '[not(preceding-sibling::* or following-sibling::*)]',
- 'empty': "[count(*) = 0 and (count(text()) = 0 or translate(text(), ' \t\r\n', '') = '')]",
- 'checked': "[@checked]",
- 'disabled': "[@disabled]",
- 'enabled': "[not(@disabled)]",
- 'not': function(m) {
- var e = m[6], p = Selector.patterns,
- x = Selector.xpath, le, v;
-
- var exclusion = [];
- while (e && le != e && (/\S/).test(e)) {
- le = e;
- for (var i in p) {
- if (m = e.match(p[i])) {
- v = Object.isFunction(x[i]) ? x[i](m) : new Template(x[i]).evaluate(m);
- exclusion.push("(" + v.substring(1, v.length - 1) + ")");
- e = e.replace(m[0], '');
- break;
- }
- }
- }
- return "[not(" + exclusion.join(" and ") + ")]";
+
+ toCSS: function() {
+ var args = $A(arguments);
+ var keys = (args.length === 0) ? Element.Layout.PROPERTIES :
+ args.join(' ').split(' ');
+ var css = {};
+
+ keys.each( function(key) {
+ if (!Element.Layout.PROPERTIES.include(key)) return;
+ if (Element.Layout.COMPOSITE_PROPERTIES.include(key)) return;
+
+ var value = this.get(key);
+ if (value != null) css[cssNameFor(key)] = value + 'px';
+ }, this);
+ return css;
+ },
+
+ inspect: function() {
+ return "#<Element.Layout>";
+ }
+ });
+
+ Object.extend(Element.Layout, {
+ PROPERTIES: $w('height width top left right bottom border-left border-right border-top border-bottom padding-left padding-right padding-top padding-bottom margin-top margin-bottom margin-left margin-right padding-box-width padding-box-height border-box-width border-box-height margin-box-width margin-box-height'),
+
+ COMPOSITE_PROPERTIES: $w('padding-box-width padding-box-height margin-box-width margin-box-height border-box-width border-box-height'),
+
+ COMPUTATIONS: {
+ 'height': function(element) {
+ if (!this._preComputing) this._begin();
+
+ var bHeight = this.get('border-box-height');
+ if (bHeight <= 0) return 0;
+
+ var bTop = this.get('border-top'),
+ bBottom = this.get('border-bottom');
+
+ var pTop = this.get('padding-top'),
+ pBottom = this.get('padding-bottom');
+
+ if (!this._preComputing) this._end();
+
+ return bHeight - bTop - bBottom - pTop - pBottom;
},
- 'nth-child': function(m) {
- return Selector.xpath.pseudos.nth("(count(./preceding-sibling::*) + 1) ", m);
+
+ 'width': function(element) {
+ if (!this._preComputing) this._begin();
+
+ var bWidth = this.get('border-box-width');
+ if (bWidth <= 0) return 0;
+
+ var bLeft = this.get('border-left'),
+ bRight = this.get('border-right');
+
+ var pLeft = this.get('padding-left'),
+ pRight = this.get('padding-right');
+
+ if (!this._preComputing) this._end();
+
+ return bWidth - bLeft - bRight - pLeft - pRight;
},
- 'nth-last-child': function(m) {
- return Selector.xpath.pseudos.nth("(count(./following-sibling::*) + 1) ", m);
+
+ 'padding-box-height': function(element) {
+ var height = this.get('height'),
+ pTop = this.get('padding-top'),
+ pBottom = this.get('padding-bottom');
+
+ return height + pTop + pBottom;
},
- 'nth-of-type': function(m) {
- return Selector.xpath.pseudos.nth("position() ", m);
+
+ 'padding-box-width': function(element) {
+ var width = this.get('width'),
+ pLeft = this.get('padding-left'),
+ pRight = this.get('padding-right');
+
+ return width + pLeft + pRight;
},
- 'nth-last-of-type': function(m) {
- return Selector.xpath.pseudos.nth("(last() + 1 - position()) ", m);
+
+ 'border-box-height': function(element) {
+ return element.offsetHeight;
},
- 'first-of-type': function(m) {
- m[6] = "1"; return Selector.xpath.pseudos['nth-of-type'](m);
+
+ 'border-box-width': function(element) {
+ return element.offsetWidth;
},
- 'last-of-type': function(m) {
- m[6] = "1"; return Selector.xpath.pseudos['nth-last-of-type'](m);
+
+ 'margin-box-height': function(element) {
+ var bHeight = this.get('border-box-height'),
+ mTop = this.get('margin-top'),
+ mBottom = this.get('margin-bottom');
+
+ if (bHeight <= 0) return 0;
+
+ return bHeight + mTop + mBottom;
},
- 'only-of-type': function(m) {
- var p = Selector.xpath.pseudos; return p['first-of-type'](m) + p['last-of-type'](m);
+
+ 'margin-box-width': function(element) {
+ var bWidth = this.get('border-box-width'),
+ mLeft = this.get('margin-left'),
+ mRight = this.get('margin-right');
+
+ if (bWidth <= 0) return 0;
+
+ return bWidth + mLeft + mRight;
},
- nth: function(fragment, m) {
- var mm, formula = m[6], predicate;
- if (formula == 'even') formula = '2n+0';
- if (formula == 'odd') formula = '2n+1';
- if (mm = formula.match(/^(\d+)$/)) // digit only
- return '[' + fragment + "= " + mm[1] + ']';
- if (mm = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { // an+b
- if (mm[1] == "-") mm[1] = -1;
- var a = mm[1] ? Number(mm[1]) : 1;
- var b = mm[2] ? Number(mm[2]) : 0;
- predicate = "[((#{fragment} - #{b}) mod #{a} = 0) and " +
- "((#{fragment} - #{b}) div #{a} >= 0)]";
- return new Template(predicate).evaluate({
- fragment: fragment, a: a, b: b });
- }
+
+ 'top': function(element) {
+ var offset = element.positionedOffset();
+ return offset.top;
+ },
+
+ 'bottom': function(element) {
+ var offset = element.positionedOffset(),
+ parent = element.getOffsetParent(),
+ pHeight = parent.measure('height');
+
+ var mHeight = this.get('border-box-height');
+
+ return pHeight - mHeight - offset.top;
+ },
+
+ 'left': function(element) {
+ var offset = element.positionedOffset();
+ return offset.left;
+ },
+
+ 'right': function(element) {
+ var offset = element.positionedOffset(),
+ parent = element.getOffsetParent(),
+ pWidth = parent.measure('width');
+
+ var mWidth = this.get('border-box-width');
+
+ return pWidth - mWidth - offset.left;
+ },
+
+ 'padding-top': function(element) {
+ return getPixelValue(element, 'paddingTop');
+ },
+
+ 'padding-bottom': function(element) {
+ return getPixelValue(element, 'paddingBottom');
+ },
+
+ 'padding-left': function(element) {
+ return getPixelValue(element, 'paddingLeft');
+ },
+
+ 'padding-right': function(element) {
+ return getPixelValue(element, 'paddingRight');
+ },
+
+ 'border-top': function(element) {
+ return Object.isNumber(element.clientTop) ? element.clientTop :
+ getPixelValue(element, 'borderTopWidth');
+ },
+
+ 'border-bottom': function(element) {
+ return Object.isNumber(element.clientBottom) ? element.clientBottom :
+ getPixelValue(element, 'borderBottomWidth');
+ },
+
+ 'border-left': function(element) {
+ return Object.isNumber(element.clientLeft) ? element.clientLeft :
+ getPixelValue(element, 'borderLeftWidth');
+ },
+
+ 'border-right': function(element) {
+ return Object.isNumber(element.clientRight) ? element.clientRight :
+ getPixelValue(element, 'borderRightWidth');
+ },
+
+ 'margin-top': function(element) {
+ return getPixelValue(element, 'marginTop');
+ },
+
+ 'margin-bottom': function(element) {
+ return getPixelValue(element, 'marginBottom');
+ },
+
+ 'margin-left': function(element) {
+ return getPixelValue(element, 'marginLeft');
+ },
+
+ 'margin-right': function(element) {
+ return getPixelValue(element, 'marginRight');
}
}
- },
+ });
- criteria: {
- tagName: 'n = h.tagName(n, r, "#{1}", c); c = false;',
- className: 'n = h.className(n, r, "#{1}", c); c = false;',
- id: 'n = h.id(n, r, "#{1}", c); c = false;',
- attrPresence: 'n = h.attrPresence(n, r, "#{1}"); c = false;',
- attr: function(m) {
- m[3] = (m[5] || m[6]);
- return new Template('n = h.attr(n, r, "#{1}", "#{3}", "#{2}"); c = false;').evaluate(m);
- },
- pseudo: function(m) {
- if (m[6]) m[6] = m[6].replace(/"/g, '\\"');
- return new Template('n = h.pseudo(n, "#{1}", "#{6}", r, c); c = false;').evaluate(m);
- },
- descendant: 'c = "descendant";',
- child: 'c = "child";',
- adjacent: 'c = "adjacent";',
- laterSibling: 'c = "laterSibling";'
- },
-
- patterns: {
- // combinators must be listed first
- // (and descendant needs to be last combinator)
- laterSibling: /^\s*~\s*/,
- child: /^\s*>\s*/,
- adjacent: /^\s*\+\s*/,
- descendant: /^\s/,
-
- // selectors follow
- tagName: /^\s*(\*|[\w\-]+)(\b|$)?/,
- id: /^#([\w\-\*]+)(\b|$)/,
- className: /^\.([\w\-\*]+)(\b|$)/,
- pseudo: /^:((first|last|nth|nth-last|only)(-child|-of-type)|empty|checked|(en|dis)abled|not)(\((.*?)\))?(\b|$|(?=\s)|(?=:))/,
- attrPresence: /^\[([\w]+)\]/,
- attr: /\[((?:[\w-]*:)?[\w-]+)\s*(?:([!^$*~|]?=)\s*((['"])([^\4]*?)\4|([^'"][^\]]*?)))?\]/
- },
-
- // for Selector.match and Element#match
- assertions: {
- tagName: function(element, matches) {
- return matches[1].toUpperCase() == element.tagName.toUpperCase();
+ if ('getBoundingClientRect' in document.documentElement) {
+ Object.extend(Element.Layout.COMPUTATIONS, {
+ 'right': function(element) {
+ var parent = hasLayout(element.getOffsetParent());
+ var rect = element.getBoundingClientRect(),
+ pRect = parent.getBoundingClientRect();
+
+ return (pRect.right - rect.right).round();
+ },
+
+ 'bottom': function(element) {
+ var parent = hasLayout(element.getOffsetParent());
+ var rect = element.getBoundingClientRect(),
+ pRect = parent.getBoundingClientRect();
+
+ return (pRect.bottom - rect.bottom).round();
+ }
+ });
+ }
+
+ Element.Offset = Class.create({
+ initialize: function(left, top) {
+ this.left = left.round();
+ this.top = top.round();
+
+ this[0] = this.left;
+ this[1] = this.top;
},
- className: function(element, matches) {
- return Element.hasClassName(element, matches[1]);
+ relativeTo: function(offset) {
+ return new Element.Offset(
+ this.left - offset.left,
+ this.top - offset.top
+ );
},
- id: function(element, matches) {
- return element.id === matches[1];
+ inspect: function() {
+ return "#<Element.Offset left: #{left} top: #{top}>".interpolate(this);
},
- attrPresence: function(element, matches) {
- return Element.hasAttribute(element, matches[1]);
+ toString: function() {
+ return "[#{left}, #{top}]".interpolate(this);
},
- attr: function(element, matches) {
- var nodeValue = Element.readAttribute(element, matches[1]);
- return Selector.operators[matches[2]](nodeValue, matches[3]);
+ toArray: function() {
+ return [this.left, this.top];
}
- },
+ });
- handlers: {
- // UTILITY FUNCTIONS
- // joins two collections
- concat: function(a, b) {
- for (var i = 0, node; node = b[i]; i++)
- a.push(node);
- return a;
- },
+ function getLayout(element, preCompute) {
+ return new Element.Layout(element, preCompute);
+ }
- // marks an array of nodes for counting
- mark: function(nodes) {
- for (var i = 0, node; node = nodes[i]; i++)
- node._counted = true;
- return nodes;
- },
+ function measure(element, property) {
+ return $(element).getLayout().get(property);
+ }
- unmark: function(nodes) {
- for (var i = 0, node; node = nodes[i]; i++)
- node._counted = undefined;
- return nodes;
- },
+ function getDimensions(element) {
+ var layout = $(element).getLayout();
+ return {
+ width: layout.get('width'),
+ height: layout.get('height')
+ };
+ }
- // mark each child node with its position (for nth calls)
- // "ofType" flag indicates whether we're indexing for nth-of-type
- // rather than nth-child
- index: function(parentNode, reverse, ofType) {
- parentNode._counted = true;
- if (reverse) {
- for (var nodes = parentNode.childNodes, i = nodes.length - 1, j = 1; i >= 0; i--) {
- var node = nodes[i];
- if (node.nodeType == 1 && (!ofType || node._counted)) node.nodeIndex = j++;
- }
- } else {
- for (var i = 0, j = 1, nodes = parentNode.childNodes; node = nodes[i]; i++)
- if (node.nodeType == 1 && (!ofType || node._counted)) node.nodeIndex = j++;
+ function getOffsetParent(element) {
+ if (isDetached(element)) return $(document.body);
+
+ var isInline = (Element.getStyle(element, 'display') === 'inline');
+ if (!isInline && element.offsetParent) return $(element.offsetParent);
+ if (element === document.body) return $(element);
+
+ while ((element = element.parentNode) && element !== document.body) {
+ if (Element.getStyle(element, 'position') !== 'static') {
+ return (element.nodeName === 'HTML') ? $(document.body) : $(element);
}
- },
+ }
- // filters out duplicates and extends all nodes
- unique: function(nodes) {
- if (nodes.length == 0) return nodes;
- var results = [], n;
- for (var i = 0, l = nodes.length; i < l; i++)
- if (!(n = nodes[i])._counted) {
- n._counted = true;
- results.push(Element.extend(n));
- }
- return Selector.handlers.unmark(results);
- },
+ return $(document.body);
+ }
- // COMBINATOR FUNCTIONS
- descendant: function(nodes) {
- var h = Selector.handlers;
- for (var i = 0, results = [], node; node = nodes[i]; i++)
- h.concat(results, node.getElementsByTagName('*'));
- return results;
- },
- child: function(nodes) {
- var h = Selector.handlers;
- for (var i = 0, results = [], node; node = nodes[i]; i++) {
- for (var j = 0, child; child = node.childNodes[j]; j++)
- if (child.nodeType == 1 && child.tagName != '!') results.push(child);
- }
- return results;
- },
+ function cumulativeOffset(element) {
+ var valueT = 0, valueL = 0;
+ do {
+ valueT += element.offsetTop || 0;
+ valueL += element.offsetLeft || 0;
+ element = element.offsetParent;
+ } while (element);
+ return new Element.Offset(valueL, valueT);
+ }
+
+ function positionedOffset(element) {
+ var layout = element.getLayout();
- adjacent: function(nodes) {
- for (var i = 0, results = [], node; node = nodes[i]; i++) {
- var next = this.nextElementSibling(node);
- if (next) results.push(next);
+ var valueT = 0, valueL = 0;
+ do {
+ valueT += element.offsetTop || 0;
+ valueL += element.offsetLeft || 0;
+ element = element.offsetParent;
+ if (element) {
+ if (isBody(element)) break;
+ var p = Element.getStyle(element, 'position');
+ if (p !== 'static') break;
}
- return results;
- },
+ } while (element);
- laterSibling: function(nodes) {
- var h = Selector.handlers;
- for (var i = 0, results = [], node; node = nodes[i]; i++)
- h.concat(results, Element.nextSiblings(node));
- return results;
- },
+ valueL -= layout.get('margin-top');
+ valueT -= layout.get('margin-left');
- nextElementSibling: function(node) {
- while (node = node.nextSibling)
- if (node.nodeType == 1) return node;
- return null;
- },
+ return new Element.Offset(valueL, valueT);
+ }
- previousElementSibling: function(node) {
- while (node = node.previousSibling)
- if (node.nodeType == 1) return node;
- return null;
- },
+ function cumulativeScrollOffset(element) {
+ var valueT = 0, valueL = 0;
+ do {
+ valueT += element.scrollTop || 0;
+ valueL += element.scrollLeft || 0;
+ element = element.parentNode;
+ } while (element);
+ return new Element.Offset(valueL, valueT);
+ }
- // TOKEN FUNCTIONS
- tagName: function(nodes, root, tagName, combinator) {
- tagName = tagName.toUpperCase();
- var results = [], h = Selector.handlers;
- if (nodes) {
- if (combinator) {
- // fastlane for ordinary descendant combinators
- if (combinator == "descendant") {
- for (var i = 0, node; node = nodes[i]; i++)
- h.concat(results, node.getElementsByTagName(tagName));
- return results;
- } else nodes = this[combinator](nodes);
- if (tagName == "*") return nodes;
- }
- for (var i = 0, node; node = nodes[i]; i++)
- if (node.tagName.toUpperCase() == tagName) results.push(node);
- return results;
- } else return root.getElementsByTagName(tagName);
- },
+ function viewportOffset(forElement) {
+ var valueT = 0, valueL = 0, docBody = document.body;
- id: function(nodes, root, id, combinator) {
- var targetNode = $(id), h = Selector.handlers;
- if (!targetNode) return [];
- if (!nodes && root == document) return [targetNode];
- if (nodes) {
- if (combinator) {
- if (combinator == 'child') {
- for (var i = 0, node; node = nodes[i]; i++)
- if (targetNode.parentNode == node) return [targetNode];
- } else if (combinator == 'descendant') {
- for (var i = 0, node; node = nodes[i]; i++)
- if (Element.descendantOf(targetNode, node)) return [targetNode];
- } else if (combinator == 'adjacent') {
- for (var i = 0, node; node = nodes[i]; i++)
- if (Selector.handlers.previousElementSibling(targetNode) == node)
- return [targetNode];
- } else nodes = h[combinator](nodes);
- }
- for (var i = 0, node; node = nodes[i]; i++)
- if (node == targetNode) return [targetNode];
- return [];
+ var element = forElement;
+ do {
+ valueT += element.offsetTop || 0;
+ valueL += element.offsetLeft || 0;
+ if (element.offsetParent == docBody &&
+ Element.getStyle(element, 'position') == 'absolute') break;
+ } while (element = element.offsetParent);
+
+ element = forElement;
+ do {
+ if (element != docBody) {
+ valueT -= element.scrollTop || 0;
+ valueL -= element.scrollLeft || 0;
}
- return (targetNode && Element.descendantOf(targetNode, root)) ? [targetNode] : [];
- },
+ } while (element = element.parentNode);
+ return new Element.Offset(valueL, valueT);
+ }
- className: function(nodes, root, className, combinator) {
- if (nodes && combinator) nodes = this[combinator](nodes);
- return Selector.handlers.byClassName(nodes, root, className);
- },
+ function absolutize(element) {
+ element = $(element);
- byClassName: function(nodes, root, className) {
- if (!nodes) nodes = Selector.handlers.descendant([root]);
- var needle = ' ' + className + ' ';
- for (var i = 0, results = [], node, nodeClassName; node = nodes[i]; i++) {
- nodeClassName = node.className;
- if (nodeClassName.length == 0) continue;
- if (nodeClassName == className || (' ' + nodeClassName + ' ').include(needle))
- results.push(node);
- }
- return results;
- },
+ if (Element.getStyle(element, 'position') === 'absolute') {
+ return element;
+ }
- attrPresence: function(nodes, root, attr) {
- if (!nodes) nodes = root.getElementsByTagName("*");
- var results = [];
- for (var i = 0, node; node = nodes[i]; i++)
- if (Element.hasAttribute(node, attr)) results.push(node);
- return results;
- },
+ var offsetParent = getOffsetParent(element);
+ var eOffset = element.viewportOffset(),
+ pOffset = offsetParent.viewportOffset();
- attr: function(nodes, root, attr, value, operator) {
- if (!nodes) nodes = root.getElementsByTagName("*");
- var handler = Selector.operators[operator], results = [];
- for (var i = 0, node; node = nodes[i]; i++) {
- var nodeValue = Element.readAttribute(node, attr);
- if (nodeValue === null) continue;
- if (handler(nodeValue, value)) results.push(node);
- }
- return results;
- },
+ var offset = eOffset.relativeTo(pOffset);
+ var layout = element.getLayout();
- pseudo: function(nodes, name, value, root, combinator) {
- if (nodes && combinator) nodes = this[combinator](nodes);
- if (!nodes) nodes = root.getElementsByTagName("*");
- return Selector.pseudos[name](nodes, value, root);
+ element.store('prototype_absolutize_original_styles', {
+ left: element.getStyle('left'),
+ top: element.getStyle('top'),
+ width: element.getStyle('width'),
+ height: element.getStyle('height')
+ });
+
+ element.setStyle({
+ position: 'absolute',
+ top: offset.top + 'px',
+ left: offset.left + 'px',
+ width: layout.get('width') + 'px',
+ height: layout.get('height') + 'px'
+ });
+
+ return element;
+ }
+
+ function relativize(element) {
+ element = $(element);
+ if (Element.getStyle(element, 'position') === 'relative') {
+ return element;
}
- },
- pseudos: {
- 'first-child': function(nodes, value, root) {
- for (var i = 0, results = [], node; node = nodes[i]; i++) {
- if (Selector.handlers.previousElementSibling(node)) continue;
- results.push(node);
- }
- return results;
- },
- 'last-child': function(nodes, value, root) {
- for (var i = 0, results = [], node; node = nodes[i]; i++) {
- if (Selector.handlers.nextElementSibling(node)) continue;
- results.push(node);
- }
- return results;
- },
- 'only-child': function(nodes, value, root) {
- var h = Selector.handlers;
- for (var i = 0, results = [], node; node = nodes[i]; i++)
- if (!h.previousElementSibling(node) && !h.nextElementSibling(node))
- results.push(node);
- return results;
- },
- 'nth-child': function(nodes, formula, root) {
- return Selector.pseudos.nth(nodes, formula, root);
- },
- 'nth-last-child': function(nodes, formula, root) {
- return Selector.pseudos.nth(nodes, formula, root, true);
- },
- 'nth-of-type': function(nodes, formula, root) {
- return Selector.pseudos.nth(nodes, formula, root, false, true);
- },
- 'nth-last-of-type': function(nodes, formula, root) {
- return Selector.pseudos.nth(nodes, formula, root, true, true);
- },
- 'first-of-type': function(nodes, formula, root) {
- return Selector.pseudos.nth(nodes, "1", root, false, true);
- },
- 'last-of-type': function(nodes, formula, root) {
- return Selector.pseudos.nth(nodes, "1", root, true, true);
- },
- 'only-of-type': function(nodes, formula, root) {
- var p = Selector.pseudos;
- return p['last-of-type'](p['first-of-type'](nodes, formula, root), formula, root);
- },
+ var originalStyles =
+ element.retrieve('prototype_absolutize_original_styles');
- // handles the an+b logic
- getIndices: function(a, b, total) {
- if (a == 0) return b > 0 ? [b] : [];
- return $R(1, total).inject([], function(memo, i) {
- if (0 == (i - b) % a && (i - b) / a >= 0) memo.push(i);
- return memo;
- });
- },
+ if (originalStyles) element.setStyle(originalStyles);
+ return element;
+ }
- // handles nth(-last)-child, nth(-last)-of-type, and (first|last)-of-type
- nth: function(nodes, formula, root, reverse, ofType) {
- if (nodes.length == 0) return [];
- if (formula == 'even') formula = '2n+0';
- if (formula == 'odd') formula = '2n+1';
- var h = Selector.handlers, results = [], indexed = [], m;
- h.mark(nodes);
- for (var i = 0, node; node = nodes[i]; i++) {
- if (!node.parentNode._counted) {
- h.index(node.parentNode, reverse, ofType);
- indexed.push(node.parentNode);
- }
- }
- if (formula.match(/^\d+$/)) { // just a number
- formula = Number(formula);
- for (var i = 0, node; node = nodes[i]; i++)
- if (node.nodeIndex == formula) results.push(node);
- } else if (m = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { // an+b
- if (m[1] == "-") m[1] = -1;
- var a = m[1] ? Number(m[1]) : 1;
- var b = m[2] ? Number(m[2]) : 0;
- var indices = Selector.pseudos.getIndices(a, b, nodes.length);
- for (var i = 0, node, l = indices.length; node = nodes[i]; i++) {
- for (var j = 0; j < l; j++)
- if (node.nodeIndex == indices[j]) results.push(node);
+ Element.addMethods({
+ getLayout: getLayout,
+ measure: measure,
+ getDimensions: getDimensions,
+ getOffsetParent: getOffsetParent,
+ cumulativeOffset: cumulativeOffset,
+ positionedOffset: positionedOffset,
+ cumulativeScrollOffset: cumulativeScrollOffset,
+ viewportOffset: viewportOffset,
+ absolutize: absolutize,
+ relativize: relativize
+ });
+
+ function isBody(element) {
+ return element.nodeName.toUpperCase() === 'BODY';
+ }
+
+ function isDetached(element) {
+ return element !== document.body &&
+ !Element.descendantOf(element, document.body);
+ }
+
+ if ('getBoundingClientRect' in document.documentElement) {
+ Element.addMethods({
+ viewportOffset: function(element) {
+ element = $(element);
+ if (isDetached(element)) return new Element.Offset(0, 0);
+
+ var rect = element.getBoundingClientRect(),
+ docEl = document.documentElement;
+ return new Element.Offset(rect.left - docEl.clientLeft,
+ rect.top - docEl.clientTop);
+ },
+
+ positionedOffset: function(element) {
+ element = $(element);
+ var parent = element.getOffsetParent();
+ if (isDetached(element)) return new Element.Offset(0, 0);
+
+ if (element.offsetParent &&
+ element.offsetParent.nodeName.toUpperCase() === 'HTML') {
+ return positionedOffset(element);
}
- }
- h.unmark(nodes);
- h.unmark(indexed);
- return results;
- },
- 'empty': function(nodes, value, root) {
- for (var i = 0, results = [], node; node = nodes[i]; i++) {
- // IE treats comments as element nodes
- if (node.tagName == '!' || (node.firstChild && !node.innerHTML.match(/^\s*$/))) continue;
- results.push(node);
- }
- return results;
- },
+ var eOffset = element.viewportOffset(),
+ pOffset = isBody(parent) ? viewportOffset(parent) :
+ parent.viewportOffset();
+ var retOffset = eOffset.relativeTo(pOffset);
- 'not': function(nodes, selector, root) {
- var h = Selector.handlers, selectorType, m;
- var exclusions = new Selector(selector).findElements(root);
- h.mark(exclusions);
- for (var i = 0, results = [], node; node = nodes[i]; i++)
- if (!node._counted) results.push(node);
- h.unmark(exclusions);
- return results;
- },
+ var layout = element.getLayout();
+ var top = retOffset.top - layout.get('margin-top');
+ var left = retOffset.left - layout.get('margin-left');
- 'enabled': function(nodes, value, root) {
- for (var i = 0, results = [], node; node = nodes[i]; i++)
- if (!node.disabled) results.push(node);
- return results;
- },
+ return new Element.Offset(left, top);
+ }
+ });
+ }
+})();
+window.$$ = function() {
+ var expression = $A(arguments).join(', ');
+ return Prototype.Selector.select(expression, document);
+};
- 'disabled': function(nodes, value, root) {
- for (var i = 0, results = [], node; node = nodes[i]; i++)
- if (node.disabled) results.push(node);
- return results;
- },
+Prototype.Selector = (function() {
- 'checked': function(nodes, value, root) {
- for (var i = 0, results = [], node; node = nodes[i]; i++)
- if (node.checked) results.push(node);
- return results;
- }
- },
+ function select() {
+ throw new Error('Method "Prototype.Selector.select" must be defined.');
+ }
- operators: {
- '=': function(nv, v) { return nv == v; },
- '!=': function(nv, v) { return nv != v; },
- '^=': function(nv, v) { return nv.startsWith(v); },
- '$=': function(nv, v) { return nv.endsWith(v); },
- '*=': function(nv, v) { return nv.include(v); },
- '~=': function(nv, v) { return (' ' + nv + ' ').include(' ' + v + ' '); },
- '|=': function(nv, v) { return ('-' + nv.toUpperCase() + '-').include('-' + v.toUpperCase() + '-'); }
- },
+ function match() {
+ throw new Error('Method "Prototype.Selector.match" must be defined.');
+ }
- matchElements: function(elements, expression) {
- var matches = new Selector(expression).findElements(), h = Selector.handlers;
- h.mark(matches);
- for (var i = 0, results = [], element; element = elements[i]; i++)
- if (element._counted) results.push(element);
- h.unmark(matches);
- return results;
- },
+ function find(elements, expression, index) {
+ index = index || 0;
+ var match = Prototype.Selector.match, length = elements.length, matchIndex = 0, i;
- findElement: function(elements, expression, index) {
- if (Object.isNumber(expression)) {
- index = expression; expression = false;
+ for (i = 0; i < length; i++) {
+ if (match(elements[i], expression) && index == matchIndex++) {
+ return Element.extend(elements[i]);
+ }
}
- return Selector.matchElements(elements, expression || '*')[index || 0];
- },
+ }
- findChildElements: function(element, expressions) {
- var exprs = expressions.join(',');
- expressions = [];
- exprs.scan(/(([\w#:.~>+()\s-]+|\*|\[.*?\])+)\s*(,|$)/, function(m) {
- expressions.push(m[1].strip());
- });
- var results = [], h = Selector.handlers;
- for (var i = 0, l = expressions.length, selector; i < l; i++) {
- selector = new Selector(expressions[i].strip());
- h.concat(results, selector.findElements(element));
+ function extendElements(elements) {
+ for (var i = 0, length = elements.length; i < length; i++) {
+ Element.extend(elements[i]);
}
- return (l > 1) ? h.unique(results) : results;
+ return elements;
}
-});
-if (Prototype.Browser.IE) {
- // IE returns comment nodes on getElementsByTagName("*").
- // Filter them out.
- Selector.handlers.concat = function(a, b) {
- for (var i = 0, node; node = b[i]; i++)
- if (node.tagName !== "!") a.push(node);
- return a;
+
+ var K = Prototype.K;
+
+ return {
+ select: select,
+ match: match,
+ find: find,
+ extendElements: (Element.extend === K) ? K : extendElements,
+ extendElement: Element.extend
};
+})();
+Prototype._original_property = window.Sizzle;
+/*!
+ * Sizzle CSS Selector Engine - v1.0
+ * Copyright 2009, The Dojo Foundation
+ * Released under the MIT, BSD, and GPL Licenses.
+ * More information: http://sizzlejs.com/
+ */
+(function(){
+
+var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
+ done = 0,
+ toString = Object.prototype.toString,
+ hasDuplicate = false,
+ baseHasDuplicate = true;
+
+[0, 0].sort(function(){
+ baseHasDuplicate = false;
+ return 0;
+});
+
+var Sizzle = function(selector, context, results, seed) {
+ results = results || [];
+ var origContext = context = context || document;
+
+ if ( context.nodeType !== 1 && context.nodeType !== 9 ) {
+ return [];
+ }
+
+ if ( !selector || typeof selector !== "string" ) {
+ return results;
+ }
+
+ var parts = [], m, set, checkSet, check, mode, extra, prune = true, contextXML = isXML(context),
+ soFar = selector;
+
+ while ( (chunker.exec(""), m = chunker.exec(soFar)) !== null ) {
+ soFar = m[3];
+
+ parts.push( m[1] );
+
+ if ( m[2] ) {
+ extra = m[3];
+ break;
+ }
+ }
+
+ if ( parts.length > 1 && origPOS.exec( selector ) ) {
+ if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
+ set = posProcess( parts[0] + parts[1], context );
+ } else {
+ set = Expr.relative[ parts[0] ] ?
+ [ context ] :
+ Sizzle( parts.shift(), context );
+
+ while ( parts.length ) {
+ selector = parts.shift();
+
+ if ( Expr.relative[ selector ] )
+ selector += parts.shift();
+
+ set = posProcess( selector, set );
+ }
+ }
+ } else {
+ if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML &&
+ Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) {
+ var ret = Sizzle.find( parts.shift(), context, contextXML );
+ context = ret.expr ? Sizzle.filter( ret.expr, ret.set )[0] : ret.set[0];
+ }
+
+ if ( context ) {
+ var ret = seed ?
+ { expr: parts.pop(), set: makeArray(seed) } :
+ Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML );
+ set = ret.expr ? Sizzle.filter( ret.expr, ret.set ) : ret.set;
+
+ if ( parts.length > 0 ) {
+ checkSet = makeArray(set);
+ } else {
+ prune = false;
+ }
+
+ while ( parts.length ) {
+ var cur = parts.pop(), pop = cur;
+
+ if ( !Expr.relative[ cur ] ) {
+ cur = "";
+ } else {
+ pop = parts.pop();
+ }
+
+ if ( pop == null ) {
+ pop = context;
+ }
+
+ Expr.relative[ cur ]( checkSet, pop, contextXML );
+ }
+ } else {
+ checkSet = parts = [];
+ }
+ }
+
+ if ( !checkSet ) {
+ checkSet = set;
+ }
+
+ if ( !checkSet ) {
+ throw "Syntax error, unrecognized expression: " + (cur || selector);
+ }
+
+ if ( toString.call(checkSet) === "[object Array]" ) {
+ if ( !prune ) {
+ results.push.apply( results, checkSet );
+ } else if ( context && context.nodeType === 1 ) {
+ for ( var i = 0; checkSet[i] != null; i++ ) {
+ if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && contains(context, checkSet[i])) ) {
+ results.push( set[i] );
+ }
+ }
+ } else {
+ for ( var i = 0; checkSet[i] != null; i++ ) {
+ if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
+ results.push( set[i] );
+ }
+ }
+ }
+ } else {
+ makeArray( checkSet, results );
+ }
+
+ if ( extra ) {
+ Sizzle( extra, origContext, results, seed );
+ Sizzle.uniqueSort( results );
+ }
+
+ return results;
+};
+
+Sizzle.uniqueSort = function(results){
+ if ( sortOrder ) {
+ hasDuplicate = baseHasDuplicate;
+ results.sort(sortOrder);
+
+ if ( hasDuplicate ) {
+ for ( var i = 1; i < results.length; i++ ) {
+ if ( results[i] === results[i-1] ) {
+ results.splice(i--, 1);
+ }
+ }
+ }
+ }
+
+ return results;
+};
+
+Sizzle.matches = function(expr, set){
+ return Sizzle(expr, null, null, set);
+};
+
+Sizzle.find = function(expr, context, isXML){
+ var set, match;
+
+ if ( !expr ) {
+ return [];
+ }
+
+ for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
+ var type = Expr.order[i], match;
+
+ if ( (match = Expr.leftMatch[ type ].exec( expr )) ) {
+ var left = match[1];
+ match.splice(1,1);
+
+ if ( left.substr( left.length - 1 ) !== "\\" ) {
+ match[1] = (match[1] || "").replace(/\\/g, "");
+ set = Expr.find[ type ]( match, context, isXML );
+ if ( set != null ) {
+ expr = expr.replace( Expr.match[ type ], "" );
+ break;
+ }
+ }
+ }
+ }
+
+ if ( !set ) {
+ set = context.getElementsByTagName("*");
+ }
+
+ return {set: set, expr: expr};
+};
+
+Sizzle.filter = function(expr, set, inplace, not){
+ var old = expr, result = [], curLoop = set, match, anyFound,
+ isXMLFilter = set && set[0] && isXML(set[0]);
+
+ while ( expr && set.length ) {
+ for ( var type in Expr.filter ) {
+ if ( (match = Expr.match[ type ].exec( expr )) != null ) {
+ var filter = Expr.filter[ type ], found, item;
+ anyFound = false;
+
+ if ( curLoop == result ) {
+ result = [];
+ }
+
+ if ( Expr.preFilter[ type ] ) {
+ match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
+
+ if ( !match ) {
+ anyFound = found = true;
+ } else if ( match === true ) {
+ continue;
+ }
+ }
+
+ if ( match ) {
+ for ( var i = 0; (item = curLoop[i]) != null; i++ ) {
+ if ( item ) {
+ found = filter( item, match, i, curLoop );
+ var pass = not ^ !!found;
+
+ if ( inplace && found != null ) {
+ if ( pass ) {
+ anyFound = true;
+ } else {
+ curLoop[i] = false;
+ }
+ } else if ( pass ) {
+ result.push( item );
+ anyFound = true;
+ }
+ }
+ }
+ }
+
+ if ( found !== undefined ) {
+ if ( !inplace ) {
+ curLoop = result;
+ }
+
+ expr = expr.replace( Expr.match[ type ], "" );
+
+ if ( !anyFound ) {
+ return [];
+ }
+
+ break;
+ }
+ }
+ }
+
+ if ( expr == old ) {
+ if ( anyFound == null ) {
+ throw "Syntax error, unrecognized expression: " + expr;
+ } else {
+ break;
+ }
+ }
+
+ old = expr;
+ }
+
+ return curLoop;
+};
+
+var Expr = Sizzle.selectors = {
+ order: [ "ID", "NAME", "TAG" ],
+ match: {
+ ID: /#((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
+ CLASS: /\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
+ NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/,
+ ATTR: /\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,
+ TAG: /^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/,
+ CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,
+ POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,
+ PSEUDO: /:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]*)((?:\([^\)]+\)|[^\2\(\)]*)+)\2\))?/
+ },
+ leftMatch: {},
+ attrMap: {
+ "class": "className",
+ "for": "htmlFor"
+ },
+ attrHandle: {
+ href: function(elem){
+ return elem.getAttribute("href");
+ }
+ },
+ relative: {
+ "+": function(checkSet, part, isXML){
+ var isPartStr = typeof part === "string",
+ isTag = isPartStr && !/\W/.test(part),
+ isPartStrNotTag = isPartStr && !isTag;
+
+ if ( isTag && !isXML ) {
+ part = part.toUpperCase();
+ }
+
+ for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
+ if ( (elem = checkSet[i]) ) {
+ while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}
+
+ checkSet[i] = isPartStrNotTag || elem && elem.nodeName === part ?
+ elem || false :
+ elem === part;
+ }
+ }
+
+ if ( isPartStrNotTag ) {
+ Sizzle.filter( part, checkSet, true );
+ }
+ },
+ ">": function(checkSet, part, isXML){
+ var isPartStr = typeof part === "string";
+
+ if ( isPartStr && !/\W/.test(part) ) {
+ part = isXML ? part : part.toUpperCase();
+
+ for ( var i = 0, l = checkSet.length; i < l; i++ ) {
+ var elem = checkSet[i];
+ if ( elem ) {
+ var parent = elem.parentNode;
+ checkSet[i] = parent.nodeName === part ? parent : false;
+ }
+ }
+ } else {
+ for ( var i = 0, l = checkSet.length; i < l; i++ ) {
+ var elem = checkSet[i];
+ if ( elem ) {
+ checkSet[i] = isPartStr ?
+ elem.parentNode :
+ elem.parentNode === part;
+ }
+ }
+
+ if ( isPartStr ) {
+ Sizzle.filter( part, checkSet, true );
+ }
+ }
+ },
+ "": function(checkSet, part, isXML){
+ var doneName = done++, checkFn = dirCheck;
+
+ if ( !/\W/.test(part) ) {
+ var nodeCheck = part = isXML ? part : part.toUpperCase();
+ checkFn = dirNodeCheck;
+ }
+
+ checkFn("parentNode", part, doneName, checkSet, nodeCheck, isXML);
+ },
+ "~": function(checkSet, part, isXML){
+ var doneName = done++, checkFn = dirCheck;
+
+ if ( typeof part === "string" && !/\W/.test(part) ) {
+ var nodeCheck = part = isXML ? part : part.toUpperCase();
+ checkFn = dirNodeCheck;
+ }
+
+ checkFn("previousSibling", part, doneName, checkSet, nodeCheck, isXML);
+ }
+ },
+ find: {
+ ID: function(match, context, isXML){
+ if ( typeof context.getElementById !== "undefined" && !isXML ) {
+ var m = context.getElementById(match[1]);
+ return m ? [m] : [];
+ }
+ },
+ NAME: function(match, context, isXML){
+ if ( typeof context.getElementsByName !== "undefined" ) {
+ var ret = [], results = context.getElementsByName(match[1]);
+
+ for ( var i = 0, l = results.length; i < l; i++ ) {
+ if ( results[i].getAttribute("name") === match[1] ) {
+ ret.push( results[i] );
+ }
+ }
+
+ return ret.length === 0 ? null : ret;
+ }
+ },
+ TAG: function(match, context){
+ return context.getElementsByTagName(match[1]);
+ }
+ },
+ preFilter: {
+ CLASS: function(match, curLoop, inplace, result, not, isXML){
+ match = " " + match[1].replace(/\\/g, "") + " ";
+
+ if ( isXML ) {
+ return match;
+ }
+
+ for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
+ if ( elem ) {
+ if ( not ^ (elem.className && (" " + elem.className + " ").indexOf(match) >= 0) ) {
+ if ( !inplace )
+ result.push( elem );
+ } else if ( inplace ) {
+ curLoop[i] = false;
+ }
+ }
+ }
+
+ return false;
+ },
+ ID: function(match){
+ return match[1].replace(/\\/g, "");
+ },
+ TAG: function(match, curLoop){
+ for ( var i = 0; curLoop[i] === false; i++ ){}
+ return curLoop[i] && isXML(curLoop[i]) ? match[1] : match[1].toUpperCase();
+ },
+ CHILD: function(match){
+ if ( match[1] == "nth" ) {
+ var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
+ match[2] == "even" && "2n" || match[2] == "odd" && "2n+1" ||
+ !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
+
+ match[2] = (test[1] + (test[2] || 1)) - 0;
+ match[3] = test[3] - 0;
+ }
+
+ match[0] = done++;
+
+ return match;
+ },
+ ATTR: function(match, curLoop, inplace, result, not, isXML){
+ var name = match[1].replace(/\\/g, "");
+
+ if ( !isXML && Expr.attrMap[name] ) {
+ match[1] = Expr.attrMap[name];
+ }
+
+ if ( match[2] === "~=" ) {
+ match[4] = " " + match[4] + " ";
+ }
+
+ return match;
+ },
+ PSEUDO: function(match, curLoop, inplace, result, not){
+ if ( match[1] === "not" ) {
+ if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) {
+ match[3] = Sizzle(match[3], null, null, curLoop);
+ } else {
+ var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
+ if ( !inplace ) {
+ result.push.apply( result, ret );
+ }
+ return false;
+ }
+ } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
+ return true;
+ }
+
+ return match;
+ },
+ POS: function(match){
+ match.unshift( true );
+ return match;
+ }
+ },
+ filters: {
+ enabled: function(elem){
+ return elem.disabled === false && elem.type !== "hidden";
+ },
+ disabled: function(elem){
+ return elem.disabled === true;
+ },
+ checked: function(elem){
+ return elem.checked === true;
+ },
+ selected: function(elem){
+ elem.parentNode.selectedIndex;
+ return elem.selected === true;
+ },
+ parent: function(elem){
+ return !!elem.firstChild;
+ },
+ empty: function(elem){
+ return !elem.firstChild;
+ },
+ has: function(elem, i, match){
+ return !!Sizzle( match[3], elem ).length;
+ },
+ header: function(elem){
+ return /h\d/i.test( elem.nodeName );
+ },
+ text: function(elem){
+ return "text" === elem.type;
+ },
+ radio: function(elem){
+ return "radio" === elem.type;
+ },
+ checkbox: function(elem){
+ return "checkbox" === elem.type;
+ },
+ file: function(elem){
+ return "file" === elem.type;
+ },
+ password: function(elem){
+ return "password" === elem.type;
+ },
+ submit: function(elem){
+ return "submit" === elem.type;
+ },
+ image: function(elem){
+ return "image" === elem.type;
+ },
+ reset: function(elem){
+ return "reset" === elem.type;
+ },
+ button: function(elem){
+ return "button" === elem.type || elem.nodeName.toUpperCase() === "BUTTON";
+ },
+ input: function(elem){
+ return /input|select|textarea|button/i.test(elem.nodeName);
+ }
+ },
+ setFilters: {
+ first: function(elem, i){
+ return i === 0;
+ },
+ last: function(elem, i, match, array){
+ return i === array.length - 1;
+ },
+ even: function(elem, i){
+ return i % 2 === 0;
+ },
+ odd: function(elem, i){
+ return i % 2 === 1;
+ },
+ lt: function(elem, i, match){
+ return i < match[3] - 0;
+ },
+ gt: function(elem, i, match){
+ return i > match[3] - 0;
+ },
+ nth: function(elem, i, match){
+ return match[3] - 0 == i;
+ },
+ eq: function(elem, i, match){
+ return match[3] - 0 == i;
+ }
+ },
+ filter: {
+ PSEUDO: function(elem, match, i, array){
+ var name = match[1], filter = Expr.filters[ name ];
+
+ if ( filter ) {
+ return filter( elem, i, match, array );
+ } else if ( name === "contains" ) {
+ return (elem.textContent || elem.innerText || "").indexOf(match[3]) >= 0;
+ } else if ( name === "not" ) {
+ var not = match[3];
+
+ for ( var i = 0, l = not.length; i < l; i++ ) {
+ if ( not[i] === elem ) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+ },
+ CHILD: function(elem, match){
+ var type = match[1], node = elem;
+ switch (type) {
+ case 'only':
+ case 'first':
+ while ( (node = node.previousSibling) ) {
+ if ( node.nodeType === 1 ) return false;
+ }
+ if ( type == 'first') return true;
+ node = elem;
+ case 'last':
+ while ( (node = node.nextSibling) ) {
+ if ( node.nodeType === 1 ) return false;
+ }
+ return true;
+ case 'nth':
+ var first = match[2], last = match[3];
+
+ if ( first == 1 && last == 0 ) {
+ return true;
+ }
+
+ var doneName = match[0],
+ parent = elem.parentNode;
+
+ if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {
+ var count = 0;
+ for ( node = parent.firstChild; node; node = node.nextSibling ) {
+ if ( node.nodeType === 1 ) {
+ node.nodeIndex = ++count;
+ }
+ }
+ parent.sizcache = doneName;
+ }
+
+ var diff = elem.nodeIndex - last;
+ if ( first == 0 ) {
+ return diff == 0;
+ } else {
+ return ( diff % first == 0 && diff / first >= 0 );
+ }
+ }
+ },
+ ID: function(elem, match){
+ return elem.nodeType === 1 && elem.getAttribute("id") === match;
+ },
+ TAG: function(elem, match){
+ return (match === "*" && elem.nodeType === 1) || elem.nodeName === match;
+ },
+ CLASS: function(elem, match){
+ return (" " + (elem.className || elem.getAttribute("class")) + " ")
+ .indexOf( match ) > -1;
+ },
+ ATTR: function(elem, match){
+ var name = match[1],
+ result = Expr.attrHandle[ name ] ?
+ Expr.attrHandle[ name ]( elem ) :
+ elem[ name ] != null ?
+ elem[ name ] :
+ elem.getAttribute( name ),
+ value = result + "",
+ type = match[2],
+ check = match[4];
+
+ return result == null ?
+ type === "!=" :
+ type === "=" ?
+ value === check :
+ type === "*=" ?
+ value.indexOf(check) >= 0 :
+ type === "~=" ?
+ (" " + value + " ").indexOf(check) >= 0 :
+ !check ?
+ value && result !== false :
+ type === "!=" ?
+ value != check :
+ type === "^=" ?
+ value.indexOf(check) === 0 :
+ type === "$=" ?
+ value.substr(value.length - check.length) === check :
+ type === "|=" ?
+ value === check || value.substr(0, check.length + 1) === check + "-" :
+ false;
+ },
+ POS: function(elem, match, i, array){
+ var name = match[2], filter = Expr.setFilters[ name ];
+
+ if ( filter ) {
+ return filter( elem, i, match, array );
+ }
+ }
+ }
+};
+
+var origPOS = Expr.match.POS;
+
+for ( var type in Expr.match ) {
+ Expr.match[ type ] = new RegExp( Expr.match[ type ].source + /(?![^\[]*\])(?![^\(]*\))/.source );
+ Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source );
+}
+
+var makeArray = function(array, results) {
+ array = Array.prototype.slice.call( array, 0 );
+
+ if ( results ) {
+ results.push.apply( results, array );
+ return results;
+ }
+
+ return array;
+};
+
+try {
+ Array.prototype.slice.call( document.documentElement.childNodes, 0 );
+
+} catch(e){
+ makeArray = function(array, results) {
+ var ret = results || [];
+
+ if ( toString.call(array) === "[object Array]" ) {
+ Array.prototype.push.apply( ret, array );
+ } else {
+ if ( typeof array.length === "number" ) {
+ for ( var i = 0, l = array.length; i < l; i++ ) {
+ ret.push( array[i] );
+ }
+ } else {
+ for ( var i = 0; array[i]; i++ ) {
+ ret.push( array[i] );
+ }
+ }
+ }
+
+ return ret;
+ };
+}
+
+var sortOrder;
+
+if ( document.documentElement.compareDocumentPosition ) {
+ sortOrder = function( a, b ) {
+ if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) {
+ if ( a == b ) {
+ hasDuplicate = true;
+ }
+ return 0;
+ }
+
+ var ret = a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1;
+ if ( ret === 0 ) {
+ hasDuplicate = true;
+ }
+ return ret;
+ };
+} else if ( "sourceIndex" in document.documentElement ) {
+ sortOrder = function( a, b ) {
+ if ( !a.sourceIndex || !b.sourceIndex ) {
+ if ( a == b ) {
+ hasDuplicate = true;
+ }
+ return 0;
+ }
+
+ var ret = a.sourceIndex - b.sourceIndex;
+ if ( ret === 0 ) {
+ hasDuplicate = true;
+ }
+ return ret;
+ };
+} else if ( document.createRange ) {
+ sortOrder = function( a, b ) {
+ if ( !a.ownerDocument || !b.ownerDocument ) {
+ if ( a == b ) {
+ hasDuplicate = true;
+ }
+ return 0;
+ }
+
+ var aRange = a.ownerDocument.createRange(), bRange = b.ownerDocument.createRange();
+ aRange.setStart(a, 0);
+ aRange.setEnd(a, 0);
+ bRange.setStart(b, 0);
+ bRange.setEnd(b, 0);
+ var ret = aRange.compareBoundaryPoints(Range.START_TO_END, bRange);
+ if ( ret === 0 ) {
+ hasDuplicate = true;
+ }
+ return ret;
+ };
+}
+
+(function(){
+ var form = document.createElement("div"),
+ id = "script" + (new Date).getTime();
+ form.innerHTML = "<a name='" + id + "'/>";
+
+ var root = document.documentElement;
+ root.insertBefore( form, root.firstChild );
+
+ if ( !!document.getElementById( id ) ) {
+ Expr.find.ID = function(match, context, isXML){
+ if ( typeof context.getElementById !== "undefined" && !isXML ) {
+ var m = context.getElementById(match[1]);
+ return m ? m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? [m] : undefined : [];
+ }
+ };
+
+ Expr.filter.ID = function(elem, match){
+ var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
+ return elem.nodeType === 1 && node && node.nodeValue === match;
+ };
+ }
+
+ root.removeChild( form );
+ root = form = null; // release memory in IE
+})();
+
+(function(){
+
+ var div = document.createElement("div");
+ div.appendChild( document.createComment("") );
+
+ if ( div.getElementsByTagName("*").length > 0 ) {
+ Expr.find.TAG = function(match, context){
+ var results = context.getElementsByTagName(match[1]);
+
+ if ( match[1] === "*" ) {
+ var tmp = [];
+
+ for ( var i = 0; results[i]; i++ ) {
+ if ( results[i].nodeType === 1 ) {
+ tmp.push( results[i] );
+ }
+ }
+
+ results = tmp;
+ }
+
+ return results;
+ };
+ }
+
+ div.innerHTML = "<a href='#'></a>";
+ if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
+ div.firstChild.getAttribute("href") !== "#" ) {
+ Expr.attrHandle.href = function(elem){
+ return elem.getAttribute("href", 2);
+ };
+ }
+
+ div = null; // release memory in IE
+})();
+
+if ( document.querySelectorAll ) (function(){
+ var oldSizzle = Sizzle, div = document.createElement("div");
+ div.innerHTML = "<p class='TEST'></p>";
+
+ if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
+ return;
+ }
+
+ Sizzle = function(query, context, extra, seed){
+ context = context || document;
+
+ if ( !seed && context.nodeType === 9 && !isXML(context) ) {
+ try {
+ return makeArray( context.querySelectorAll(query), extra );
+ } catch(e){}
+ }
+
+ return oldSizzle(query, context, extra, seed);
+ };
+
+ for ( var prop in oldSizzle ) {
+ Sizzle[ prop ] = oldSizzle[ prop ];
+ }
+
+ div = null; // release memory in IE
+})();
+
+if ( document.getElementsByClassName && document.documentElement.getElementsByClassName ) (function(){
+ var div = document.createElement("div");
+ div.innerHTML = "<div class='test e'></div><div class='test'></div>";
+
+ if ( div.getElementsByClassName("e").length === 0 )
+ return;
+
+ div.lastChild.className = "e";
+
+ if ( div.getElementsByClassName("e").length === 1 )
+ return;
+
+ Expr.order.splice(1, 0, "CLASS");
+ Expr.find.CLASS = function(match, context, isXML) {
+ if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
+ return context.getElementsByClassName(match[1]);
+ }
+ };
+
+ div = null; // release memory in IE
+})();
+
+function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
+ var sibDir = dir == "previousSibling" && !isXML;
+ for ( var i = 0, l = checkSet.length; i < l; i++ ) {
+ var elem = checkSet[i];
+ if ( elem ) {
+ if ( sibDir && elem.nodeType === 1 ){
+ elem.sizcache = doneName;
+ elem.sizset = i;
+ }
+ elem = elem[dir];
+ var match = false;
+
+ while ( elem ) {
+ if ( elem.sizcache === doneName ) {
+ match = checkSet[elem.sizset];
+ break;
+ }
+
+ if ( elem.nodeType === 1 && !isXML ){
+ elem.sizcache = doneName;
+ elem.sizset = i;
+ }
+
+ if ( elem.nodeName === cur ) {
+ match = elem;
+ break;
+ }
+
+ elem = elem[dir];
+ }
+
+ checkSet[i] = match;
+ }
+ }
}
-function $$() {
- return Selector.findChildElements(document, $A(arguments));
+function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
+ var sibDir = dir == "previousSibling" && !isXML;
+ for ( var i = 0, l = checkSet.length; i < l; i++ ) {
+ var elem = checkSet[i];
+ if ( elem ) {
+ if ( sibDir && elem.nodeType === 1 ) {
+ elem.sizcache = doneName;
+ elem.sizset = i;
+ }
+ elem = elem[dir];
+ var match = false;
+
+ while ( elem ) {
+ if ( elem.sizcache === doneName ) {
+ match = checkSet[elem.sizset];
+ break;
+ }
+
+ if ( elem.nodeType === 1 ) {
+ if ( !isXML ) {
+ elem.sizcache = doneName;
+ elem.sizset = i;
+ }
+ if ( typeof cur !== "string" ) {
+ if ( elem === cur ) {
+ match = true;
+ break;
+ }
+
+ } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
+ match = elem;
+ break;
+ }
+ }
+
+ elem = elem[dir];
+ }
+
+ checkSet[i] = match;
+ }
+ }
}
+
+var contains = document.compareDocumentPosition ? function(a, b){
+ return a.compareDocumentPosition(b) & 16;
+} : function(a, b){
+ return a !== b && (a.contains ? a.contains(b) : true);
+};
+
+var isXML = function(elem){
+ return elem.nodeType === 9 && elem.documentElement.nodeName !== "HTML" ||
+ !!elem.ownerDocument && elem.ownerDocument.documentElement.nodeName !== "HTML";
+};
+
+var posProcess = function(selector, context){
+ var tmpSet = [], later = "", match,
+ root = context.nodeType ? [context] : context;
+
+ while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
+ later += match[0];
+ selector = selector.replace( Expr.match.PSEUDO, "" );
+ }
+
+ selector = Expr.relative[selector] ? selector + "*" : selector;
+
+ for ( var i = 0, l = root.length; i < l; i++ ) {
+ Sizzle( selector, root[i], tmpSet );
+ }
+
+ return Sizzle.filter( later, tmpSet );
+};
+
+
+window.Sizzle = Sizzle;
+
+})();
+
+;(function(engine) {
+ var extendElements = Prototype.Selector.extendElements;
+
+ function select(selector, scope) {
+ return extendElements(engine(selector, scope || document));
+ }
+
+ function match(element, selector) {
+ return engine.matches(selector, [element]).length == 1;
+ }
+
+ Prototype.Selector.engine = engine;
+ Prototype.Selector.select = select;
+ Prototype.Selector.match = match;
+})(Sizzle);
+
+window.Sizzle = Prototype._original_property;
+delete Prototype._original_property;
+
var Form = {
reset: function(form) {
- $(form).reset();
+ form = $(form);
+ form.reset();
return form;
},
@@ -3392,10 +4967,9 @@ var Form = {
var data = elements.inject({ }, function(result, element) {
if (!element.disabled && element.name) {
key = element.name; value = $(element).getValue();
- if (value != null && (element.type != 'submit' || (!submitted &&
+ if (value != null && element.type != 'file' && (element.type != 'submit' || (!submitted &&
submit !== false && (!submit || key == submit) && (submitted = true)))) {
if (key in result) {
- // a key is already present; construct an array of values
if (!Object.isArray(result[key])) result[key] = [result[key]];
result[key].push(value);
}
@@ -3415,13 +4989,18 @@ Form.Methods = {
},
getElements: function(form) {
- return $A($(form).getElementsByTagName('*')).inject([],
- function(elements, child) {
- if (Form.Element.Serializers[child.tagName.toLowerCase()])
- elements.push(Element.extend(child));
- return elements;
- }
- );
+ var elements = $(form).getElementsByTagName('*'),
+ element,
+ arr = [ ],
+ serializers = Form.Element.Serializers;
+ for (var i = 0; element = elements[i]; i++) {
+ arr.push(element);
+ }
+ return arr.inject([], function(elements, child) {
+ if (serializers[child.tagName.toLowerCase()])
+ elements.push(Element.extend(child));
+ return elements;
+ })
},
getInputs: function(form, typeName, name) {
@@ -3461,7 +5040,7 @@ Form.Methods = {
}).sortBy(function(element) { return element.tabIndex }).first();
return firstByIndex ? firstByIndex : elements.find(function(element) {
- return ['input', 'select', 'textarea'].include(element.tagName.toLowerCase());
+ return /^(?:input|select|textarea)$/i.test(element.tagName);
});
},
@@ -3492,6 +5071,7 @@ Form.Methods = {
/*--------------------------------------------------------------------------*/
+
Form.Element = {
focus: function(element) {
$(element).focus();
@@ -3505,6 +5085,7 @@ Form.Element = {
};
Form.Element.Methods = {
+
serialize: function(element) {
element = $(element);
if (!element.disabled && element.name) {
@@ -3545,7 +5126,7 @@ Form.Element.Methods = {
try {
element.focus();
if (element.select && (element.tagName.toLowerCase() != 'input' ||
- !['button', 'reset', 'submit'].include(element.type)))
+ !(/^(?:button|reset|submit)$/i.test(element.type))))
element.select();
} catch (e) { }
return element;
@@ -3553,7 +5134,6 @@ Form.Element.Methods = {
disable: function(element) {
element = $(element);
- element.blur();
element.disabled = true;
return element;
},
@@ -3568,6 +5148,7 @@ Form.Element.Methods = {
/*--------------------------------------------------------------------------*/
var Field = Form.Element;
+
var $F = Form.Element.Methods.getValue;
/*--------------------------------------------------------------------------*/
@@ -3593,22 +5174,22 @@ Form.Element.Serializers = {
else element.value = value;
},
- select: function(element, index) {
- if (Object.isUndefined(index))
+ select: function(element, value) {
+ if (Object.isUndefined(value))
return this[element.type == 'select-one' ?
'selectOne' : 'selectMany'](element);
else {
- var opt, value, single = !Object.isArray(index);
+ var opt, currentValue, single = !Object.isArray(value);
for (var i = 0, length = element.length; i < length; i++) {
opt = element.options[i];
- value = this.optionValue(opt);
+ currentValue = this.optionValue(opt);
if (single) {
- if (value == index) {
+ if (currentValue == value) {
opt.selected = true;
return;
}
}
- else opt.selected = index.include(value);
+ else opt.selected = value.include(currentValue);
}
}
},
@@ -3630,13 +5211,13 @@ Form.Element.Serializers = {
},
optionValue: function(opt) {
- // extend element because hasAttribute may not be native
return Element.extend(opt).hasAttribute('value') ? opt.value : opt.text;
}
};
/*--------------------------------------------------------------------------*/
+
Abstract.TimedObserver = Class.create(PeriodicalExecuter, {
initialize: function($super, element, frequency, callback) {
$super(callback, frequency);
@@ -3718,323 +5299,475 @@ Form.EventObserver = Class.create(Abstract.EventObserver, {
return Form.serialize(this.element);
}
});
-if (!window.Event) var Event = { };
-
-Object.extend(Event, {
- KEY_BACKSPACE: 8,
- KEY_TAB: 9,
- KEY_RETURN: 13,
- KEY_ESC: 27,
- KEY_LEFT: 37,
- KEY_UP: 38,
- KEY_RIGHT: 39,
- KEY_DOWN: 40,
- KEY_DELETE: 46,
- KEY_HOME: 36,
- KEY_END: 35,
- KEY_PAGEUP: 33,
- KEY_PAGEDOWN: 34,
- KEY_INSERT: 45,
-
- cache: { },
-
- relatedTarget: function(event) {
- var element;
- switch(event.type) {
- case 'mouseover': element = event.fromElement; break;
- case 'mouseout': element = event.toElement; break;
- default: return null;
- }
- return Element.extend(element);
- }
-});
+(function() {
-Event.Methods = (function() {
- var isButton;
+ var Event = {
+ KEY_BACKSPACE: 8,
+ KEY_TAB: 9,
+ KEY_RETURN: 13,
+ KEY_ESC: 27,
+ KEY_LEFT: 37,
+ KEY_UP: 38,
+ KEY_RIGHT: 39,
+ KEY_DOWN: 40,
+ KEY_DELETE: 46,
+ KEY_HOME: 36,
+ KEY_END: 35,
+ KEY_PAGEUP: 33,
+ KEY_PAGEDOWN: 34,
+ KEY_INSERT: 45,
+
+ cache: {}
+ };
+
+ var docEl = document.documentElement;
+ var MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED = 'onmouseenter' in docEl
+ && 'onmouseleave' in docEl;
+ var _isButton;
if (Prototype.Browser.IE) {
var buttonMap = { 0: 1, 1: 4, 2: 2 };
- isButton = function(event, code) {
- return event.button == buttonMap[code];
+ _isButton = function(event, code) {
+ return event.button === buttonMap[code];
};
-
} else if (Prototype.Browser.WebKit) {
- isButton = function(event, code) {
+ _isButton = function(event, code) {
switch (code) {
case 0: return event.which == 1 && !event.metaKey;
case 1: return event.which == 1 && event.metaKey;
default: return false;
}
};
-
} else {
- isButton = function(event, code) {
+ _isButton = function(event, code) {
return event.which ? (event.which === code + 1) : (event.button === code);
};
}
- return {
- isLeftClick: function(event) { return isButton(event, 0) },
- isMiddleClick: function(event) { return isButton(event, 1) },
- isRightClick: function(event) { return isButton(event, 2) },
+ function isLeftClick(event) { return _isButton(event, 0) }
- element: function(event) {
- var node = Event.extend(event).target;
- return Element.extend(node.nodeType == Node.TEXT_NODE ? node.parentNode : node);
- },
+ function isMiddleClick(event) { return _isButton(event, 1) }
- findElement: function(event, expression) {
- var element = Event.element(event);
- if (!expression) return element;
- var elements = [element].concat(element.ancestors());
- return Selector.findElement(elements, expression, 0);
- },
+ function isRightClick(event) { return _isButton(event, 2) }
- pointer: function(event) {
- return {
- x: event.pageX || (event.clientX +
- (document.documentElement.scrollLeft || document.body.scrollLeft)),
- y: event.pageY || (event.clientY +
- (document.documentElement.scrollTop || document.body.scrollTop))
- };
- },
+ function element(event) {
+ event = Event.extend(event);
+
+ var node = event.target, type = event.type,
+ currentTarget = event.currentTarget;
+
+ if (currentTarget && currentTarget.tagName) {
+ if (type === 'load' || type === 'error' ||
+ (type === 'click' && currentTarget.tagName.toLowerCase() === 'input'
+ && currentTarget.type === 'radio'))
+ node = currentTarget;
+ }
- pointerX: function(event) { return Event.pointer(event).x },
- pointerY: function(event) { return Event.pointer(event).y },
+ if (node.nodeType == Node.TEXT_NODE)
+ node = node.parentNode;
- stop: function(event) {
- Event.extend(event);
- event.preventDefault();
- event.stopPropagation();
- event.stopped = true;
+ return Element.extend(node);
+ }
+
+ function findElement(event, expression) {
+ var element = Event.element(event);
+ if (!expression) return element;
+ while (element) {
+ if (Object.isElement(element) && Prototype.Selector.match(element, expression)) {
+ return Element.extend(element);
+ }
+ element = element.parentNode;
}
+ }
+
+ function pointer(event) {
+ return { x: pointerX(event), y: pointerY(event) };
+ }
+
+ function pointerX(event) {
+ var docElement = document.documentElement,
+ body = document.body || { scrollLeft: 0 };
+
+ return event.pageX || (event.clientX +
+ (docElement.scrollLeft || body.scrollLeft) -
+ (docElement.clientLeft || 0));
+ }
+
+ function pointerY(event) {
+ var docElement = document.documentElement,
+ body = document.body || { scrollTop: 0 };
+
+ return event.pageY || (event.clientY +
+ (docElement.scrollTop || body.scrollTop) -
+ (docElement.clientTop || 0));
+ }
+
+
+ function stop(event) {
+ Event.extend(event);
+ event.preventDefault();
+ event.stopPropagation();
+
+ event.stopped = true;
+ }
+
+ Event.Methods = {
+ isLeftClick: isLeftClick,
+ isMiddleClick: isMiddleClick,
+ isRightClick: isRightClick,
+
+ element: element,
+ findElement: findElement,
+
+ pointer: pointer,
+ pointerX: pointerX,
+ pointerY: pointerY,
+
+ stop: stop
};
-})();
-Event.extend = (function() {
+
var methods = Object.keys(Event.Methods).inject({ }, function(m, name) {
m[name] = Event.Methods[name].methodize();
return m;
});
if (Prototype.Browser.IE) {
+ function _relatedTarget(event) {
+ var element;
+ switch (event.type) {
+ case 'mouseover': element = event.fromElement; break;
+ case 'mouseout': element = event.toElement; break;
+ default: return null;
+ }
+ return Element.extend(element);
+ }
+
Object.extend(methods, {
stopPropagation: function() { this.cancelBubble = true },
preventDefault: function() { this.returnValue = false },
- inspect: function() { return "[object Event]" }
+ inspect: function() { return '[object Event]' }
});
- return function(event) {
+ Event.extend = function(event, element) {
if (!event) return false;
if (event._extendedByPrototype) return event;
event._extendedByPrototype = Prototype.emptyFunction;
var pointer = Event.pointer(event);
+
Object.extend(event, {
- target: event.srcElement,
- relatedTarget: Event.relatedTarget(event),
+ target: event.srcElement || element,
+ relatedTarget: _relatedTarget(event),
pageX: pointer.x,
pageY: pointer.y
});
+
return Object.extend(event, methods);
};
-
} else {
- Event.prototype = Event.prototype || document.createEvent("HTMLEvents").__proto__;
+ Event.prototype = window.Event.prototype || document.createEvent('HTMLEvents').__proto__;
Object.extend(Event.prototype, methods);
- return Prototype.K;
+ Event.extend = Prototype.K;
}
-})();
-Object.extend(Event, (function() {
- var cache = Event.cache;
+ function _createResponder(element, eventName, handler) {
+ var registry = Element.retrieve(element, 'prototype_event_registry');
- function getEventID(element) {
- if (element._eventID) return element._eventID;
- arguments.callee.id = arguments.callee.id || 1;
- return element._eventID = ++arguments.callee.id;
- }
-
- function getDOMEventName(eventName) {
- if (eventName && eventName.include(':')) return "dataavailable";
- return eventName;
- }
+ if (Object.isUndefined(registry)) {
+ CACHE.push(element);
+ registry = Element.retrieve(element, 'prototype_event_registry', $H());
+ }
- function getCacheForID(id) {
- return cache[id] = cache[id] || { };
- }
+ var respondersForEvent = registry.get(eventName);
+ if (Object.isUndefined(respondersForEvent)) {
+ respondersForEvent = [];
+ registry.set(eventName, respondersForEvent);
+ }
- function getWrappersForEventName(id, eventName) {
- var c = getCacheForID(id);
- return c[eventName] = c[eventName] || [];
- }
+ if (respondersForEvent.pluck('handler').include(handler)) return false;
- function createWrapper(element, eventName, handler) {
- var id = getEventID(element);
- var c = getWrappersForEventName(id, eventName);
- if (c.pluck("handler").include(handler)) return false;
+ var responder;
+ if (eventName.include(":")) {
+ responder = function(event) {
+ if (Object.isUndefined(event.eventName))
+ return false;
- var wrapper = function(event) {
- if (!Event || !Event.extend ||
- (event.eventName && event.eventName != eventName))
+ if (event.eventName !== eventName)
return false;
- Event.extend(event);
- handler.call(element, event)
- };
+ Event.extend(event, element);
+ handler.call(element, event);
+ };
+ } else {
+ if (!MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED &&
+ (eventName === "mouseenter" || eventName === "mouseleave")) {
+ if (eventName === "mouseenter" || eventName === "mouseleave") {
+ responder = function(event) {
+ Event.extend(event, element);
+
+ var parent = event.relatedTarget;
+ while (parent && parent !== element) {
+ try { parent = parent.parentNode; }
+ catch(e) { parent = element; }
+ }
- wrapper.handler = handler;
- c.push(wrapper);
- return wrapper;
- }
+ if (parent === element) return;
- function findWrapper(id, eventName, handler) {
- var c = getWrappersForEventName(id, eventName);
- return c.find(function(wrapper) { return wrapper.handler == handler });
- }
+ handler.call(element, event);
+ };
+ }
+ } else {
+ responder = function(event) {
+ Event.extend(event, element);
+ handler.call(element, event);
+ };
+ }
+ }
- function destroyWrapper(id, eventName, handler) {
- var c = getCacheForID(id);
- if (!c[eventName]) return false;
- c[eventName] = c[eventName].without(findWrapper(id, eventName, handler));
+ responder.handler = handler;
+ respondersForEvent.push(responder);
+ return responder;
}
- function destroyCache() {
- for (var id in cache)
- for (var eventName in cache[id])
- cache[id][eventName] = null;
+ function _destroyCache() {
+ for (var i = 0, length = CACHE.length; i < length; i++) {
+ Event.stopObserving(CACHE[i]);
+ CACHE[i] = null;
+ }
}
- if (window.attachEvent) {
- window.attachEvent("onunload", destroyCache);
+ var CACHE = [];
+
+ if (Prototype.Browser.IE)
+ window.attachEvent('onunload', _destroyCache);
+
+ if (Prototype.Browser.WebKit)
+ window.addEventListener('unload', Prototype.emptyFunction, false);
+
+
+ var _getDOMEventName = Prototype.K,
+ translations = { mouseenter: "mouseover", mouseleave: "mouseout" };
+
+ if (!MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED) {
+ _getDOMEventName = function(eventName) {
+ return (translations[eventName] || eventName);
+ };
}
- return {
- observe: function(element, eventName, handler) {
- element = $(element);
- var name = getDOMEventName(eventName);
+ function observe(element, eventName, handler) {
+ element = $(element);
- var wrapper = createWrapper(element, eventName, handler);
- if (!wrapper) return element;
+ var responder = _createResponder(element, eventName, handler);
- if (element.addEventListener) {
- element.addEventListener(name, wrapper, false);
- } else {
- element.attachEvent("on" + name, wrapper);
+ if (!responder) return element;
+
+ if (eventName.include(':')) {
+ if (element.addEventListener)
+ element.addEventListener("dataavailable", responder, false);
+ else {
+ element.attachEvent("ondataavailable", responder);
+ element.attachEvent("onfilterchange", responder);
}
+ } else {
+ var actualEventName = _getDOMEventName(eventName);
+
+ if (element.addEventListener)
+ element.addEventListener(actualEventName, responder, false);
+ else
+ element.attachEvent("on" + actualEventName, responder);
+ }
+
+ return element;
+ }
+
+ function stopObserving(element, eventName, handler) {
+ element = $(element);
+
+ var registry = Element.retrieve(element, 'prototype_event_registry');
+ if (!registry) return element;
+ if (!eventName) {
+ registry.each( function(pair) {
+ var eventName = pair.key;
+ stopObserving(element, eventName);
+ });
return element;
- },
+ }
- stopObserving: function(element, eventName, handler) {
- element = $(element);
- var id = getEventID(element), name = getDOMEventName(eventName);
+ var responders = registry.get(eventName);
+ if (!responders) return element;
- if (!handler && eventName) {
- getWrappersForEventName(id, eventName).each(function(wrapper) {
- element.stopObserving(eventName, wrapper.handler);
- });
- return element;
+ if (!handler) {
+ responders.each(function(r) {
+ stopObserving(element, eventName, r.handler);
+ });
+ return element;
+ }
- } else if (!eventName) {
- Object.keys(getCacheForID(id)).each(function(eventName) {
- element.stopObserving(eventName);
- });
- return element;
+ var responder = responders.find( function(r) { return r.handler === handler; });
+ if (!responder) return element;
+
+ if (eventName.include(':')) {
+ if (element.removeEventListener)
+ element.removeEventListener("dataavailable", responder, false);
+ else {
+ element.detachEvent("ondataavailable", responder);
+ element.detachEvent("onfilterchange", responder);
}
+ } else {
+ var actualEventName = _getDOMEventName(eventName);
+ if (element.removeEventListener)
+ element.removeEventListener(actualEventName, responder, false);
+ else
+ element.detachEvent('on' + actualEventName, responder);
+ }
- var wrapper = findWrapper(id, eventName, handler);
- if (!wrapper) return element;
+ registry.set(eventName, responders.without(responder));
- if (element.removeEventListener) {
- element.removeEventListener(name, wrapper, false);
- } else {
- element.detachEvent("on" + name, wrapper);
- }
+ return element;
+ }
- destroyWrapper(id, eventName, handler);
+ function fire(element, eventName, memo, bubble) {
+ element = $(element);
- return element;
- },
+ if (Object.isUndefined(bubble))
+ bubble = true;
- fire: function(element, eventName, memo) {
- element = $(element);
- if (element == document && document.createEvent && !element.dispatchEvent)
- element = document.documentElement;
+ if (element == document && document.createEvent && !element.dispatchEvent)
+ element = document.documentElement;
- if (document.createEvent) {
- var event = document.createEvent("HTMLEvents");
- event.initEvent("dataavailable", true, true);
- } else {
- var event = document.createEventObject();
- event.eventType = "ondataavailable";
- }
+ var event;
+ if (document.createEvent) {
+ event = document.createEvent('HTMLEvents');
+ event.initEvent('dataavailable', true, true);
+ } else {
+ event = document.createEventObject();
+ event.eventType = bubble ? 'ondataavailable' : 'onfilterchange';
+ }
- event.eventName = eventName;
- event.memo = memo || { };
+ event.eventName = eventName;
+ event.memo = memo || { };
- if (document.createEvent) {
- element.dispatchEvent(event);
- } else {
- element.fireEvent(event.eventType, event);
- }
+ if (document.createEvent)
+ element.dispatchEvent(event);
+ else
+ element.fireEvent(event.eventType, event);
+
+ return Event.extend(event);
+ }
+
+ Event.Handler = Class.create({
+ initialize: function(element, eventName, selector, callback) {
+ this.element = $(element);
+ this.eventName = eventName;
+ this.selector = selector;
+ this.callback = callback;
+ this.handler = this.handleEvent.bind(this);
+ },
- return Event.extend(event);
+ start: function() {
+ Event.observe(this.element, this.eventName, this.handler);
+ return this;
+ },
+
+ stop: function() {
+ Event.stopObserving(this.element, this.eventName, this.handler);
+ return this;
+ },
+
+ handleEvent: function(event) {
+ var element = event.findElement(this.selector);
+ if (element) this.callback.call(this.element, event, element);
}
- };
-})());
+ });
-Object.extend(Event, Event.Methods);
+ function on(element, eventName, selector, callback) {
+ element = $(element);
+ if (Object.isFunction(selector) && Object.isUndefined(callback)) {
+ callback = selector, selector = null;
+ }
-Element.addMethods({
- fire: Event.fire,
- observe: Event.observe,
- stopObserving: Event.stopObserving
-});
+ return new Event.Handler(element, eventName, selector, callback).start();
+ }
-Object.extend(document, {
- fire: Element.Methods.fire.methodize(),
- observe: Element.Methods.observe.methodize(),
- stopObserving: Element.Methods.stopObserving.methodize()
-});
+ Object.extend(Event, Event.Methods);
+
+ Object.extend(Event, {
+ fire: fire,
+ observe: observe,
+ stopObserving: stopObserving,
+ on: on
+ });
+
+ Element.addMethods({
+ fire: fire,
+
+ observe: observe,
+
+ stopObserving: stopObserving,
+
+ on: on
+ });
+
+ Object.extend(document, {
+ fire: fire.methodize(),
+
+ observe: observe.methodize(),
+
+ stopObserving: stopObserving.methodize(),
+
+ on: on.methodize(),
+
+ loaded: false
+ });
+
+ if (window.Event) Object.extend(window.Event, Event);
+ else window.Event = Event;
+})();
(function() {
/* Support for the DOMContentLoaded event is based on work by Dan Webb,
- Matthias Miller, Dean Edwards and John Resig. */
+ Matthias Miller, Dean Edwards, John Resig, and Diego Perini. */
- var timer, fired = false;
+ var timer;
function fireContentLoadedEvent() {
- if (fired) return;
- if (timer) window.clearInterval(timer);
- document.fire("dom:loaded");
- fired = true;
+ if (document.loaded) return;
+ if (timer) window.clearTimeout(timer);
+ document.loaded = true;
+ document.fire('dom:loaded');
}
- if (document.addEventListener) {
- if (Prototype.Browser.WebKit) {
- timer = window.setInterval(function() {
- if (/loaded|complete/.test(document.readyState))
- fireContentLoadedEvent();
- }, 0);
-
- Event.observe(window, "load", fireContentLoadedEvent);
+ function checkReadyState() {
+ if (document.readyState === 'complete') {
+ document.stopObserving('readystatechange', checkReadyState);
+ fireContentLoadedEvent();
+ }
+ }
- } else {
- document.addEventListener("DOMContentLoaded",
- fireContentLoadedEvent, false);
+ function pollDoScroll() {
+ try { document.documentElement.doScroll('left'); }
+ catch(e) {
+ timer = pollDoScroll.defer();
+ return;
}
+ fireContentLoadedEvent();
+ }
+ if (document.addEventListener) {
+ document.addEventListener('DOMContentLoaded', fireContentLoadedEvent, false);
} else {
- document.write("<script id=__onDOMContentLoaded defer src=//:><\/script>");
- $("__onDOMContentLoaded").onreadystatechange = function() {
- if (this.readyState == "complete") {
- this.onreadystatechange = null;
- fireContentLoadedEvent();
- }
- };
+ document.observe('readystatechange', checkReadyState);
+ if (window == top)
+ timer = pollDoScroll.defer();
}
+
+ Event.observe(window, 'load', fireContentLoadedEvent);
})();
+
+Element.addMethods();
+
/*------------------------------- DEPRECATED -------------------------------*/
Hash.toQueryString = Object.toQueryString;
@@ -4063,16 +5796,9 @@ var Insertion = {
var $continue = new Error('"throw $continue" is deprecated, use "return" instead');
-// This should be moved to script.aculo.us; notice the deprecated methods
-// further below, that map to the newer Element methods.
var Position = {
- // set to true if needed, warning: firefox performance problems
- // NOT neeeded for page scrolling, only if draggable contained in
- // scrollable elements
includeScrollOffsets: false,
- // must be called before calling withinIncludingScrolloffset, every time the
- // page is scrolled
prepare: function() {
this.deltaX = window.pageXOffset
|| document.documentElement.scrollLeft
@@ -4084,7 +5810,6 @@ var Position = {
|| 0;
},
- // caches x/y coordinate pair to use with overlap
within: function(element, x, y) {
if (this.includeScrollOffsets)
return this.withinIncludingScrolloffsets(element, x, y);
@@ -4111,7 +5836,6 @@ var Position = {
this.xcomp < this.offset[0] + element.offsetWidth);
},
- // within must be called directly before
overlap: function(mode, element) {
if (!mode) return 0;
if (mode == 'vertical')
@@ -4122,7 +5846,6 @@ var Position = {
element.offsetWidth;
},
- // Deprecation layer -- use newer Element methods now (1.5.2).
cumulativeOffset: Element.Methods.cumulativeOffset,
@@ -4222,4 +5945,57 @@ Object.extend(Element.ClassNames.prototype, Enumerable);
/*--------------------------------------------------------------------------*/
-Element.addMethods(); \ No newline at end of file
+(function() {
+ window.Selector = Class.create({
+ initialize: function(expression) {
+ this.expression = expression.strip();
+ },
+
+ findElements: function(rootElement) {
+ return Prototype.Selector.select(this.expression, rootElement);
+ },
+
+ match: function(element) {
+ return Prototype.Selector.match(element, this.expression);
+ },
+
+ toString: function() {
+ return this.expression;
+ },
+
+ inspect: function() {
+ return "#<Selector: " + this.expression + ">";
+ }
+ });
+
+ Object.extend(Selector, {
+ matchElements: function(elements, expression) {
+ var match = Prototype.Selector.match,
+ results = [];
+
+ for (var i = 0, length = elements.length; i < length; i++) {
+ var element = elements[i];
+ if (match(element, expression)) {
+ results.push(Element.extend(element));
+ }
+ }
+ return results;
+ },
+
+ findElement: function(elements, expression, index) {
+ index = index || 0;
+ var matchIndex = 0, element;
+ for (var i = 0, length = elements.length; i < length; i++) {
+ element = elements[i];
+ if (Prototype.Selector.match(element, expression) && index === matchIndex++) {
+ return Element.extend(element);
+ }
+ }
+ },
+
+ findChildElements: function(element, expressions) {
+ var selector = expressions.toArray().join(', ');
+ return Prototype.Selector.select(selector, element || document);
+ }
+ });
+})();
diff --git a/public/javascripts/rails.js b/public/javascripts/rails.js
new file mode 100644
index 000000000..5cea13c15
--- /dev/null
+++ b/public/javascripts/rails.js
@@ -0,0 +1,202 @@
+(function() {
+ Ajax.Responders.register({
+ onCreate: function(request) {
+ var token = $$('meta[name=csrf-token]')[0];
+ if (token) {
+ if (!request.options.requestHeaders) request.options.requestHeaders = {};
+ request.options.requestHeaders['X-CSRF-Token'] = token.readAttribute('content');
+ }
+ }
+ });
+
+ // Technique from Juriy Zaytsev
+ // http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/
+ function isEventSupported(eventName) {
+ var el = document.createElement('div');
+ eventName = 'on' + eventName;
+ var isSupported = (eventName in el);
+ if (!isSupported) {
+ el.setAttribute(eventName, 'return;');
+ isSupported = typeof el[eventName] == 'function';
+ }
+ el = null;
+ return isSupported;
+ }
+
+ function isForm(element) {
+ return Object.isElement(element) && element.nodeName.toUpperCase() == 'FORM';
+ }
+
+ function isInput(element) {
+ if (Object.isElement(element)) {
+ var name = element.nodeName.toUpperCase();
+ return name == 'INPUT' || name == 'SELECT' || name == 'TEXTAREA';
+ }
+ else return false;
+ }
+
+ var submitBubbles = isEventSupported('submit'),
+ changeBubbles = isEventSupported('change');
+
+ if (!submitBubbles || !changeBubbles) {
+ // augment the Event.Handler class to observe custom events when needed
+ Event.Handler.prototype.initialize = Event.Handler.prototype.initialize.wrap(
+ function(init, element, eventName, selector, callback) {
+ init(element, eventName, selector, callback);
+ // is the handler being attached to an element that doesn't support this event?
+ if ( (!submitBubbles && this.eventName == 'submit' && !isForm(this.element)) ||
+ (!changeBubbles && this.eventName == 'change' && !isInput(this.element)) ) {
+ // "submit" => "emulated:submit"
+ this.eventName = 'emulated:' + this.eventName;
+ }
+ }
+ );
+ }
+
+ if (!submitBubbles) {
+ // discover forms on the page by observing focus events which always bubble
+ document.on('focusin', 'form', function(focusEvent, form) {
+ // special handler for the real "submit" event (one-time operation)
+ if (!form.retrieve('emulated:submit')) {
+ form.on('submit', function(submitEvent) {
+ var emulated = form.fire('emulated:submit', submitEvent, true);
+ // if custom event received preventDefault, cancel the real one too
+ if (emulated.returnValue === false) submitEvent.preventDefault();
+ });
+ form.store('emulated:submit', true);
+ }
+ });
+ }
+
+ if (!changeBubbles) {
+ // discover form inputs on the page
+ document.on('focusin', 'input, select, textarea', function(focusEvent, input) {
+ // special handler for real "change" events
+ if (!input.retrieve('emulated:change')) {
+ input.on('change', function(changeEvent) {
+ input.fire('emulated:change', changeEvent, true);
+ });
+ input.store('emulated:change', true);
+ }
+ });
+ }
+
+ function handleRemote(element) {
+ var method, url, params;
+
+ var event = element.fire("ajax:before");
+ if (event.stopped) return false;
+
+ if (element.tagName.toLowerCase() === 'form') {
+ method = element.readAttribute('method') || 'post';
+ url = element.readAttribute('action');
+ // serialize the form with respect to the submit button that was pressed
+ params = element.serialize({ submit: element.retrieve('rails:submit-button') });
+ // clear the pressed submit button information
+ element.store('rails:submit-button', null);
+ } else {
+ method = element.readAttribute('data-method') || 'get';
+ url = element.readAttribute('href');
+ params = {};
+ }
+
+ new Ajax.Request(url, {
+ method: method,
+ parameters: params,
+ evalScripts: true,
+
+ onCreate: function(response) { element.fire("ajax:create", response); },
+ onComplete: function(response) { element.fire("ajax:complete", response); },
+ onSuccess: function(response) { element.fire("ajax:success", response); },
+ onFailure: function(response) { element.fire("ajax:failure", response); }
+ });
+
+ element.fire("ajax:after");
+ }
+
+ function insertHiddenField(form, name, value) {
+ form.insert(new Element('input', { type: 'hidden', name: name, value: value }));
+ }
+
+ function handleMethod(element) {
+ var method = element.readAttribute('data-method'),
+ url = element.readAttribute('href'),
+ csrf_param = $$('meta[name=csrf-param]')[0],
+ csrf_token = $$('meta[name=csrf-token]')[0];
+
+ var form = new Element('form', { method: "POST", action: url, style: "display: none;" });
+ $(element.parentNode).insert(form);
+
+ if (method !== 'post') {
+ insertHiddenField(form, '_method', method);
+ }
+
+ if (csrf_param) {
+ insertHiddenField(form, csrf_param.readAttribute('content'), csrf_token.readAttribute('content'));
+ }
+
+ form.submit();
+ }
+
+ function disableFormElements(form) {
+ form.select('input[type=submit][data-disable-with]').each(function(input) {
+ input.store('rails:original-value', input.getValue());
+ input.setValue(input.readAttribute('data-disable-with')).disable();
+ });
+ }
+
+ function enableFormElements(form) {
+ form.select('input[type=submit][data-disable-with]').each(function(input) {
+ input.setValue(input.retrieve('rails:original-value')).enable();
+ });
+ }
+
+ function allowAction(element) {
+ var message = element.readAttribute('data-confirm');
+ return !message || confirm(message);
+ }
+
+ document.on('click', 'a[data-confirm], a[data-remote], a[data-method]', function(event, link) {
+ if (!allowAction(link)) {
+ event.stop();
+ return false;
+ }
+
+ if (link.readAttribute('data-remote')) {
+ handleRemote(link);
+ event.stop();
+ } else if (link.readAttribute('data-method')) {
+ handleMethod(link);
+ event.stop();
+ }
+ });
+
+ document.on("click", "form input[type=submit], form button[type=submit], form button:not([type])", function(event, button) {
+ // register the pressed submit button
+ event.findElement('form').store('rails:submit-button', button.name || false);
+ });
+
+ document.on("submit", function(event) {
+ var form = event.findElement();
+
+ if (!allowAction(form)) {
+ event.stop();
+ return false;
+ }
+
+ if (form.readAttribute('data-remote')) {
+ handleRemote(form);
+ event.stop();
+ } else {
+ disableFormElements(form);
+ }
+ });
+
+ document.on('ajax:create', 'form', function(event, form) {
+ if (form == event.findElement()) disableFormElements(form);
+ });
+
+ document.on('ajax:complete', 'form', function(event, form) {
+ if (form == event.findElement()) enableFormElements(form);
+ });
+})();
diff --git a/script/about b/script/about
deleted file mode 100755
index 49a7c2609..000000000
--- a/script/about
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/usr/bin/env ruby
-require File.expand_path(File.dirname(__FILE__) + '/../config/boot.rb')
-require 'commands/about'
diff --git a/script/alert-comment-on-request b/script/alert-comment-on-request
index 74782aa13..849f4a8d8 100755
--- a/script/alert-comment-on-request
+++ b/script/alert-comment-on-request
@@ -1,7 +1,4 @@
#!/bin/bash
-
-cd "`dirname "$0"`"
-
-bundle exec ./runner 'RequestMailer.alert_comment_on_request'
-
-
+TOP_DIR="$(dirname "$BASH_SOURCE")/.."
+cd "$TOP_DIR"
+bundle exec rails runner 'RequestMailer.alert_comment_on_request'
diff --git a/script/alert-new-response-reminders b/script/alert-new-response-reminders
index 59fa76df1..148706d49 100755
--- a/script/alert-new-response-reminders
+++ b/script/alert-new-response-reminders
@@ -1,7 +1,4 @@
#!/bin/bash
-
-cd "`dirname "$0"`"
-
-bundle exec ./runner 'RequestMailer.alert_new_response_reminders'
-
-
+TOP_DIR="$(dirname "$BASH_SOURCE")/.."
+cd "$TOP_DIR"
+bundle exec rails runner 'RequestMailer.alert_new_response_reminders'
diff --git a/script/alert-not-clarified-request b/script/alert-not-clarified-request
index a38fbc70e..8d61c1800 100755
--- a/script/alert-not-clarified-request
+++ b/script/alert-not-clarified-request
@@ -1,7 +1,4 @@
#!/bin/bash
-
-cd "`dirname "$0"`"
-
-bundle exec ./runner 'RequestMailer.alert_not_clarified_request'
-
-
+TOP_DIR="$(dirname "$BASH_SOURCE")/.."
+cd "$TOP_DIR"
+bundle exec rails runner 'RequestMailer.alert_not_clarified_request'
diff --git a/script/alert-overdue-requests b/script/alert-overdue-requests
index 46450f1f2..ebc2897a0 100755
--- a/script/alert-overdue-requests
+++ b/script/alert-overdue-requests
@@ -1,5 +1,4 @@
#!/bin/bash
-
-cd "`dirname "$0"`"
-
-bundle exec ./runner 'RequestMailer.alert_overdue_requests()'
+TOP_DIR="$(dirname "$BASH_SOURCE")/.."
+cd "$TOP_DIR"
+bundle exec rails runner 'RequestMailer.alert_overdue_requests'
diff --git a/script/alert-tracks b/script/alert-tracks
index 117f7a406..17426b4e0 100755
--- a/script/alert-tracks
+++ b/script/alert-tracks
@@ -1,11 +1,9 @@
#!/bin/bash
-
-LOC=`dirname $0`
-
+TOP_DIR="$(dirname "$BASH_SOURCE")/.."
+cd "$TOP_DIR"
if [ "$1" == "--loop" ]
then
- "$LOC/runner" 'TrackMailer.alert_tracks_loop'
+ bundle exec rails runner 'TrackMailer.alert_tracks_loop'
else
- "$LOC/runner" 'TrackMailer.alert_tracks'
+ bundle exec rails runner 'TrackMailer.alert_tracks'
fi
-
diff --git a/script/annotate-models b/script/annotate-models
index b6e01c010..7b6daa3c5 100755
--- a/script/annotate-models
+++ b/script/annotate-models
@@ -2,4 +2,4 @@
#
# annotates the models in app/ with schema information
-bundle exec annotate -m -p before --exclude tests,fixtures
+bundle exec annotate --show-migration --position before --exclude tests,fixtures
diff --git a/script/autospec b/script/autospec
deleted file mode 100755
index 837bbd7f4..000000000
--- a/script/autospec
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/usr/bin/env ruby
-gem 'test-unit', '1.2.3' if RUBY_VERSION.to_f >= 1.9
-ENV['RSPEC'] = 'true' # allows autotest to discover rspec
-ENV['AUTOTEST'] = 'true' # allows autotest to run w/ color on linux
-system((RUBY_PLATFORM =~ /mswin|mingw/ ? 'autotest.bat' : 'autotest'), *ARGV) ||
- $stderr.puts("Unable to find autotest. Please install ZenTest or fix your PATH")
diff --git a/script/breakpointer b/script/breakpointer
deleted file mode 100755
index 46a01d1b2..000000000
--- a/script/breakpointer
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/usr/bin/env ruby
-require File.expand_path(File.dirname(__FILE__) + '/../config/boot.rb')
-require 'commands/breakpointer'
diff --git a/script/cache-incoming-emails b/script/cache-incoming-emails
index 0b3069bd7..b13efbd8c 100644..100755
--- a/script/cache-incoming-emails
+++ b/script/cache-incoming-emails
@@ -4,6 +4,4 @@
# Will take a while to run! Can use after clear-caches to refresh the database
# level caches if you like.
-cd "`dirname "$0"`"
-
-bundle exec ./runner 'IncomingMessage.find_each() { |im| print "info request " + im.info_request.id.to_s + ", incoming message " + im.id.to_s + ": " + im.extract_attachments!.count.to_s + " attachments extracted to " + im.foi_attachments[0].directory + "; main body folded: " + im.get_main_body_text_folded.size.to_s + " attachment clipped:" + im.get_attachment_text_clipped.size.to_s + "\n" }'
+bundle exec rails runner 'IncomingMessage.find_each { |im| print "info request " + im.info_request.id.to_s + ", incoming message " + im.id.to_s + ": " + im.extract_attachments!.count.to_s + " attachments extracted to " + im.foi_attachments[0].directory + "; main body folded: " + im.get_main_body_text_folded.size.to_s + " attachment clipped:" + im.get_attachment_text_clipped.size.to_s + "\n" }'
diff --git a/script/check-recent-requests-sent b/script/check-recent-requests-sent
index 7840dba4a..8f21fb6e7 100755
--- a/script/check-recent-requests-sent
+++ b/script/check-recent-requests-sent
@@ -1,8 +1,4 @@
#!/bin/bash
-
-cd "`dirname "$0"`"
-
-bundle exec ./runner 'MailServerLog.check_recent_requests_have_been_sent'
-
-
-
+TOP_DIR="$(dirname "$BASH_SOURCE")/.."
+cd "$TOP_DIR"
+bundle exec rails runner 'MailServerLog.check_recent_requests_have_been_sent'
diff --git a/script/clear-caches b/script/clear-caches
index 43fec2811..20ee3df19 100755
--- a/script/clear-caches
+++ b/script/clear-caches
@@ -1,13 +1,11 @@
#!/bin/bash
-
+TOP_DIR="$(dirname "$BASH_SOURCE")/.."
+cd "$TOP_DIR"
# Clear the cache of attachment and body text.
-cd "`dirname "$0"`"
-
-bundle exec ./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\")"
+bundle exec rails 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
-mv $LOC/../cache $LOC/../old-cache
-rm -fr $LOC/../old-cache
-
+rm -fr $TOP_DIR/old-cache
+mv $TOP_DIR/cache $TOP_DIR/old-cache
+rm -fr $TOP_DIR/old-cache
diff --git a/script/console b/script/console
deleted file mode 100755
index 83386647f..000000000
--- a/script/console
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/usr/bin/env ruby
-require File.expand_path(File.dirname(__FILE__) + '/../config/boot.rb')
-require 'commands/console'
diff --git a/script/dbconsole b/script/dbconsole
deleted file mode 100755
index 39042fad3..000000000
--- a/script/dbconsole
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/usr/bin/env ruby
-require File.expand_path(File.dirname(__FILE__) + '/../config/boot.rb')
-require 'commands/dbconsole'
diff --git a/script/delete-old-things b/script/delete-old-things
index 063d85e1f..a97ba4869 100755
--- a/script/delete-old-things
+++ b/script/delete-old-things
@@ -1,6 +1,5 @@
#!/bin/bash
-
-cd "`dirname "$0"`"
-
-bundle exec ./runner 'PostRedirect.delete_old_post_redirects()'
-bundle exec ./runner 'TrackThingsSentEmail.delete_old_track_things_sent_email()'
+TOP_DIR="$(dirname "$BASH_SOURCE")/.."
+cd "$TOP_DIR"
+bundle exec rails runner 'PostRedirect.delete_old_post_redirects'
+bundle exec rails runner 'TrackThingsSentEmail.delete_old_track_things_sent_email'
diff --git a/script/destroy b/script/destroy
deleted file mode 100755
index fddc5160d..000000000
--- a/script/destroy
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/usr/bin/env ruby
-require File.expand_path(File.dirname(__FILE__) + '/../config/boot.rb')
-require 'commands/destroy'
diff --git a/script/direct-rspec b/script/direct-rspec
deleted file mode 100755
index 50a1daba1..000000000
--- a/script/direct-rspec
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/bin/bash
-
-./vendor/plugins/rspec/bin/spec $1
-
-# spec/controllers/request_controller_spec.rb
-
-#ruby -I/home/francis/keep/devel/mysociety/foi/vendor/plugins/rspec/lib /home/francis/keep/devel/mysociety/foi/vendor/plugins/rspec/bin/spec spec/controllers/admin_public_body_controller_spec.rb spec/controllers/application_spec.rb spec/controllers/request_controller_spec.rb spec/controllers/user_controller_spec.rb spec/controllers/admin_controller_spec.rb spec/controllers/body_controller_spec.rb spec/models/incoming_message_spec.rb spec/models/user_spec.rb spec/models/request_mailer_spec.rb spec/models/post_redirect_spec.rb spec/models/public_body_spec.rb spec/models/info_request_spec.rb spec/models/user_mailer_spec.rb spec/models/outgoing_message_spec.rb --options /home/francis/keep/devel/mysociety/foi/spec/spec.opts
-
diff --git a/script/generate b/script/generate
deleted file mode 100755
index fb8139d12..000000000
--- a/script/generate
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/usr/bin/env ruby
-require File.expand_path(File.dirname(__FILE__) + '/../config/boot.rb')
-require 'commands/generate'
diff --git a/script/handle-mail-replies.rb b/script/handle-mail-replies.rb
index 4e35ee0cf..da0fc8e96 100755
--- a/script/handle-mail-replies.rb
+++ b/script/handle-mail-replies.rb
@@ -14,10 +14,10 @@
# config file ourselves.
$alaveteli_dir = File.expand_path(File.join(File.dirname(__FILE__), '..'))
$:.push(File.join($alaveteli_dir, "commonlib", "rblib"))
-load "config.rb"
+load 'config.rb'
$:.push(File.join($alaveteli_dir, "lib"))
$:.push(File.join($alaveteli_dir, "lib", "mail_handler"))
-require "configuration"
+load 'configuration.rb'
MySociety::Config.set_file(File.join($alaveteli_dir, 'config', 'general'), true)
MySociety::Config.load_default
require 'mail_handler'
@@ -165,7 +165,7 @@ def is_oof?(message)
end
def forward_on(raw_message)
- IO.popen("/usr/sbin/sendmail -i #{Configuration::forward_nonbounce_responses_to}", "w") do |f|
+ IO.popen("/usr/sbin/sendmail -i #{AlaveteliConfiguration::forward_nonbounce_responses_to}", "w") do |f|
f.write(raw_message);
f.close;
end
diff --git a/script/load-mail-server-logs b/script/load-mail-server-logs
index 9ff7a1401..770bf7026 100755
--- a/script/load-mail-server-logs
+++ b/script/load-mail-server-logs
@@ -14,7 +14,7 @@ then
*) f=$(pwd)/$1 ;;
esac
cd "$LOC"
- bundle exec ./runner 'MailServerLog.load_file("'$f'")'
+ bundle exec rails runner 'MailServerLog.load_file("'$f'")'
exit
fi
@@ -23,5 +23,5 @@ cd "$LOC"
LATEST=$( ls $OPTION_MTA_LOG_PATH 2>/dev/null | sort | tail -3 )
for X in $LATEST
do
- bundle exec ./runner 'MailServerLog.load_file("'$X'")'
+ bundle exec rails runner 'MailServerLog.load_file("'$X'")'
done
diff --git a/script/load-sample-data b/script/load-sample-data
index 86e1af128..e91516886 100755
--- a/script/load-sample-data
+++ b/script/load-sample-data
@@ -4,16 +4,28 @@
# the fact that the fixtures aren't aware of the fact that RawEmails
# have a filesystem representation of their contents
-LOC=`dirname "$0"`
+export LOC=`dirname "$0"`
-bundle exec rake --silent spec:db:fixtures:load
+bundle exec rails runner /dev/stdin <<END
+require 'rspec/rails'
+require "#{ENV['LOC']}/../spec/support/load_file_fixtures.rb"
+require "#{ENV['LOC']}/../spec/support/email_helpers.rb"
-"$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
+RSpec.configure do |config|
+ config.fixture_path = "#{::Rails.root}/spec/fixtures"
+end
+
+# HACK: Normally to load fixtures you'd run `rake db:fixtures:load` but since we
+# have .csv files in the fixtures folder Rails tries to load those too. Therefore
+# we've pinched some code to load the fixtures:
+# https://github.com/rails/rails/blob/v3.1.11/activerecord/lib/active_record/railties/databases.rake#L311
+fixtures_dir = "#{ENV['LOC']}/../spec/fixtures"
+
+Dir["#{fixtures_dir}/**/*.yml"].each do |fixture_file|
+ ActiveRecord::Fixtures.create_fixtures(fixtures_dir, fixture_file[(fixtures_dir.size + 1)..-5])
+end
load_raw_emails_data
END
-echo "Loaded fixtures. You may now wish to run $LOC/update-xapian-index"
+echo "Loaded fixtures. You may now wish to run $LOC/update-xapian-index"
diff --git a/script/mailin b/script/mailin
index b4d77f7a4..f782df215 100755
--- a/script/mailin
+++ b/script/mailin
@@ -13,7 +13,7 @@ source commonlib/shlib/deployfns
read_conf config/general
-script/runner 'RequestMailer.receive(STDIN.read)' <"$INPUT" >"$OUTPUT" 2>&1
+bundle exec rails runner 'RequestMailer.receive(STDIN.read)' <"$INPUT" >"$OUTPUT" 2>&1
ERROR_CODE=$?
if [ ! "$ERROR_CODE" = "0" ]
then
diff --git a/script/performance/benchmarker b/script/performance/benchmarker
deleted file mode 100755
index 28bfceea0..000000000
--- a/script/performance/benchmarker
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/usr/bin/env ruby
-require File.expand_path(File.dirname(__FILE__) + '/../config/boot.rb')
-require 'commands/performance/benchmarker'
diff --git a/script/performance/profiler b/script/performance/profiler
deleted file mode 100755
index 11baf44f2..000000000
--- a/script/performance/profiler
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/usr/bin/env ruby
-require File.expand_path(File.dirname(__FILE__) + '/../config/boot.rb')
-require 'commands/performance/profiler'
diff --git a/script/performance/request b/script/performance/request
deleted file mode 100755
index fff6fe660..000000000
--- a/script/performance/request
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/usr/bin/env ruby
-require File.expand_path(File.dirname(__FILE__) + '/../config/boot.rb')
-require 'commands/performance/request'
diff --git a/script/plugin b/script/plugin
deleted file mode 100755
index 49f5c441f..000000000
--- a/script/plugin
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/usr/bin/env ruby
-require File.expand_path(File.dirname(__FILE__) + '/../config/boot.rb')
-require 'commands/plugin'
diff --git a/script/process/inspector b/script/process/inspector
deleted file mode 100755
index 467962602..000000000
--- a/script/process/inspector
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/usr/bin/env ruby
-require File.expand_path(File.dirname(__FILE__) + '/../config/boot.rb')
-require 'commands/process/inspector'
diff --git a/script/process/reaper b/script/process/reaper
deleted file mode 100755
index 2eea898db..000000000
--- a/script/process/reaper
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/usr/bin/env ruby
-require File.expand_path(File.dirname(__FILE__) + '/../config/boot.rb')
-require 'commands/process/reaper'
diff --git a/script/process/spawner b/script/process/spawner
deleted file mode 100755
index ac417c3a7..000000000
--- a/script/process/spawner
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/usr/bin/env ruby
-require File.expand_path(File.dirname(__FILE__) + '/../config/boot.rb')
-require 'commands/process/spawner'
diff --git a/script/purge-varnish b/script/purge-varnish
index 932cf6635..abc6daeaf 100755
--- a/script/purge-varnish
+++ b/script/purge-varnish
@@ -1,11 +1,12 @@
#!/bin/bash
-LOC=`dirname $0`
+TOP_DIR="$(dirname "$BASH_SOURCE")/.."
+cd "$TOP_DIR"
if [ "$1" == "--loop" ]
then
- "$LOC/runner" 'PurgeRequest.purge_all_loop'
+ bundle exec rails runner 'PurgeRequest.purge_all_loop'
else
- "$LOC/runner" 'PurgeRequest.purge_all'
+ bundle exec rails runner 'PurgeRequest.purge_all'
fi
diff --git a/script/rails b/script/rails
new file mode 100755
index 000000000..f8da2cffd
--- /dev/null
+++ b/script/rails
@@ -0,0 +1,6 @@
+#!/usr/bin/env ruby
+# This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
+
+APP_PATH = File.expand_path('../../config/application', __FILE__)
+require File.expand_path('../../config/boot', __FILE__)
+require 'rails/commands'
diff --git a/script/rails-post-deploy b/script/rails-post-deploy
index a1c613312..4048c852f 100755
--- a/script/rails-post-deploy
+++ b/script/rails-post-deploy
@@ -6,15 +6,20 @@
# recent version.
#
# Copyright (c) 2007 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
set -e
#set -x # debug
-APP_DIR=`pwd`
+TOP_DIR="$(dirname "$BASH_SOURCE")/.."
+cd "$TOP_DIR"
# make sure that there is an app directory, so are in a rails app tree
-cd app/..
+if ! [ -d app ]
+then
+ echo "Error: the 'app' directory didn't exist"
+ exit 1
+fi
# read config file in for later (STAGING_SITE)
if [ -e "config/general" ] || [ -e "config/general.yml" ]
@@ -27,11 +32,11 @@ else
fi
# create initial log files
-if [ -e $APP_DIR/../logs ]
+if [ -e $TOP_DIR/../logs ]
then
# mySociety servers have logs dir in level above
rm -f log
- ln -s $APP_DIR/../logs log
+ ln -s $TOP_DIR/../logs log
else
# otherwise just make the directory
if [ -h log ]
@@ -42,10 +47,10 @@ else
mkdir -p log
fi
# link the "downloads" directory in the cache to somewhere it can be served
-if [ ! -e "$APP_DIR/public/download" ]
+if [ ! -e "$TOP_DIR/public/download" ]
then
- mkdir -p "$APP_DIR/cache/zips/download"
- ln -s "$APP_DIR/cache/zips/download" "$APP_DIR/public/"
+ mkdir -p "$TOP_DIR/cache/zips/download"
+ ln -s "$TOP_DIR/cache/zips/download" "$TOP_DIR/public/"
fi
cd log
diff --git a/script/request-creation-graph b/script/request-creation-graph
index d49a361b8..ef1d2cf73 100755
--- a/script/request-creation-graph
+++ b/script/request-creation-graph
@@ -3,7 +3,7 @@
# Plot graph of rate of request creation
#
# Copyright (c) 2008 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org. WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org. WWW: http://www.mysociety.org/
GPLOT_OUTPUT="set terminal png font 'Vera.ttf' 9 size 1600,600"
EXTENSION=".png"
diff --git a/script/runner b/script/runner
index 1575848de..32a0e6b7e 100755
--- a/script/runner
+++ b/script/runner
@@ -6,7 +6,6 @@ script_dir = File.dirname(__FILE__)
alaveteli_dir = File.expand_path(File.join(script_dir, ".."))
Dir.chdir(alaveteli_dir) do
- require File.join(alaveteli_dir, 'config', 'boot')
if daemon_mode
# Run in daemon mode.
@@ -20,12 +19,13 @@ Dir.chdir(alaveteli_dir) do
# Load the runner in a subprocess
pid = fork do
- require 'commands/runner'
+ exec("bundle exec rails runner #{ARGV[1]}")
exit 0
end
# If the environment variable PIDFILE is present,
# write the pid of the daemon process to that file.
+
if ENV.has_key? "PIDFILE"
File.open(ENV["PIDFILE"], 'w') do |fh|
fh.puts pid
@@ -35,6 +35,6 @@ Dir.chdir(alaveteli_dir) do
Process.detach(pid)
else
# Not daemon mode
- require 'commands/runner'
+ exec("bundle exec rails runner #{ARGV[1]}")
end
end
diff --git a/script/server b/script/server
deleted file mode 100755
index dc3edabd5..000000000
--- a/script/server
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/usr/bin/env ruby
-require File.expand_path(File.dirname(__FILE__) + '/../config/boot.rb')
-require 'commands/server'
diff --git a/script/spec b/script/spec
deleted file mode 100755
index 46fdbe6e4..000000000
--- a/script/spec
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/usr/bin/env ruby
-if ARGV.any? {|arg| %w[--drb -X --generate-options -G --help -h --version -v].include?(arg)}
- require 'rubygems' unless ENV['NO_RUBYGEMS']
-else
- gem 'test-unit', '1.2.3' if RUBY_VERSION.to_f >= 1.9
- ENV["RAILS_ENV"] ||= 'test'
- require File.expand_path(File.dirname(__FILE__) + "/../config/environment") unless defined?(RAILS_ROOT)
-end
-require 'spec/autorun'
-exit ::Spec::Runner::CommandLine.run
diff --git a/script/spec-all-pairs b/script/spec-all-pairs
deleted file mode 100755
index 6d7bb17c4..000000000
--- a/script/spec-all-pairs
+++ /dev/null
@@ -1,81 +0,0 @@
-#!/bin/bash
-
-# Try all ordered pairs of spec files,
-# to winkle out order-dependent failures.
-
-log_file=/dev/null
-
-test_pair () {
- bundle exec 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/spec_server b/script/spec_server
deleted file mode 100755
index dfdf8ff6c..000000000
--- a/script/spec_server
+++ /dev/null
@@ -1,116 +0,0 @@
-#!/usr/bin/env ruby
-$LOAD_PATH.unshift File.dirname(__FILE__) + '/../vendor/plugins/rspec/lib' # For rspec installed as plugin
-require 'rubygems'
-require 'drb/drb'
-require 'rbconfig'
-require 'spec'
-require 'optparse'
-
-# This is based on Florian Weber's TDDMate
-module Spec
- module Runner
- class RailsSpecServer
- def run(argv, stderr, stdout)
- $stdout = stdout
- $stderr = stderr
-
- base = ActiveRecord::Base
- def base.clear_reloadable_connections!
- active_connections.each do |name, conn|
- if conn.requires_reloading?
- conn.disconnect!
- active_connections.delete(name)
- end
- end
- end
-
- if ActionController.const_defined?(:Dispatcher)
- dispatcher = ::ActionController::Dispatcher.new($stdout)
- dispatcher.cleanup_application
- elsif ::Dispatcher.respond_to?(:reset_application!)
- ::Dispatcher.reset_application!
- else
- raise "Application reloading failed"
- end
- if Object.const_defined?(:Fixtures) && Fixtures.respond_to?(:reset_cache)
- Fixtures.reset_cache
- end
-
- ::Dependencies.mechanism = :load
- require_dependency('application.rb') unless Object.const_defined?(:ApplicationController)
- load File.dirname(__FILE__) + '/../spec/spec_helper.rb'
-
- if in_memory_database?
- load "#{Rails.root}/db/schema.rb" # use db agnostic schema by default
- ActiveRecord::Migrator.up('db/migrate') # use migrations
- end
-
- ::Spec::Runner::CommandLine.run(
- ::Spec::Runner::OptionParser.parse(
- argv,
- $stderr,
- $stdout
- )
- )
- end
-
- def in_memory_database?
- ENV["RAILS_ENV"] == "test" and
- ::ActiveRecord::Base.connection.class.to_s == "ActiveRecord::ConnectionAdapters::SQLite3Adapter" and
- ::Rails::Configuration.new.database_configuration['test']['database'] == ':memory:'
- end
- end
- end
-end
-puts "Loading Rails environment"
-
-ENV["RAILS_ENV"] = "test"
-require File.expand_path(File.dirname(__FILE__) + "/../config/environment")
-require 'dispatcher'
-
-def restart_test_server
- puts "restarting"
- config = ::Config::CONFIG
- ruby = File::join(config['bindir'], config['ruby_install_name']) + config['EXEEXT']
- command_line = [ruby, $0, ARGV].flatten.join(' ')
- exec(command_line)
-end
-
-def daemonize(pid_file = nil)
- return yield if $DEBUG
- pid = Process.fork{
- Process.setsid
- Dir.chdir(Rails.root)
- trap("SIGINT"){ exit! 0 }
- trap("SIGTERM"){ exit! 0 }
- trap("SIGHUP"){ restart_test_server }
- File.open("/dev/null"){|f|
- STDERR.reopen f
- STDIN.reopen f
- STDOUT.reopen f
- }
- yield
- }
- puts "spec_server launched. (PID: %d)" % pid
- File.open(pid_file,"w"){|f| f.puts pid } if pid_file
- exit! 0
-end
-
-options = Hash.new
-opts = OptionParser.new
-opts.on("-d", "--daemon"){|v| options[:daemon] = true }
-opts.on("-p", "--pid PIDFILE"){|v| options[:pid] = v }
-opts.parse!(ARGV)
-
-puts "Ready"
-exec_server = lambda {
- trap("USR2") { restart_test_server } if Signal.list.has_key?("USR2")
- DRb.start_service("druby://localhost:8989", Spec::Runner::RailsSpecServer.new)
- DRb.thread.join
-}
-
-if options[:daemon]
- daemonize(options[:pid], &exec_server)
-else
- exec_server.call
-end
diff --git a/script/stop-new-responses-on-old-requests b/script/stop-new-responses-on-old-requests
index 1e325403e..07257d6b2 100755
--- a/script/stop-new-responses-on-old-requests
+++ b/script/stop-new-responses-on-old-requests
@@ -1,7 +1,4 @@
#!/bin/bash
-
-cd "`dirname "$0"`"
-
-bundle exec ./runner 'InfoRequest.stop_new_responses_on_old_requests()'
-
-
+TOP_DIR="$(dirname "$BASH_SOURCE")/.."
+cd "$TOP_DIR"
+bundle exec rails runner 'InfoRequest.stop_new_responses_on_old_requests'
diff --git a/script/test-run b/script/test-run
deleted file mode 100755
index 7810b57d5..000000000
--- a/script/test-run
+++ /dev/null
@@ -1,5 +0,0 @@
-#!/bin/bash
-
-cd ../
-bundle exec rake spec
-
diff --git a/script/user-use-graph b/script/user-use-graph
index 205e02416..f508c9cb6 100755
--- a/script/user-use-graph
+++ b/script/user-use-graph
@@ -3,7 +3,7 @@
# Plot graph of user use of site.
#
# Copyright (c) 2009 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org. WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org. WWW: http://www.mysociety.org/
GPLOT_OUTPUT="set terminal png font 'Vera.ttf' 9 size 1200,400"
EXTENSION=".png"
diff --git a/script/wraptest b/script/wraptest
deleted file mode 100755
index 780c9b4a2..000000000
--- a/script/wraptest
+++ /dev/null
@@ -1,43 +0,0 @@
-#!/usr/bin/env ruby
-#
-# wraptest:
-# Test email wrapping function
-#
-# Copyright (c) 2007 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
-#
-
-$:.push(File.join(File.dirname(__FILE__), '../../rblib'))
-load "format.rb"
-
-test_email = '''Dear Sir or Madam,
-
-Again and again I extend this sentence and yet again I extend this sentence and yet again I extend this sentence and yet again I extend this sentence and yet again I extend this sentence and yet again I extend this sentence and yet again I extend this sentence and yet again I extend this sentence and yet again I extend this sentence and yet again I extend this sentence and yet again I extend this sentence and yet again I extend this sentence and yet again I extend this sentence and yet again I extend this sentence and yet again I extend this sentence and yet again I extend this sentence and yet again I extend this sentence and yet again I extend this sentence and yet
-
-Hey you.
-
-Yours faithfully,
-
-Boo!
-
---
-
-Sent using GovernmentSpy, a project of UKCOD, registered charity number
-1076346. Is frabcus@fastmail.fm the wrong
-address for Freedom of Information requests to The Geraldine Quango? If so please let us know by emailing
-team@governmentspy quoting reference PB2.
-We\'ll make sure future ones go to the right place.
-'''
-
-test_email.gsub!(/\n/, "\r\n")
-
-puts MySociety::Format.wrap_email_body(test_email)
-
-#puts MySociety::Format.wrap_email_body("Hello this is a string.
-#
-#And another.
-#And a third.")
-
-
-
-
diff --git a/spec/controllers/admin_censor_rule_controller_spec.rb b/spec/controllers/admin_censor_rule_controller_spec.rb
index fb9ddf594..37ffd9764 100644
--- a/spec/controllers/admin_censor_rule_controller_spec.rb
+++ b/spec/controllers/admin_censor_rule_controller_spec.rb
@@ -1,20 +1,16 @@
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
describe AdminCensorRuleController, "when making censor rules from the admin interface" do
- integrate_views
- before do
- basic_auth_login @request
- PurgeRequest.destroy_all
- end
-
-
+ render_views
+ before { basic_auth_login @request }
+
it "should create a censor rule and purge the corresponding request from varnish" do
- ir = info_requests(:fancy_dog_request)
+ ir = info_requests(:fancy_dog_request)
post :create, :censor_rule => {
:text => "meat",
:replacement => "tofu",
:last_edit_comment => "none",
- :info_request => ir
+ :info_request_id => ir
}
PurgeRequest.all().first.model_id.should == ir.id
end
diff --git a/spec/controllers/admin_general_controller_spec.rb b/spec/controllers/admin_general_controller_spec.rb
index dc1eb0d97..971960762 100644
--- a/spec/controllers/admin_general_controller_spec.rb
+++ b/spec/controllers/admin_general_controller_spec.rb
@@ -4,7 +4,7 @@ describe AdminGeneralController do
describe "when viewing front page of admin interface" do
- integrate_views
+ render_views
before { basic_auth_login @request }
it "should render the front page" do
@@ -14,8 +14,7 @@ describe AdminGeneralController do
it "should redirect to include trailing slash" do
get :index
- response.should redirect_to(:controller => 'admin_general',
- :action => 'index')
+ response.should redirect_to admin_general_index_url(:trailing_slash => true)
end
end
diff --git a/spec/controllers/admin_public_body_controller_spec.rb b/spec/controllers/admin_public_body_controller_spec.rb
index 317c186fa..8a72db724 100644
--- a/spec/controllers/admin_public_body_controller_spec.rb
+++ b/spec/controllers/admin_public_body_controller_spec.rb
@@ -1,16 +1,7 @@
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
describe AdminPublicBodyController, "when administering public bodies" do
- integrate_views
-
- before do
- @old_filters = ActionController::Routing::Routes.filters
- ActionController::Routing::Routes.filters = RoutingFilter::Chain.new
- end
-
- after do
- ActionController::Routing::Routes.filters = @old_filters
- end
+ render_views
it "shows the index page" do
get :index
@@ -38,7 +29,7 @@ describe AdminPublicBodyController, "when administering public bodies" do
it "saves edits to a public body" do
public_bodies(:humpadink_public_body).name.should == "Department for Humpadinking"
post :update, { :id => 3, :public_body => { :name => "Renamed", :short_name => "", :tag_string => "some tags", :request_email => 'edited@localhost', :last_edit_comment => 'From test code' } }
- response.flash[:notice].should include('successful')
+ request.flash[:notice].should include('successful')
pb = PublicBody.find(public_bodies(:humpadink_public_body).id)
pb.name.should == "Renamed"
end
@@ -66,7 +57,7 @@ describe AdminPublicBodyController, "when administering public bodies" do
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."
+ request.flash[:notice].should == "Added tag to table of bodies."
response.should redirect_to(:action=>'list')
PublicBody.find_by_tag("department").count.should == n
end
@@ -86,8 +77,7 @@ describe AdminPublicBodyController, "when administering public bodies" do
before do
PublicBody.stub!(:import_csv).and_return([[],[]])
- @file_object = mock("a file upload", :read => 'some contents',
- :original_filename => 'contents.txt')
+ @file_object = fixture_file_upload('/files/fake-authority-type.csv')
end
it 'should handle a nil csv file param' do
@@ -106,7 +96,7 @@ describe AdminPublicBodyController, "when administering public bodies" do
it 'should assign the original filename to the view' do
post :import_csv, { :csv_file => @file_object,
:commit => 'Dry run'}
- assigns[:original_csv_file].should == 'contents.txt'
+ assigns[:original_csv_file].should == 'fake-authority-type.csv'
end
end
@@ -154,7 +144,7 @@ end
describe AdminPublicBodyController, "when administering public bodies and paying attention to authentication" do
- integrate_views
+ render_views
before do
config = MySociety::Config.load_default()
@@ -217,7 +207,7 @@ describe AdminPublicBodyController, "when administering public bodies and paying
it "doesn't let people with good emergency account credentials log in if the emergency user is disabled" do
setup_emergency_credentials('biz', 'fuz')
- Configuration.stub!(:disable_emergency_user).and_return(true)
+ AlaveteliConfiguration.stub!(:disable_emergency_user).and_return(true)
n = PublicBody.count
basic_auth_login(@request, "biz", "fuz")
post :show, { :id => public_bodies(:humpadink_public_body).id, :emergency => 1}
@@ -276,7 +266,7 @@ describe AdminPublicBodyController, "when administering public bodies and paying
end
describe AdminPublicBodyController, "when administering public bodies with i18n" do
- integrate_views
+ render_views
it "shows the index page" do
get :index
@@ -295,7 +285,7 @@ describe AdminPublicBodyController, "when administering public bodies with i18n"
get :edit, {:id => 3, :locale => :en}
# When editing a body, the controller returns all available translations
- assigns[:public_body].translation("es").name.should == 'El Department for Humpadinking'
+ assigns[:public_body].find_translation_by_locale("es").name.should == 'El Department for Humpadinking'
assigns[:public_body].name.should == 'Department for Humpadinking'
response.should render_template('edit')
end
@@ -317,7 +307,7 @@ describe AdminPublicBodyController, "when administering public bodies with i18n"
}
}
}
- response.flash[:notice].should include('successful')
+ request.flash[:notice].should include('successful')
end
pb = PublicBody.find(public_bodies(:humpadink_public_body).id)
@@ -338,16 +328,7 @@ describe AdminPublicBodyController, "when administering public bodies with i18n"
end
describe AdminPublicBodyController, "when creating public bodies with i18n" do
- integrate_views
-
- before do
- @old_filters = ActionController::Routing::Routes.filters
- ActionController::Routing::Routes.filters = RoutingFilter::Chain.new
- end
-
- after do
- ActionController::Routing::Routes.filters = @old_filters
- end
+ render_views
it "creates a new public body in one locale" do
n = PublicBody.count
diff --git a/spec/controllers/admin_request_controller_spec.rb b/spec/controllers/admin_request_controller_spec.rb
index 8a3934685..b7b726507 100644
--- a/spec/controllers/admin_request_controller_spec.rb
+++ b/spec/controllers/admin_request_controller_spec.rb
@@ -1,16 +1,11 @@
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
describe AdminRequestController, "when administering requests" do
- integrate_views
+ render_views
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
@@ -39,7 +34,7 @@ describe AdminRequestController, "when administering requests" do
:awaiting_description => false,
:allow_new_responses_from => 'anybody',
:handle_rejected_responses => 'bounce' } }
- response.flash[:notice].should include('successful')
+ request.flash[:notice].should include('successful')
ir = InfoRequest.find(info_requests(:fancy_dog_request).id)
ir.title.should == "Renamed"
end
@@ -64,7 +59,7 @@ describe AdminRequestController, "when administering requests" do
it "saves edits to an outgoing_message" do
outgoing_messages(:useless_outgoing_message).body.should include("fancy dog")
post :update_outgoing, { :id => outgoing_messages(:useless_outgoing_message), :outgoing_message => { :body => "Why do you have such a delicious cat?" } }
- response.flash[:notice].should include('successful')
+ request.flash[:notice].should include('successful')
ir = OutgoingMessage.find(outgoing_messages(:useless_outgoing_message).id)
ir.body.should include("delicious cat")
end
@@ -82,15 +77,10 @@ describe AdminRequestController, "when administering requests" do
end
describe AdminRequestController, "when administering the holding pen" do
- integrate_views
+ render_views
before(:each) do
basic_auth_login @request
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
@@ -100,7 +90,7 @@ describe AdminRequestController, "when administering the holding pen" do
ir.save!
receive_incoming_mail('incoming-request-plain.email', ir.incoming_email, "frob@nowhere.com")
get :show_raw_email, :id => InfoRequest.holding_pen_request.get_last_response.raw_email.id
- response.should have_text(/Only the authority can reply to this request/)
+ response.should contain "Only the authority can reply to this request"
end
it "allows redelivery even to a closed request" do
@@ -164,7 +154,7 @@ describe AdminRequestController, "when administering the holding pen" do
receive_incoming_mail('incoming-request-plain.email', ir.incoming_email, "")
InfoRequest.holding_pen_request.incoming_messages.length.should == 2
get :show_raw_email, :id => interesting_email
- response.should have_text(/Could not identify the request/)
+ response.should contain "Could not identify the request"
assigns[:info_requests][0].should == ir
end
@@ -260,13 +250,13 @@ describe AdminRequestController, "when administering the holding pen" do
end
it 'should not send a notification email' do
- ContactMailer.should_not_receive(:deliver_from_admin_message)
+ ContactMailer.should_not_receive(:from_admin_message)
make_request
end
it 'should add a notice to the flash saying that the request has been hidden' do
make_request
- response.flash[:notice].should == "This external request has been hidden"
+ request.flash[:notice].should == "This external request has been hidden"
end
it 'should expire the file cache for the request' do
diff --git a/spec/controllers/admin_track_controller_spec.rb b/spec/controllers/admin_track_controller_spec.rb
index 728c79f1f..f2de6c0d3 100644
--- a/spec/controllers/admin_track_controller_spec.rb
+++ b/spec/controllers/admin_track_controller_spec.rb
@@ -1,7 +1,7 @@
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
describe AdminTrackController, "when administering tracks" do
- integrate_views
+ render_views
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 cf3665c9f..a6e5a0d7e 100644
--- a/spec/controllers/admin_user_controller_spec.rb
+++ b/spec/controllers/admin_user_controller_spec.rb
@@ -1,7 +1,7 @@
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
describe AdminUserController, "when administering users" do
- integrate_views
+ render_views
it "shows the index/list page" do
get :index
diff --git a/spec/controllers/api_controller_spec.rb b/spec/controllers/api_controller_spec.rb
index 1c320f85c..66b8e33f0 100644
--- a/spec/controllers/api_controller_spec.rb
+++ b/spec/controllers/api_controller_spec.rb
@@ -7,7 +7,7 @@ def normalise_whitespace(s)
return s
end
-Spec::Matchers.define :be_equal_modulo_whitespace_to do |expected|
+RSpec::Matchers.define :be_equal_modulo_whitespace_to do |expected|
match do |actual|
normalise_whitespace(actual) == normalise_whitespace(expected)
end
@@ -173,7 +173,7 @@ describe ApiController, "when using the API" do
"body" => "xxx"
}.to_json
- response.status.should == "500 Internal Server Error"
+ response.status.should == 500
ActiveSupport::JSON.decode(response.body)["errors"].should == [
"Request #{request_id} cannot be updated using the API"]
@@ -195,7 +195,7 @@ describe ApiController, "when using the API" do
"body" => "xxx"
}.to_json
- response.status.should == "500 Internal Server Error"
+ response.status.should == 500
ActiveSupport::JSON.decode(response.body)["errors"].should == [
"You do not own request #{request_id}"]
@@ -213,12 +213,12 @@ describe ApiController, "when using the API" do
"body" => "Are you joking, or are you serious?"
}.to_json,
:attachments => [
- fixture_file_upload("files/tfl.pdf")
+ fixture_file_upload("/files/tfl.pdf")
]
# Make sure it worked
- response.status.to_i.should == 500
+ response.status.should == 500
errors = ActiveSupport::JSON.decode(response.body)["errors"]
errors.should == ["You cannot attach files to messages in the 'request' direction"]
end
@@ -242,7 +242,7 @@ describe ApiController, "when using the API" do
"body" => response_body
}.to_json,
:attachments => [
- fixture_file_upload("files/tfl.pdf")
+ fixture_file_upload("/files/tfl.pdf")
]
# And make sure it worked
@@ -259,7 +259,7 @@ describe ApiController, "when using the API" do
attachments.size.should == 1
attachment = attachments[0]
attachment.filename.should == "tfl.pdf"
- attachment.body.should == load_file_fixture("tfl.pdf", as_binary=true)
+ attachment.body.should == load_file_fixture("tfl.pdf")
end
it "should show information about a request" do
@@ -286,7 +286,7 @@ describe ApiController, "when using the API" do
:feed_type => "atom"
response.should be_success
- response.should render_template("api/request_events.atom")
+ response.should render_template("api/request_events")
assigns[:events].size.should > 0
assigns[:events].each do |event|
event.info_request.public_body.should == public_bodies(:geraldine_public_body)
@@ -341,7 +341,7 @@ describe ApiController, "when using the API" do
:feed_type => "atom"
response.should be_success
- response.should render_template("api/request_events.atom")
+ response.should render_template("api/request_events")
assigns[:events].size.should > 0
assigns[:events].each do |event|
event.created_at.should >= Date.new(2010, 1, 1)
@@ -360,7 +360,7 @@ describe ApiController, "when using the API" do
"sent_at" => sent_at,
"body" => response_body
}.to_json
- response.status.should == "404 Not Found"
+ response.status.should == 404
ActiveSupport::JSON.decode(response.body)["errors"].should == ["Could not find request 123459876"]
end
@@ -376,7 +376,7 @@ describe ApiController, "when using the API" do
"sent_at" => sent_at,
"body" => response_body
}.to_json
- response.status.should == "500 Internal Server Error"
+ response.status.should == 500
ActiveSupport::JSON.decode(response.body)["errors"].should == ["Request #{request_id} cannot be updated using the API"]
end
end
diff --git a/spec/controllers/comment_controller_spec.rb b/spec/controllers/comment_controller_spec.rb
index 4a7acee23..c03615ce2 100644
--- a/spec/controllers/comment_controller_spec.rb
+++ b/spec/controllers/comment_controller_spec.rb
@@ -1,7 +1,7 @@
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
describe CommentController, "when commenting on a request" do
- integrate_views
+ render_views
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 642ed0e05..4a1c8b134 100644
--- a/spec/controllers/general_controller_spec.rb
+++ b/spec/controllers/general_controller_spec.rb
@@ -12,30 +12,39 @@ describe GeneralController, "when trying to show the blog" do
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"
+ response.status.should == 200
assigns[:blog_items].count.should == 0
end
end
describe GeneralController, 'when getting the blog feed' do
+ before do
+ AlaveteliConfiguration.stub!(:blog_feed).and_return("http://blog.example.com")
+ end
+
it 'should add a lang param correctly to a url with no querystring' do
- Configuration.stub!(:blog_feed).and_return("http://blog.example.com")
get :blog
assigns[:feed_url].should == "http://blog.example.com?lang=en"
end
it 'should add a lang param correctly to a url with an existing querystring' do
- Configuration.stub!(:blog_feed).and_return("http://blog.example.com?alt=rss")
+ AlaveteliConfiguration.stub!(:blog_feed).and_return("http://blog.example.com?alt=rss")
get :blog
assigns[:feed_url].should == "http://blog.example.com?alt=rss&lang=en"
end
+ it 'should parse an item from an example feed' do
+ controller.stub!(:quietly_try_to_open).and_return(load_file_fixture("blog_feed.atom"))
+ get :blog
+ assigns[:blog_items].count.should == 1
+ end
+
end
describe GeneralController, "when showing the frontpage" do
- integrate_views
+ render_views
before do
public_body = mock_model(PublicBody, :name => "Example Public Body",
@@ -58,14 +67,14 @@ describe GeneralController, "when showing the frontpage" do
it "should render the front page with default language" do
get :frontpage
- response.should have_tag('html[lang="en"]')
+ response.should have_selector('html[lang="en"]')
end
it "should render the front page with default language" do
old_default_locale = I18n.default_locale
I18n.default_locale = "es"
get :frontpage
- response.should have_tag('html[lang="es"]')
+ response.should have_selector('html[lang="es"]')
I18n.default_locale = old_default_locale
end
@@ -77,7 +86,7 @@ describe GeneralController, "when showing the frontpage" do
old_default_locale = I18n.default_locale
I18n.default_locale = "es"
get :frontpage
- response.should have_tag('html[lang="es"]')
+ response.should have_selector('html[lang="es"]')
I18n.default_locale = old_default_locale
end
@@ -87,7 +96,7 @@ describe GeneralController, "when showing the frontpage" do
accept_language = "es-ES,en-GB,en-US;q=0.8,en;q=0.6"
request.env['HTTP_ACCEPT_LANGUAGE'] = accept_language
get :frontpage
- response.should have_tag('html[lang="es"]')
+ response.should have_selector('html[lang="es"]')
request.env['HTTP_ACCEPT_LANGUAGE'] = nil
end
@@ -104,11 +113,11 @@ describe GeneralController, "when showing the frontpage" do
before do
@default_lang_home_link = /href=".*\/en\//
@other_lang_home_link = /href=".*\/es\//
- @old_include_default_locale_in_urls = Configuration::include_default_locale_in_urls
+ @old_include_default_locale_in_urls = AlaveteliConfiguration::include_default_locale_in_urls
end
def set_default_locale_in_urls(value)
- Configuration.stub!(:include_default_locale_in_urls).and_return(value)
+ AlaveteliConfiguration.stub!(:include_default_locale_in_urls).and_return(value)
load Rails.root.join("config/initializers/fast_gettext.rb")
end
@@ -120,13 +129,13 @@ describe GeneralController, "when showing the frontpage" do
it 'should generate URLs without a locale prepended' do
get :frontpage
- response.should_not have_text(@default_lang_home_link)
+ response.should_not contain @default_lang_home_link
end
it 'should render the front page in the default language when no locale param
is present and the session locale is not the default' do
get(:frontpage, {}, {:locale => 'es'})
- response.should_not have_text(@other_lang_home_link)
+ response.should_not contain @other_lang_home_link
end
end
@@ -134,7 +143,7 @@ describe GeneralController, "when showing the frontpage" do
INCLUDE_DEFAULT_LOCALE_IN_URLS is true' do
set_default_locale_in_urls(true)
get :frontpage
- response.should have_text(@default_lang_home_link)
+ response.body.should match /#{@default_lang_home_link}/
end
after do
@@ -150,28 +159,28 @@ describe GeneralController, "when showing the frontpage" do
it "should generate URLs with a locale prepended when there's more than one locale set" do
get :frontpage
- response.should have_text(home_link_regex)
+ response.body.should match home_link_regex
end
it "should use our test PO files rather than the application one" do
I18n.default_locale = :es
get :frontpage
- response.should have_text(/XOXO/)
+ response.body.should match /XOXO/
I18n.default_locale = :en
end
it "should generate URLs that include the locale when using one that includes an underscore" do
I18n.default_locale = :"en_GB"
get :frontpage
- response.should have_text(/href="\/en_GB\//)
+ response.body.should match /href="\/en_GB\//
I18n.default_locale = :en
end
it "should fall back to the language if the territory is unknown" do
I18n.default_locale = :"en_US"
get :frontpage
- response.should have_text(/href="\/en\//)
- response.should_not have_text(/href="\/en_US\//)
+ response.body.should match /href="\/en\//
+ response.body.should_not match /href="\/en_US\//
I18n.default_locale = :en
end
@@ -181,7 +190,7 @@ describe GeneralController, "when showing the frontpage" do
FastGettext.default_available_locales = I18n.available_locales = ['en']
get :frontpage
- response.should_not have_text(home_link_regex)
+ response.should_not contain home_link_regex
FastGettext.default_available_locales = old_fgt_available_locales
I18n.available_locales = old_i18n_available_locales
@@ -235,7 +244,7 @@ end
describe GeneralController, 'when using xapian search' do
- integrate_views
+ render_views
# rebuild xapian index after fixtures loaded
before(:each) do
@@ -249,7 +258,7 @@ describe GeneralController, 'when using xapian search' do
end
it "should find info request when searching for '\"fancy dog\"'" do
- get :search, :combined => ['"fancy dog"']
+ get :search, :combined => '"fancy dog"'
response.should render_template('search')
assigns[:xapian_requests].matches_estimated.should == 1
assigns[:xapian_requests].results.size.should == 1
@@ -259,7 +268,7 @@ describe GeneralController, 'when using xapian search' do
end
it "should find public body and incoming message when searching for 'geraldine quango'" do
- get :search, :combined => ['geraldine quango']
+ get :search, :combined => 'geraldine quango'
response.should render_template('search')
assigns[:xapian_requests].matches_estimated.should == 1
@@ -272,7 +281,7 @@ describe GeneralController, 'when using xapian search' do
end
it "should filter results based on end of URL being 'all'" do
- get :search, :combined => ['"bob"', "all"]
+ get :search, :combined => "bob/all"
assigns[:xapian_requests].results.map{|x| x[:model]}.should =~ [
info_request_events(:useless_outgoing_message_event),
info_request_events(:silly_outgoing_message_event),
@@ -284,14 +293,14 @@ describe GeneralController, 'when using xapian search' do
end
it "should filter results based on end of URL being 'users'" do
- get :search, :combined => ['"bob"', "users"]
+ get :search, :combined => "bob/users"
assigns[:xapian_requests].should == nil
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"]
+ get :search, :combined => "bob/requests"
assigns[:xapian_requests].results.map{|x|x[:model]}.should =~ [
info_request_events(:useless_outgoing_message_event),
info_request_events(:silly_outgoing_message_event),
@@ -303,7 +312,7 @@ describe GeneralController, 'when using xapian search' do
end
it "should filter results based on end of URL being 'bodies'" do
- get :search, :combined => ['"quango"', "bodies"]
+ get :search, :combined => "quango/bodies"
assigns[:xapian_requests].should == nil
assigns[:xapian_users].should == nil
assigns[:xapian_bodies].results.map{|x|x[:model]}.should == [public_bodies(:geraldine_public_body)]
@@ -317,7 +326,7 @@ describe GeneralController, 'when using xapian search' do
end
it "should not show unconfirmed users" do
- get :search, :combined => ["unconfirmed", "users"]
+ get :search, :combined => "unconfirmed/users"
response.should render_template('search')
assigns[:xapian_users].results.map{|x|x[:model]}.should == []
end
@@ -328,13 +337,13 @@ describe GeneralController, 'when using xapian search' do
u.save!
update_xapian_index
- get :search, :combined => ["unconfirmed", "users"]
+ get :search, :combined => "unconfirmed/users"
response.should render_template('search')
assigns[:xapian_users].results.map{|x|x[:model]}.should == [u]
end
it "should show tracking links for requests-only searches" do
- get :search, :combined => ['"bob"', "requests"]
+ get :search, :combined => "bob/requests"
response.body.should include('Track this search')
end
diff --git a/spec/controllers/help_controller_spec.rb b/spec/controllers/help_controller_spec.rb
index 28fd08c80..0f6f75eb9 100644
--- a/spec/controllers/help_controller_spec.rb
+++ b/spec/controllers/help_controller_spec.rb
@@ -1,7 +1,7 @@
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
describe HelpController, "when using help" do
- integrate_views
+ render_views
it "shows the about page" do
get :about
diff --git a/spec/controllers/public_body_controller_spec.rb b/spec/controllers/public_body_controller_spec.rb
index 8f5b79489..22d8418c9 100644
--- a/spec/controllers/public_body_controller_spec.rb
+++ b/spec/controllers/public_body_controller_spec.rb
@@ -2,7 +2,7 @@
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
describe PublicBodyController, "when showing a body" do
- integrate_views
+ render_views
before(:each) do
load_raw_emails_data
@@ -50,17 +50,16 @@ describe PublicBodyController, "when showing a body" do
it "should assign the body using same locale as that used in url_name" do
get :show, {:url_name => "edfh", :view => 'all', :show_locale => "es"}
- response.should include_text("Baguette")
+ response.should contain("Baguette")
end
it "should redirect use to the relevant locale even when url_name is for a different locale" do
- old_filters = ActionController::Routing::Routes.filters
- ActionController::Routing::Routes.filters = RoutingFilter::Chain.new
+ RoutingFilter.active = false
get :show, {:url_name => "edfh", :view => 'all'}
response.should redirect_to "http://test.host/body/dfh"
- ActionController::Routing::Routes.filters = old_filters
+ RoutingFilter.active = true
end
it "should remember the filter (view) setting on redirecting" do
@@ -80,7 +79,7 @@ describe PublicBodyController, "when showing a body" do
end
describe PublicBodyController, "when listing bodies" do
- integrate_views
+ render_views
it "should be successful" do
get :list
@@ -108,9 +107,12 @@ describe PublicBodyController, "when listing bodies" do
response.should render_template('list')
- 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[:public_bodies].should == [ public_bodies(:other_public_body),
+ public_bodies(:humpadink_public_body),
+ public_bodies(:forlorn_public_body),
+ public_bodies(:geraldine_public_body),
+ public_bodies(:sensible_walks_public_body),
+ public_bodies(:silly_walks_public_body) ]
assigns[:tag].should == "all"
assigns[:description].should == ""
end
@@ -148,11 +150,20 @@ describe PublicBodyController, "when listing bodies" do
get :list, :tag => "other"
response.should render_template('list')
- assigns[:public_bodies].should =~ PublicBody.all(:conditions => "id not in (#{public_bodies(:humpadink_public_body).id}, #{PublicBody.internal_admin_body.id})")
+ assigns[:public_bodies].should == [ public_bodies(:other_public_body),
+ public_bodies(:forlorn_public_body),
+ public_bodies(:geraldine_public_body),
+ public_bodies(:sensible_walks_public_body),
+ public_bodies(:silly_walks_public_body) ]
get :list
response.should render_template('list')
- assigns[:public_bodies].should =~ PublicBody.all(:conditions => "id <> #{PublicBody.internal_admin_body.id}")
+ assigns[:public_bodies].should == [ public_bodies(:other_public_body),
+ public_bodies(:humpadink_public_body),
+ public_bodies(:forlorn_public_body),
+ public_bodies(:geraldine_public_body),
+ public_bodies(:sensible_walks_public_body),
+ public_bodies(:silly_walks_public_body) ]
end
it "should list a machine tagged thing, should get it in both ways" do
@@ -194,7 +205,7 @@ end
describe PublicBodyController, "when doing type ahead searches" do
- integrate_views
+ render_views
before(:each) do
load_raw_emails_data
diff --git a/spec/controllers/request_controller_spec.rb b/spec/controllers/request_controller_spec.rb
index 672c2c361..83e2b1767 100644
--- a/spec/controllers/request_controller_spec.rb
+++ b/spec/controllers/request_controller_spec.rb
@@ -2,7 +2,6 @@
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
describe RequestController, "when listing recent requests" do
-
before(:each) do
load_raw_emails_data
get_fixtures_xapian_index
@@ -90,7 +89,7 @@ describe RequestController, "when listing recent requests" do
end
it "should assign the first page of results" do
- xap_results = mock_model(ActsAsXapian::Search,
+ xap_results = mock(ActsAsXapian::Search,
:results => (1..25).to_a.map { |m| { :model => m } },
:matches_estimated => 1000000)
@@ -103,7 +102,7 @@ describe RequestController, "when listing recent requests" do
end
it "should return 404 for pages we don't want to serve up" do
- xap_results = mock_model(ActsAsXapian::Search,
+ xap_results = mock(ActsAsXapian::Search,
:results => (1..25).to_a.map { |m| { :model => m } },
:matches_estimated => 1000000)
lambda {
@@ -120,10 +119,7 @@ describe RequestController, "when listing recent requests" do
end
describe RequestController, "when changing things that appear on the request page" do
-
- before do
- PurgeRequest.destroy_all
- end
+ render_views
it "should purge the downstream cache when mail is received" do
ir = info_requests(:fancy_dog_request)
@@ -189,7 +185,7 @@ describe RequestController, "when changing things that appear on the request pag
end
describe RequestController, "when showing one request" do
- integrate_views
+ render_views
before(:each) do
load_raw_emails_data
@@ -218,20 +214,20 @@ describe RequestController, "when showing one request" do
end
it "should redirect from a numeric URL to pretty one" do
- get :show, :url_title => info_requests(:naughty_chicken_request).id
+ get :show, :url_title => info_requests(:naughty_chicken_request).id.to_s
response.should redirect_to(:action => 'show', :url_title => info_requests(:naughty_chicken_request).url_title)
end
it 'should show actions the request owner can take' do
get :show, :url_title => 'why_do_you_have_such_a_fancy_dog'
- response.should have_tag('div#owner_actions')
+ response.should have_selector('div#owner_actions')
end
describe 'when the request does allow comments' do
it 'should have a comment link' do
get :show, { :url_title => 'why_do_you_have_such_a_fancy_dog' },
{ :user_id => users(:admin_user).id }
- response.should have_tag('#anyone_actions', /Add an annotation/)
+ response.should have_selector('#anyone_actions', :content => "Add an annotation")
end
end
@@ -239,7 +235,7 @@ describe RequestController, "when showing one request" do
it 'should not have a comment link' do
get :show, { :url_title => 'spam_1' },
{ :user_id => users(:admin_user).id }
- response.should_not have_tag('#anyone_actions', /Add an annotation/)
+ response.should_not have_selector('#anyone_actions', :content => "Add an annotation")
end
end
@@ -256,13 +252,13 @@ describe RequestController, "when showing one request" do
it 'should show the describe state form' do
get :show, { :url_title => 'why_do_you_have_such_a_fancy_dog' },
{ :user_id => users(:admin_user).id }
- response.should have_tag('div.describe_state_form')
+ response.should have_selector('div.describe_state_form')
end
it 'should ask the user to use the describe state from' do
get :show, { :url_title => 'why_do_you_have_such_a_fancy_dog' },
{ :user_id => users(:admin_user).id }
- response.should have_tag('p#request_status', :text => /answer the question above/)
+ response.should have_selector('p#request_status', :content => "answer the question above")
end
end
@@ -280,7 +276,7 @@ describe RequestController, "when showing one request" do
it 'should give a link to requesting an internal review' do
get :show, { :url_title => 'why_do_you_have_such_a_fancy_dog' },
{ :user_id => users(:admin_user).id }
- response.should have_tag('p#request_status', :text =>/requesting an internal review/)
+ response.should have_selector('p#request_status', :content => "requesting an internal review")
end
end
@@ -298,7 +294,7 @@ describe RequestController, "when showing one request" do
it 'should give a link to make a followup' do
get :show, { :url_title => 'why_do_you_have_such_a_fancy_dog' },
{ :user_id => users(:admin_user).id }
- response.should have_tag('p#request_status a', :text =>/send a follow up message/)
+ response.should have_selector('p#request_status a', :content => "send a follow up message")
end
end
@@ -315,7 +311,7 @@ describe RequestController, "when showing one request" do
it 'should not display actions the request owner can take' do
get :show, :url_title => 'balalas'
- response.should_not have_tag('div#owner_actions')
+ response.should_not have_selector('div#owner_actions')
end
end
@@ -341,12 +337,12 @@ describe RequestController, "when showing one request" do
it 'should not show the describe state form' do
make_request
- response.should_not have_tag('div.describe_state_form')
+ response.should_not have_selector('div.describe_state_form')
end
it 'should not ask the user to use the describe state form' do
make_request
- response.should_not have_tag('p#request_status', :text => /answer the question above/)
+ response.should_not have_selector('p#request_status', :content => "answer the question above")
end
end
@@ -363,7 +359,7 @@ describe RequestController, "when showing one request" do
it 'should not give a link to requesting an internal review' do
make_request
- response.should_not have_tag('p#request_status', :text =>/requesting an internal review/)
+ response.should_not have_selector('p#request_status', :content => "requesting an internal review")
end
end
@@ -379,12 +375,12 @@ describe RequestController, "when showing one request" do
it 'should not give a link to make a followup' do
make_request
- response.should_not have_tag('p#request_status a', :text =>/send a follow up message/)
+ response.should_not have_selector('p#request_status a', :content => "send a follow up message")
end
it 'should not give a link to sign in (in the request status paragraph)' do
make_request
- response.should_not have_tag('p#request_status a', :text => /sign in/)
+ response.should_not have_selector('p#request_status a', :content => "sign in")
end
end
@@ -447,7 +443,7 @@ describe RequestController, "when showing one request" do
describe 'when handling incoming mail' do
- integrate_views
+ render_views
it "should receive incoming messages, send email to creator, and show them" do
ir = info_requests(:fancy_dog_request)
@@ -481,13 +477,13 @@ describe RequestController, "when showing one request" do
(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'], :skip_cache => 1
+ get :get_attachment, :incoming_message_id => ir.incoming_messages[1].id, :id => ir.id, :part => 2, :file_name => 'hello world.txt', :skip_cache => 1
response.content_type.should == "text/plain"
- response.should have_text(/Second hello/)
+ response.should contain "Second hello"
- get :get_attachment, :incoming_message_id => ir.incoming_messages[1].id, :id => ir.id, :part => 3, :file_name => ['hello.txt'], :skip_cache => 1
+ get :get_attachment, :incoming_message_id => ir.incoming_messages[1].id, :id => ir.id, :part => 3, :file_name => 'hello world.txt', :skip_cache => 1
response.content_type.should == "text/plain"
- response.should have_text(/First hello/)
+ response.should contain "First hello"
end
it 'should cache an attachment on a request with normal prominence' do
@@ -498,24 +494,23 @@ describe RequestController, "when showing one request" do
get :get_attachment, :incoming_message_id => ir.incoming_messages[1].id,
:id => ir.id,
:part => 2,
- :file_name => ['hello.txt']
-
+ :file_name => 'hello world.txt'
end
it "should convert message body to UTF8" do
ir = info_requests(:fancy_dog_request)
receive_incoming_mail('iso8859_2_raw_email.email', ir.incoming_email)
get :show, :url_title => 'why_do_you_have_such_a_fancy_dog'
- response.should have_text(/tënde/u)
+ response.should contain "tënde"
end
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
- get :get_attachment_as_html, :incoming_message_id => ir.incoming_messages[1].id, :id => ir.id, :part => 2, :file_name => ['hello.txt.html'], :skip_cache => 1
+ get :get_attachment_as_html, :incoming_message_id => ir.incoming_messages[1].id, :id => ir.id, :part => 2, :file_name => 'hello world.txt.html', :skip_cache => 1
response.content_type.should == "text/html"
- response.should have_text(/Second hello/)
+ response.should contain "Second hello"
end
# This is a regression test for a bug where URLs of this form were causing 500 errors
@@ -534,11 +529,11 @@ describe RequestController, "when showing one request" do
ir.reload
ugly_id = "55195"
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
+ get :get_attachment, :incoming_message_id => ir.incoming_messages[1].id, :id => ugly_id, :part => 2, :file_name => 'hello world.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
+ get :get_attachment_as_html, :incoming_message_id => ir.incoming_messages[1].id, :id => ugly_id, :part => 2, :file_name => 'hello world.txt', :skip_cache => 1
}.should raise_error(ActiveRecord::RecordNotFound)
end
it "should return 404 when incoming message and request ids don't match" do
@@ -547,7 +542,7 @@ describe RequestController, "when showing one request" do
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
+ get :get_attachment_as_html, :incoming_message_id => ir.incoming_messages[1].id, :id => wrong_id, :part => 2, :file_name => 'hello world.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
@@ -557,11 +552,11 @@ describe RequestController, "when showing one request" do
ugly_id = "%d95" % [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
+ get :get_attachment, :incoming_message_id => ir.incoming_messages[1].id, :id => ugly_id, :part => 2, :file_name => 'hello world.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
+ get :get_attachment_as_html, :incoming_message_id => ir.incoming_messages[1].id, :id => ugly_id, :part => 2, :file_name => 'hello world.txt', :skip_cache => 1
}.should raise_error(ActiveRecord::RecordNotFound)
end
it "should return 404 when incoming message and request ids don't match" do
@@ -570,7 +565,7 @@ describe RequestController, "when showing one request" do
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
+ get :get_attachment_as_html, :incoming_message_id => ir.incoming_messages[1].id, :id => wrong_id, :part => 2, :file_name => 'hello world.txt.html', :skip_cache => 1
}.should raise_error(ActiveRecord::RecordNotFound)
end
@@ -578,41 +573,64 @@ describe RequestController, "when showing one request" 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
+ 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/)
+ response.should contain "Walberswick Parish Council"
end
- it "should not cause a reparsing of the raw email, even when the result would be a 404" do
+ it "should not cause a reparsing of the raw email, even when the attachment can't be found" do
ir = info_requests(:fancy_dog_request)
receive_incoming_mail('incoming-request-two-same-name.email', ir.incoming_email)
ir.reload
- attachment = IncomingMessage.get_attachment_by_url_part_number(ir.incoming_messages[1].get_attachments_for_display, 2)
- attachment.body.should have_text(/Second hello/)
+ attachment = IncomingMessage.get_attachment_by_url_part_number_and_filename(ir.incoming_messages[1].get_attachments_for_display, 2, 'hello world.txt')
+ attachment.body.should contain "Second hello"
# change the raw_email associated with the message; this only be reparsed when explicitly asked for
ir.incoming_messages[1].raw_email.data = ir.incoming_messages[1].raw_email.data.sub("Second", "Third")
- # asking for an attachment by the wrong filename results
- # in a 404 for browsing users. This shouldn't cause a
- # re-parse...
- lambda {
- get :get_attachment_as_html, :incoming_message_id => ir.incoming_messages[1].id, :id => ir.id, :part => 2, :file_name => ['hello.txt.baz.html'], :skip_cache => 1
- }.should raise_error(ActiveRecord::RecordNotFound)
+ # asking for an attachment by the wrong filename should result in redirecting
+ # back to the incoming message, but shouldn't cause a reparse:
+ get :get_attachment_as_html, :incoming_message_id => ir.incoming_messages[1].id, :id => ir.id, :part => 2, :file_name => 'hello world.txt.baz.html', :skip_cache => 1
+ response.status.should == 303
- attachment = IncomingMessage.get_attachment_by_url_part_number(ir.incoming_messages[1].get_attachments_for_display, 2)
- attachment.body.should have_text(/Second hello/)
+ attachment = IncomingMessage.get_attachment_by_url_part_number_and_filename(ir.incoming_messages[1].get_attachments_for_display, 2, 'hello world.txt')
+ attachment.body.should contain "Second hello"
# ...nor should asking for it by its correct filename...
- get :get_attachment_as_html, :incoming_message_id => ir.incoming_messages[1].id, :id => ir.id, :part => 2, :file_name => ['hello.txt.html'], :skip_cache => 1
- response.should_not have_text(/Third hello/)
+ get :get_attachment_as_html, :incoming_message_id => ir.incoming_messages[1].id, :id => ir.id, :part => 2, :file_name => 'hello world.txt.html', :skip_cache => 1
+ response.should_not contain "Third hello"
# ...but if we explicitly ask for attachments to be extracted, then they should be
force = true
ir.incoming_messages[1].parse_raw_email!(force)
- attachment = IncomingMessage.get_attachment_by_url_part_number(ir.incoming_messages[1].get_attachments_for_display, 2)
- attachment.body.should have_text(/Second hello/)
- get :get_attachment_as_html, :incoming_message_id => ir.incoming_messages[1].id, :id => ir.id, :part => 2, :file_name => ['hello.txt.html'], :skip_cache => 1
- response.should have_text(/Third hello/)
+ ir.reload
+ attachment = IncomingMessage.get_attachment_by_url_part_number_and_filename(ir.incoming_messages[1].get_attachments_for_display, 2, 'hello world.txt')
+ attachment.body.should contain "Third hello"
+ get :get_attachment_as_html, :incoming_message_id => ir.incoming_messages[1].id, :id => ir.id, :part => 2, :file_name => 'hello world.txt.html', :skip_cache => 1
+ response.should contain "Third hello"
+ end
+
+ it "should redirect to the incoming message if there's a wrong part number and an ambiguous filename" do
+ ir = info_requests(:fancy_dog_request)
+ receive_incoming_mail('incoming-request-two-same-name.email', ir.incoming_email)
+ ir.reload
+
+ im = ir.incoming_messages[1]
+
+ attachment = IncomingMessage.get_attachment_by_url_part_number_and_filename(im.get_attachments_for_display, 5, 'hello world.txt')
+ attachment.should be_nil
+
+ get :get_attachment_as_html, :incoming_message_id => im.id, :id => ir.id, :part => 5, :file_name => 'hello world.txt', :skip_cache => 1
+ response.status.should == 303
+ new_location = response.header['Location']
+ new_location.should match(/request\/#{ir.url_title}#incoming-#{im.id}/)
+ end
+
+ it "should find a uniquely named filename even if the URL part number was wrong" do
+ ir = info_requests(:fancy_dog_request)
+ receive_incoming_mail('incoming-request-pdf-attachment.email', ir.incoming_email)
+ ir.reload
+ get :get_attachment, :incoming_message_id => ir.incoming_messages[1].id, :id => ir.id, :part => 5, :file_name => 'fs 50379341.pdf', :skip_cache => 1
+ response.content_type.should == "application/pdf"
end
it "should treat attachments with unknown extensions as binary" do
@@ -620,19 +638,17 @@ describe RequestController, "when showing one request" do
receive_incoming_mail('incoming-request-attachment-unknown-extension.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.qwglhm'], :skip_cache => 1
+ get :get_attachment, :incoming_message_id => ir.incoming_messages[1].id, :id => ir.id, :part => 2, :file_name => 'hello.qwglhm', :skip_cache => 1
response.content_type.should == "application/octet-stream"
- response.should have_text(/an unusual sort of file/)
+ response.should contain "an unusual sort of file"
end
it "should not download attachments with wrong file name" do
ir = info_requests(:fancy_dog_request)
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,
- :file_name => ['http://trying.to.hack']
- }.should raise_error(ActiveRecord::RecordNotFound)
+ get :get_attachment, :incoming_message_id => ir.incoming_messages[1].id, :id => ir.id, :part => 2, :file_name => 'http://trying.to.hack'
+ response.status.should == 303
end
it "should censor attachments downloaded as binary" do
@@ -648,9 +664,9 @@ describe RequestController, "when showing one request" do
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
+ get :get_attachment, :incoming_message_id => ir.incoming_messages[1].id, :id => ir.id, :part => 2, :file_name => 'hello world.txt', :skip_cache => 1
response.content_type.should == "text/plain"
- response.should have_text(/xxxxxx hello/)
+ response.should contain "xxxxxx hello"
ensure
ir.censor_rules.clear
end
@@ -670,9 +686,9 @@ describe RequestController, "when showing one request" do
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
+ get :get_attachment, :incoming_message_id => ir.incoming_messages[1].id, :id => ir.id, :part => 2, :file_name => 'hello world.txt', :skip_cache => 1
response.content_type.should == "text/plain"
- response.should have_text(/xxxxxx hello/)
+ response.should contain "xxxxxx hello"
ensure
ir.user.censor_rules.clear
end
@@ -694,21 +710,27 @@ describe RequestController, "when showing one request" do
get :show, :url_title => 'why_do_you_have_such_a_fancy_dog'
assert assigns[:info_request].info_request_events[3].incoming_message.get_attachments_for_display.count == 2
# the issue is that the info_request_events have got cached on them the old info_requests.
- # where i'm at: trying to replace those fields that got re-read from the raw email. however tests are failing in very strange ways. currently I don't appear to be getting any attachments parsed in at all when in the template (see "*****" in _correspondence.rhtml) but do when I'm in the code.
+ # where i'm at: trying to replace those fields that got re-read from the raw email. however tests are failing in very strange ways. currently I don't appear to be getting any attachments parsed in at all when in the template (see "*****" in _correspondence.html.erb) but do when I'm in the code.
# so at this point, assigns[:info_request].incoming_messages[1].get_attachments_for_display is returning stuff, but the equivalent thing in the template isn't.
# but something odd is that the above is return a whole load of attachments which aren't there in the controller
- response.body.should have_tag("p.attachment strong", /hello.txt/m)
+ response.body.should have_selector("p.attachment strong") do |s|
+ s.should contain /hello world.txt/m
+ end
censor_rule = CensorRule.new()
- censor_rule.text = "hello.txt"
+ # Note that the censor rule applies to the original filename,
+ # not the display_filename:
+ censor_rule.text = "hello-world.txt"
censor_rule.replacement = "goodbye.txt"
censor_rule.last_edit_editor = "unknown"
censor_rule.last_edit_comment = "none"
ir.censor_rules << censor_rule
begin
get :show, :url_title => 'why_do_you_have_such_a_fancy_dog'
- response.body.should have_tag("p.attachment strong", /goodbye.txt/m)
+ response.body.should have_selector("p.attachment strong") do |s|
+ s.should contain /goodbye.txt/m
+ end
ensure
ir.censor_rules.clear
end
@@ -731,19 +753,19 @@ describe RequestController, "when showing one request" do
ir = info_requests(:fancy_dog_request)
session[:user_id] = ir.user.id # bob_smith_user
get :download_entire_request, :url_title => title
- assigns[:url_path].should have_text(/#{title}.zip$/)
+ assigns[:url_path].should contain /#{title}.zip$/
old_path = assigns[:url_path]
- response.location.should have_text(/#{assigns[:url_path]}$/)
+ response.location.should contain /#{assigns[:url_path]}$/
zipfile = Zip::ZipFile.open(File.join(File.dirname(__FILE__), "../../cache/zips", old_path)) { |zipfile|
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
- assigns[:url_path].should have_text(/#{title}.zip$/)
+ assigns[:url_path].should contain /#{title}.zip$/
old_path = assigns[:url_path]
- response.location.should have_text(/#{assigns[:url_path]}$/)
+ response.location.should contain /#{assigns[:url_path]}$/
zipfile = Zip::ZipFile.open(File.join(File.dirname(__FILE__), "../../cache/zips", old_path)) { |zipfile|
- zipfile.count.should == 3 # the message plus two "hello.txt" files
+ zipfile.count.should == 3 # the message plus two "hello-world.txt" files
}
# The path of the zip file is based on the hash of the timestamp of the last request
@@ -752,11 +774,11 @@ describe RequestController, "when showing one request" do
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 contain /#{title}.zip$/
assigns[:url_path].should_not == old_path
- response.location.should have_text(/#{assigns[:url_path]}/)
+ response.location.should contain assigns[:url_path]
zipfile = Zip::ZipFile.open(File.join(File.dirname(__FILE__), "../../cache/zips", assigns[:url_path])) { |zipfile|
- zipfile.count.should == 4 # the message, two hello.txt plus the unknown attachment
+ zipfile.count.should == 4 # the message, two hello-world.txt plus the unknown attachment
}
end
@@ -764,14 +786,13 @@ describe RequestController, "when showing one request" do
info_request = info_requests(:external_request)
get :download_entire_request, { :url_title => info_request.url_title },
{ :user_id => users(:bob_smith_user) }
- response.location.should have_text(/#{assigns[:url_path]}$/)
+ response.location.should contain /#{assigns[:url_path]}$/
end
end
end
end
describe RequestController, "when changing prominence of a request" do
-
before(:each) do
load_raw_emails_data
end
@@ -795,6 +816,16 @@ describe RequestController, "when changing prominence of a request" do
response.should render_template('hidden')
end
+ it 'should not show hidden requests if requested using json' do
+ ir = info_requests(:fancy_dog_request)
+ ir.prominence = 'hidden'
+ ir.save!
+
+ session[:user_id] = ir.user.id # bob_smith_user
+ get :show, :url_title => 'why_do_you_have_such_a_fancy_dog', :format => 'json'
+ response.code.should == '410'
+ end
+
it "should show hidden requests if logged in as super user" do
ir = info_requests(:fancy_dog_request)
ir.prominence = 'hidden'
@@ -853,14 +884,14 @@ describe RequestController, "when changing prominence of a request" do
:part => 2,
:skip_cache => 1
response.content_type.should == "text/html"
- response.should_not have_text(/Second hello/)
+ response.should_not contain "Second hello"
response.should render_template('request/hidden')
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_not contain "First hello"
response.should render_template('request/hidden')
response.code.should == '410'
end
@@ -876,7 +907,7 @@ describe RequestController, "when changing prominence of a request" do
get :get_attachment_as_html, :incoming_message_id => ir.incoming_messages[1].id,
:id => ir.id,
:part => 2,
- :file_name => ['hello.txt']
+ :file_name => 'hello world.txt'
end.should raise_error(ActiveRecord::RecordNotFound)
end
@@ -891,7 +922,7 @@ describe RequestController, "when changing prominence of a request" do
get :get_attachment_as_html, :incoming_message_id => ir.incoming_messages[1].id,
:id => ir.id,
:part => 2,
- :file_name => ['hello.txt']
+ :file_name => 'hello world.txt'
end.should raise_error(ActiveRecord::RecordNotFound)
end
@@ -904,11 +935,11 @@ end
# end
describe RequestController, "when searching for an authority" do
-
# Whether or not sign-in is required for this step is configurable,
# so we make sure we're logged in, just in case
before do
@user = users(:bob_smith_user)
+ get_fixtures_xapian_index
end
it "should return nothing for the empty query string" do
@@ -920,6 +951,7 @@ describe RequestController, "when searching for an authority" do
end
it "should return matching bodies" do
+
session[:user_id] = @user.id
get :select_authority, :query => "Quango"
@@ -944,7 +976,7 @@ describe RequestController, "when searching for an authority" do
end
describe RequestController, "when creating a new request" do
- integrate_views
+ render_views
before do
@user = users(:bob_smith_user)
@@ -1036,7 +1068,7 @@ describe RequestController, "when creating a new request" do
response.should redirect_to show_new_request_url(:url_title => ir.url_title)
# This test uses an explicit path because it's relied in
# Google Analytics goals:
- response.redirected_to.should =~ /request\/why_is_your_quango_called_gerald\/new$/
+ response.redirect_url.should =~ /request\/why_is_your_quango_called_gerald\/new$/
end
it "should give an error if the same request is submitted twice" do
@@ -1180,7 +1212,7 @@ describe RequestController, "when making a new request" do
end
describe RequestController, "when viewing an individual response for reply/followup" do
- integrate_views
+ render_views
before(:each) do
load_raw_emails_data
@@ -1201,7 +1233,7 @@ describe RequestController, "when viewing an individual response for reply/follo
it "should offer the opportunity to reply to the main address" do
session[:user_id] = users(:bob_smith_user).id
get :show_response, :id => info_requests(:fancy_dog_request).id, :incoming_message_id => incoming_messages(:useless_incoming_message)
- response.body.should have_tag("div#other_recipients ul li", /the main FOI contact address for/)
+ response.body.should have_selector("div#other_recipients ul li", :content => "the main FOI contact address for")
end
it "should offer an opportunity to reply to another address" do
@@ -1211,17 +1243,32 @@ describe RequestController, "when viewing an individual response for reply/follo
ir.save!
receive_incoming_mail('incoming-request-plain.email', ir.incoming_email, "Frob <frob@bonce.com>")
get :show_response, :id => ir.id, :incoming_message_id => incoming_messages(:useless_incoming_message)
- response.body.should have_tag("div#other_recipients ul li", /Frob/)
+ response.body.should have_selector("div#other_recipients ul li", :content => "Frob")
end
- it "should not show individual responses if request hidden, even if request owner" do
- ir = info_requests(:fancy_dog_request)
- ir.prominence = 'hidden'
- ir.save!
+ context 'when a request is hidden' do
+
+ before do
+ ir = info_requests(:fancy_dog_request)
+ ir.prominence = 'hidden'
+ ir.save!
+
+ session[:user_id] = users(:bob_smith_user).id
+ end
+
+ it "should not show individual responses, even if request owner" do
+ get :show_response, :id => info_requests(:fancy_dog_request).id, :incoming_message_id => incoming_messages(:useless_incoming_message)
+ response.should render_template('request/hidden')
+ end
+
+ it 'should respond to a json request for a hidden request with a 410 code and no body' do
+ get :show_response, :id => info_requests(:fancy_dog_request).id,
+ :incoming_message_id => incoming_messages(:useless_incoming_message),
+ :format => 'json'
+
+ response.code.should == '410'
+ end
- session[:user_id] = users(:bob_smith_user).id
- get :show_response, :id => info_requests(:fancy_dog_request).id, :incoming_message_id => incoming_messages(:useless_incoming_message)
- response.should render_template('request/hidden')
end
describe 'when viewing a response for an external request' do
@@ -1295,7 +1342,9 @@ describe RequestController, "when classifying an information request" do
before do
@dog_request.stub!(:is_old_unclassified?).and_return(true)
- RequestMailer.stub!(:deliver_old_unclassified_updated)
+ mail_mock = mock("mail")
+ mail_mock.stub(:deliver)
+ RequestMailer.stub!(:old_unclassified_updated).and_return(mail_mock)
end
describe 'when the user is not logged in' do
@@ -1332,7 +1381,7 @@ describe RequestController, "when classifying an information request" do
end
it 'should send an email to the requester letting them know someone has updated the status of their request' do
- RequestMailer.should_receive(:deliver_old_unclassified_updated)
+ RequestMailer.should_receive(:old_unclassified_updated)
post_status('rejected')
end
@@ -1364,7 +1413,7 @@ describe RequestController, "when classifying an information request" do
deliveries = ActionMailer::Base.deliveries
deliveries.size.should == 1
mail = deliveries[0]
- mail.from_addrs.first.to_s.should == users(:silly_name_user).name_and_email
+ mail.from_addrs.first.to_s.should == users(:silly_name_user).email
end
end
end
@@ -1403,7 +1452,9 @@ describe RequestController, "when classifying an information request" do
end
it 'should send an email to the requester letting them know someone has updated the status of their request' do
- RequestMailer.should_receive(:deliver_old_unclassified_updated)
+ mail_mock = mock("mail")
+ mail_mock.stub :deliver
+ RequestMailer.should_receive(:old_unclassified_updated).and_return(mail_mock)
post_status('rejected')
end
@@ -1442,7 +1493,7 @@ describe RequestController, "when classifying an information request" do
end
it 'should not send an email to the requester letting them know someone has updated the status of their request' do
- RequestMailer.should_not_receive(:deliver_old_unclassified_updated)
+ RequestMailer.should_not_receive(:old_unclassified_updated)
post_status('rejected')
end
@@ -1499,7 +1550,7 @@ describe RequestController, "when classifying an information request" do
end
it 'should not send an email to the requester letting them know someone has updated the status of their request' do
- RequestMailer.should_not_receive(:deliver_old_unclassified_updated)
+ RequestMailer.should_not_receive(:old_unclassified_updated)
post_status('rejected')
end
@@ -1562,11 +1613,10 @@ describe RequestController, "when classifying an information request" do
@dog_request = info_requests(:fancy_dog_request)
@dog_request.stub!(:each).and_return([@dog_request])
InfoRequest.stub!(:find).and_return(@dog_request)
- @old_filters = ActionController::Routing::Routes.filters
- ActionController::Routing::Routes.filters = RoutingFilter::Chain.new
+ RoutingFilter.active = false
end
after do
- ActionController::Routing::Routes.filters = @old_filters
+ RoutingFilter.active = true
end
def request_url
@@ -1670,7 +1720,7 @@ describe RequestController, "when classifying an information request" do
end
describe RequestController, "when sending a followup message" do
- integrate_views
+ render_views
before(:each) do
load_raw_emails_data
@@ -1723,7 +1773,7 @@ describe RequestController, "when sending a followup message" do
deliveries.size.should == 1
mail = deliveries[0]
mail.body.should =~ /What a useless response! You suck./
- mail.to_addrs.first.to_s.should == "FOI Person <foiperson@localhost>"
+ mail.to_addrs.first.to_s.should == "foiperson@localhost"
response.should redirect_to(:action => 'show', :url_title => info_requests(:fancy_dog_request).url_title)
@@ -1752,7 +1802,7 @@ end
# it can't check the URLs in the emails I don't think, ugh.
describe RequestController, "sending overdue request alerts" do
- integrate_views
+ render_views
before(:each) do
load_raw_emails_data
@@ -1770,9 +1820,9 @@ describe RequestController, "sending overdue request alerts" do
mail = chicken_mails[0]
mail.body.should =~ /promptly, as normally/
- mail.to_addrs.first.to_s.should == info_requests(:naughty_chicken_request).user.name_and_email
+ mail.to_addrs.first.to_s.should == info_requests(:naughty_chicken_request).user.email
- mail.body =~ /(http:\/\/.*\/c\/(.*))/
+ mail.body.to_s =~ /(http:\/\/.*\/c\/(.*))/
mail_url = $1
mail_token = $2
@@ -1799,7 +1849,7 @@ describe RequestController, "sending overdue request alerts" do
mail = chicken_mails[0]
mail.body.should =~ /promptly, as normally/
- mail.to_addrs.first.to_s.should == info_requests(:naughty_chicken_request).user.name_and_email
+ mail.to_addrs.first.to_s.should == info_requests(:naughty_chicken_request).user.email
end
it "should send not actually send the overdue alert if the user is banned but should
@@ -1827,9 +1877,9 @@ describe RequestController, "sending overdue request alerts" do
mail = chicken_mails[0]
mail.body.should =~ /required by law/
- mail.to_addrs.first.to_s.should == info_requests(:naughty_chicken_request).user.name_and_email
+ mail.to_addrs.first.to_s.should == info_requests(:naughty_chicken_request).user.email
- mail.body =~ /(http:\/\/.*\/c\/(.*))/
+ mail.body.to_s =~ /(http:\/\/.*\/c\/(.*))/
mail_url = $1
mail_token = $2
@@ -1897,7 +1947,7 @@ describe RequestController, "sending overdue request alerts" do
end
describe RequestController, "sending unclassified new response reminder alerts" do
- integrate_views
+ render_views
before(:each) do
load_raw_emails_data
@@ -1910,8 +1960,8 @@ describe RequestController, "sending unclassified new response reminder alerts"
deliveries.size.should == 3 # sufficiently late it sends reminders too
mail = deliveries[0]
mail.body.should =~ /To let everyone know/
- mail.to_addrs.first.to_s.should == info_requests(:fancy_dog_request).user.name_and_email
- mail.body =~ /(http:\/\/.*\/c\/(.*))/
+ mail.to_addrs.first.to_s.should == info_requests(:fancy_dog_request).user.email
+ mail.body.to_s =~ /(http:\/\/.*\/c\/(.*))/
mail_url = $1
mail_token = $2
@@ -1927,7 +1977,7 @@ describe RequestController, "sending unclassified new response reminder alerts"
end
describe RequestController, "clarification required alerts" do
- integrate_views
+ render_views
before(:each) do
load_raw_emails_data
end
@@ -1946,8 +1996,8 @@ describe RequestController, "clarification required alerts" do
deliveries.size.should == 1
mail = deliveries[0]
mail.body.should =~ /asked you to explain/
- mail.to_addrs.first.to_s.should == info_requests(:fancy_dog_request).user.name_and_email
- mail.body =~ /(http:\/\/.*\/c\/(.*))/
+ mail.to_addrs.first.to_s.should == info_requests(:fancy_dog_request).user.email
+ mail.body.to_s =~ /(http:\/\/.*\/c\/(.*))/
mail_url = $1
mail_token = $2
@@ -1980,7 +2030,7 @@ describe RequestController, "clarification required alerts" do
end
describe RequestController, "comment alerts" do
- integrate_views
+ render_views
before(:each) do
load_raw_emails_data
end
@@ -1999,8 +2049,8 @@ describe RequestController, "comment alerts" do
deliveries = ActionMailer::Base.deliveries
mail = deliveries[0]
mail.body.should =~ /has annotated your/
- mail.to_addrs.first.to_s.should == info_requests(:fancy_dog_request).user.name_and_email
- mail.body =~ /(http:\/\/.*)/
+ mail.to_addrs.first.to_s.should == info_requests(:fancy_dog_request).user.email
+ mail.body.to_s =~ /(http:\/\/.*)/
mail_url = $1
mail_url.should match("/request/why_do_you_have_such_a_fancy_dog#comment-#{new_comment.id}")
@@ -2049,8 +2099,8 @@ describe RequestController, "comment alerts" do
deliveries.size.should == 1
mail = deliveries[0]
mail.body.should =~ /There are 2 new annotations/
- mail.to_addrs.first.to_s.should == info_requests(:fancy_dog_request).user.name_and_email
- mail.body =~ /(http:\/\/.*)/
+ mail.to_addrs.first.to_s.should == info_requests(:fancy_dog_request).user.email
+ mail.body.to_s =~ /(http:\/\/.*)/
mail_url = $1
mail_url.should match("/request/why_do_you_have_such_a_fancy_dog#comment-#{comments(:silly_comment).id}")
@@ -2059,7 +2109,7 @@ describe RequestController, "comment alerts" do
end
describe RequestController, "when viewing comments" do
- integrate_views
+ render_views
before(:each) do
load_raw_emails_data
end
@@ -2067,22 +2117,26 @@ describe RequestController, "when viewing comments" do
it "should link to the user who submitted it" do
session[:user_id] = users(:bob_smith_user).id
get :show, :url_title => 'why_do_you_have_such_a_fancy_dog'
- response.body.should have_tag("div#comment-1 h2", /Silly.*left an annotation/m)
- response.body.should_not have_tag("div#comment-1 h2", /You.*left an annotation/m)
+ response.body.should have_selector("div#comment-1 h2") do |s|
+ s.should contain /Silly.*left an annotation/m
+ s.should_not contain /You.*left an annotation/m
+ end
end
it "should link to the user who submitted to it, even if it is you" do
session[:user_id] = users(:silly_name_user).id
get :show, :url_title => 'why_do_you_have_such_a_fancy_dog'
- response.body.should have_tag("div#comment-1 h2", /Silly.*left an annotation/m)
- response.body.should_not have_tag("div#comment-1 h2", /You.*left an annotation/m)
+ response.body.should have_selector("div#comment-1 h2") do |s|
+ s.should contain /Silly.*left an annotation/m
+ s.should_not contain /You.*left an annotation/m
+ end
end
end
describe RequestController, "authority uploads a response from the web interface" do
- integrate_views
+ render_views
before(:each) do
# domain after the @ is used for authentication of FOI officers, so to test it
@@ -2120,7 +2174,7 @@ describe RequestController, "authority uploads a response from the web interface
session[:user_id] = @normal_user.id
# post up a photo of the parrot
- parrot_upload = fixture_file_upload('files/parrot.png','image/png')
+ parrot_upload = fixture_file_upload('/files/parrot.png','image/png')
post :upload_response, :url_title => 'why_do_you_have_such_a_fancy_dog',
:body => "Find attached a picture of a parrot",
:file_1 => parrot_upload,
@@ -2148,7 +2202,7 @@ describe RequestController, "authority uploads a response from the web interface
session[:user_id] = @foi_officer_user.id
# post up a photo of the parrot
- parrot_upload = fixture_file_upload('files/parrot.png','image/png')
+ parrot_upload = fixture_file_upload('/files/parrot.png','image/png')
post :upload_response, :url_title => 'why_do_you_have_such_a_fancy_dog',
:body => "Find attached a picture of a parrot",
:file_1 => parrot_upload,
@@ -2172,7 +2226,6 @@ describe RequestController, "authority uploads a response from the web interface
end
describe RequestController, "when showing JSON version for API" do
-
before(:each) do
load_raw_emails_data
end
@@ -2191,25 +2244,28 @@ describe RequestController, "when showing JSON version for API" do
end
describe RequestController, "when doing type ahead searches" do
+ render_views
- integrate_views
+ before :each do
+ get_fixtures_xapian_index
+ end
it "should return nothing for the empty query string" do
get :search_typeahead, :q => ""
- response.should render_template('request/_search_ahead.rhtml')
+ response.should render_template('request/_search_ahead')
assigns[:xapian_requests].should be_nil
end
it "should return a request matching the given keyword, but not users with a matching description" do
get :search_typeahead, :q => "chicken"
- response.should render_template('request/_search_ahead.rhtml')
+ response.should render_template('request/_search_ahead')
assigns[:xapian_requests].results.size.should == 1
assigns[:xapian_requests].results[0][:model].title.should == info_requests(:naughty_chicken_request).title
end
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')
+ response.should render_template('request/_search_ahead')
assigns[:xapian_requests].results.map{|x|x[:model].info_request}.should =~ [
info_requests(:fancy_dog_request),
info_requests(:naughty_chicken_request),
@@ -2219,13 +2275,13 @@ describe RequestController, "when doing type ahead searches" do
it "should not return matches for short words" do
get :search_typeahead, :q => "a"
- response.should render_template('request/_search_ahead.rhtml')
+ response.should render_template('request/_search_ahead')
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')
+ response.should render_template('request/_search_ahead')
assigns[:xapian_requests].results.size.should ==1
end
@@ -2250,7 +2306,11 @@ describe RequestController, "when doing type ahead searches" do
end
describe RequestController, "when showing similar requests" do
- integrate_views
+ render_views
+
+ before do
+ get_fixtures_xapian_index
+ end
it "should work" do
get :similar, :url_title => info_requests(:badger_request).url_title
@@ -2292,7 +2352,7 @@ describe RequestController, "when reporting a request when not logged in" do
end
describe RequestController, "when reporting a request (logged in)" do
- integrate_views
+ render_views
before do
@user = users(:robin_user)
@@ -2368,7 +2428,6 @@ describe RequestController, "when reporting a request (logged in)" do
end
describe RequestController, "when caching fragments" do
-
it "should not fail with long filenames" do
long_name = "blahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblah.txt"
info_request = mock(InfoRequest, :user_can_view? => true,
@@ -2382,9 +2441,9 @@ describe RequestController, "when caching fragments" do
attachment = mock(FoiAttachment, :display_filename => long_name,
:body_as_html => ['some text', 'wrapper'])
IncomingMessage.stub!(:find).with("44").and_return(incoming_message)
- IncomingMessage.stub!(:get_attachment_by_url_part_number).and_return(attachment)
+ IncomingMessage.stub!(:get_attachment_by_url_part_number_and_filename).and_return(attachment)
InfoRequest.stub!(:find).with("132").and_return(info_request)
- params = { :file_name => [long_name],
+ params = { :file_name => long_name,
:controller => "request",
:action => "get_attachment_as_html",
:id => "132",
diff --git a/spec/controllers/services_controller_spec.rb b/spec/controllers/services_controller_spec.rb
index a9950d520..399f48acb 100644
--- a/spec/controllers/services_controller_spec.rb
+++ b/spec/controllers/services_controller_spec.rb
@@ -4,7 +4,7 @@ require 'fakeweb'
describe ServicesController, "when returning a message for people in other countries" do
- integrate_views
+ render_views
# store and restore the locale in the context of the test suite to isolate
# changes made in these tests
@@ -54,27 +54,27 @@ describe ServicesController, "when returning a message for people in other count
it "should return the 'another country' message if the service responds OK" do
config = MySociety::Config.load_default()
config['ISO_COUNTRY_CODE'] = "DE"
- Configuration.stub!(:gaze_url).and_return('http://denmark.com')
+ AlaveteliConfiguration.stub!(:gaze_url).and_return('http://denmark.com')
FakeWeb.register_uri(:get, %r|denmark.com|, :body => "DK")
get :other_country_message
response.should be_success
response.body.should == 'Hello! We have an <a href="/help/alaveteli?country_name=Deutschland">important message</a> for visitors outside Deutschland <span class="close-button">X</span>'
end
it "should default to no message if the country_from_ip domain doesn't exist" do
- Configuration.stub!(:gaze_url).and_return('http://12123sdf14qsd.com')
+ AlaveteliConfiguration.stub!(:gaze_url).and_return('http://12123sdf14qsd.com')
get :other_country_message
response.should be_success
response.body.should == ''
end
it "should default to no message if the country_from_ip service doesn't exist" do
- Configuration.stub!(:gaze_url).and_return('http://www.google.com')
+ AlaveteliConfiguration.stub!(:gaze_url).and_return('http://www.google.com')
get :other_country_message
response.should be_success
response.body.should == ''
end
it "should default to no message if the country_from_ip service returns an error" do
FakeWeb.register_uri(:get, %r|500.com|, :body => "Error", :status => ["500", "Error"])
- Configuration.stub!(:gaze_url).and_return('http://500.com')
+ AlaveteliConfiguration.stub!(:gaze_url).and_return('http://500.com')
get :other_country_message
response.should be_success
response.body.should == ''
diff --git a/spec/controllers/track_controller_spec.rb b/spec/controllers/track_controller_spec.rb
index 5505afe59..5a766b1e1 100644
--- a/spec/controllers/track_controller_spec.rb
+++ b/spec/controllers/track_controller_spec.rb
@@ -49,14 +49,14 @@ describe TrackController, "when making a new track on a request" do
it "should save a search track and redirect to the right place" do
session[:user_id] = @user.id
@track_thing.should_receive(:save!)
- get :track_search_query, :query_array => ["bob variety:sent"], :feed => 'track'
+ get :track_search_query, :query_array => "bob variety:sent", :feed => 'track'
response.should redirect_to(:controller => 'general', :action => 'search', :combined => ["bob", "requests"])
end
end
describe TrackController, "when sending alerts for a track" do
- integrate_views
+ render_views
before(:each) do
load_raw_emails_data
@@ -65,8 +65,7 @@ describe TrackController, "when sending alerts for a track" do
it "should send alerts" do
# Don't do clever locale-insertion-unto-URL stuff
- old_filters = ActionController::Routing::Routes.filters
- ActionController::Routing::Routes.filters = RoutingFilter::Chain.new
+ RoutingFilter.active = false
# set the time the comment event happened at to within the last week
ire = info_request_events(:silly_comment_event)
@@ -80,7 +79,7 @@ describe TrackController, "when sending alerts for a track" do
mail = deliveries[0]
mail.body.should =~ /Alter your subscription/
mail.to_addrs.first.to_s.should include(users(:silly_name_user).email)
- mail.body =~ /(http:\/\/.*\/c\/(.*))/
+ mail.body.to_s =~ /(http:\/\/.*\/c\/(.*))/
mail_url = $1
mail_token = $2
@@ -114,7 +113,7 @@ describe TrackController, "when sending alerts for a track" do
deliveries.size.should == 0
# Restore the routing filters
- ActionController::Routing::Routes.filters = old_filters
+ RoutingFilter.active = true
end
it "should send localised alerts" do
@@ -133,7 +132,7 @@ describe TrackController, "when sending alerts for a track" do
end
describe TrackController, "when viewing RSS feed for a track" do
- integrate_views
+ render_views
before(:each) do
load_raw_emails_data
@@ -145,6 +144,7 @@ describe TrackController, "when viewing RSS feed for a track" do
get :track_request, :feed => 'feed', :url_title => track_thing.info_request.url_title
response.should render_template('track/atom_feed')
+ response.content_type.should == 'application/atom+xml'
# XXX should check it is an atom.builder type being rendered, not sure how to
assigns[:xapian_object].matches_estimated.should == 3
@@ -163,7 +163,7 @@ end
describe TrackController, "when viewing JSON version of a track feed" do
- integrate_views
+ render_views
before(:each) do
load_raw_emails_data
@@ -205,7 +205,7 @@ end
describe TrackController, "when tracking a public body" do
- integrate_views
+ render_views
before(:each) do
load_raw_emails_data
diff --git a/spec/controllers/user_controller_spec.rb b/spec/controllers/user_controller_spec.rb
index 23006803b..1d8e3dcc3 100644
--- a/spec/controllers/user_controller_spec.rb
+++ b/spec/controllers/user_controller_spec.rb
@@ -5,7 +5,7 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
# http://rspec.rubyforge.org/rspec-rails/1.1.12/classes/Spec/Rails/Example/ControllerExampleGroup.html
describe UserController, "when showing a user" do
- integrate_views
+ render_views
before(:each) do
load_raw_emails_data
get_fixtures_xapian_index
@@ -64,7 +64,7 @@ describe UserController, "when showing a user" do
end
describe UserController, "when signing in" do
- integrate_views
+ render_views
def get_last_postredirect
post_redirects = PostRedirect.find_by_sql("select * from post_redirects order by id desc limit 1")
@@ -74,7 +74,7 @@ describe UserController, "when signing in" do
it "should show sign in / sign up page" do
get :signin
- response.should have_tag("input#signin_token")
+ response.should have_selector("input#signin_token")
end
it "should create post redirect to / when you just go to /signin" do
@@ -100,8 +100,7 @@ describe UserController, "when signing in" do
end
it "should log in when you give right email/password, and redirect to where you were" do
- old_filters = ActionController::Routing::Routes.filters
- ActionController::Routing::Routes.filters = RoutingFilter::Chain.new
+ RoutingFilter.active = false
get :signin, :r => "/list"
response.should render_template('sign')
@@ -112,14 +111,13 @@ describe UserController, "when signing in" do
session[:user_id].should == users(:bob_smith_user).id
# 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
+ ActionMailer::Base.deliveries.should be_empty
- ActionController::Routing::Routes.filters = old_filters
+ RoutingFilter.active = true
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
+ RoutingFilter.active = false
post_redirect = "something invalid"
lambda {
@@ -132,7 +130,7 @@ describe UserController, "when signing in" do
response.should render_template('sign')
assigns[:post_redirect].should == nil
- ActionController::Routing::Routes.filters = old_filters
+ RoutingFilter.active = true
end
# No idea how to test this in the test framework :(
@@ -152,12 +150,11 @@ describe UserController, "when signing in" do
:token => post_redirect.token
}
response.should render_template('confirm')
- response.should send_email
+ ActionMailer::Base.deliveries.should_not be_empty
end
it "should confirm your email, log you in and redirect you to where you were after you click an email link" do
- old_filters = ActionController::Routing::Routes.filters
- ActionController::Routing::Routes.filters = RoutingFilter::Chain.new
+ RoutingFilter.active = false
get :signin, :r => "/list"
post_redirect = get_last_postredirect
@@ -165,19 +162,19 @@ describe UserController, "when signing in" do
post :signin, { :user_signin => { :email => 'unconfirmed@localhost', :password => 'jonespassword' },
:token => post_redirect.token
}
- response.should send_email
+ ActionMailer::Base.deliveries.should_not be_empty
deliveries = ActionMailer::Base.deliveries
deliveries.size.should == 1
mail = deliveries[0]
- mail.body =~ /(http:\/\/.*(\/c\/(.*)))/
+ mail.body.to_s =~ /(http:\/\/.*(\/c\/(.*)))/
mail_url = $1
mail_path = $2
mail_token = $3
# check is right confirmation URL
mail_token.should == post_redirect.email_token
- params_from(:get, mail_path).should == { :controller => 'user', :action => 'confirm', :email_token => mail_token }
+ Rails.application.routes.recognize_path(mail_path).should == { :controller => 'user', :action => 'confirm', :email_token => mail_token }
# check confirmation URL works
session[:user_id].should be_nil
@@ -185,12 +182,11 @@ describe UserController, "when signing in" do
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
+ RoutingFilter.active = true
end
it "should keep you logged in if you click a confirmation link and are already logged in as an admin" do
- old_filters = ActionController::Routing::Routes.filters
- ActionController::Routing::Routes.filters = RoutingFilter::Chain.new
+ RoutingFilter.active = false
get :signin, :r => "/list"
post_redirect = get_last_postredirect
@@ -198,19 +194,19 @@ describe UserController, "when signing in" do
post :signin, { :user_signin => { :email => 'unconfirmed@localhost', :password => 'jonespassword' },
:token => post_redirect.token
}
- response.should send_email
+ ActionMailer::Base.deliveries.should_not be_empty
deliveries = ActionMailer::Base.deliveries
deliveries.size.should == 1
mail = deliveries[0]
- mail.body =~ /(http:\/\/.*(\/c\/(.*)))/
+ mail.body.to_s =~ /(http:\/\/.*(\/c\/(.*)))/
mail_url = $1
mail_path = $2
mail_token = $3
# check is right confirmation URL
mail_token.should == post_redirect.email_token
- params_from(:get, mail_path).should == { :controller => 'user', :action => 'confirm', :email_token => mail_token }
+ Rails.application.routes.recognize_path(mail_path).should == { :controller => 'user', :action => 'confirm', :email_token => mail_token }
# Log in as an admin
session[:user_id] = users(:admin_user).id
@@ -222,19 +218,19 @@ describe UserController, "when signing in" do
# And the redirect should still work, of course
response.should redirect_to(:controller => 'request', :action => 'list', :post_redirect => 1)
- ActionController::Routing::Routes.filters = old_filters
+ RoutingFilter.active = true
end
end
describe UserController, "when signing up" do
- integrate_views
+ render_views
it "should be an error if you type the password differently each time" do
post :signup, { :user_signup => { :email => 'new@localhost', :name => 'New Person',
:password => 'sillypassword', :password_confirmation => 'sillypasswordtwo' }
}
- assigns[:user_signup].errors[:password].should == 'Please enter the same password twice'
+ assigns[:user_signup].errors[:password].should == ['Please enter the same password twice']
end
it "should be an error to sign up with a misformatted email" do
@@ -285,7 +281,7 @@ describe UserController, "when signing up" do
end
describe UserController, "when signing out" do
- integrate_views
+ render_views
it "should log you out and redirect to the home page" do
session[:user_id] = users(:bob_smith_user).id
@@ -295,21 +291,20 @@ describe UserController, "when signing out" do
end
it "should log you out and redirect you to where you were" do
- old_filters = ActionController::Routing::Routes.filters
- ActionController::Routing::Routes.filters = RoutingFilter::Chain.new
+ RoutingFilter.active = false
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
+ RoutingFilter.active = true
end
end
describe UserController, "when sending another user a message" do
- integrate_views
+ render_views
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)
@@ -337,16 +332,16 @@ describe UserController, "when sending another user a message" do
deliveries = ActionMailer::Base.deliveries
deliveries.size.should == 1
mail = deliveries[0]
- mail.body.should include("Bob Smith has used #{Configuration::site_name} to send you the message below")
+ mail.body.should include("Bob Smith has used #{AlaveteliConfiguration::site_name} to send you the message below")
mail.body.should include("Just a test!")
#mail.to_addrs.first.to_s.should == users(:silly_name_user).name_and_email # XXX fix some nastiness with quoting name_and_email
- mail.from_addrs.first.to_s.should == users(:bob_smith_user).name_and_email
+ mail.from_addrs.first.to_s.should == users(:bob_smith_user).email
end
end
describe UserController, "when changing password" do
- integrate_views
+ render_views
it "should show the email form when not logged in" do
get :signchangepassword
@@ -386,7 +381,7 @@ describe UserController, "when changing password" do
post :signchangepassword, { :user => { :password => 'ooo', :password_confirmation => 'ooo' },
:submitted_signchangepassword_do => 1
}
- users(:bob_smith_user).hashed_password.should != old_hash
+ users(:bob_smith_user).reload.hashed_password.should_not == old_hash
response.should redirect_to(:controller => 'user', :action => 'show', :url_name => users(:bob_smith_user).url_name)
end
@@ -416,7 +411,7 @@ describe UserController, "when changing password" do
end
describe UserController, "when changing email address" do
- integrate_views
+ render_views
it "should require login" do
get :signchangeemail
@@ -500,10 +495,10 @@ describe UserController, "when changing email address" do
deliveries = ActionMailer::Base.deliveries
deliveries.size.should == 1
mail = deliveries[0]
- mail.body.should include("confirm that you want to change")
+ mail.body.should include("confirm that you want to \nchange")
mail.to.should == [ 'newbob@localhost' ]
- mail.body =~ /(http:\/\/.*(\/c\/(.*)))/
+ mail.body.to_s =~ /(http:\/\/.*(\/c\/(.*)))/
mail_url = $1
mail_path = $2
mail_token = $3
@@ -561,16 +556,13 @@ describe UserController, "when changing email address" do
end
describe UserController, "when using profile photos" do
- integrate_views
+ render_views
before do
@user = users(:bob_smith_user)
- @uploadedfile = File.open(file_fixture_name("parrot.png"))
- @uploadedfile.stub!(:original_filename).and_return('parrot.png')
-
- @uploadedfile_2 = File.open(file_fixture_name("parrot.jpg"))
- @uploadedfile_2.stub!(:original_filename).and_return('parrot.jpg')
+ @uploadedfile = fixture_file_upload("/files/parrot.png")
+ @uploadedfile_2 = fixture_file_upload("/files/parrot.jpg")
end
it "should not let you change profile photo if you're not logged in as the user" do
@@ -631,9 +623,10 @@ describe UserController, "when showing JSON version for API" do
end
describe UserController, "when viewing the wall" do
- integrate_views
+ render_views
before(:each) do
+ load_raw_emails_data
get_fixtures_xapian_index
end
diff --git a/spec/fixtures/files/blog_feed.atom b/spec/fixtures/files/blog_feed.atom
new file mode 100644
index 000000000..f49693938
--- /dev/null
+++ b/spec/fixtures/files/blog_feed.atom
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<rss version="2.0"
+ xmlns:content="http://purl.org/rss/1.0/modules/content/"
+ xmlns:wfw="http://wellformedweb.org/CommentAPI/"
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:atom="http://www.w3.org/2005/Atom"
+ xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
+ xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
+ >
+
+<channel>
+ <title>A Blog Feed</title>
+ <atom:link href="http://example.com/feed/" rel="self" type="application/rss+xml" />
+ <link>http://www.example.com</link>
+ <description>Stuff</description>
+ <lastBuildDate>Tue, 30 Apr 2013 14:34:15 +0000</lastBuildDate>
+ <language>en</language>
+ <sy:updatePeriod>hourly</sy:updatePeriod>
+ <sy:updateFrequency>1</sy:updateFrequency>
+ <generator>http://wordpress.org/?v=3.3.2</generator>
+ <item>
+ <title>Example Post</title>
+ <link>http://www.example.com/example-post</link>
+ <comments>http://www.example.com/example-post#comments</comments>
+ <pubDate>Mon, 01 Apr 2013 19:26:08 +0000</pubDate>
+ <dc:creator>Example Blogger</dc:creator>
+ <category><![CDATA[FOI]]></category>
+
+ <guid isPermaLink="false">http://www.example.com/?id=333</guid>
+ <description><![CDATA[An example post [...]]]></description>
+ <content:encoded><![CDATA[<h3>A blog post</h3>
+<p>Example post</p>
+]]></content:encoded>
+ <wfw:commentRss>http://www.example.com/feed/</wfw:commentRss>
+ <slash:comments>2</slash:comments>
+ </item>
+
+ </channel>
+</rss>
diff --git a/spec/fixtures/files/incoming-request-two-same-name.email b/spec/fixtures/files/incoming-request-two-same-name.email
index f1024d607..ecd322fe4 100644
--- a/spec/fixtures/files/incoming-request-two-same-name.email
+++ b/spec/fixtures/files/incoming-request-two-same-name.email
@@ -13,13 +13,13 @@ Content-Disposition: inline
--Q68bSM7Ycu6FN28Q
Content-Type: text/plain; charset=us-ascii
-Content-Disposition: attachment; filename="hello.txt"
+Content-Disposition: attachment; filename="hello-world.txt"
Second hello
--Q68bSM7Ycu6FN28Q
Content-Type: text/plain; charset=us-ascii
-Content-Disposition: attachment; filename="hello.txt"
+Content-Disposition: attachment; filename="hello-world.txt"
First hello
diff --git a/spec/fixtures/files/inline-uuencode.email b/spec/fixtures/files/inline-uuencode.email
new file mode 100644
index 000000000..3134ba3ad
--- /dev/null
+++ b/spec/fixtures/files/inline-uuencode.email
@@ -0,0 +1,27 @@
+From foo@bar Mon Jun 01 17:14:44 2009
+Return-path: <foo@bar>
+Envelope-to: foi@quux
+Delivery-date: Mon, 01 Jun 2009 17:14:44 +0100
+From: <foo@bar>
+To: <request-whatever@quux>
+Subject: something or other
+Date: Mon, 1 Jun 2009 17:14:37 +0100
+X-MimeOLE: Produced By Microsoft MimeOLE V6.00.3790.181
+Message-ID: <baz@xyzzy>
+
+Thanks for your email - here's a truncated attachment
+for you:
+
+**********************************************************************
+
+begin 666 ResponseT7363 9.doc
+MT,\1X*&Q&N$`````````````````````/@`#`/[_"0`&```````````````"
+M````) ``````````$ ``+@````$```#^____`````",```!L````________
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+#````
+`
+end
+
+The original of this email was scanned for viruses or something
+like that.
diff --git a/spec/fixtures/files/malformed-to-and-cc.email b/spec/fixtures/files/malformed-to-and-cc.email
new file mode 100644
index 000000000..4fbb6e21e
--- /dev/null
+++ b/spec/fixtures/files/malformed-to-and-cc.email
@@ -0,0 +1,11 @@
+From foo@bar Wed Mar 12 14:58:26 2008
+Return-path: <foo@bar>
+Subject: example email
+To: <bar@example.org
+Cc: baz@example.org>
+From: quux@example.org
+Date: Mon, 7 May 2012 12:47:06 +0100
+Mime-Version: 1.0
+Content-Type: text/plain; charset=utf-8
+
+A very basic email, but with malformed To: and Cc: lines
diff --git a/spec/fixtures/files/mislabelled-as-iso-8859-1.email b/spec/fixtures/files/mislabelled-as-iso-8859-1.email
new file mode 100644
index 000000000..6c8e6109e
--- /dev/null
+++ b/spec/fixtures/files/mislabelled-as-iso-8859-1.email
@@ -0,0 +1,20 @@
+From foo@bar Thu Mar 01 15:02:33 2012
+Return-path: <foo@bar>
+Envelope-to: foi@quux
+Delivery-date: Thu, 01 Mar 2012 15:02:33 +0000
+Date: Thu, 01 Mar 2012 15:01:58 +0000
+Subject: some FOI request
+To: foi@quux
+From: foo@bar
+MIME-Version: 1.0
+Content-Type: text/plain; charset="iso-8859-1"
+Content-Transfer-Encoding: 7bit
+Message-Id: <2468@bar.local>
+
+Dear Whoever,
+
+THERE'S A DASH NEXT REQUEST FOR INFORMATION
+
+Best regards,
+Other Person
+
diff --git a/spec/fixtures/files/multipart-no-final-boundary.email b/spec/fixtures/files/multipart-no-final-boundary.email
new file mode 100644
index 000000000..9c16dad52
--- /dev/null
+++ b/spec/fixtures/files/multipart-no-final-boundary.email
@@ -0,0 +1,21 @@
+From foo@bar Thu Sep 13 10:34:44 2012
+Return-path: <foo@bar>
+Envelope-to: foi@example.org
+Delivery-date: Thu, 13 Sep 2012 10:34:44 +0100
+From: foo@bar
+To: foi@example.org
+Subject: an acknowledgement email
+Date: Thu, 13 Sep 2012 10:08:03 +0100
+Message-ID: <987654@foo.local>
+Content-Type: multipart/mixed; boundary="-----7D81B75CCC90D2974F7A1CBD"
+
+This is a multi-part message in MIME format.
+-------7D81B75CCC90D2974F7A1CBD
+Content-Type: text/html
+
+<div>
+ <p>
+ This is an acknowledgement of your email, that irritatingly
+ leaves out the final MIME boundary.
+ </p>
+<div>
diff --git a/spec/fixtures/files/nested-attachments-premature-end.email b/spec/fixtures/files/nested-attachments-premature-end.email
new file mode 100644
index 000000000..6b13808dc
--- /dev/null
+++ b/spec/fixtures/files/nested-attachments-premature-end.email
@@ -0,0 +1,110 @@
+From someone@example.org Mon May 15 13:10:29 2012
+Return-path: <someone@example.org>
+Envelope-to: foi@example.org
+Delivery-date: Mon, 15 May 2012 13:10:29 +0100
+Message-Id: <abcde@baz.local>
+Date: Mon, 15 May 2012 09:48:48 +0100
+From: "Example Person" <someone@example.org>
+To: <request@example.org>
+Subject: some FOI request or other
+Mime-Version: 1.0
+Content-Type: multipart/mixed; boundary="=__outer__="
+
+This is a MIME message. If you are reading this text, you may want to
+consider changing to a mail reader or gateway that understands how to
+properly handle MIME multipart messages.
+
+--=__outer__=
+Content-Type: multipart/alternative; boundary="=__inner__="
+
+--=__inner__=
+Content-Type: text/plain; charset="utf-8"
+Content-Transfer-Encoding: quoted-printable
+X-MIME-Autoconverted: from 8bit to quoted-printable by something
+
+Hello
+=20
+Please find some information attached.
+=20
+
+--=__inner__=
+Content-Description: HTML
+Content-Type: text/html; charset="utf-8"
+Content-Transfer-Encoding: quoted-printable
+
+<html>
+ <head>
+ <title>some title text</title>
+ </head>
+ <body>
+ <p>blah blah blah</p>
+ </body>
+</html>
+
+--=__inner__=--
+
+--=__outer__=
+Content-Type: message/rfc822
+
+Return-path: <foo@bar>
+Date: Mon, 7 May 2012 12:47:06 +0100
+From: someone-else@example.org
+To: foi@example.org
+Message-Id: <56789@quux.local>
+Subject: a freedom of information requests
+Mime-Version: 1.0
+Content-Type: text/plain; charset=utf-8
+
+ Dear Whoever,
+
+ Please could you let me know, um, whatever ...
+
+ Yours faithfully,
+
+ Whoever I Am
+
+--=__outer__=
+Content-Type: text/plain; charset=US-ASCII
+Content-Disposition: inline
+Content-Transfer-Encoding: quoted-printable
+
+ Dear Whowever,
+ =20
+ Please could you let me know, um, whatever ...
+ =20
+ Yours faithfully,
+ =20
+ Whoever I Am
+ =20
+
+--=__outer__=--
+
+--=__outer__=
+Content-Type: application/png; name="maroon-square.png"
+Content-Transfer-Encoding: base64
+Content-Disposition: attachment; filename="maroon-square.png"
+
+iVBORw0KGgoAAAANSUhEUgAAAEEAAABCCAYAAAAIY7vrAAAABmJLR0QA/wD/AP+g
+vaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3QQeDSEx8qultwAAABl0
+RVh0Q29tbWVudABDcmVhdGVkIHdpdGggR0lNUFeBDhcAAAMzSURBVHja7VtL2psw
+DNS4rPv1Gj1Kt71Az9ZT9F7dN9MFGGThB/YfKDX2Kp8DRBpLowcKvn/5ShERiAgl
+srh8aT93tJzWdae8XR0CEICwUx59K54H4QFKp0Eg5alrAwEYIDx5DRAGCAOEAcIA
+QaUFfDoIHJawpEbOPd0dRPjJDWIUiEwt933+8es2Ovz++a3dCkREXmwD4ZbsVln6
+cLkef14duAMqAGCkY0A+jBNgXGFZU/eKa3fhZjlQqLhHKF9oFbpulE2Z/oFrXTd+
+nlOWkn1dMHXrAiWguq0iG9uk/REjBggPtgQOED781my4wwBhgDBAmPmUAwR0X0UO
+dxggnA8CO5xocU8HoAoEDwA6nOyCH+ZMKQ4zy+QbNBoUirquMPBJcgPyJkOi+c7S
+ohhn6ZctzDIrcFalIspYILG1et9WABUtt6WztLq+/0Amp9sCnsCBUhfvK4FLiRCA
+QwC7JABGTngrIIPnIjf6R5We0uxz3j+FbCvdy2nlY/IgcfrMRQuFHIC9Sap3AW8n
+2gZ+cZYCVn4LzBxxnykNgJpWN8lt7yw+QCMxan2s8lQXcNlDlpAW7YmIXMszTgoH
+rU91+8OFYXN9ikz/LyLgExSCDlaO+cdGsIEQkyUAIgFMKRTEn3vDjFFHwWSIzEQC
+cmN4IHVNGG2PQXhhsuRl3jihwQyB6H1274gV1BhKLKNt4ZEpkygeeoC+xytdK1cr
+oX0EACphnTZXbbLMmL/YBGo9lSU1OmBONMnTlQUqTa4y1VgAddg0hdTR04lyT0Xq
+8RYAyHVyBX6ET/9wTBD6TWVCMH5Qo3yhXju3bNY/BBMdsoLYBMmnzQdOP56O36s5
+40r1D7UWYV5dNT2nbxVBAHb43Y36CdbXfTii6isU/U7ZXLQ4w/V/wotFoilVF2kl
+w7YCDrIPkj4/G9fao7q0rYSSJdgeSqmQrCU+r/j8rOv/gpuKPm5Lffen5eN+ljeo
+rcfW0Om2Enm9KwDZAgrG98txX9cMe6X2E5SGU29VTE17lFAUkMybsXclndu31BGX
+hcgWv8oxonYtkf/jhc10WPGgm2IZncKlu+sg8vLm7hDSwk3f2/wFEzN3v6aAXQ0A
+AAAASUVORK5CYII=
+
+--=__outer__=--
+
diff --git a/spec/fixtures/files/no-part-charset-random-data.email b/spec/fixtures/files/no-part-charset-random-data.email
new file mode 100644
index 000000000..d51fd3f38
--- /dev/null
+++ b/spec/fixtures/files/no-part-charset-random-data.email
@@ -0,0 +1,30 @@
+From xxxx@yahoo.cn Mon Oct 08 14:01:34 2012
+Return-path: <xxxx@yahoo.cn>
+Envelope-to: foi@atlas.ukcod.org.uk
+Delivery-date: Mon, 08 Oct 2012 14:01:34 +0100
+Received: (qmail 63864 invoked from network); 8 Oct 2012 13:01:12 -0000
+DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.cn; s=s1024; t=1349701272; bh=T/mtlIYvhB/L5RO+CvTazeAdGf1n1zsGXBoA8EKGT9M=; h=Message-ID:X-Yahoo-Newman-Property:X-YMail-OSG:X-Yahoo-SMTP:Received:X-mailer:From:Subject:To:Content-Transfer-Encoding:Content-Type:Date; b=LYI/PXvA7DA746bmyprChUg7N8YDvN9XE/bhfTt5MW7siOmxHHzn1w+s5X33PvLI0x0UfJLo+MCkTnGPKnG5BYY38US8PkocJYyphrvF/eaUl3ALf8UvxHBOJX1iIi89Xp2NnfbS8lz9kZAWifb9GOnOA5/kLDcL5/WJXliit2k=
+Message-ID: <xxxx@xxxx.yahoo.com>
+X-Yahoo-Newman-Property: ymail-5
+X-YMail-OSG: nPs5jgsVM1myUoKjeEPTxxalz4BM6BZMEUYu.E8NPMPQyo_
+ Yej8T2WCTurn767NOwhuDIqNxC2QGZINqfjmKcdyW7a1P_Zxqr9GsjgxODci
+ ihwr7qYAGDDbcsrB.PX4epnJZHl3yAwoGW.1ReEZnXQANFcNep7.zNEbZ_2k
+ RU1IhI9aHYvxPxt5RWugwOoFRh9P8Ym35A88IMazNtVaBiBEXF6Vk8Aqr9XP
+ 3Vh9xOT9Pn6X8qOUjNXkdb3xB4S5AAIRSE9mqhL1KzHBwdVQs25IoM_2FV2b
+ gPsQGgL4_mwBH0WcEMhdj7Kn6Nfb44L.50E_V3DH.8P7KzDK8zNVXSbAqohX
+ Qi6MzUK2frr8IyZyYzHb.ekff7kAcJgUoHvhnyPar8tRYxhQT3_xsUTzsx8N
+ oWckVPh_i3OT7U4ObgekqgtteMoYqPH2eF1SZXamGBAs-
+X-Yahoo-SMTP: YUQHwRWswBDjbw_M.D6EP4KpT9khlJErDRBQi4ySZQ--
+X-mailer: MIME::Lite 3.027 (F2.74; T1.31; A2.07; B3.13; Q3.13)
+From: =?GB2312?B?zsJKaWFu?= Bing <xxxx@yahoo.cn>
+Subject: =?GB2312?B?yM7A1svJ?=
+To: FOI Person <EMAIL_TO>
+Content-Transfer-Encoding: base64
+Content-Type: text/plain
+Date: Tue, 9 Oct 2012 20:53:06 +0800
+
+HPBSqsndNBX+ER4hyBoPhhnclcWKVFgbevdD5cJvfI/ARbxRYqA28hZ49Pf6A/ks
+NdVh4N5VPgRs/7SHYPfw5625pZJYTLj6nVdYk76sxnjiiAmwCJWGjPoWvO7nHUBv
+fuLXtNVq5HmD0bWWjAbSk2n74PW7v5izbNO2fjHyiyX2CIof0rriXDmOldJqoebO
+ejybrjG+Tahpu3FF1Mw98HfswzkdB46u/izLCzdUQVM=
+
diff --git a/spec/fixtures/files/part-without-charset-in-content-type.email b/spec/fixtures/files/part-without-charset-in-content-type.email
new file mode 100644
index 000000000..439d52cc3
--- /dev/null
+++ b/spec/fixtures/files/part-without-charset-in-content-type.email
@@ -0,0 +1,38 @@
+From example@example.com Wed Sep 15 17:55:40 2010
+Return-path: <example@example.com>
+Envelope-to: example@example.com
+Delivery-date: Wed, 15 Sep 2010 17:55:40 +0100
+From: <example@example.com>
+To: <request-xxxxx@whatdotheyknow.com>
+Date: Wed, 15 Sep 2010 17:56:03 +0100
+Subject: FOI Internal Review response
+Thread-Topic: FOI Internal Review response
+Thread-Index: xxxxx
+Message-ID: <xxxxxx>
+Accept-Language: en-US, en-GB
+Content-Language: en-US
+X-MS-Has-Attach: yes
+X-MS-TNEF-Correlator:
+acceptlanguage: en-US, en-GB
+Content-Type: multipart/mixed;
+ boundary="_002_E6527350F565F54A88C36C23F6C2B86702618AD0DF95SDCCPMSXMB5_"
+MIME-Version: 1.0
+
+--_002_E6527350F565F54A88C36C23F6C2B86702618AD0DF95SDCCPMSXMB5_
+Content-Type: text/plain; charset="utf-8"
+Content-Transfer-Encoding: base64
+
+someencodedtext=
+
+--_002_E6527350F565F54A88C36C23F6C2B86702618AD0DF95SDCCPMSXMB5_
+Content-Type: document/pdf; name="document.pdf"
+Content-Description: document.pdf
+Content-Disposition: attachment; filename="document.pdf";
+ size=62103; creation-date="Wed, 15 Sep 2010 17:54:27 GMT";
+ modification-date="Wed, 15 Sep 2010 17:54:27 GMT"
+Content-Transfer-Encoding: base64
+
+somemoreencodedtext=
+
+--_002_E6527350F565F54A88C36C23F6C2B86702618AD0DF95SDCCPMSXMB5_--
+
diff --git a/spec/fixtures/files/subject-bad-utf-8-trailing-base64.email b/spec/fixtures/files/subject-bad-utf-8-trailing-base64.email
new file mode 100644
index 000000000..dad621877
--- /dev/null
+++ b/spec/fixtures/files/subject-bad-utf-8-trailing-base64.email
@@ -0,0 +1,5 @@
+From: foo@bar
+To: baz@quux
+Subject: =?UTF-8?B?aGVsbG/w?=
+
+Hello, this is the text of the email.
diff --git a/spec/fixtures/files/subject-bad-utf-8-trailing-quoted-printable.email b/spec/fixtures/files/subject-bad-utf-8-trailing-quoted-printable.email
new file mode 100644
index 000000000..b80deb4e8
--- /dev/null
+++ b/spec/fixtures/files/subject-bad-utf-8-trailing-quoted-printable.email
@@ -0,0 +1,5 @@
+From: foo@bar
+To: baz@quux
+Subject: =?UTF-8?Q?hello=F0=?=
+
+Hello, this is the text of the email.
diff --git a/spec/fixtures/files/tnef-attachment-empty.email b/spec/fixtures/files/tnef-attachment-empty.email
new file mode 100644
index 000000000..7967aa95b
--- /dev/null
+++ b/spec/fixtures/files/tnef-attachment-empty.email
@@ -0,0 +1,196 @@
+From hello@blah.local Fri Feb 21 16:23:14 2013
+Return-path: <bar@example.org>
+Envelope-to: foo@example.org
+Delivery-date: Fri, 21 Feb 2013 16:23:14 +0000
+Content-Type: multipart/mixed;
+ boundary="_000_553468B23EE29B4F8836CBD0E1B2A15A275C3AA855POLNIEXMBV2po_"
+From: <bar@example.org>
+To: <foo@example.org>
+Sender: <hello@blah.local>
+Date: Fri, 21 Feb 2013 16:23:04 +0000
+Subject: here's a useless email
+Message-ID: <12345@blah.local>
+Accept-Language: en-US, en-GB
+Content-Language: en-US
+X-MS-Has-Attach:
+X-MS-TNEF-Correlator: <12345@blah.local>
+acceptlanguage: en-US, en-GB
+MIME-Version: 1.0
+
+--_000_553468B23EE29B4F8836CBD0E1B2A15A275C3AA855POLNIEXMBV2po_
+Content-Type: text/plain; charset="us-ascii"
+Content-Transfer-Encoding: quoted-printable
+
+This attachment just has a body from one of the tests
+in the tnef package in Debian.
+
+--_000_553468B23EE29B4F8836CBD0E1B2A15A275C3AA855POLNIEXMBV2po_
+Content-Disposition: attachment; filename="winmail.dat"
+Content-Transfer-Encoding: base64
+Content-Type: application/ms-tnef; name="winmail.dat"
+
+eJ8+IiURAQaQCAAEAAAAAAABAAEAAQeQBgAIAAAA5AQAAAAAAADoAAENgAQAAgAA
+AAIAAgABBYADAA4AAADVBwQAGQAKAA8AIwABADYBASCAAwAOAAAA1QcEABkACgAP
+ACQAAQA3AQEJgAEAIQAAADBEREEwRkNCQ0MwN0MxNDE5MkVFODZGQzQyRDE1Qjk1
+AGYHAQSQBgBkAgAAAQAAAA8AAAAfAAEwAQAAABAAAAAzAGsAdQBzAGUAcgAyAAAA
+HwACMAEAAAAGAAAARQBYAAAAAAAfAAMwAQAAAI4AAAAvAE8APQBCAFIALQBFAFgA
+QwBIAC0AVABFAFMAVAAvAE8AVQA9AEYASQBSAFMAVAAgAEEARABNAEkATgBJAFMA
+VABSAEEAVABJAFYARQAgAEcAUgBPAFUAUAAvAEMATgA9AFIARQBDAEkAUABJAEUA
+TgBUAFMALwBDAE4APQAzAGsAdQBzAGUAcgAyAAAAAAADAAAwAAAAAAMA/18AAAAA
+AwAVDAEAAAACAQswAQAAAEoAAABFWDovTz1CUi1FWENILVRFU1QvT1U9RklSU1Qg
+QURNSU5JU1RSQVRJVkUgR1JPVVAvQ049UkVDSVBJRU5UUy9DTj0zS1VTRVIyAAAA
+HwAgOgEAAAAQAAAAMwBrAHUAcwBlAHIAMgAAAAMA/V8BAAAACwBAOgAA+T8CAfdf
+AQAAAGMAAAAAAAAA3KdAyMBCEBq0uQgAKy/hggEAAAAAAAAAL289QlItRVhDSC1U
+RVNUL291PUZpcnN0IEFkbWluaXN0cmF0aXZlIEdyb3VwL2NuPVJlY2lwaWVudHMv
+Y249M2t1c2VyMgAAAwAAOQAAAAAfAP45AQAAAEoAAAAzAGsAdQBzAGUAcgAyAEAA
+YgByAGUAeABjAGgAYQBuAGcAZQAuAGQAbwBsAHAAaABpAG4AcwBlAGEAcgBjAGgA
+LgBjAG8AbQAAAAAAAwBxOgAAAAAfAPZfAQAAABAAAAAzAGsAdQBzAGUAcgAyAAAA
+m2sBA5AGAEwbAAAzAAAACwACAAEAAAAfABoAAQAAABIAAABJAFAATQAuAE4AbwB0
+AGUAAAAAAAMAJgAAAAAAAwA2AAAAAAAfADcAAQAAAB4AAABCAGkAbABsACAAbwBm
+ACAAUgBpAGcAaAB0AHMAAAAAAEAAOQBgQvtkuknFAR8APQABAAAAAgAAAAAAAAAC
+AUcAAQAAADgAAABjPXVzO2E9IDtwPUJSLUVYQ0gtVEVTVDtsPUJSLUVYQ0gtREVW
+MS0wNTA0MjUxNzE1MzZaLTE0AB8AcAABAAAAHgAAAEIAaQBsAGwAIABvAGYAIABS
+AGkAZwBoAHQAcwAAAAAAAgFxAAEAAAAWAAAAAcVJumT7yarjal9+TnmqsNvwaipi
+/QAAHwAaDAEAAAAQAAAAMwBrAHIAZQBsAGEAeQAAAB8AHQ4BAAAAHgAAAEIAaQBs
+AGwAIABvAGYAIABSAGkAZwBoAHQAcwAAAAAAAgETEAEAAADuFAAAPCFET0NUWVBF
+IEhUTUwgUFVCTElDICItLy9XM0MvL0RURCBIVE1MIDQuMCBUcmFuc2l0aW9uYWwv
+L0VOIj4NCjxIVE1MPjxIRUFEPg0KPE1FVEEgaHR0cC1lcXVpdj1Db250ZW50LVR5
+cGUgY29udGVudD0idGV4dC9odG1sOyBjaGFyc2V0PXVzLWFzY2lpIj4NCjxNRVRB
+IGNvbnRlbnQ9Ik1TSFRNTCA2LjAwLjM3OTAuMTgzMCIgbmFtZT1HRU5FUkFUT1I+
+PC9IRUFEPg0KPEJPRFk+DQo8RElWPg0KPERJVj48Rk9OVCBmYWNlPUFyaWFsIHNp
+emU9Mj5USEUgQklMTCBPRiBSSUdIVFM8QlI+QW1lbmRtZW50cyAxLTEwIG9mIHRo
+ZSANCkNvbnN0aXR1dGlvbjwvRk9OVD48L0RJVj4NCjxESVY+Jm5ic3A7PC9ESVY+
+DQo8RElWPjxGT05UIGZhY2U9QXJpYWwgc2l6ZT0yPlRoZSBDb252ZW50aW9ucyBv
+ZiBhIG51bWJlciBvZiB0aGUgU3RhdGVzIGhhdmluZywgDQphdCB0aGUgdGltZSBv
+ZiBhZG9wdGluZyB0aGUgQ29uc3RpdHV0aW9uLCBleHByZXNzZWQgYSBkZXNpcmUs
+IGluIG9yZGVyIHRvIA0KcHJldmVudCBtaXNjb25zdHJ1Y3Rpb24gb3IgYWJ1c2Ug
+b2YgaXRzIHBvd2VycywgdGhhdCBmdXJ0aGVyIGRlY2xhcmF0b3J5IGFuZCANCnJl
+c3RyaWN0aXZlIGNsYXVzZXMgc2hvdWxkIGJlIGFkZGVkLCBhbmQgYXMgZXh0ZW5k
+aW5nIHRoZSBncm91bmQgb2YgcHVibGljIA0KY29uZmlkZW5jZSBpbiB0aGUgR292
+ZXJubWVudCB3aWxsIGJlc3QgaW5zdXJlIHRoZSBiZW5lZmljZW50IGVuZHMgb2Yg
+aXRzIA0KaW5zdGl0dXRpb247IDxCUj5SZXNvbHZlZCwgYnkgdGhlIFNlbmF0ZSBh
+bmQgSG91c2Ugb2YgUmVwcmVzZW50YXRpdmVzIG9mIHRoZSANClVuaXRlZCBTdGF0
+ZXMgb2YgQW1lcmljYSwgaW4gQ29uZ3Jlc3MgYXNzZW1ibGVkLCB0d28tdGhpcmRz
+IG9mIGJvdGggSG91c2VzIA0KY29uY3VycmluZywgdGhhdCB0aGUgZm9sbG93aW5n
+IGFydGljbGVzIGJlIHByb3Bvc2VkIHRvIHRoZSBMZWdpc2xhdHVyZXMgb2YgdGhl
+IA0Kc2V2ZXJhbCBTdGF0ZXMsIGFzIGFtZW5kbWVudHMgdG8gdGhlIENvbnN0aXR1
+dGlvbiBvZiB0aGUgVW5pdGVkIFN0YXRlczsgYWxsIG9yIA0KYW55IG9mIHdoaWNo
+IGFydGljbGVzLCB3aGVuIHJhdGlmaWVkIGJ5IHRocmVlLWZvdXJ0aHMgb2YgdGhl
+IHNhaWQgTGVnaXNsYXR1cmVzLCANCnRvIGJlIHZhbGlkIHRvIGFsbCBpbnRlbnRz
+IGFuZCBwdXJwb3NlcyBhcyBwYXJ0IG9mIHRoZSBzYWlkIENvbnN0aXR1dGlvbiwg
+DQpuYW1lbHk6IDwvRk9OVD48L0RJVj4NCjxESVY+Jm5ic3A7PC9ESVY+DQo8RElW
+PjxGT05UIGZhY2U9QXJpYWwgc2l6ZT0yPkFtZW5kbWVudCBJPC9GT05UPjwvRElW
+Pg0KPERJVj4mbmJzcDs8L0RJVj4NCjxESVY+PEZPTlQgZmFjZT1BcmlhbCBzaXpl
+PTI+Q29uZ3Jlc3Mgc2hhbGwgbWFrZSBubyBsYXcgcmVzcGVjdGluZyBhbiANCmVz
+dGFibGlzaG1lbnQgb2YgcmVsaWdpb24sIG9yIHByb2hpYml0aW5nIHRoZSBmcmVl
+IGV4ZXJjaXNlIHRoZXJlb2Y7IG9yIA0KYWJyaWRnaW5nIHRoZSBmcmVlZG9tIG9m
+IHNwZWVjaCwgb3Igb2YgdGhlIHByZXNzOyBvciB0aGUgcmlnaHQgb2YgdGhlIHBl
+b3BsZSANCnBlYWNlYWJseSB0byBhc3NlbWJsZSwgYW5kIHRvIHBldGl0aW9uIHRo
+ZSBnb3Zlcm5tZW50IGZvciBhIHJlZHJlc3Mgb2YgDQpncmlldmFuY2VzLiA8L0ZP
+TlQ+PC9ESVY+DQo8RElWPiZuYnNwOzwvRElWPg0KPERJVj48Rk9OVCBmYWNlPUFy
+aWFsIHNpemU9Mj5BbWVuZG1lbnQgSUk8L0ZPTlQ+PC9ESVY+DQo8RElWPiZuYnNw
+OzwvRElWPg0KPERJVj48Rk9OVCBmYWNlPUFyaWFsIHNpemU9Mj5BIHdlbGwgcmVn
+dWxhdGVkIG1pbGl0aWEsIGJlaW5nIG5lY2Vzc2FyeSB0byB0aGUgDQpzZWN1cml0
+eSBvZiBhIGZyZWUgc3RhdGUsIHRoZSByaWdodCBvZiB0aGUgcGVvcGxlIHRvIGtl
+ZXAgYW5kIGJlYXIgYXJtcywgc2hhbGwgDQpub3QgYmUgaW5mcmluZ2VkLiA8L0ZP
+TlQ+PC9ESVY+DQo8RElWPiZuYnNwOzwvRElWPg0KPERJVj48Rk9OVCBmYWNlPUFy
+aWFsIHNpemU9Mj5BbWVuZG1lbnQgSUlJPC9GT05UPjwvRElWPg0KPERJVj4mbmJz
+cDs8L0RJVj4NCjxESVY+PEZPTlQgZmFjZT1BcmlhbCBzaXplPTI+Tm8gc29sZGll
+ciBzaGFsbCwgaW4gdGltZSBvZiBwZWFjZSBiZSBxdWFydGVyZWQgaW4gDQphbnkg
+aG91c2UsIHdpdGhvdXQgdGhlIGNvbnNlbnQgb2YgdGhlIG93bmVyLCBub3IgaW4g
+dGltZSBvZiB3YXIsIGJ1dCBpbiBhIG1hbm5lciANCnRvIGJlIHByZXNjcmliZWQg
+YnkgbGF3LiA8L0ZPTlQ+PC9ESVY+DQo8RElWPiZuYnNwOzwvRElWPg0KPERJVj48
+Rk9OVCBmYWNlPUFyaWFsIHNpemU9Mj5BbWVuZG1lbnQgSVY8L0ZPTlQ+PC9ESVY+
+DQo8RElWPiZuYnNwOzwvRElWPg0KPERJVj48Rk9OVCBmYWNlPUFyaWFsIHNpemU9
+Mj5UaGUgcmlnaHQgb2YgdGhlIHBlb3BsZSB0byBiZSBzZWN1cmUgaW4gdGhlaXIg
+DQpwZXJzb25zLCBob3VzZXMsIHBhcGVycywgYW5kIGVmZmVjdHMsIGFnYWluc3Qg
+dW5yZWFzb25hYmxlIHNlYXJjaGVzIGFuZCANCnNlaXp1cmVzLCBzaGFsbCBub3Qg
+YmUgdmlvbGF0ZWQsIGFuZCBubyB3YXJyYW50cyBzaGFsbCBpc3N1ZSwgYnV0IHVw
+b24gcHJvYmFibGUgDQpjYXVzZSwgc3VwcG9ydGVkIGJ5IG9hdGggb3IgYWZmaXJt
+YXRpb24sIGFuZCBwYXJ0aWN1bGFybHkgZGVzY3JpYmluZyB0aGUgcGxhY2UgDQp0
+byBiZSBzZWFyY2hlZCwgYW5kIHRoZSBwZXJzb25zIG9yIHRoaW5ncyB0byBiZSBz
+ZWl6ZWQuIDwvRk9OVD48L0RJVj4NCjxESVY+Jm5ic3A7PC9ESVY+DQo8RElWPjxG
+T05UIGZhY2U9QXJpYWwgc2l6ZT0yPkFtZW5kbWVudCBWPC9GT05UPjwvRElWPg0K
+PERJVj4mbmJzcDs8L0RJVj4NCjxESVY+PEZPTlQgZmFjZT1BcmlhbCBzaXplPTI+
+Tm8gcGVyc29uIHNoYWxsIGJlIGhlbGQgdG8gYW5zd2VyIGZvciBhIGNhcGl0YWws
+IG9yIA0Kb3RoZXJ3aXNlIGluZmFtb3VzIGNyaW1lLCB1bmxlc3Mgb24gYSBwcmVz
+ZW50bWVudCBvciBpbmRpY3RtZW50IG9mIGEgZ3JhbmQganVyeSwgDQpleGNlcHQg
+aW4gY2FzZXMgYXJpc2luZyBpbiB0aGUgbGFuZCBvciBuYXZhbCBmb3JjZXMsIG9y
+IGluIHRoZSBtaWxpdGlhLCB3aGVuIGluIA0KYWN0dWFsIHNlcnZpY2UgaW4gdGlt
+ZSBvZiB3YXIgb3IgcHVibGljIGRhbmdlcjsgbm9yIHNoYWxsIGFueSBwZXJzb24g
+YmUgc3ViamVjdCANCmZvciB0aGUgc2FtZSBvZmZlbnNlIHRvIGJlIHR3aWNlIHB1
+dCBpbiBqZW9wYXJkeSBvZiBsaWZlIG9yIGxpbWI7IG5vciBzaGFsbCBiZSANCmNv
+bXBlbGxlZCBpbiBhbnkgY3JpbWluYWwgY2FzZSB0byBiZSBhIHdpdG5lc3MgYWdh
+aW5zdCBoaW1zZWxmLCBub3IgYmUgZGVwcml2ZWQgDQpvZiBsaWZlLCBsaWJlcnR5
+LCBvciBwcm9wZXJ0eSwgd2l0aG91dCBkdWUgcHJvY2VzcyBvZiBsYXc7IG5vciBz
+aGFsbCBwcml2YXRlIA0KcHJvcGVydHkgYmUgdGFrZW4gZm9yIHB1YmxpYyB1c2Us
+IHdpdGhvdXQganVzdCBjb21wZW5zYXRpb24uIDwvRk9OVD48L0RJVj4NCjxESVY+
+Jm5ic3A7PC9ESVY+DQo8RElWPjxGT05UIGZhY2U9QXJpYWwgc2l6ZT0yPkFtZW5k
+bWVudCBWSTwvRk9OVD48L0RJVj4NCjxESVY+Jm5ic3A7PC9ESVY+DQo8RElWPjxG
+T05UIGZhY2U9QXJpYWwgc2l6ZT0yPkluIGFsbCBjcmltaW5hbCBwcm9zZWN1dGlv
+bnMsIHRoZSBhY2N1c2VkIHNoYWxsIA0KZW5qb3kgdGhlIHJpZ2h0IHRvIGEgc3Bl
+ZWR5IGFuZCBwdWJsaWMgdHJpYWwsIGJ5IGFuIGltcGFydGlhbCBqdXJ5IG9mIHRo
+ZSBzdGF0ZSANCmFuZCBkaXN0cmljdCB3aGVyZWluIHRoZSBjcmltZSBzaGFsbCBo
+YXZlIGJlZW4gY29tbWl0dGVkLCB3aGljaCBkaXN0cmljdCBzaGFsbCANCmhhdmUg
+YmVlbiBwcmV2aW91c2x5IGFzY2VydGFpbmVkIGJ5IGxhdywgYW5kIHRvIGJlIGlu
+Zm9ybWVkIG9mIHRoZSBuYXR1cmUgYW5kIA0KY2F1c2Ugb2YgdGhlIGFjY3VzYXRp
+b247IHRvIGJlIGNvbmZyb250ZWQgd2l0aCB0aGUgd2l0bmVzc2VzIGFnYWluc3Qg
+aGltOyB0byANCmhhdmUgY29tcHVsc29yeSBwcm9jZXNzIGZvciBvYnRhaW5pbmcg
+d2l0bmVzc2VzIGluIGhpcyBmYXZvciwgYW5kIHRvIGhhdmUgdGhlIA0KYXNzaXN0
+YW5jZSBvZiBjb3Vuc2VsIGZvciBoaXMgZGVmZW5zZS4gPC9GT05UPjwvRElWPg0K
+PERJVj4mbmJzcDs8L0RJVj4NCjxESVY+PEZPTlQgZmFjZT1BcmlhbCBzaXplPTI+
+QW1lbmRtZW50IFZJSTwvRk9OVD48L0RJVj4NCjxESVY+Jm5ic3A7PC9ESVY+DQo8
+RElWPjxGT05UIGZhY2U9QXJpYWwgc2l6ZT0yPkluIHN1aXRzIGF0IGNvbW1vbiBs
+YXcsIHdoZXJlIHRoZSB2YWx1ZSBpbiANCmNvbnRyb3ZlcnN5IHNoYWxsIGV4Y2Vl
+ZCB0d2VudHkgZG9sbGFycywgdGhlIHJpZ2h0IG9mIHRyaWFsIGJ5IGp1cnkgc2hh
+bGwgYmUgDQpwcmVzZXJ2ZWQsIGFuZCBubyBmYWN0IHRyaWVkIGJ5IGEganVyeSwg
+c2hhbGwgYmUgb3RoZXJ3aXNlIHJlZXhhbWluZWQgaW4gYW55IA0KY291cnQgb2Yg
+dGhlIFVuaXRlZCBTdGF0ZXMsIHRoYW4gYWNjb3JkaW5nIHRvIHRoZSBydWxlcyBv
+ZiB0aGUgY29tbW9uIGxhdy4gDQo8L0ZPTlQ+PC9ESVY+DQo8RElWPiZuYnNwOzwv
+RElWPg0KPERJVj48Rk9OVCBmYWNlPUFyaWFsIHNpemU9Mj5BbWVuZG1lbnQgVklJ
+STwvRk9OVD48L0RJVj4NCjxESVY+Jm5ic3A7PC9ESVY+DQo8RElWPjxGT05UIGZh
+Y2U9QXJpYWwgc2l6ZT0yPkV4Y2Vzc2l2ZSBiYWlsIHNoYWxsIG5vdCBiZSByZXF1
+aXJlZCwgbm9yIGV4Y2Vzc2l2ZSANCmZpbmVzIGltcG9zZWQsIG5vciBjcnVlbCBh
+bmQgdW51c3VhbCBwdW5pc2htZW50cyBpbmZsaWN0ZWQuIDwvRk9OVD48L0RJVj4N
+CjxESVY+Jm5ic3A7PC9ESVY+DQo8RElWPjxGT05UIGZhY2U9QXJpYWwgc2l6ZT0y
+PkFtZW5kbWVudCBJWDwvRk9OVD48L0RJVj4NCjxESVY+Jm5ic3A7PC9ESVY+DQo8
+RElWPjxGT05UIGZhY2U9QXJpYWwgc2l6ZT0yPlRoZSBlbnVtZXJhdGlvbiBpbiB0
+aGUgQ29uc3RpdHV0aW9uLCBvZiBjZXJ0YWluIA0KcmlnaHRzLCBzaGFsbCBub3Qg
+YmUgY29uc3RydWVkIHRvIGRlbnkgb3IgZGlzcGFyYWdlIG90aGVycyByZXRhaW5l
+ZCBieSB0aGUgDQpwZW9wbGUuIDwvRk9OVD48L0RJVj4NCjxESVY+Jm5ic3A7PC9E
+SVY+DQo8RElWPjxGT05UIGZhY2U9QXJpYWwgc2l6ZT0yPkFtZW5kbWVudCBYPC9G
+T05UPjwvRElWPg0KPERJVj4mbmJzcDs8L0RJVj4NCjxESVY+PEZPTlQgZmFjZT1B
+cmlhbCBzaXplPTI+VGhlIHBvd2VycyBub3QgZGVsZWdhdGVkIHRvIHRoZSBVbml0
+ZWQgU3RhdGVzIGJ5IA0KdGhlIENvbnN0aXR1dGlvbiwgbm9yIHByb2hpYml0ZWQg
+YnkgaXQgdG8gdGhlIHN0YXRlcywgYXJlIHJlc2VydmVkIHRvIHRoZSBzdGF0ZXMg
+DQpyZXNwZWN0aXZlbHksIG9yIHRvIHRoZSBwZW9wbGUuIDwvRk9OVD48L0RJVj48
+L0RJVj48L0JPRFk+PC9IVE1MPg0KAAAfADUQAQAAAKIAAAA8ADQANQAyADAARgA2
+ADEANQAxAEQAQQBGADIAQQA0ADQAQgBBADgANwA4AEIARgAyAEYAMwA4ADAAMwA0
+ADgARQAyADYARQA1AEAAYgByAC0AZQB4AGMAaAAtAGQAZQB2ADEALgBiAHIAZQB4
+AGMAaABhAG4AZwBlAC4AZABvAGwAcABoAGkAbgBzAGUAYQByAGMAaAAuAGMAbwBt
+AD4AAAAAAAMAgBD/////HwDzEAEAAAAmAAAAQgBpAGwAbAAgAG8AZgAgAFIAaQBn
+AGgAdABzAC4ARQBNAEwAAAAAAAsA9BAAAAAACwD1EAAAAAALAPYQAAAAAEAABzBR
+lpFluknFAUAACDBRlpFluknFAQMA3j+fTgAAAwDxPwkEAAAfAPg/AQAAABAAAAAz
+AGsAcgBlAGwAYQB5AAAAAgH5PwEAAABjAAAAAAAAANynQMjAQhAatLkIACsv4YIB
+AAAAAAAAAC9PPUJSLUVYQ0gtVEVTVC9PVT1GSVJTVCBBRE1JTklTVFJBVElWRSBH
+Uk9VUC9DTj1SRUNJUElFTlRTL0NOPTNLUkVMQVkAAB8A+j8BAAAAEAAAADMAawBy
+AGUAbABhAHkAAAACAfs/AQAAAGMAAAAAAAAA3KdAyMBCEBq0uQgAKy/hggEAAAAA
+AAAAL089QlItRVhDSC1URVNUL09VPUZJUlNUIEFETUlOSVNUUkFUSVZFIEdST1VQ
+L0NOPVJFQ0lQSUVOVFMvQ049M0tSRUxBWQAAAwD9P+QEAAADABlAAAAAAAMAGkAA
+AAAAHwAwQAEAAAAQAAAAMwBLAFIARQBMAEEAWQAAAB8AMUABAAAAEAAAADMASwBS
+AEUATABBAFkAAAAfADhAAQAAABAAAAAzAEsAUgBFAEwAQQBZAAAAHwA5QAEAAAAQ
+AAAAMwBLAFIARQBMAEEAWQAAAAMAdkD/////AwACWQAAFgADAAlZAgAAAAsAhYEI
+IAYAAAAAAMAAAAAAAABGAAAAAA6FAAAAAAAAAwCdgQggBgAAAAAAwAAAAAAAAEYA
+AAAAUoUAAJjDAQAfAJ6BCCAGAAAAAADAAAAAAAAARgAAAABUhQAAAQAAAAoAAAAx
+ADEALgAwAAAAAAADAOmBCCAGAAAAAADAAAAAAAAARgAAAAABhQAAAAAAAAsA7oEI
+IAYAAAAAAMAAAAAAAABGAAAAAAOFAAAAAAAAAwD4gQggBgAAAAAAwAAAAAAAAEYA
+AAAAEIUAAAAAAAADAP+BCCAGAAAAAADAAAAAAAAARgAAAAAYhQAAAAAAAAsAIIII
+IAYAAAAAAMAAAAAAAABGAAAAAAaFAAAAAAAACwAkggggBgAAAAAAwAAAAAAAAEYA
+AAAAgoUAAAAAAAAfACaCCCAGAAAAAADAAAAAAAAARgAAAACDhQAAAQAAACYAAAA0
+ADAANQAxADMAMQA1ADEANwAtADIANQAwADQAMgAwADAANQAAAAAAAwBxggggBgAA
+AAAAwAAAAAAAAEYAAAAAk4UAAAAAAAALACkAAAAAAAsAIwAAAAAAAgF/AAEAAABR
+AAAAPDQ1MjBGNjE1MURBRjJBNDRCQTg3OEJGMkYzODAzNDhFMjZFNUBici1leGNo
+LWRldjEuYnJleGNoYW5nZS5kb2xwaGluc2VhcmNoLmNvbT4AAAAAC/o=
+
+--_000_553468B23EE29B4F8836CBD0E1B2A15A275C3AA855POLNIEXMBV2po_--
+
diff --git a/spec/fixtures/files/tnef-attachment-truncated.email b/spec/fixtures/files/tnef-attachment-truncated.email
new file mode 100644
index 000000000..365a5a442
--- /dev/null
+++ b/spec/fixtures/files/tnef-attachment-truncated.email
@@ -0,0 +1,34 @@
+From hello@blah.local Fri Feb 21 16:23:14 2013
+Return-path: <bar@example.org>
+Envelope-to: foo@example.org
+Delivery-date: Fri, 21 Feb 2013 16:23:14 +0000
+Content-Type: multipart/mixed;
+ boundary="_000_553468B23EE29B4F8836CBD0E1B2A15A275C3AA855POLNIEXMBV2po_"
+From: <bar@example.org>
+To: <foo@example.org>
+Sender: <hello@blah.local>
+Date: Fri, 21 Feb 2013 16:23:04 +0000
+Subject: here's a useless email
+Message-ID: <12345@blah.local>
+Accept-Language: en-US, en-GB
+Content-Language: en-US
+X-MS-Has-Attach:
+X-MS-TNEF-Correlator: <12345@blah.local>
+acceptlanguage: en-US, en-GB
+MIME-Version: 1.0
+
+--_000_553468B23EE29B4F8836CBD0E1B2A15A275C3AA855POLNIEXMBV2po_
+Content-Type: text/plain; charset="us-ascii"
+Content-Transfer-Encoding: quoted-printable
+
+Some introductory text here, before the malformed TNEF attachment.
+
+--_000_553468B23EE29B4F8836CBD0E1B2A15A275C3AA855POLNIEXMBV2po_
+Content-Disposition: attachment; filename="winmail.dat"
+Content-Transfer-Encoding: base64
+Content-Type: application/ms-tnef; name="winmail.dat"
+
+eJ8+IkV9AQaQCAAEAAAAAAABAAEAAQeQBgAIAAAA5AQAAAAAAADoAAEJgAEAIQAAAEMyRUUzRUYx
+
+--_000_553468B23EE29B4F8836CBD0E1B2A15A275C3AA855POLNIEXMBV2po_--
+
diff --git a/spec/fixtures/foi_attachments.yml b/spec/fixtures/foi_attachments.yml
deleted file mode 100644
index 8b1378917..000000000
--- a/spec/fixtures/foi_attachments.yml
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/spec/fixtures/theme_views/core/application_mailer/core_only.rhtml b/spec/fixtures/theme_views/core/application_mailer/core_only.html.erb
index 53b7798ec..53b7798ec 100644
--- a/spec/fixtures/theme_views/core/application_mailer/core_only.rhtml
+++ b/spec/fixtures/theme_views/core/application_mailer/core_only.html.erb
diff --git a/spec/fixtures/theme_views/core/application_mailer/multipart_core_only.rhtml b/spec/fixtures/theme_views/core/application_mailer/multipart_core_only.html.erb
index 646a349f8..646a349f8 100644
--- a/spec/fixtures/theme_views/core/application_mailer/multipart_core_only.rhtml
+++ b/spec/fixtures/theme_views/core/application_mailer/multipart_core_only.html.erb
diff --git a/spec/fixtures/theme_views/core/application_mailer/simple.rhtml b/spec/fixtures/theme_views/core/application_mailer/simple.html.erb
index a3937c940..a3937c940 100644
--- a/spec/fixtures/theme_views/core/application_mailer/simple.rhtml
+++ b/spec/fixtures/theme_views/core/application_mailer/simple.html.erb
diff --git a/spec/fixtures/theme_views/theme_one/application_mailer/multipart_theme_only.rhtml b/spec/fixtures/theme_views/theme_one/application_mailer/multipart_theme_only.html.erb
index d6423fbb4..d6423fbb4 100644
--- a/spec/fixtures/theme_views/theme_one/application_mailer/multipart_theme_only.rhtml
+++ b/spec/fixtures/theme_views/theme_one/application_mailer/multipart_theme_only.html.erb
diff --git a/spec/fixtures/theme_views/theme_one/application_mailer/simple.rhtml b/spec/fixtures/theme_views/theme_one/application_mailer/simple.html.erb
index ad43e0c87..ad43e0c87 100644
--- a/spec/fixtures/theme_views/theme_one/application_mailer/simple.rhtml
+++ b/spec/fixtures/theme_views/theme_one/application_mailer/simple.html.erb
diff --git a/spec/fixtures/theme_views/theme_one/application_mailer/theme_only.rhtml b/spec/fixtures/theme_views/theme_one/application_mailer/theme_only.html.erb
index 865445815..865445815 100644
--- a/spec/fixtures/theme_views/theme_one/application_mailer/theme_only.rhtml
+++ b/spec/fixtures/theme_views/theme_one/application_mailer/theme_only.html.erb
diff --git a/spec/helpers/link_to_helper_spec.rb b/spec/helpers/link_to_helper_spec.rb
index 3e997f9f9..4cc1d415b 100644
--- a/spec/helpers/link_to_helper_spec.rb
+++ b/spec/helpers/link_to_helper_spec.rb
@@ -8,11 +8,10 @@ describe LinkToHelper do
before do
@mock_request = mock_model(InfoRequest, :url_title => 'test_title')
- @old_filters = ActionController::Routing::Routes.filters
- ActionController::Routing::Routes.filters = RoutingFilter::Chain.new
+ RoutingFilter.active = false
end
after do
- ActionController::Routing::Routes.filters = @old_filters
+ RoutingFilter.active = true
end
diff --git a/spec/integration/admin_spec.rb b/spec/integration/admin_spec.rb
index e148ea3ca..8a5e59ba2 100644
--- a/spec/integration/admin_spec.rb
+++ b/spec/integration/admin_spec.rb
@@ -13,7 +13,7 @@ describe "When administering the site" do
# Now fetch the "log in as" link to log in as Bob
get_via_redirect "/admin/user/login_as/#{users(:bob_smith_user).id}", nil, {
- "Authorization" => "Basic " + Base64.encode64("#{Configuration::admin_username}:#{Configuration::admin_password}").strip
+ "Authorization" => "Basic " + Base64.encode64("#{AlaveteliConfiguration::admin_username}:#{AlaveteliConfiguration::admin_password}").strip
}
response.should be_success
session[:user_id].should == users(:bob_smith_user).id
diff --git a/spec/integration/errors_spec.rb b/spec/integration/errors_spec.rb
index a44ed7051..17a0153c2 100644
--- a/spec/integration/errors_spec.rb
+++ b/spec/integration/errors_spec.rb
@@ -1,53 +1,130 @@
+# -*- coding: utf-8 -*-
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
-describe "When rendering errors" do
+describe "When errors occur" do
- before(:each) do
- load_raw_emails_data
- ActionController::Base.consider_all_requests_local = false
+ def set_consider_all_requests_local(value)
+ @requests_local = Rails.application.config.consider_all_requests_local
+ Rails.application.config.consider_all_requests_local = value
end
- after(:each) do
- ActionController::Base.consider_all_requests_local = true
+ def restore_consider_all_requests_local
+ Rails.application.config.consider_all_requests_local = @requests_local
end
- it "should render a 404 for unrouteable URLs" do
- get("/frobsnasm")
- response.body.should include("The page doesn't exist")
- response.code.should == "404"
- end
- it "should render a 404 for users that don't exist" do
- get("/user/wobsnasm")
- response.body.should include("The page doesn't exist")
- response.code.should == "404"
- end
- it "should render a 404 for bodies that don't exist" do
- get("/body/wobsnasm")
- response.body.should include("The page doesn't exist")
- response.code.should == "404"
+ before(:each) do
+ # This should happen automatically before each test but doesn't with these integration
+ # tests for some reason.
+ ActionMailer::Base.deliveries = []
end
- it "should render a 500 for general errors" do
- ir = info_requests(:naughty_chicken_request)
- # Set an invalid state for the request. Note that update_attribute doesn't run the validations
- ir.update_attribute(:described_state, "crotchety")
- get("/request/#{ir.url_title}")
- response.code.should == "500"
+
+ after(:each) do
+ restore_consider_all_requests_local
end
- it "should render a 403 for attempts at directory listing for attachments" do
- # make a fake cache
- foi_cache_path = File.expand_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.body.should include("Directory listing not allowed")
- response.code.should == "403"
- get("/request/101/response/1/attach/html" )
- response.body.should include("Directory listing not allowed")
- response.code.should == "403"
+
+ context 'when considering all requests local (by default all in development)' do
+
+ before(:each) { set_consider_all_requests_local(true) }
+
+ it 'should show a full trace for general errors' do
+ InfoRequest.stub!(:find_by_url_title!).and_raise("An example error")
+ get("/request/example")
+ response.body.should have_selector('div[id=traces]')
+ response.body.should match('An example error')
+ end
+
end
- it "should render a 404 for non-existent 'details' pages for requests" do
- get("/details/request/wobble" )
- response.body.should include("The page doesn't exist")
- response.code.should == "404"
+
+ context 'when not considering all requests local' do
+
+ before(:each) { set_consider_all_requests_local(false) }
+
+ it "should render a 404 for unrouteable URLs using the general/exception_caught template" do
+ get("/frobsnasm")
+ response.should render_template('general/exception_caught')
+ response.code.should == "404"
+ end
+
+ it "should render a 404 for users or bodies that don't exist using the general/exception_caught
+ template" do
+ ['/user/wobsnasm', '/body/wobsnasm'].each do |non_existent_url|
+ get(non_existent_url)
+ response.should render_template('general/exception_caught')
+ response.code.should == "404"
+ end
+ end
+
+ it "should render a 500 for general errors using the general/exception_caught template" do
+ InfoRequest.stub!(:find_by_url_title!).and_raise("An example error")
+ get("/request/example")
+ response.should render_template('general/exception_caught')
+ response.body.should match('An example error')
+ response.code.should == "500"
+ end
+
+ it 'should render a 500 for json errors' do
+ InfoRequest.stub!(:find_by_url_title!).and_raise("An example error")
+ get("/request/example.json")
+ response.code.should == '500'
+ end
+
+ it 'should render a 404 for a non-found xml request' do
+ get("/frobsnasm.xml")
+ response.code.should == '404'
+ end
+
+ it 'should notify of a general error' do
+ InfoRequest.stub!(:find_by_url_title!).and_raise("An example error")
+ get("/request/example")
+ deliveries = ActionMailer::Base.deliveries
+ deliveries.size.should == 1
+ mail = deliveries[0]
+ mail.body.should =~ /An example error/
+ end
+
+ it 'should log a general error' do
+ Rails.logger.should_receive(:fatal)
+ InfoRequest.stub!(:find_by_url_title!).and_raise("An example error")
+ get("/request/example")
+ end
+
+ it 'should assign the locale for the general/exception_caught template' do
+ InfoRequest.stub!(:find_by_url_title!).and_raise("An example error")
+ get("/es/request/example")
+ response.should render_template('general/exception_caught')
+ response.body.should match('Lo sentimos, hubo un problema procesando esta página')
+ response.body.should match('An example error')
+ end
+
+ it "should render a 403 with text body for attempts at directory listing for attachments" do
+ # make a fake cache
+ foi_cache_path = File.expand_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.body.should include("Directory listing not allowed")
+ response.code.should == "403"
+ get("/request/101/response/1/attach/html" )
+ response.body.should include("Directory listing not allowed")
+ response.code.should == "403"
+ end
+
+ it "return a 403 for a JSON PermissionDenied error" do
+ InfoRequest.stub!(:find_by_url_title!).and_raise(ApplicationController::PermissionDenied)
+ get("/request/example.json")
+ response.code.should == '403'
+ end
+
+ context "in the admin interface" do
+
+ it 'should show a full trace for general errors' do
+ InfoRequest.stub!(:find).and_raise("An example error")
+ get("/admin/request/show/333")
+ response.body.should have_selector('div[id=traces]')
+ response.body.should match('An example error')
+ end
+
+ end
+
end
-end
+end
diff --git a/spec/integration/search_request_spec.rb b/spec/integration/search_request_spec.rb
index c564032a6..23a62e97b 100644
--- a/spec/integration/search_request_spec.rb
+++ b/spec/integration/search_request_spec.rb
@@ -13,10 +13,8 @@ describe "When searching" do
end
it "should redirect requests with search in query string to URL-based page" do
- url = '/search/all?query=bob'
- request_via_redirect("post", url)
- response.request.url.should_not include(url)
- response.request.url.should include("/search/bob/all")
+ post '/search/all?query=bob'
+ response.should redirect_to "/en/search/bob/all"
end
it "should correctly execute simple search" do
diff --git a/spec/lib/basic_encoding_tests.rb b/spec/lib/basic_encoding_tests.rb
new file mode 100644
index 000000000..35d35fd4a
--- /dev/null
+++ b/spec/lib/basic_encoding_tests.rb
@@ -0,0 +1,157 @@
+# -*- coding: utf-8 -*-
+require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
+
+def bytes_to_binary_string( bytes, claimed_encoding = nil )
+ claimed_encoding ||= 'ASCII-8BIT'
+ bytes_string = bytes.pack('c*')
+ if RUBY_VERSION.to_f >= 1.9
+ bytes_string.force_encoding! claimed_encoding
+ end
+ bytes_string
+end
+
+random_string = bytes_to_binary_string [ 0x0f, 0x58, 0x1c, 0x8f, 0xa4, 0xcf,
+ 0xf6, 0x8c, 0x9d, 0xa7, 0x06, 0xd9,
+ 0xf7, 0x90, 0x6c, 0x6f]
+
+windows_1252_string = bytes_to_binary_string [ 0x44, 0x41, 0x53, 0x48, 0x20,
+ 0x96, 0x20, 0x44, 0x41, 0x53,
+ 0x48 ]
+
+# It's a shame this example is so long, but if we don't take enough it
+# gets misinterpreted as Shift_JIS
+
+gb_18030_bytes = [ 0xb9, 0xf3, 0xb9, 0xab, 0xcb, 0xbe, 0xb8, 0xba, 0xd4, 0xf0,
+ 0xc8, 0xcb, 0x28, 0xbe, 0xad, 0xc0, 0xed, 0x2f, 0xb2, 0xc6,
+ 0xce, 0xf1, 0x29, 0xc4, 0xfa, 0xba, 0xc3, 0xa3, 0xba, 0x0d,
+ 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0xb1, 0xbe, 0xb9, 0xab, 0xcb, 0xbe, 0xd4,
+ 0xda, 0x31, 0x39, 0x39, 0x37, 0xc4, 0xea, 0xb3, 0xc9, 0xc1,
+ 0xa2, 0xb9, 0xfa, 0xbc, 0xd2, 0xb9, 0xa4, 0xc9, 0xcc, 0xd7,
+ 0xa2, 0xb2, 0xe1, 0x2e, 0xca, 0xb5, 0xc1, 0xa6, 0xd0, 0xdb,
+ 0xba, 0xf1, 0xa1, 0xa3, 0xd3, 0xd0, 0xb6, 0xc0, 0xc1, 0xa2,
+ 0xcb, 0xb0, 0xce, 0xf1, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xd7, 0xa8, 0xd2, 0xb5,
+ 0xc8, 0xcb, 0xd4, 0xb1, 0x3b, 0xd4, 0xda, 0xc8, 0xab, 0xb9,
+ 0xfa, 0xb8, 0xf7, 0xb3, 0xc7, 0xca, 0xd0, 0xc9, 0xe8, 0xc1,
+ 0xa2, 0xb7, 0xd6, 0xb9, 0xab, 0xcb, 0xbe, 0xa3, 0xa8, 0xd5,
+ 0xe3, 0xbd, 0xad, 0xa1, 0xa2, 0xc9, 0xcf, 0xba, 0xa3, 0xa1,
+ 0xa2, 0xb9, 0xe3, 0xd6, 0xdd, 0xa1, 0xa2, 0xbd, 0xad, 0xcb,
+ 0xd5, 0xb5, 0xc8, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0xb5, 0xd8, 0xb7, 0xbd, 0xa3,
+ 0xa9, 0xd2, 0xf2, 0xbd, 0xf8, 0xcf, 0xee, 0xbd, 0xcf, 0xb6,
+ 0xe0, 0xcf, 0xd6, 0xcd, 0xea, 0xb3, 0xc9, 0xb2, 0xbb, 0xc1,
+ 0xcb, 0xc3, 0xbf, 0xd4, 0xc2, 0xcf, 0xfa, 0xca, 0xdb, 0xb6,
+ 0xee, 0xb6, 0xc8, 0xa1, 0xa3, 0xc3, 0xbf, 0xd4, 0xc2, 0xd3,
+ 0xd0, 0xd2, 0xbb, 0xb2, 0xbf, 0xb7, 0xd6, 0x0d, 0x0a, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xd4,
+ 0xf6, 0xd6, 0xb5, 0xb6, 0x90, 0xa3, 0xa8, 0x36, 0x2d, 0x37,
+ 0x25, 0xd7, 0xf3, 0xd3, 0xd2, 0x29, 0xba, 0xcd, 0xc6, 0xd5,
+ 0xc6, 0xb1, 0xa3, 0xa8, 0x30, 0x2e, 0x35, 0x25, 0x2d, 0x32,
+ 0x25, 0x20, 0xd7, 0xf3, 0xd3, 0xd2, 0xa3, 0xa9, 0xd3, 0xc5,
+ 0xbb, 0xdd, 0xb4, 0xfa, 0xbf, 0xaa, 0xbb, 0xf2, 0xba, 0xcf,
+ 0xd7, 0xf7, 0xa3, 0xac, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xb5, 0xe3, 0xca, 0xfd,
+ 0xbd, 0xcf, 0xb5, 0xcd, 0xa1, 0xa3, 0xb4, 0xfa, 0xc0, 0xed,
+ 0xb7, 0xb6, 0xce, 0xa7, 0xc8, 0xe7, 0xcf, 0xc2, 0xa3, 0xba,
+ 0x0d, 0x0a ]
+
+gb_18030_spam_string = bytes_to_binary_string gb_18030_bytes
+
+describe "normalize_string_to_utf8" do
+
+ describe "when passed uniterpretable character data" do
+
+ it "should reject it as invalid" do
+
+ expect {
+ normalize_string_to_utf8 random_string
+ }.to raise_error(EncodingNormalizationError)
+
+ expect {
+ normalize_string_to_utf8 random_string, 'UTF-8'
+ }.to raise_error(EncodingNormalizationError)
+
+ end
+ end
+
+ describe "when passed unlabelled Windows 1252 data" do
+
+ it "should correctly convert it to UTF-8" do
+
+ normalized = normalize_string_to_utf8 windows_1252_string
+
+ normalized.should == "DASH – DASH"
+
+ end
+
+ end
+
+ describe "when passed GB 18030 data" do
+
+ it "should correctly convert it to UTF-8 if unlabelled" do
+
+ normalized = normalize_string_to_utf8 gb_18030_spam_string
+
+ normalized.should start_with("贵公司负责人")
+
+ end
+
+ end
+
+end
+
+describe "convert_string_to_utf8_or_binary" do
+
+ describe "when passed uniterpretable character data" do
+
+ it "should return it as a binary string" do
+
+ converted = convert_string_to_utf8_or_binary random_string
+ converted.should == random_string
+
+ if RUBY_VERSION.to_f >= 1.9
+ converted.encoding.should == 'ASCII-8BIT'
+ end
+
+ converted = convert_string_to_utf8_or_binary random_string,'UTF-8'
+ converted.should == random_string
+
+ if RUBY_VERSION.to_f >= 1.9
+ converted.encoding.should == 'ASCII-8BIT'
+ end
+
+ end
+ end
+
+ describe "when passed unlabelled Windows 1252 data" do
+
+ it "should correctly convert it to UTF-8" do
+
+ converted = convert_string_to_utf8_or_binary windows_1252_string
+
+ converted.should == "DASH – DASH"
+
+ if RUBY_VERSION.to_f >= 1.9
+ converted.encoding.should == 'UTF-8'
+ end
+ end
+
+ end
+
+ describe "when passed GB 18030 data" do
+
+ it "should correctly convert it to UTF-8 if unlabelled" do
+
+ converted = convert_string_to_utf8_or_binary gb_18030_spam_string
+
+ converted.should start_with("贵公司负责人")
+
+ if RUBY_VERSION.to_f >= 1.9
+ converted.encoding.should == 'UTF-8'
+ end
+ end
+
+ end
+
+end
diff --git a/spec/lib/mail_handler/mail_handler_spec.rb b/spec/lib/mail_handler/mail_handler_spec.rb
index 48c32e2bc..272b56d0b 100644
--- a/spec/lib/mail_handler/mail_handler_spec.rb
+++ b/spec/lib/mail_handler/mail_handler_spec.rb
@@ -20,12 +20,46 @@ describe 'when creating a mail object from raw data' do
mail.to.should == ["request-66666-caa77777@whatdotheyknow.com", "foi@example.com"]
end
+ it 'should return nil for malformed To: and Cc: lines' do
+ mail = get_fixture_mail('malformed-to-and-cc.email')
+ mail.to.should == nil
+ mail.cc.should == nil
+ end
+
it 'should convert an iso8859 email to utf8' do
mail = get_fixture_mail('iso8859_2_raw_email.email')
- mail.subject.should have_text(/gjatë/u)
+ mail.subject.should match /gjatë/u
MailHandler.get_part_body(mail).is_utf8?.should == true
end
+ it 'should not be confused by subject lines with malformed UTF-8 at the end' do
+ # The base64 subject line was generated with:
+ # printf "hello\360" | base64
+ # ... and wrapping the result in '=?UTF-8?B?' and '?='
+ mail = get_fixture_mail('subject-bad-utf-8-trailing-base64.email')
+ mail.subject.should == 'hello'
+ # The quoted printable subject line was generated with:
+ # printf "hello\360" | qprint -b -e
+ # ... and wrapping the result in '=?UTF-8?Q?' and '?='
+ mail = get_fixture_mail('subject-bad-utf-8-trailing-quoted-printable.email')
+ mail.subject.should == 'hello'
+ end
+
+ it 'should convert a Windows-1252 body mislabelled as ISO-8859-1 to UTF-8' do
+ mail = get_fixture_mail('mislabelled-as-iso-8859-1.email')
+ body = MailHandler.get_part_body(mail)
+ body.is_utf8?.should == true
+ # This email is broken in at least these two ways:
+ # 1. It contains a top bit set character (0x96) despite the
+ # "Content-Transfer-Encoding: 7bit"
+ # 2. The charset in the Content-Type header is "iso-8859-1"
+ # but 0x96 is actually a Windows-1252 en dash, which would
+ # be Unicode codepoint 2013. It should be possible to
+ # spot the mislabelling, since 0x96 isn't a valid
+ # ISO-8859-1 character.
+ body.should match(/ \xe2\x80\x93 /)
+ end
+
end
describe 'when asked for the from name' do
@@ -275,6 +309,12 @@ end
describe 'when getting attachment attributes' do
+ it 'should handle a mail with a non-multipart part with no charset in the Content-Type header' do
+ mail = get_fixture_mail('part-without-charset-in-content-type.email')
+ attributes = MailHandler.get_attachment_attributes(mail)
+ attributes.size.should == 2
+ end
+
it 'should get two attachment parts from a multipart mail with text and html alternatives
and an image' do
mail = get_fixture_mail('quoted-subject-iso8859-1.email')
@@ -282,6 +322,13 @@ describe 'when getting attachment attributes' do
attributes.size.should == 2
end
+ it 'should get one attachment from a multipart mail with text and HTML alternatives, which should be UTF-8' do
+ mail = get_fixture_mail('iso8859_2_raw_email.email')
+ attributes = MailHandler.get_attachment_attributes(mail)
+ attributes.length.should == 1
+ attributes[0][:body].is_utf8?.should == true
+ end
+
it 'should expand a mail attached as text' do
# Note that this spec will only pass using Tmail in the timezone set as datetime headers
# are rendered out in the local time - using the Mail gem this is not necessary
@@ -304,6 +351,52 @@ describe 'when getting attachment attributes' do
attributes = MailHandler.get_attachment_attributes(mail)
end
+ it 'should ignore truncated TNEF attachment' do
+ mail = get_fixture_mail('tnef-attachment-truncated.email')
+ attributes = MailHandler.get_attachment_attributes(mail)
+ attributes.length.should == 2
+ end
+
+ it 'should ignore anything beyond the final MIME boundary' do
+ pending do
+ # This example raw email has a premature closing boundary for
+ # the outer multipart/mixed - my reading of RFC 1521 is that
+ # the "epilogue" beyond that should be ignored.
+ # See https://github.com/mysociety/alaveteli/issues/922 for
+ # more discussion.
+ mail = get_fixture_mail('nested-attachments-premature-end.email')
+ attributes = MailHandler.get_attachment_attributes(mail)
+ attributes.length.should == 3
+ end
+ end
+
+ it 'should cope with a missing final MIME boundary' do
+ mail = get_fixture_mail('multipart-no-final-boundary.email')
+ attributes = MailHandler.get_attachment_attributes(mail)
+ attributes.length.should == 1
+ attributes[0][:body].should match(/This is an acknowledgement of your email/)
+ attributes[0][:content_type].should == "text/plain"
+ attributes[0][:url_part_number].should == 1
+ end
+
+ it 'should ignore a TNEF attachment with no usable contents' do
+ # FIXME: "no usable contents" is slightly misleading. The
+ # attachment in this example email does have usable content in
+ # the body of the TNEF attachment, but the invocation of tnef
+ # historically used to unpack these attachments doesn't add
+ # the --save-body parameter, so that they have been ignored so
+ # far. We probably should include the body from such
+ # attachments, but, at the moment, with the pending upgrade to
+ # Rails 3, we just want to check that the behaviour is the
+ # same as before.
+ mail = get_fixture_mail('tnef-attachment-empty.email')
+ attributes = MailHandler.get_attachment_attributes(mail)
+ attributes.length.should == 2
+ # This is the size of the TNEF-encoded attachment; currently,
+ # we expect the code just to return this without decoding:
+ attributes[1][:body].length.should == 7769
+ end
+
it 'should produce a consistent set of url_part_numbers, content_types, within_rfc822_subjects
and filenames from an example mail with lots of attachments' do
mail = get_fixture_mail('many-attachments-date-header.email')
@@ -385,3 +478,11 @@ describe 'when getting attachment attributes' do
end
end
end
+
+describe 'when getting the address part from an address string' do
+
+ it 'should handle non-ascii characters in the name input' do
+ address = "\"Someone’s name\" <test@example.com>"
+ MailHandler.address_from_string(address).should == 'test@example.com'
+ end
+end
diff --git a/spec/lib/sendmail_return_path_spec.rb b/spec/lib/sendmail_return_path_spec.rb
index 137869b6e..83436c2bd 100644
--- a/spec/lib/sendmail_return_path_spec.rb
+++ b/spec/lib/sendmail_return_path_spec.rb
@@ -1,5 +1,10 @@
# This is a test of the monkey patches in sendmail_return_path.rb
+# In Rails 3 the monkeypatches are not needed anymore because sendmail now has the "-f" flag
+# set correctly. So, strictly these tests are testing the Rails internals. So, that means we really
+# should delete them. Let's do that later when things have settled down. For the time being leave
+# them in
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
describe "when sending email with an altered return path" do
@@ -28,10 +33,10 @@ describe "when sending email with an altered return path" do
Net::SMTP.stub!(:new).and_return(mock_smtp)
with_delivery_method :smtp do
- ContactMailer.deliver_to_admin_message(
+ ContactMailer.to_admin_message(
"Mr. Test", "test@localhost", "Test script spec/lib/sendmail_return_path_spec.rb",
"This is just a test for a test script", nil, nil, nil
- )
+ ).deliver
end
deliveries = ActionMailer::Base.deliveries
@@ -40,12 +45,12 @@ describe "when sending email with an altered return path" do
it "should set the return path when sending email using sendmail" do
with_stub_popen do
- IO.should_receive(:popen).once.with('/usr/sbin/sendmail -i -t -f "test@localhost"', "w+")
+ IO.should_receive(:popen).once.with('/usr/sbin/sendmail -i -t -f "test@localhost" postmaster@localhost', "w+")
with_delivery_method :sendmail do
- ContactMailer.deliver_to_admin_message(
+ ContactMailer.to_admin_message(
"Mr. Test", "test@localhost", "Test script spec/lib/sendmail_return_path_spec.rb",
"This is just a test for a test script", nil, nil, nil
- )
+ ).deliver
end
end
diff --git a/spec/lib/timezone_fixes_spec.rb b/spec/lib/timezone_fixes_spec.rb
index 9d6ade526..8a9a3bf31 100644
--- a/spec/lib/timezone_fixes_spec.rb
+++ b/spec/lib/timezone_fixes_spec.rb
@@ -3,6 +3,11 @@
# We use MailServerLogDone here just as a totally random model that has a datetime type.
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
+# In Rails 3 the monkeypatch that these tests are testing is not necessary. So,
+# since these tests are testing the Rails internals you could argue that they shouldn't
+# be here. Well, you're right. But let's leave them in for the time being until the upgrade is finished.
+# Then, we should probably delete this whole file
+
describe "when doing things with timezones" do
it "should preserve time objects with local time conversion to default timezone UTC
diff --git a/spec/models/application_mailer_spec.rb b/spec/mailers/application_mailer_spec.rb
index acf5f43bc..d8993f78f 100644
--- a/spec/models/application_mailer_spec.rb
+++ b/spec/mailers/application_mailer_spec.rb
@@ -8,8 +8,7 @@ describe ApplicationMailer do
def set_base_views
ApplicationMailer.class_eval do
@previous_view_paths = self.view_paths.dup
- self.view_paths.clear
- self.view_paths << File.join(Rails.root, 'spec', 'fixtures', 'theme_views', 'core')
+ self.view_paths = [File.join(Rails.root, 'spec', 'fixtures', 'theme_views', 'core')]
end
end
@@ -27,13 +26,13 @@ describe ApplicationMailer do
def prepend_theme_views(theme_name)
ApplicationMailer.class_eval do
- view_paths.unshift File.join(Rails.root, 'spec', 'fixtures', 'theme_views', theme_name)
+ prepend_view_path File.join(Rails.root, 'spec', 'fixtures', 'theme_views', theme_name)
end
end
def append_theme_views(theme_name)
ApplicationMailer.class_eval do
- view_paths << File.join(Rails.root, 'spec', 'fixtures', 'theme_views', theme_name)
+ append_view_path File.join(Rails.root, 'spec', 'fixtures', 'theme_views', theme_name)
end
end
@@ -45,11 +44,8 @@ describe ApplicationMailer do
def create_multipart_method(method_name)
ApplicationMailer.send(:define_method, method_name) do
- attachment :content_type => 'message/rfc822',
- :body => 'xxx',
- :filename => "original.eml",
- :transfer_encoding => '7bit',
- :content_disposition => 'inline'
+ attachments['original.eml'] = 'xxx'
+ mail
end
end
@@ -62,32 +58,32 @@ describe ApplicationMailer do
it 'should render a theme template in preference to a core template' do
prepend_theme_views('theme_one')
- @mail = ApplicationMailer.create_simple()
+ @mail = ApplicationMailer.simple
@mail.body.should match('Theme simple')
end
it 'should render the template provided by the theme if no template is available in core' do
prepend_theme_views('theme_one')
- @mail = ApplicationMailer.create_theme_only()
+ @mail = ApplicationMailer.theme_only
@mail.body.should match('Theme only')
end
it 'should render the template provided by core if there is no theme template' do
prepend_theme_views('theme_one')
- @mail = ApplicationMailer.create_core_only()
+ @mail = ApplicationMailer.core_only
@mail.body.should match('Core only')
end
- it 'should raise an error if the template is in neither core nor theme' do
+ it 'should render an empty body if the template is in neither core nor theme' do
prepend_theme_views('theme_one')
- expected_error = 'Missing template application_mailer/neither.erb in view path'
- lambda{ ApplicationMailer.create_neither() }.should raise_error(/#{expected_error}/)
+ @mail = ApplicationMailer.neither
+ @mail.body.should be_empty
end
it 'should render a multipart email using a theme template' do
prepend_theme_views('theme_one')
create_multipart_method('multipart_theme_only')
- @mail = ApplicationMailer.create_multipart_theme_only()
+ @mail = ApplicationMailer.multipart_theme_only
@mail.parts.size.should == 2
message_part = @mail.parts[0].to_s
message_part.should match("Theme multipart")
@@ -96,7 +92,7 @@ describe ApplicationMailer do
it 'should render a multipart email using a core template' do
prepend_theme_views('theme_one')
create_multipart_method('multipart_core_only')
- @mail = ApplicationMailer.create_multipart_core_only()
+ @mail = ApplicationMailer.multipart_core_only
@mail.parts.size.should == 2
message_part = @mail.parts[0].to_s
message_part.should match("Core multipart")
@@ -108,32 +104,32 @@ describe ApplicationMailer do
it 'should render a core template in preference to a theme template' do
append_theme_views('theme_one')
- @mail = ApplicationMailer.create_simple()
+ @mail = ApplicationMailer.simple
@mail.body.should match('Core simple')
end
it 'should render the template provided by the theme if no template is available in core' do
append_theme_views('theme_one')
- @mail = ApplicationMailer.create_theme_only()
+ @mail = ApplicationMailer.theme_only
@mail.body.should match('Theme only')
end
it 'should render the template provided by core if there is no theme template' do
append_theme_views('theme_one')
- @mail = ApplicationMailer.create_core_only()
+ @mail = ApplicationMailer.core_only
@mail.body.should match('Core only')
end
- it 'should raise an error if the template is in neither core nor theme' do
+ it 'should render an empty body if the template is in neither core nor theme' do
append_theme_views('theme_one')
- expected_error = 'Missing template application_mailer/neither.erb in view path'
- lambda{ ApplicationMailer.create_neither() }.should raise_error(/#{expected_error}/)
+ @mail = ApplicationMailer.neither
+ @mail.body.should be_empty
end
it 'should render a multipart email using a core template' do
append_theme_views('theme_one')
create_multipart_method('multipart_core_only')
- @mail = ApplicationMailer.create_multipart_core_only()
+ @mail = ApplicationMailer.multipart_core_only
@mail.parts.size.should == 2
message_part = @mail.parts[0].to_s
message_part.should match("Core multipart")
@@ -142,7 +138,7 @@ describe ApplicationMailer do
it 'should render a multipart email using a theme template' do
append_theme_views('theme_one')
create_multipart_method('multipart_theme_only')
- @mail = ApplicationMailer.create_multipart_theme_only()
+ @mail = ApplicationMailer.multipart_theme_only
@mail.parts.size.should == 2
message_part = @mail.parts[0].to_s
message_part.should match("Theme multipart")
diff --git a/spec/models/outgoing_mailer_spec.rb b/spec/mailers/outgoing_mailer_spec.rb
index 5d1ea2dfb..5d1ea2dfb 100644
--- a/spec/models/outgoing_mailer_spec.rb
+++ b/spec/mailers/outgoing_mailer_spec.rb
diff --git a/spec/models/request_mailer_spec.rb b/spec/mailers/request_mailer_spec.rb
index 40133eedc..23806b35b 100644
--- a/spec/models/request_mailer_spec.rb
+++ b/spec/mailers/request_mailer_spec.rb
@@ -34,7 +34,7 @@ describe RequestMailer, " when receiving incoming mail" do
deliveries = ActionMailer::Base.deliveries
deliveries.size.should == 1
mail = deliveries[0]
- mail.to.should == [ Configuration::contact_email ]
+ mail.to.should == [ AlaveteliConfiguration::contact_email ]
deliveries.clear
end
@@ -54,7 +54,7 @@ describe RequestMailer, " when receiving incoming mail" do
deliveries = ActionMailer::Base.deliveries
deliveries.size.should == 1
mail = deliveries[0]
- mail.to.should == [ Configuration::contact_email ]
+ mail.to.should == [ AlaveteliConfiguration::contact_email ]
deliveries.clear
end
@@ -74,7 +74,7 @@ describe RequestMailer, " when receiving incoming mail" do
deliveries = ActionMailer::Base.deliveries
deliveries.size.should == 1
mail = deliveries[0]
- mail.to.should == [ Configuration::contact_email ]
+ mail.to.should == [ AlaveteliConfiguration::contact_email ]
deliveries.clear
end
@@ -99,7 +99,7 @@ describe RequestMailer, " when receiving incoming mail" do
mail.multipart?.should == true
mail.parts.size.should == 2
message_part = mail.parts[0].to_s
- bounced_mail = MailHandler.mail_from_raw_email(mail.parts[1].body)
+ bounced_mail = MailHandler.mail_from_raw_email(mail.parts[1].body.to_s)
bounced_mail.to.should == [ ir.incoming_email ]
bounced_mail.from.should == [ 'geraldinequango@localhost' ]
bounced_mail.body.include?("That's so totally a rubbish question").should be_true
@@ -160,7 +160,7 @@ describe RequestMailer, " when receiving incoming mail" do
deliveries = ActionMailer::Base.deliveries
deliveries.size.should == 1
mail = deliveries[0]
- mail.to.should == [ Configuration::contact_email ]
+ mail.to.should == [ AlaveteliConfiguration::contact_email ]
deliveries.clear
end
@@ -212,7 +212,9 @@ describe RequestMailer, "when sending reminders to requesters to classify a resp
:url_title => 'test_title',
:user => @mock_user)
InfoRequest.stub!(:find).and_return([@mock_request])
- RequestMailer.stub!(:deliver_new_response_reminder_alert)
+ mail_mock = mock("mail")
+ mail_mock.stub(:deliver)
+ RequestMailer.stub(:new_response_reminder_alert).and_return(mail_mock)
@sent_alert = mock_model(UserInfoRequestSentAlert, :user= =>nil,
:info_request= => nil,
:alert_type= => nil,
@@ -244,7 +246,7 @@ describe RequestMailer, "when sending reminders to requesters to classify a resp
query_params[:conditions].should == expected_conditions
query_params[:include].should == [ :user ]
query_params[:order].should == 'info_requests.id'
- end
+ end.and_return [@mock_request]
send_alerts
end
@@ -269,7 +271,7 @@ describe RequestMailer, "when sending reminders to requesters to classify a resp
end
it 'should not send the reminder' do
- RequestMailer.should_not_receive(:deliver_new_response_reminder_alert)
+ RequestMailer.should_not_receive(:new_response_reminder_alert)
send_alerts
end
@@ -293,7 +295,7 @@ describe RequestMailer, "when sending reminders to requesters to classify a resp
end
it 'should send the reminder' do
- RequestMailer.should_receive(:deliver_new_response_reminder_alert)
+ RequestMailer.should_receive(:new_response_reminder_alert)
send_alerts
end
end
@@ -311,7 +313,7 @@ describe RequestMailer, 'when sending mail when someone has updated an old uncla
:public_body => @public_body,
:display_status => 'Refused.',
:url_title => 'test_request')
- @mail = RequestMailer.create_old_unclassified_updated(@info_request)
+ @mail = RequestMailer.old_unclassified_updated(@info_request)
end
it 'should have the subject "Someone has updated the status of your request"' do
@@ -344,7 +346,7 @@ describe RequestMailer, 'when sending a new response email' do
end
it 'should not error when sending mails requests with characters requiring quoting in the subject' do
- @mail = RequestMailer.create_new_response(@info_request, @incoming_message)
+ @mail = RequestMailer.new_response(@info_request, @incoming_message)
end
end
@@ -362,13 +364,13 @@ describe RequestMailer, 'requires_admin' do
end
it 'body should contain the full admin URL' do
- mail = RequestMailer.deliver_requires_admin(@info_request)
+ mail = RequestMailer.requires_admin(@info_request).deliver
mail.body.should include('http://test.host/en/admin/request/show/123')
end
it "body should contain the message from the user" do
- mail = RequestMailer.deliver_requires_admin(@info_request, nil, "Something has gone wrong")
+ mail = RequestMailer.requires_admin(@info_request, nil, "Something has gone wrong").deliver
mail.body.should include 'Something has gone wrong'
end
diff --git a/spec/models/track_mailer_spec.rb b/spec/mailers/track_mailer_spec.rb
index 97f12b8f5..a3b849980 100644
--- a/spec/models/track_mailer_spec.rb
+++ b/spec/mailers/track_mailer_spec.rb
@@ -5,7 +5,9 @@ describe TrackMailer do
describe 'when sending email alerts for tracked things' do
before do
- TrackMailer.stub!(:deliver_event_digest)
+ mail_mock = mock("mail")
+ mail_mock.stub(:deliver)
+ TrackMailer.stub!(:event_digest).and_return(mail_mock)
Time.stub!(:now).and_return(Time.utc(2007, 11, 12, 23, 59))
end
@@ -79,21 +81,21 @@ describe TrackMailer do
sent_email = mock_model(TrackThingsSentEmail, :info_request_event_id => @found_event.id)
@track_things_sent_emails_array.stub!(:find).and_return([sent_email]) # this is for the date range find (created in last 14 days)
@xapian_search.stub!(:results).and_return([@search_result])
- TrackMailer.should_not_receive(:deliver_event_digest)
+ TrackMailer.should_not_receive(:event_digest)
TrackMailer.alert_tracks
end
it 'should not include in the email any events not sent in a previous tracking email that were described before the track was set up' do
@found_event.stub!(:described_at).and_return(@track_thing.created_at - 1.day)
@xapian_search.stub!(:results).and_return([@search_result])
- TrackMailer.should_not_receive(:deliver_event_digest)
+ TrackMailer.should_not_receive(:event_digest)
TrackMailer.alert_tracks
end
it 'should include in the email any events that the user has not been sent a tracking email on that have been described since the track was set up' do
@found_event.stub!(:described_at).and_return(@track_thing.created_at + 1.day)
@xapian_search.stub!(:results).and_return([@search_result])
- TrackMailer.should_receive(:deliver_event_digest)
+ TrackMailer.should_receive(:event_digest)
TrackMailer.alert_tracks
end
@@ -129,7 +131,7 @@ describe TrackMailer do
it 'should not ask for any daily track things for the user' do
expected_conditions = [ "tracking_user_id = ? and track_medium = ?", @user.id, 'email_daily' ]
- TrackThing.should_not_receive(:find).with(:all, :conditions => expected_conditions).and_return([])
+ TrackThing.should_not_receive(:find).with(:all, :conditions => expected_conditions)
TrackMailer.alert_tracks
end
@@ -137,7 +139,7 @@ describe TrackMailer do
@user.stub(:should_be_emailed?).and_return(true)
@user.stub(:receive_email_alerts).and_return(false)
expected_conditions = [ "tracking_user_id = ? and track_medium = ?", @user.id, 'email_daily' ]
- TrackThing.should_not_receive(:find).with(:all, :conditions => expected_conditions).and_return([])
+ TrackThing.should_not_receive(:find).with(:all, :conditions => expected_conditions)
TrackMailer.alert_tracks
end
@@ -169,7 +171,7 @@ describe TrackMailer do
:name_and_email => MailHandler.address_from_name_and_email('Tippy Test', 'tippy@localhost'),
:url_name => 'tippy_test'
)
- TrackMailer.deliver_event_digest(@user, []) # no items in it email for minimal test
+ TrackMailer.event_digest(@user, []).deliver # no items in it email for minimal test
end
it 'should deliver one email, with right headers' do
@@ -193,16 +195,16 @@ describe TrackMailer do
context "force ssl is off" do
# Force SSL is off in the tests. Since the code that selectively switches the protocols
# is in the initialiser for Rails it's hard to test. Hmmm...
- # We could Configuration.stub!(:force_ssl).and_return(true) but the config/environment.rb
- # wouldn't get reloaded
+ # We could AlaveteliConfiguration.stub!(:force_ssl).and_return(true) but the config/environment.rb
+ # wouldn't get reloaded
it "should have http links in the email" do
deliveries = ActionMailer::Base.deliveries
deliveries.size.should == 1
mail = deliveries[0]
-
- mail.body.should include("http://")
- mail.body.should_not include("https://")
+
+ mail.body.should include("http://")
+ mail.body.should_not include("https://")
end
end
end
diff --git a/spec/models/censor_rule_spec.rb b/spec/models/censor_rule_spec.rb
index c11b05a03..3782cc630 100644
--- a/spec/models/censor_rule_spec.rb
+++ b/spec/models/censor_rule_spec.rb
@@ -73,10 +73,10 @@ end
describe 'when validating rules' do
- describe 'should be invalid without text' do
+ it 'should be invalid without text' do
censor_rule = CensorRule.new
censor_rule.valid?.should == false
- censor_rule.errors.on(:text).should == "can't be blank"
+ censor_rule.errors[:text].should == ["can't be blank"]
end
describe 'when validating a regexp rule' do
@@ -96,7 +96,7 @@ describe 'when validating rules' do
it 'should add an error message to the text field with the regexp error message' do
Regexp.stub!(:new).and_raise(RegexpError.new("very bad regexp"))
@censor_rule.valid?.should == false
- @censor_rule.errors.on(:text).should == "very bad regexp"
+ @censor_rule.errors[:text].should == ["very bad regexp"]
end
end
@@ -106,7 +106,7 @@ describe 'when validating rules' do
it 'should not add any error message to the text field' do
Regexp.stub!(:new)
@censor_rule.valid?
- @censor_rule.errors.on(:text).should == nil
+ @censor_rule.errors[:text].should == []
end
end
@@ -134,15 +134,21 @@ describe 'when validating rules' do
it 'should not allow a global text censor rule (without user_id, request_id or public_body_id)' do
@censor_rule.valid?.should == false
- @expected_error = 'Censor must apply to an info request a user or a body; is invalid'
- @censor_rule.errors.full_messages.should == [@expected_error]
+
+ expected_error = ["Rule must apply to an info request, a user or a body"]
+ @censor_rule.errors[:user].should == expected_error
+ @censor_rule.errors[:info_request].should == expected_error
+ @censor_rule.errors[:public_body].should == expected_error
end
it 'should not allow a global regex censor rule (without user_id, request_id or public_body_id)' do
@censor_rule.regexp = true
@censor_rule.valid?.should == false
- @expected_error = 'Censor must apply to an info request a user or a body; is invalid'
- @censor_rule.errors.full_messages.should == [@expected_error]
+
+ expected_error = ["Rule must apply to an info request, a user or a body"]
+ @censor_rule.errors[:user].should == expected_error
+ @censor_rule.errors[:info_request].should == expected_error
+ @censor_rule.errors[:public_body].should == expected_error
end
end
diff --git a/spec/models/contact_mailer_spec.rb b/spec/models/contact_mailer_spec.rb
deleted file mode 100644
index 3af55ad77..000000000
--- a/spec/models/contact_mailer_spec.rb
+++ /dev/null
@@ -1,22 +0,0 @@
-require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
-
-describe ContactMailer, "when sending mail with a SafeBuffer name param (as when a suspended user
- sends a message)" do
- before do
-
- end
-
- it 'should set a "from" address correctly' do
- mail = ContactMailer.create_to_admin_message('test (account suspended)'.html_safe,
- 'test@example.com',
- 'Test subject',
- 'Test message',
- mock_model(User, :url_name => 'test_user'),
- mock_model(InfoRequest, :url_title => 'test_request'),
- mock_model(PublicBody, :url_name => 'test_public_body'))
- mail.from.should_not be_nil
- end
-
-end
-
-
diff --git a/spec/models/foi_attachment_spec.rb b/spec/models/foi_attachment_spec.rb
index 537a3363c..9b0115c44 100644
--- a/spec/models/foi_attachment_spec.rb
+++ b/spec/models/foi_attachment_spec.rb
@@ -1,6 +1,6 @@
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
-describe FoiAttachment, " when calculating due date" do
+describe FoiAttachment do
before(:each) do
load_raw_emails_data
diff --git a/spec/models/incoming_message_spec.rb b/spec/models/incoming_message_spec.rb
index f53a5856a..03152f5ff 100644
--- a/spec/models/incoming_message_spec.rb
+++ b/spec/models/incoming_message_spec.rb
@@ -27,7 +27,7 @@ describe IncomingMessage, " when dealing with incoming mail" do
end
it "should correctly fold various types of footer" do
- Dir.glob(File.join(Spec::Runner.configuration.fixture_path, "files", "email-folding-example-*.txt")).each do |file|
+ Dir.glob(File.join(RSpec.configuration.fixture_path, "files", "email-folding-example-*.txt")).each do |file|
message = File.read(file)
parsed = IncomingMessage.remove_quoted_sections(message)
expected = File.read("#{file}.expected")
@@ -59,12 +59,19 @@ describe IncomingMessage, " when dealing with incoming mail" do
message.subject.should == "Câmara Responde: Banco de ideias"
end
- it 'should not error on display of a message which has no charset set on the body part and
- is not good utf-8' do
+ it 'should deal with GB18030 text even if the charset is missing' do
ir = info_requests(:fancy_dog_request)
receive_incoming_mail('no-part-charset-bad-utf8.email', ir.incoming_email)
message = ir.incoming_messages[1]
message.parse_raw_email!
+ message.get_main_body_text_internal.should include("贵公司负责人")
+ end
+
+ it 'should not error on display of a message which has no charset set on the body part and is not good UTF-8' do
+ ir = info_requests(:fancy_dog_request)
+ receive_incoming_mail('no-part-charset-random-data.email', ir.incoming_email)
+ message = ir.incoming_messages[1]
+ message.parse_raw_email!
message.get_main_body_text_internal.should include("The above text was badly encoded")
end
@@ -353,7 +360,7 @@ describe IncomingMessage, " when censoring data" do
end
it "should apply hard-coded privacy rules to HTML files" do
- data = "http://#{Configuration::domain}/c/cheese"
+ data = "http://#{AlaveteliConfiguration::domain}/c/cheese"
@im.html_mask_stuff!(data)
data.should == "[WDTK login link]"
end
@@ -405,12 +412,24 @@ describe IncomingMessage, " when uudecoding bad messages" do
im.stub!(:mail).and_return(mail)
im.extract_attachments!
+ im.reload
attachments = im.foi_attachments
attachments.size.should == 2
attachments[1].filename.should == 'moo.txt'
im.get_attachments_for_display.size.should == 1
end
+ it "should still work when parsed from the raw email" do
+ raw_email = load_file_fixture 'inline-uuencode.email'
+ mail = MailHandler.mail_from_raw_email(raw_email)
+ im = incoming_messages :useless_incoming_message
+ im.stub!(:raw_email).and_return(raw_email)
+ im.stub!(:mail).and_return(mail)
+ im.parse_raw_email!
+ attachments = im.foi_attachments
+ attachments.size.should == 2
+ end
+
it "should apply censor rules" do
mail = get_fixture_mail('incoming-request-bad-uuencoding.email')
@@ -523,3 +542,46 @@ describe IncomingMessage, "when TNEF attachments are attached to messages" do
end
end
+describe IncomingMessage, "when extracting attachments" do
+
+ it 'handles the case where reparsing changes the body of the main part
+ and the cached attachment has been deleted' do
+ # original set of attachment attributes
+ attachment_attributes = { :url_part_number => 1,
+ :within_rfc822_subject => nil,
+ :content_type => "text/plain",
+ :charset => nil,
+ :body => "No way!\n",
+ :hexdigest => "0c8b1b0f5cb9c94ed15a180e73b5c7d1",
+ :filename => nil }
+
+ # Make a small change in the body returned for the attachment
+ new_attachment_attributes = attachment_attributes.merge(:body => "No way!",
+ :hexdigest => "74d2c0a41e074f9cebe49324d5b47414")
+
+
+ # Simulate parsing with the original attachments
+ MailHandler.stub!(:get_attachment_attributes).and_return([attachment_attributes])
+ incoming_message = incoming_messages(:useless_incoming_message)
+
+ # Extract the attachments
+ incoming_message.extract_attachments!
+
+ # delete the cached file for the main body part
+ main = incoming_message.get_main_body_text_part
+ main.delete_cached_file!
+
+ # Simulate reparsing with the slightly changed body
+ MailHandler.stub!(:get_attachment_attributes).and_return([new_attachment_attributes])
+
+ # Re-extract the attachments
+ incoming_message.extract_attachments!
+
+ attachments = incoming_message.foi_attachments
+ attachments.size.should == 1
+ attachments.first.hexdigest.should == "74d2c0a41e074f9cebe49324d5b47414"
+ attachments.first.body.should == 'No way!'
+ end
+
+end
+
diff --git a/spec/models/info_request_event_spec.rb b/spec/models/info_request_event_spec.rb
index 796f8b840..eb0de8c86 100644
--- a/spec/models/info_request_event_spec.rb
+++ b/spec/models/info_request_event_spec.rb
@@ -1,3 +1,4 @@
+# coding: utf-8
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
describe InfoRequestEvent do
@@ -21,7 +22,7 @@ describe InfoRequestEvent do
:event_type => 'sent',
:params => {})
event.should_receive(:xapian_mark_needs_index)
- event.run_callbacks(:after_save)
+ event.run_callbacks(:save)
end
end
@@ -118,6 +119,13 @@ describe InfoRequestEvent do
@info_request_event.same_email_as_previous_send?.should be_true
end
+ it 'should handle non-ascii characters in the name input' do
+ address = "\"Someone’s name\" <test@example.com>"
+ @info_request_event.stub!(:params).and_return(:email => address)
+ @info_request_event.stub_chain(:info_request, :get_previous_email_sent_to).and_return(address)
+ @info_request_event.same_email_as_previous_send?.should be_true
+ end
+
end
end
diff --git a/spec/models/info_request_spec.rb b/spec/models/info_request_spec.rb
index 728a538f9..3eb88b2bb 100644
--- a/spec/models/info_request_spec.rb
+++ b/spec/models/info_request_spec.rb
@@ -426,8 +426,8 @@ describe InfoRequest do
before do
Time.stub!(:now).and_return(Time.utc(2007, 11, 9, 23, 59))
- @mock_comment_event = safe_mock_model(InfoRequestEvent, :created_at => Time.now - 23.days, :event_type => 'comment', :response? => false)
- @mock_response_event = safe_mock_model(InfoRequestEvent, :created_at => Time.now - 22.days, :event_type => 'response', :response? => true)
+ @mock_comment_event = mock_model(InfoRequestEvent, :created_at => Time.now - 23.days, :event_type => 'comment', :response? => false)
+ @mock_response_event = mock_model(InfoRequestEvent, :created_at => Time.now - 22.days, :event_type => 'response', :response? => true)
@info_request = InfoRequest.new(:prominence => 'normal',
:awaiting_description => true,
:info_request_events => [@mock_response_event, @mock_comment_event])
@@ -457,16 +457,16 @@ describe InfoRequest do
describe 'when applying censor rules' do
before do
- @global_rule = safe_mock_model(CensorRule, :apply_to_text! => nil,
+ @global_rule = mock_model(CensorRule, :apply_to_text! => nil,
:apply_to_binary! => nil)
- @user_rule = safe_mock_model(CensorRule, :apply_to_text! => nil,
+ @user_rule = mock_model(CensorRule, :apply_to_text! => nil,
:apply_to_binary! => nil)
- @request_rule = safe_mock_model(CensorRule, :apply_to_text! => nil,
+ @request_rule = mock_model(CensorRule, :apply_to_text! => nil,
:apply_to_binary! => nil)
- @body_rule = safe_mock_model(CensorRule, :apply_to_text! => nil,
+ @body_rule = mock_model(CensorRule, :apply_to_text! => nil,
:apply_to_binary! => nil)
- @user = safe_mock_model(User, :censor_rules => [@user_rule])
- @body = safe_mock_model(PublicBody, :censor_rules => [@body_rule])
+ @user = mock_model(User, :censor_rules => [@user_rule])
+ @body = mock_model(PublicBody, :censor_rules => [@body_rule])
@info_request = InfoRequest.new(:prominence => 'normal',
:awaiting_description => true,
:title => 'title')
diff --git a/spec/models/mail_server_log_spec.rb b/spec/models/mail_server_log_spec.rb
index d0a1d202f..2b44a4559 100644
--- a/spec/models/mail_server_log_spec.rb
+++ b/spec/models/mail_server_log_spec.rb
@@ -3,7 +3,7 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
describe MailServerLog do
describe ".load_file" do
before :each do
- Configuration.stub!(:incoming_email_domain).and_return("example.com")
+ AlaveteliConfiguration.stub!(:incoming_email_domain).and_return("example.com")
File.stub_chain(:stat, :mtime).and_return(DateTime.new(2012, 10, 10))
end
@@ -64,8 +64,8 @@ describe MailServerLog do
describe ".email_addresses_on_line" do
before :each do
- Configuration.stub!(:incoming_email_domain).and_return("example.com")
- Configuration.stub!(:incoming_email_prefix).and_return("foi+")
+ AlaveteliConfiguration.stub!(:incoming_email_domain).and_return("example.com")
+ AlaveteliConfiguration.stub!(:incoming_email_prefix).and_return("foi+")
end
it "recognises a single incoming email" do
@@ -106,7 +106,7 @@ describe MailServerLog do
# Postfix logs for a single email go over multiple lines. They are all tied together with the Queue ID.
# See http://onlamp.com/onlamp/2004/01/22/postfix.html
it "loads the postfix log and untangles seperate email transactions using the queue ID" do
- Configuration.stub!(:incoming_email_domain).and_return("example.com")
+ AlaveteliConfiguration.stub!(:incoming_email_domain).and_return("example.com")
log.stub!(:rewind)
ir1 = info_requests(:fancy_dog_request)
ir2 = info_requests(:naughty_chicken_request)
@@ -135,7 +135,7 @@ describe MailServerLog do
describe ".scan_for_postfix_queue_ids" do
it "returns the queue ids of interest with the connected email addresses" do
- Configuration.stub!(:incoming_email_domain).and_return("example.com")
+ AlaveteliConfiguration.stub!(:incoming_email_domain).and_return("example.com")
MailServerLog.scan_for_postfix_queue_ids(log).should == {
"CB55836EE58C" => ["request-14-e0e09f97@example.com"],
"9634B16F7F7" => ["request-10-1234@example.com"]
diff --git a/spec/models/public_body_spec.rb b/spec/models/public_body_spec.rb
index 0b1bfccd7..bc693b4da 100644
--- a/spec/models/public_body_spec.rb
+++ b/spec/models/public_body_spec.rb
@@ -169,6 +169,14 @@ describe PublicBody, " when saving" do
@public_body.save!
@public_body.first_letter.should == 'T'
end
+
+ it "should save the name when renaming an existing public body" do
+ public_body = public_bodies(:geraldine_public_body)
+ public_body.name = "Mark's Public Body"
+ public_body.save!
+
+ public_body.name.should == "Mark's Public Body"
+ end
end
describe PublicBody, "when searching" do
diff --git a/spec/models/user_mailer_spec.rb b/spec/models/user_mailer_spec.rb
deleted file mode 100644
index 0792aaab2..000000000
--- a/spec/models/user_mailer_spec.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
-
-describe UserMailer, " when blah" do
- before do
- end
-end
-
-
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index 870e3efb8..96c169604 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -163,10 +163,10 @@ end
describe User, "when reindexing referencing models" do
before do
- @request_event = safe_mock_model(InfoRequestEvent, :xapian_mark_needs_index => true)
- @request = safe_mock_model(InfoRequest, :info_request_events => [@request_event])
- @comment_event = safe_mock_model(InfoRequestEvent, :xapian_mark_needs_index => true)
- @comment = safe_mock_model(Comment, :info_request_events => [@comment_event])
+ @request_event = mock_model(InfoRequestEvent, :xapian_mark_needs_index => true)
+ @request = mock_model(InfoRequest, :info_request_events => [@request_event])
+ @comment_event = mock_model(InfoRequestEvent, :xapian_mark_needs_index => true)
+ @comment = mock_model(Comment, :info_request_events => [@comment_event])
@user = User.new(:comments => [@comment], :info_requests => [@request])
end
diff --git a/spec/script/mailin_spec.rb b/spec/script/mailin_spec.rb
index acd06ff3b..46ad39f7f 100644
--- a/spec/script/mailin_spec.rb
+++ b/spec/script/mailin_spec.rb
@@ -32,6 +32,8 @@ describe "When importing mail into the application" do
ir = info_requests(:other_request)
incoming_message = ir.incoming_messages[0]
incoming_message.fully_destroy
+ # And get rid of any remaining purge requests
+ PurgeRequest.destroy_all
end
end
diff --git a/spec/spec.opts b/spec/spec.opts
deleted file mode 100644
index ff5051c37..000000000
--- a/spec/spec.opts
+++ /dev/null
@@ -1,3 +0,0 @@
---colour
---format
-specdoc
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index 33e39e6e4..57ab88da2 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -1,242 +1,141 @@
-require 'simplecov'
-require 'coveralls'
-
-# Generate coverage locally in html as well as in coveralls.io
-SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
- SimpleCov::Formatter::HTMLFormatter,
- Coveralls::SimpleCov::Formatter
-]
-SimpleCov.start('rails') do
- add_filter 'commonlib'
- add_filter 'vendor/plugins'
-end
-
-# This file is copied to ~/spec when you run 'ruby script/generate rspec'
-# from the project root directory.
-ENV["RAILS_ENV"] = 'test'
-require File.expand_path(File.join('..', '..', 'config', 'environment'), __FILE__)
-require 'spec/autorun'
-require 'spec/rails'
-
-# set a default username and password so we can test
-config = MySociety::Config.load_default()
-config['ADMIN_USERNAME'] = 'foo'
-config['ADMIN_PASSWORD'] = 'baz'
-
-# tests assume 20 days
-config['REPLY_LATE_AFTER_DAYS'] = 20
-
-# register a fake Varnish server
-require 'fakeweb'
-FakeWeb.register_uri(:purge, %r|varnish.localdomain|, :body => "OK")
-
-Webrat.configure do |config|
- config.mode = :rails
-end
-
-# Use test-specific translations
-FastGettext.add_text_domain 'app', :path => File.join(File.dirname(__FILE__), 'fixtures', 'locale'), :type => :po
-FastGettext.default_text_domain = 'app'
-Spec::Runner.configure do |config|
- # If you're not using ActiveRecord you should remove these
- # lines, delete config/database.yml and disable :active_record
- # in your config/boot.rb
-
- # 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
-
- # This section makes the garbage collector run less often to speed up tests
- last_gc_run = Time.now
-
- config.before(:each) do
- GC.disable
- end
-
- config.after(:each) do
- if Time.now - last_gc_run > 4
- GC.enable
- GC.start
- last_gc_run = Time.now
+require 'rubygems'
+require 'spork'
+#uncomment the following line to use spork with the debugger
+#require 'spork/ext/ruby-debug'
+
+Spork.prefork do
+ # Loading more in this block will cause your tests to run faster. However,
+ # if you change any configuration or code from libraries loaded here, you'll
+ # need to restart spork for it take effect.
+
+ # This file is copied to spec/ when you run 'rails generate rspec:install'
+ ENV["RAILS_ENV"] ||= 'test'
+ require File.expand_path("../../config/environment", __FILE__)
+ require 'rspec/rails'
+ require 'rspec/autorun'
+
+ # Requires supporting ruby files with custom matchers and macros, etc,
+ # in spec/support/ and its subdirectories.
+ Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
+
+ # Use test-specific translations
+ FastGettext.add_text_domain 'app', :path => File.join(File.dirname(__FILE__), 'fixtures', 'locale'), :type => :po
+ FastGettext.default_text_domain = 'app'
+
+ RSpec.configure do |config|
+ # ## Mock Framework
+ #
+ # If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
+ #
+ # config.mock_with :mocha
+ # config.mock_with :flexmock
+ # config.mock_with :rr
+
+ # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
+ config.fixture_path = "#{::Rails.root}/spec/fixtures"
+
+ # The order (!) of this is important thanks to foreign keys
+ 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,
+ :has_tag_string_tags,
+ :holidays
+
+ # If you're not using ActiveRecord, or you'd prefer not to run each of your
+ # examples within a transaction, remove the following line or assign false
+ # instead of true.
+ config.use_transactional_fixtures = true
+
+ # If true, the base class of anonymous controllers will be inferred
+ # automatically. This will be the default behavior in future versions of
+ # rspec-rails.
+ config.infer_base_class_for_anonymous_controllers = false
+
+ # Run specs in random order to surface order dependencies. If you find an
+ # order dependency and want to debug it, you can fix the order by providing
+ # the seed, which is printed after each run.
+ # --seed 1234
+ config.order = "random"
+
+ # This is a workaround for a strange thing where ActionMailer::Base.deliveries isn't being
+ # cleared out correctly in controller specs. So, do it here for everything.
+ config.before(:each) do
+ ActionMailer::Base.deliveries = []
end
- end
- # == Fixtures
- #
- # You can declare fixtures for each example_group like this:
- # describe "...." do
- # fixtures :table_a, :table_b
- #
- # Alternatively, if you prefer to declare them only once, you can
- # do so right here. Just uncomment the next line and replace the fixture
- # names with your fixtures.
- #
- # config.global_fixtures = :table_a, :table_b
- #
- # If you declare global fixtures, be aware that they will be declared
- # for all of your examples, even those that don't use them.
- #
- # You can also declare which fixtures to use (for example fixtures for test/fixtures):
- #
- # config.fixture_path = Rails.root + '/spec/fixtures/'
- #
- # == Mock Framework
- #
- # RSpec uses its own mocking framework by default. If you prefer to
- # use mocha, flexmock or RR, uncomment the appropriate line:
- #
- # config.mock_with :mocha
- # config.mock_with :flexmock
- # config.mock_with :rr
- #
- # == Notes
- #
- # For more information take a look at Spec::Runner::Configuration and Spec::Runner
-end
-
-# XXX No idea what namespace/class/module to put this in
-def receive_incoming_mail(email_name, email_to, email_from = 'geraldinequango@localhost')
- email_name = file_fixture_name(email_name)
- content = File.read(email_name)
- content.gsub!('EMAIL_TO', email_to)
- content.gsub!('EMAIL_FROM', email_from)
- RequestMailer.receive(content)
-end
-
-def file_fixture_name(file_name)
- return File.join(Spec::Runner.configuration.fixture_path, "files", file_name)
-end
+ # Any test that messes with the locale needs to restore the state afterwards so that it
+ # doesn't interfere with any subsequent tests. This is made more complicated by the
+ # ApplicationController#set_gettext_locale which sets the locale and so you may be setting
+ # the locale in your tests and not even realising it. So, let's make things easier for
+ # ourselves and just always restore the locale for all tests.
+ config.before(:each) do
+ @save_i18n_locale = I18n.locale
+ end
-def load_file_fixture(file_name, as_binary=false)
- file_name = file_fixture_name(file_name)
- content = File.open(file_name, 'r') do |file|
- if as_binary
- file.set_encoding(Encoding::BINARY) if file.respond_to?(:set_encoding)
- end
- file.read
+ config.after(:each) do
+ I18n.locale = @save_i18n_locale
end
- return content
-end
-def parse_all_incoming_messages
- IncomingMessage.find(:all).each{ |x| x.parse_raw_email! }
-end
+ # This section makes the garbage collector run less often to speed up tests
+ last_gc_run = Time.now
-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])
+ config.before(:each) do
+ GC.disable
end
-end
-# Rebuild the current xapian index
-def rebuild_xapian_index(terms = true, values = true, texts = true, dropfirst = true)
- if dropfirst
- begin
- ActsAsXapian.readable_init
- FileUtils.rm_r(ActsAsXapian.db_path)
- rescue RuntimeError
- end
- ActsAsXapian.writable_init
- ActsAsXapian.writable_db.close
+ config.after(:each) do
+ if Time.now - last_gc_run > 4
+ GC.enable
+ GC.start
+ last_gc_run = Time.now
+ end
end
- parse_all_incoming_messages
- # 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.
- models = [PublicBody, User, InfoRequestEvent]
- ActsAsXapian.rebuild_index(models, verbose=false, terms, values, texts, safe_rebuild=false)
-end
-
-# Create a clean xapian index based on the fixture files and the raw_email data.
-def create_fixtures_xapian_index
- load_raw_emails_data
- rebuild_xapian_index
-end
-
-def update_xapian_index
- ActsAsXapian.update_index(flush_to_disk=false, verbose=false)
-end
-
-# Copy the xapian index created in create_fixtures_xapian_index to a temporary
-# copy at the same level and point xapian at the copy
-def get_fixtures_xapian_index()
- # Create a base index for the fixtures if not already created
- $existing_xapian_db ||= create_fixtures_xapian_index
- # Store whatever the xapian db path is originally
- $original_xapian_path ||= ActsAsXapian.db_path
- path_array = $original_xapian_path.split(File::Separator)
- path_array.pop
- temp_path = File.join(path_array, 'test.temp')
- FileUtils.remove_entry_secure(temp_path, force=true)
- FileUtils.cp_r($original_xapian_path, temp_path)
- ActsAsXapian.db_path = temp_path
-end
-
-def basic_auth_login(request, username = nil, password = nil)
- username = Configuration::admin_username if username.nil?
- password = Configuration::admin_password if password.nil?
- request.env["HTTP_AUTHORIZATION"] = "Basic " + Base64::encode64("#{username}:#{password}")
-end
-
-# to_ary differs in Ruby 1.8 and 1.9
-# @see http://yehudakatz.com/2010/01/02/the-craziest-fing-bug-ive-ever-seen/
-def safe_mock_model(model, args = {})
- mock = mock_model(model, args)
- mock.should_receive(:to_ary).any_number_of_times
- mock
-end
-
-def get_fixture_mail(filename)
- MailHandler.mail_from_raw_email(load_file_fixture(filename))
-end
-
-def load_test_categories
- PublicBodyCategories.add(:en, [
- "Local and regional",
- [ "local_council", "Local councils", "a local council" ],
- "Miscellaneous",
- [ "other", "Miscellaneous", "miscellaneous" ],])
-end
+ end
+ # XXX No idea what namespace/class/module to put this in
+ # Create a clean xapian index based on the fixture files and the raw_email data.
+ def create_fixtures_xapian_index
+ load_raw_emails_data
+ rebuild_xapian_index
+ end
-# Monkeypatch applicationcontroller because the `render_to_string`
-# method in the original breaks all the rspec test assertions such as
-# `should render_template('foo')`. Same problem as
-# http://stackoverflow.com/questions/8174415/is-it-possible-to-assert-template-or-render-template-against-the-same-partial-wi
-# - a bug in either Rails or Rspec I don't have the time to fix :(
+ def with_env_tz(new_tz = 'US/Eastern')
+ old_tz, ENV['TZ'] = ENV['TZ'], new_tz
+ yield
+ ensure
+ old_tz ? ENV['TZ'] = old_tz : ENV.delete('TZ')
+ end
-class ApplicationController < ActionController::Base
- def set_popup_banner
- @popup_banner = nil
- end
-end
+ def with_active_record_default_timezone(zone)
+ old_zone, ActiveRecord::Base.default_timezone = ActiveRecord::Base.default_timezone, zone
+ yield
+ ensure
+ ActiveRecord::Base.default_timezone = old_zone
+ end
+ def load_test_categories
+ PublicBodyCategories.add(:en, [
+ "Local and regional",
+ [ "local_council", "Local councils", "a local council" ],
+ "Miscellaneous",
+ [ "other", "Miscellaneous", "miscellaneous" ],])
+ end
-def with_env_tz(new_tz = 'US/Eastern')
- old_tz, ENV['TZ'] = ENV['TZ'], new_tz
- yield
-ensure
- old_tz ? ENV['TZ'] = old_tz : ENV.delete('TZ')
+ def basic_auth_login(request, username = nil, password = nil)
+ username = AlaveteliConfiguration::admin_username if username.nil?
+ password = AlaveteliConfiguration::admin_password if password.nil?
+ request.env["HTTP_AUTHORIZATION"] = "Basic " + Base64::encode64("#{username}:#{password}")
+ end
end
-def with_active_record_default_timezone(zone)
- old_zone, ActiveRecord::Base.default_timezone = ActiveRecord::Base.default_timezone, zone
- yield
-ensure
- ActiveRecord::Base.default_timezone = old_zone
+Spork.each_run do
+ # This code will be run each time you run your specs.
end
diff --git a/spec/support/email_helpers.rb b/spec/support/email_helpers.rb
new file mode 100644
index 000000000..252b1f137
--- /dev/null
+++ b/spec/support/email_helpers.rb
@@ -0,0 +1,23 @@
+def load_raw_emails_data
+ raw_emails_yml = File.join(RSpec.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
+end
+
+def receive_incoming_mail(email_name, email_to, email_from = 'geraldinequango@localhost')
+ email_name = file_fixture_name(email_name)
+ content = File.open(email_name, 'rb') { |f| f.read }
+ content.gsub!('EMAIL_TO', email_to)
+ content.gsub!('EMAIL_FROM', email_from)
+ RequestMailer.receive(content)
+end
+
+def get_fixture_mail(filename)
+ MailHandler.mail_from_raw_email(load_file_fixture(filename))
+end
+
+def parse_all_incoming_messages
+ IncomingMessage.find(:all).each{ |x| x.parse_raw_email! }
+end
diff --git a/spec/support/load_file_fixtures.rb b/spec/support/load_file_fixtures.rb
new file mode 100644
index 000000000..a54505e99
--- /dev/null
+++ b/spec/support/load_file_fixtures.rb
@@ -0,0 +1,8 @@
+def file_fixture_name(file_name)
+ return File.join(RSpec.configuration.fixture_path, "files", file_name)
+end
+
+def load_file_fixture(file_name)
+ file_name = file_fixture_name(file_name)
+ return File.open(file_name, 'rb') { |f| f.read }
+end
diff --git a/spec/support/xapian_index.rb b/spec/support/xapian_index.rb
new file mode 100644
index 000000000..344c28ebb
--- /dev/null
+++ b/spec/support/xapian_index.rb
@@ -0,0 +1,42 @@
+# Rebuild the current xapian index
+def rebuild_xapian_index(terms = true, values = true, texts = true, dropfirst = true)
+ if dropfirst
+ begin
+ ActsAsXapian.readable_init
+ FileUtils.rm_r(ActsAsXapian.db_path)
+ rescue RuntimeError
+ end
+ ActsAsXapian.writable_init
+ ActsAsXapian.writable_db.close
+ end
+ parse_all_incoming_messages
+ # 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.
+ models = [PublicBody, User, InfoRequestEvent]
+ ActsAsXapian.rebuild_index(models, verbose=false, terms, values, texts, safe_rebuild=false)
+end
+
+def update_xapian_index
+ ActsAsXapian.update_index(flush_to_disk=false, verbose=false)
+end
+
+# Copy the xapian index created in create_fixtures_xapian_index to a temporary
+# copy at the same level and point xapian at the copy
+def get_fixtures_xapian_index()
+ # Create a base index for the fixtures if not already created
+ $existing_xapian_db ||= create_fixtures_xapian_index
+ # Store whatever the xapian db path is originally
+ $original_xapian_path ||= ActsAsXapian.db_path
+ path_array = $original_xapian_path.split(File::Separator)
+ path_array.pop
+ temp_path = File.join(path_array, 'test.temp')
+ FileUtils.remove_entry_secure(temp_path, force=true)
+ FileUtils.cp_r($original_xapian_path, temp_path)
+ ActsAsXapian.db_path = temp_path
+end
+
+# Create a clean xapian index based on the fixture files and the raw_email data.
+def create_fixtures_xapian_index
+ load_raw_emails_data
+ rebuild_xapian_index
+end
diff --git a/spec/views/public_body/show.rhtml_spec.rb b/spec/views/public_body/show.html.erb_spec.rb
index 23e92dedd..0559fc8ef 100644
--- a/spec/views/public_body/show.rhtml_spec.rb
+++ b/spec/views/public_body/show.html.erb_spec.rb
@@ -1,6 +1,6 @@
require File.expand_path(File.join('..', '..', '..', 'spec_helper'), __FILE__)
-describe "when viewing a body" do
+describe "public_body/show" do
before do
@pb = mock_model(PublicBody,
:name => 'Test Quango',
@@ -17,59 +17,57 @@ describe "when viewing a body" do
@pb.stub!(:is_requestable?).and_return(true)
@pb.stub!(:has_notes?).and_return(false)
@pb.stub!(:has_tag?).and_return(false)
- @xap = mock_model(ActsAsXapian::Search, :matches_estimated => 2)
+ @xap = mock(ActsAsXapian::Search, :matches_estimated => 2)
@xap.stub!(:results).and_return([
{ :model => mock_event },
{ :model => mock_event }
])
- assigns[:public_body] = @pb
- assigns[:track_thing] = mock_model(TrackThing,
- :track_type => 'public_body_updates', :public_body => @pb, :params => {})
- assigns[:xapian_requests] = @xap
- assigns[:page] = 1
- assigns[:per_page] = 10
- # work round a bug in ActionController::TestRequest; allows request.query_string to work in the template
- request.env["REQUEST_URI"] = ""
+ assign(:public_body, @pb)
+ assign(:track_thing, mock_model(TrackThing,
+ :track_type => 'public_body_updates', :public_body => @pb, :params => {}))
+ assign(:xapian_requests, @xap)
+ assign(:page, 1)
+ assign(:per_page, 10)
end
it "should be successful" do
- render "public_body/show"
- response.should be_success
+ render
+ controller.response.should be_success
end
it "should show the body's name" do
- render "public_body/show"
- response.should have_tag("h1", "Test Quango")
+ render
+ response.should have_selector('h1', :content => "Test Quango")
end
it "should tell total number of requests" do
- render "public_body/show"
- response.should include_text("4 Freedom of Information requests")
+ render
+ response.should match "4 Freedom of Information requests"
end
it "should cope with no results" do
@pb.stub!(:info_requests).and_return([])
- render "public_body/show"
- response.should have_tag("p", /Nobody has made any Freedom of Information requests/m)
+ render
+ response.should have_selector('p', :content => "Nobody has made any Freedom of Information requests")
end
it "should cope with Xapian being down" do
- assigns[:xapian_requests] = nil
- render "public_body/show"
- response.should have_tag("p", /The search index is currently offline/m)
+ assign(:xapian_requests, nil)
+ render
+ response.should match "The search index is currently offline"
end
it "should link to Charity Commission site if we have numbers to do so" do
@pb.stub!(:has_tag?).and_return(true)
@pb.stub!(:get_tag_values).and_return(['98765', '12345'])
- render "public_body/show"
- response.should have_tag("div#header_right") do
- with_tag("a[href*=?]", /charity-commission.gov.uk.*RegisteredCharityNumber=98765$/)
+ render
+ response.should have_selector("div#header_right") do
+ have_selector "a", :href => /charity-commission.gov.uk.*RegisteredCharityNumber=98765$/
end
- response.should have_tag("div#header_right") do
- with_tag("a[href*=?]", /charity-commission.gov.uk.*RegisteredCharityNumber=12345$/)
+ response.should have_selector("div#header_right") do
+ have_selector "a", :href => /www.charity-commission.gov.uk.*RegisteredCharityNumber=12345$/
end
end
@@ -77,17 +75,17 @@ describe "when viewing a body" do
@pb.stub!(:has_tag?).and_return(true)
@pb.stub!(:get_tag_values).and_return(['SC1234'])
- render "public_body/show"
- response.should have_tag("div#header_right") do
- with_tag("a[href*=?]", /www.oscr.org.uk.*id=SC1234$/)
+ render
+ response.should have_selector("div#header_right") do
+ have_selector "a", :href => /www.oscr.org.uk.*id=SC1234$/
end
end
it "should not link to Charity Commission site if we don't have number" do
- render "public_body/show"
- response.should have_tag("div#header_right") do
- without_tag("a[href*=?]", /charity-commission.gov.uk/)
+ render
+ response.should have_selector("div#header_right") do
+ have_selector "a", :href => /charity-commission.gov.uk/
end
end
diff --git a/spec/views/request/_after_actions.rhtml_spec.rb b/spec/views/request/_after_actions.html.erb_spec.rb
index 548990c9f..ae398f4ce 100644
--- a/spec/views/request/_after_actions.rhtml_spec.rb
+++ b/spec/views/request/_after_actions.html.erb_spec.rb
@@ -15,51 +15,27 @@ describe 'when displaying actions that can be taken with regard to a request' do
:comments_allowed? => true,
:url_title => 'test_request',
:all_can_view? => true)
- assigns[:info_request] = @mock_request
- end
-
- def do_render
- render :partial => 'request/after_actions'
- end
-
- def expect_owner_div
- do_render
- response.should have_tag('div#owner_actions'){ yield }
- end
-
- def expect_anyone_div
- do_render
- response.should have_tag('div#anyone_actions'){ yield }
- end
-
- def expect_owner_link(text)
- expect_owner_div{ with_tag('a', :text => text) }
- end
-
- def expect_no_owner_link(text)
- expect_owner_div{ without_tag('a', :text => text) }
- end
-
- def expect_anyone_link(text)
- expect_anyone_div{ with_tag('a', :text => text) }
- end
-
- def expect_no_anyone_link(text)
- expect_anyone_div{ without_tag('a', :text => text) }
+ assign :info_request, @mock_request
end
describe 'if the request is old and unclassified' do
before do
- assigns[:old_unclassified] = true
+ assign :old_unclassified, true
end
it 'should not display a link for the request owner to update the status of the request' do
- expect_no_owner_link('Update the status of this request')
+ render :partial => 'request/after_actions'
+ response.should have_selector('div#owner_actions') do |div|
+ div.should_not have_selector('a', :content => 'Update the status of this request')
+ end
end
it 'should display a link for anyone to update the status of the request' do
- expect_anyone_link('Update the status of this request')
+ render :partial => 'request/after_actions'
+ response.should have_selector('div#anyone_actions') do |div|
+ div.should have_selector('a', :content => 'Update the status of this request')
+ end
end
end
@@ -67,27 +43,39 @@ describe 'when displaying actions that can be taken with regard to a request' do
describe 'if the request is not old and unclassified' do
before do
- assigns[:old_unclassified] = false
+ assign :old_unclassified, false
end
it 'should display a link for the request owner to update the status of the request' do
- expect_owner_link('Update the status of this request')
+ render :partial => 'request/after_actions'
+ response.should have_selector('div#owner_actions') do |div|
+ div.should have_selector('a', :content => 'Update the status of this request')
+ end
end
it 'should not display a link for anyone to update the status of the request' do
- expect_no_anyone_link('Update the status of this request')
+ render :partial => 'request/after_actions'
+ response.should have_selector('div#anyone_actions') do |div|
+ div.should_not have_selector('a', :content => 'Update the status of this request')
+ end
end
end
it 'should display a link for the request owner to request a review' do
- expect_owner_link('Request an internal review')
+ render :partial => 'request/after_actions'
+ response.should have_selector('div#owner_actions') do |div|
+ div.should have_selector('a', :content => 'Request an internal review')
+ end
end
describe 'if the request is viewable by all' do
it 'should display the link to download the entire request' do
- expect_anyone_link('Download a zip file of all correspondence')
+ render :partial => 'request/after_actions'
+ response.should have_selector('div#anyone_actions') do |div|
+ div.should have_selector('a', :content => 'Download a zip file of all correspondence')
+ end
end
end
@@ -95,7 +83,10 @@ describe 'when displaying actions that can be taken with regard to a request' do
it 'should not display the link to download the entire request' do
@mock_request.stub!(:all_can_view?).and_return(false)
- expect_no_anyone_link('Download a zip file of all correspondence')
+ render :partial => 'request/after_actions'
+ response.should have_selector('div#anyone_actions') do |div|
+ div.should_not have_selector('a', :content => 'Download a zip file of all correspondence')
+ end
end
end
diff --git a/spec/views/request/_describe_state.rhtml_spec.rb b/spec/views/request/_describe_state.html.erb_spec.rb
index 18778d5d2..88dea53c5 100644
--- a/spec/views/request/_describe_state.rhtml_spec.rb
+++ b/spec/views/request/_describe_state.html.erb_spec.rb
@@ -4,12 +4,12 @@ describe 'when showing the form for describing the state of a request' do
def expect_radio_button(value)
do_render
- response.should have_tag("input[type=radio][value=#{value}]")
+ response.should have_selector('input', :type => 'radio', :value => value)
end
def expect_no_radio_button(value)
do_render
- response.should_not have_tag("input[type=radio][value=#{value}]")
+ response.should_not have_selector('input', :type => 'radio', :value => value)
end
def do_render
@@ -24,25 +24,25 @@ describe 'when showing the form for describing the state of a request' do
:user_name => @mock_user.name,
:is_external? => false
)
- assigns[:info_request] = @mock_request
+ assign :info_request, @mock_request
end
describe 'if the user is a regular user (not the request owner)' do
before do
- assigns[:is_owning_user] = false
+ assign :is_owning_user, false
end
describe 'if the request is not old and unclassified' do
it 'should not show the form' do
do_render
- response.should_not have_tag('h2', :text => 'What best describes the status of this request now?')
+ response.should_not have_selector('h2', :content => 'What best describes the status of this request now?')
end
it 'should give a link to login' do
do_render
- response.should have_tag('a', :text => 'sign in')
+ response.should have_selector('a', :content => 'sign in')
end
end
@@ -50,22 +50,22 @@ describe 'when showing the form for describing the state of a request' do
describe 'if the request is old and unclassified' do
before do
- assigns[:old_unclassified] = true
+ assign :old_unclassified, true
end
it 'should not show the form' do
do_render
- response.should_not have_tag('h2', :text => 'What best describes the status of this request now?')
+ response.should_not have_selector('h2', :content => 'What best describes the status of this request now?')
end
it 'should show the form for someone else to classify the request' do
do_render
- response.should have_tag('h2', :text => /We need your help/)
+ response.should have_selector('h2', :content => 'We need your help')
end
it 'should not give a link to login' do
do_render
- response.should_not have_tag('a', :text => 'sign in')
+ response.should_not have_selector('a', :content => 'sign in')
end
end
@@ -74,7 +74,7 @@ describe 'when showing the form for describing the state of a request' do
describe 'if showing the form to the user owning the request' do
before do
- assigns[:is_owning_user] = true
+ assign :is_owning_user, true
end
describe 'when the request is not in internal review' do
@@ -100,7 +100,7 @@ describe 'when showing the form for describing the state of a request' do
describe 'when the user has asked to update the status of the request' do
before do
- assigns[:update_status] = true
+ assign :update_status, true
end
it 'should show a radio button to set the status to "internal_review"' do
@@ -129,7 +129,7 @@ describe 'when showing the form for describing the state of a request' do
it 'should show the text "The review has finished and overall:"' do
do_render
- response.should have_tag('p', :text => 'The review has finished and overall:')
+ response.should have_selector('p', :content => 'The review has finished and overall:')
end
end
@@ -170,4 +170,4 @@ describe 'when showing the form for describing the state of a request' do
end
end
-end \ No newline at end of file
+end
diff --git a/spec/views/request/list.rhtml_spec.rb b/spec/views/request/list.html.erb_spec.rb
index 137bc359d..521d946bc 100644
--- a/spec/views/request/list.rhtml_spec.rb
+++ b/spec/views/request/list.html.erb_spec.rb
@@ -1,12 +1,10 @@
require File.expand_path(File.join('..', '..', '..', 'spec_helper'), __FILE__)
-describe "when listing recent requests" do
+describe "request/list" do
before do
- assigns[:page] = 1
- assigns[:per_page] = 10
- # work round a bug in ActionController::TestRequest; allows request.query_string to work in the template
- request.env["REQUEST_URI"] = ""
+ assign :page, 1
+ assign :per_page, 10
end
def make_mock_event
@@ -30,21 +28,21 @@ describe "when listing recent requests" do
end
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)
+ assign :list_results, [ make_mock_event, make_mock_event ]
+ assign :matches_estimated, 2
+ assign :show_no_more_than, 100
+ render
+ response.should have_selector("div.request_listing")
+ response.should_not have_selector("p", :content => "No requests of this sort yet")
end
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")
+ assign :list_results, [ ]
+ assign :matches_estimated, 0
+ assign :show_no_more_than, 0
+ render
+ response.should have_selector("p", :content => "No requests of this sort yet")
+ response.should_not have_selector("div.request_listing")
end
end
diff --git a/spec/views/request/show.rhtml_spec.rb b/spec/views/request/show.html.erb_spec.rb
index a22f29951..4578268b2 100644
--- a/spec/views/request/show.rhtml_spec.rb
+++ b/spec/views/request/show.html.erb_spec.rb
@@ -1,6 +1,6 @@
require File.expand_path(File.join('..', '..', '..', 'spec_helper'), __FILE__)
-describe 'when viewing an information request' do
+describe 'request/show' do
before do
@mock_body = mock_model(PublicBody, :name => 'test body',
@@ -19,36 +19,28 @@ describe 'when viewing an information request' do
:is_external? => false,
:calculate_status => 'waiting_response',
:date_response_required_by => Date.today,
- :prominence => 'normal')
+ :prominence => 'normal',
+ :comments_allowed? => true,
+ :all_can_view? => true,
+ :url_title => 'test_request')
end
def request_page
- assigns[:info_request] = @mock_request
- assigns[:info_request_events] = []
- assigns[:status] = @mock_request.calculate_status
- template.stub!(:render_partial)
- render 'request/show'
- end
-
- it 'should show the sidebar' do
- template.should_receive(:render_partial).with(:partial => 'sidebar', :locals => {})
- request_page
- end
-
- it 'should show the actions people can take' do
- template.should_receive(:render_partial).with(:partial => 'after_actions', :locals => {})
- request_page
+ assign :info_request, @mock_request
+ assign :info_request_events, []
+ assign :status, @mock_request.calculate_status
+ render
end
describe 'when a status update has been requested' do
before do
- assigns[:update_status] = true
+ assign :update_status, true
end
it 'should show the first form for describing the state of the request' do
request_page
- response.should have_tag("div.describe_state_form#describe_state_form_1")
+ response.should have_selector("div.describe_state_form#describe_state_form_1")
end
end
@@ -61,12 +53,12 @@ describe 'when viewing an information request' do
it 'should show the first form for describing the state of the request' do
request_page
- response.should have_tag("div.describe_state_form#describe_state_form_1")
+ response.should have_selector("div.describe_state_form#describe_state_form_1")
end
it 'should show the second form for describing the state of the request' do
request_page
- response.should have_tag("div.describe_state_form#describe_state_form_2")
+ response.should have_selector("div.describe_state_form#describe_state_form_2")
end
end
@@ -74,7 +66,7 @@ describe 'when viewing an information request' do
describe 'when the user is the request owner' do
before do
- assigns[:is_owning_user] = true
+ assign :is_owning_user, true
end
describe 'when the request status is "waiting clarification"' do
@@ -88,18 +80,13 @@ describe 'when viewing an information request' do
before do
@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
- expected_url = "/request/#{@mock_request.id}/response/#{@mock_response.id}#followup"
- response.should have_tag("a[href=#{expected_url}]", :text => 'send a follow up message')
+ expected_url = "/en/request/#{@mock_request.id}/response/#{@mock_response.id}#followup"
+ response.should have_selector("a", :href => expected_url, :content => 'send a follow up message')
end
end
@@ -108,18 +95,13 @@ describe 'when viewing an information request' do
before do
@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
- expected_url = "/request/#{@mock_request.id}/response#followup"
- response.should have_tag("a[href=#{expected_url}]", :text => 'send a follow up message')
+ expected_url = "/en/request/#{@mock_request.id}/response#followup"
+ response.should have_selector("a", :href => expected_url, :content => 'send a follow up message')
end
end
end
diff --git a/spec/views/request_game/play.rhtml_spec.rb b/spec/views/request_game/play.html.erb_spec.rb
index 24fb6d75d..b5cf57c23 100644
--- a/spec/views/request_game/play.rhtml_spec.rb
+++ b/spec/views/request_game/play.html.erb_spec.rb
@@ -1,6 +1,6 @@
require File.expand_path(File.join('..', '..', '..', 'spec_helper'), __FILE__)
-describe 'when viewing the request game' do
+describe 'request_game/play' do
before do
@mock_body = mock_model(PublicBody, :name => 'test body',
@@ -22,15 +22,15 @@ describe 'when viewing the request game' do
:initial_request_text => 'hi there',
:display_status => 'Awaiting categorisation',
:created_at => Time.now)
- assigns[:league_table_28_days] = []
- assigns[:league_table_all_time] = []
- assigns[:requests] = [@mock_request]
- assigns[:play_urls] = true
+ assign :league_table_28_days, []
+ assign :league_table_all_time, []
+ assign :requests, [@mock_request]
+ assign :play_urls, true
end
it 'should show the correct url for a request' do
- render "request_game/play"
- response.should include_text("/categorise/request/a_test_request")
+ render
+ response.should include("/categorise/request/a_test_request")
end
diff --git a/vendor/plugins/active_record_base_without_table/CHANGELOG b/vendor/plugins/active_record_base_without_table/CHANGELOG
deleted file mode 100644
index c74809532..000000000
--- a/vendor/plugins/active_record_base_without_table/CHANGELOG
+++ /dev/null
@@ -1,3 +0,0 @@
-[27 April 2007]
-
-* Correctly cache class instance variables containing column information [Reported by Nils Jonsson]
diff --git a/vendor/plugins/active_record_base_without_table/MIT-LICENSE b/vendor/plugins/active_record_base_without_table/MIT-LICENSE
deleted file mode 100644
index 602bda208..000000000
--- a/vendor/plugins/active_record_base_without_table/MIT-LICENSE
+++ /dev/null
@@ -1,20 +0,0 @@
-Copyright (c) 2006 Jonathan Viney
-
-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/plugins/active_record_base_without_table/README b/vendor/plugins/active_record_base_without_table/README
deleted file mode 100644
index 8200d7ad6..000000000
--- a/vendor/plugins/active_record_base_without_table/README
+++ /dev/null
@@ -1,29 +0,0 @@
-= ActiveRecordBaseWithoutTable
-
-If you find this plugin useful, please consider a donation to show your support!
-
- http://www.paypal.com/cgi-bin/webscr?cmd=_send-money
-
- Email address: jonathan.viney@gmail.com
-
-== Instructions
-
-* For edge Rails r7315 or above use http://svn.viney.net.nz/things/branches/active_record_base_without_table
-
-Get the power of ActiveRecord models, including validation, without having a table in the database.
-
- class Contact < ActiveRecord::BaseWithoutTable
- column :name, :string
- column :email_address, :string
- column :message, :text
-
- validates_presence_of :name, :email_address, :string
- end
-
-This model can be used just like a regular model based on a table, except it will never be saved to the database.
-
-There is a good blog post available on the plugin:
-
- http://www.kangarooit.com/developer_blog/2007/02/email-form-validation-in-ruby-on-rails.php
-
-Any bugs, questions, comments please feel free to email me: jonathan.viney@gmail.com
diff --git a/vendor/plugins/active_record_base_without_table/Rakefile b/vendor/plugins/active_record_base_without_table/Rakefile
deleted file mode 100644
index ac9244515..000000000
--- a/vendor/plugins/active_record_base_without_table/Rakefile
+++ /dev/null
@@ -1,22 +0,0 @@
-require 'rake'
-require 'rake/testtask'
-require 'rake/rdoctask'
-
-desc 'Default: run unit tests.'
-task :default => :test
-
-desc 'Test the active_record_base_without_table plugin.'
-Rake::TestTask.new(:test) do |t|
- t.libs << 'lib'
- t.pattern = 'test/**/*_test.rb'
- t.verbose = true
-end
-
-desc 'Generate documentation for the active_record_base_without_table plugin.'
-Rake::RDocTask.new(:rdoc) do |rdoc|
- rdoc.rdoc_dir = 'rdoc'
- rdoc.title = 'ActiveRecordBaseWithoutTable'
- rdoc.options << '--line-numbers' << '--inline-source'
- rdoc.rdoc_files.include('README')
- rdoc.rdoc_files.include('lib/**/*.rb')
-end
diff --git a/vendor/plugins/active_record_base_without_table/lib/active_record/base_without_table.rb b/vendor/plugins/active_record_base_without_table/lib/active_record/base_without_table.rb
deleted file mode 100644
index 12cb05e02..000000000
--- a/vendor/plugins/active_record_base_without_table/lib/active_record/base_without_table.rb
+++ /dev/null
@@ -1,26 +0,0 @@
-module ActiveRecord
- class BaseWithoutTable < Base
- self.abstract_class = true
-
- def create_or_update
- errors.empty?
- end
-
- class << self
- def columns()
- @columns ||= []
- end
-
- def column(name, sql_type = nil, default = nil, null = true)
- columns << ActiveRecord::ConnectionAdapters::Column.new(name.to_s, default, sql_type.to_s, null)
- reset_column_information
- end
-
- # Do not reset @columns
- def reset_column_information
- generated_methods.each { |name| undef_method(name) }
- @column_names = @columns_hash = @content_columns = @dynamic_methods_hash = @read_methods = nil
- end
- end
- end
-end
diff --git a/vendor/plugins/active_record_base_without_table/test/abstract_unit.rb b/vendor/plugins/active_record_base_without_table/test/abstract_unit.rb
deleted file mode 100644
index f72a8785b..000000000
--- a/vendor/plugins/active_record_base_without_table/test/abstract_unit.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-require 'test/unit'
-
-begin
- require File.dirname(__FILE__) + '/../../../../config/boot'
- require 'active_record'
-rescue LoadError
- require 'rubygems'
- require_gem 'activerecord'
-end
-
-require File.dirname(__FILE__) + '/../lib/active_record/base_without_table'
-
-config = YAML::load(IO.read(File.dirname(__FILE__) + '/database.yml'))
-ActiveRecord::Base.logger = Logger.new(File.dirname(__FILE__) + '/debug.log')
-ActiveRecord::Base.establish_connection(config[ENV['DB'] || 'mysql'])
diff --git a/vendor/plugins/active_record_base_without_table/test/active_record_base_without_table_test.rb b/vendor/plugins/active_record_base_without_table/test/active_record_base_without_table_test.rb
deleted file mode 100644
index 8d4bd4115..000000000
--- a/vendor/plugins/active_record_base_without_table/test/active_record_base_without_table_test.rb
+++ /dev/null
@@ -1,41 +0,0 @@
-require File.dirname(__FILE__) + '/abstract_unit'
-
-class Person < ActiveRecord::BaseWithoutTable
- column :name, :string
- column :lucky_number, :integer, 4
-
- validates_presence_of :name
-end
-
-class ActiveRecordBaseWithoutTableTest < Test::Unit::TestCase
- def test_default_value
- assert_equal 4, Person.new.lucky_number
- end
-
- def test_validation
- p = Person.new
-
- assert !p.save
- assert p.errors[:name]
-
- assert p.update_attributes(:name => 'Name')
- end
-
- def test_typecast
- assert_equal 1, Person.new(:lucky_number => "1").lucky_number
- end
-
- def test_cached_column_variables_reset_when_column_defined
- cached_variables = %w(column_names columns_hash content_columns dynamic_methods_hash read_methods)
-
- Person.column_names
- Person.columns_hash
- Person.content_columns
- Person.column_methods_hash
- Person.read_methods
-
- cached_variables.each { |v| assert_not_nil Person.instance_variable_get("@#{v}") }
- Person.column :new_column, :string
- cached_variables.each { |v| assert_nil Person.instance_variable_get("@#{v}") }
- end
-end
diff --git a/vendor/plugins/active_record_base_without_table/test/database.yml b/vendor/plugins/active_record_base_without_table/test/database.yml
deleted file mode 100644
index b952dac55..000000000
--- a/vendor/plugins/active_record_base_without_table/test/database.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-mysql:
- :adapter: mysql
- :host: localhost
- :username: rails
- :password:
- :database: rails_plugin_test
diff --git a/vendor/plugins/acts_as_versioned/CHANGELOG b/vendor/plugins/acts_as_versioned/CHANGELOG
deleted file mode 100644
index 01882d767..000000000
--- a/vendor/plugins/acts_as_versioned/CHANGELOG
+++ /dev/null
@@ -1,82 +0,0 @@
-*GIT* (version numbers are overrated)
-
-* (16 Jun 2008) Backwards Compatibility is overrated (big updates for rails 2.1)
-
- * Use ActiveRecord 2.1's dirty attribute checking instead [Asa Calow]
- * Remove last traces of #non_versioned_fields
- * Remove AR::Base.find_version and AR::Base.find_versions, rely on AR association proxies and named_scope
- * Remove #versions_count, rely on AR association counter caching.
- * Remove #versioned_attributes, basically the same as AR::Base.versioned_columns
-
-* (5 Oct 2006) Allow customization of #versions association options [Dan Peterson]
-
-*0.5.1*
-
-* (8 Aug 2006) Versioned models now belong to the unversioned model. @article_version.article.class => Article [Aslak Hellesoy]
-
-*0.5* # do versions even matter for plugins?
-
-* (21 Apr 2006) Added without_locking and without_revision methods.
-
- Foo.without_revision do
- @foo.update_attributes ...
- end
-
-*0.4*
-
-* (28 March 2006) Rename non_versioned_fields to non_versioned_columns (old one is kept for compatibility).
-* (28 March 2006) Made explicit documentation note that string column names are required for non_versioned_columns.
-
-*0.3.1*
-
-* (7 Jan 2006) explicitly set :foreign_key option for the versioned model's belongs_to assocation for STI [Caged]
-* (7 Jan 2006) added tests to prove has_many :through joins work
-
-*0.3*
-
-* (2 Jan 2006) added ability to share a mixin with versioned class
-* (2 Jan 2006) changed the dynamic version model to MyModel::Version
-
-*0.2.4*
-
-* (27 Nov 2005) added note about possible destructive behavior of if_changed? [Michael Schuerig]
-
-*0.2.3*
-
-* (12 Nov 2005) fixed bug with old behavior of #blank? [Michael Schuerig]
-* (12 Nov 2005) updated tests to use ActiveRecord Schema
-
-*0.2.2*
-
-* (3 Nov 2005) added documentation note to #acts_as_versioned [Martin Jul]
-
-*0.2.1*
-
-* (6 Oct 2005) renamed dirty? to changed? to keep it uniform. it was aliased to keep it backwards compatible.
-
-*0.2*
-
-* (6 Oct 2005) added find_versions and find_version class methods.
-
-* (6 Oct 2005) removed transaction from create_versioned_table().
- this way you can specify your own transaction around a group of operations.
-
-* (30 Sep 2005) fixed bug where find_versions() would order by 'version' twice. (found by Joe Clark)
-
-* (26 Sep 2005) added :sequence_name option to acts_as_versioned to set the sequence name on the versioned model
-
-*0.1.3* (18 Sep 2005)
-
-* First RubyForge release
-
-*0.1.2*
-
-* check if module is already included when acts_as_versioned is called
-
-*0.1.1*
-
-* Adding tests and rdocs
-
-*0.1*
-
-* Initial transfer from Rails ticket: http://dev.rubyonrails.com/ticket/1974 \ No newline at end of file
diff --git a/vendor/plugins/acts_as_versioned/MIT-LICENSE b/vendor/plugins/acts_as_versioned/MIT-LICENSE
deleted file mode 100644
index 5851fdae1..000000000
--- a/vendor/plugins/acts_as_versioned/MIT-LICENSE
+++ /dev/null
@@ -1,20 +0,0 @@
-Copyright (c) 2005 Rick Olson
-
-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. \ No newline at end of file
diff --git a/vendor/plugins/acts_as_versioned/README b/vendor/plugins/acts_as_versioned/README
deleted file mode 100644
index 8961f0522..000000000
--- a/vendor/plugins/acts_as_versioned/README
+++ /dev/null
@@ -1,28 +0,0 @@
-= acts_as_versioned
-
-This library adds simple versioning to an ActiveRecord module. ActiveRecord is required.
-
-== Resources
-
-Install
-
-* gem install acts_as_versioned
-
-Rubyforge project
-
-* http://rubyforge.org/projects/ar-versioned
-
-RDocs
-
-* http://ar-versioned.rubyforge.org
-
-Subversion
-
-* http://techno-weenie.net/svn/projects/acts_as_versioned
-
-Collaboa
-
-* http://collaboa.techno-weenie.net/repository/browse/acts_as_versioned
-
-Special thanks to Dreamer on ##rubyonrails for help in early testing. His ServerSideWiki (http://serversidewiki.com)
-was the first project to use acts_as_versioned <em>in the wild</em>. \ No newline at end of file
diff --git a/vendor/plugins/acts_as_versioned/RUNNING_UNIT_TESTS b/vendor/plugins/acts_as_versioned/RUNNING_UNIT_TESTS
deleted file mode 100644
index a6e55b841..000000000
--- a/vendor/plugins/acts_as_versioned/RUNNING_UNIT_TESTS
+++ /dev/null
@@ -1,41 +0,0 @@
-== Creating the test database
-
-The default name for the test databases is "activerecord_versioned". If you
-want to use another database name then be sure to update the connection
-adapter setups you want to test with in test/connections/<your database>/connection.rb.
-When you have the database online, you can import the fixture tables with
-the test/fixtures/db_definitions/*.sql files.
-
-Make sure that you create database objects with the same user that you specified in i
-connection.rb otherwise (on Postgres, at least) tests for default values will fail.
-
-== Running with Rake
-
-The easiest way to run the unit tests is through Rake. The default task runs
-the entire test suite for all the adapters. You can also run the suite on just
-one adapter by using the tasks test_mysql_ruby, test_ruby_mysql, test_sqlite,
-or test_postresql. For more information, checkout the full array of rake tasks with "rake -T"
-
-Rake can be found at http://rake.rubyforge.org
-
-== Running by hand
-
-Unit tests are located in test directory. If you only want to run a single test suite,
-or don't want to bother with Rake, you can do so with something like:
-
- cd test; ruby -I "connections/native_mysql" base_test.rb
-
-That'll run the base suite using the MySQL-Ruby adapter. Change the adapter
-and test suite name as needed.
-
-== Faster tests
-
-If you are using a database that supports transactions, you can set the
-"AR_TX_FIXTURES" environment variable to "yes" to use transactional fixtures.
-This gives a very large speed boost. With rake:
-
- rake AR_TX_FIXTURES=yes
-
-Or, by hand:
-
- AR_TX_FIXTURES=yes ruby -I connections/native_sqlite3 base_test.rb
diff --git a/vendor/plugins/acts_as_versioned/Rakefile b/vendor/plugins/acts_as_versioned/Rakefile
deleted file mode 100644
index 3ae69e961..000000000
--- a/vendor/plugins/acts_as_versioned/Rakefile
+++ /dev/null
@@ -1,182 +0,0 @@
-require 'rubygems'
-
-Gem::manage_gems
-
-require 'rake/rdoctask'
-require 'rake/packagetask'
-require 'rake/gempackagetask'
-require 'rake/testtask'
-require 'rake/contrib/rubyforgepublisher'
-
-PKG_NAME = 'acts_as_versioned'
-PKG_VERSION = '0.3.1'
-PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
-PROD_HOST = "technoweenie@bidwell.textdrive.com"
-RUBY_FORGE_PROJECT = 'ar-versioned'
-RUBY_FORGE_USER = 'technoweenie'
-
-desc 'Default: run unit tests.'
-task :default => :test
-
-desc 'Test the calculations plugin.'
-Rake::TestTask.new(:test) do |t|
- t.libs << 'lib'
- t.pattern = 'test/**/*_test.rb'
- t.verbose = true
-end
-
-desc 'Generate documentation for the calculations plugin.'
-Rake::RDocTask.new(:rdoc) do |rdoc|
- rdoc.rdoc_dir = 'rdoc'
- rdoc.title = "#{PKG_NAME} -- Simple versioning with active record models"
- rdoc.options << '--line-numbers --inline-source'
- rdoc.rdoc_files.include('README', 'CHANGELOG', 'RUNNING_UNIT_TESTS')
- rdoc.rdoc_files.include('lib/**/*.rb')
-end
-
-spec = Gem::Specification.new do |s|
- s.name = PKG_NAME
- s.version = PKG_VERSION
- s.platform = Gem::Platform::RUBY
- s.summary = "Simple versioning with active record models"
- s.files = FileList["{lib,test}/**/*"].to_a + %w(README MIT-LICENSE CHANGELOG RUNNING_UNIT_TESTS)
- s.files.delete "acts_as_versioned_plugin.sqlite.db"
- s.files.delete "acts_as_versioned_plugin.sqlite3.db"
- s.files.delete "test/debug.log"
- s.require_path = 'lib'
- s.autorequire = 'acts_as_versioned'
- s.has_rdoc = true
- s.test_files = Dir['test/**/*_test.rb']
- s.add_dependency 'activerecord', '>= 1.10.1'
- s.add_dependency 'activesupport', '>= 1.1.1'
- s.author = "Rick Olson"
- s.email = "technoweenie@gmail.com"
- s.homepage = "http://techno-weenie.net"
-end
-
-Rake::GemPackageTask.new(spec) do |pkg|
- pkg.need_tar = true
-end
-
-desc "Publish the API documentation"
-task :pdoc => [:rdoc] do
- Rake::RubyForgePublisher.new(RUBY_FORGE_PROJECT, RUBY_FORGE_USER).upload
-end
-
-desc 'Publish the gem and API docs'
-task :publish => [:pdoc, :rubyforge_upload]
-
-desc "Publish the release files to RubyForge."
-task :rubyforge_upload => :package do
- files = %w(gem tgz).map { |ext| "pkg/#{PKG_FILE_NAME}.#{ext}" }
-
- if RUBY_FORGE_PROJECT then
- require 'net/http'
- require 'open-uri'
-
- project_uri = "http://rubyforge.org/projects/#{RUBY_FORGE_PROJECT}/"
- project_data = open(project_uri) { |data| data.read }
- group_id = project_data[/[?&]group_id=(\d+)/, 1]
- raise "Couldn't get group id" unless group_id
-
- # This echos password to shell which is a bit sucky
- if ENV["RUBY_FORGE_PASSWORD"]
- password = ENV["RUBY_FORGE_PASSWORD"]
- else
- print "#{RUBY_FORGE_USER}@rubyforge.org's password: "
- password = STDIN.gets.chomp
- end
-
- login_response = Net::HTTP.start("rubyforge.org", 80) do |http|
- data = [
- "login=1",
- "form_loginname=#{RUBY_FORGE_USER}",
- "form_pw=#{password}"
- ].join("&")
- http.post("/account/login.php", data)
- end
-
- cookie = login_response["set-cookie"]
- raise "Login failed" unless cookie
- headers = { "Cookie" => cookie }
-
- release_uri = "http://rubyforge.org/frs/admin/?group_id=#{group_id}"
- release_data = open(release_uri, headers) { |data| data.read }
- package_id = release_data[/[?&]package_id=(\d+)/, 1]
- raise "Couldn't get package id" unless package_id
-
- first_file = true
- release_id = ""
-
- files.each do |filename|
- basename = File.basename(filename)
- file_ext = File.extname(filename)
- file_data = File.open(filename, "rb") { |file| file.read }
-
- puts "Releasing #{basename}..."
-
- release_response = Net::HTTP.start("rubyforge.org", 80) do |http|
- release_date = Time.now.strftime("%Y-%m-%d %H:%M")
- type_map = {
- ".zip" => "3000",
- ".tgz" => "3110",
- ".gz" => "3110",
- ".gem" => "1400"
- }; type_map.default = "9999"
- type = type_map[file_ext]
- boundary = "rubyqMY6QN9bp6e4kS21H4y0zxcvoor"
-
- query_hash = if first_file then
- {
- "group_id" => group_id,
- "package_id" => package_id,
- "release_name" => PKG_FILE_NAME,
- "release_date" => release_date,
- "type_id" => type,
- "processor_id" => "8000", # Any
- "release_notes" => "",
- "release_changes" => "",
- "preformatted" => "1",
- "submit" => "1"
- }
- else
- {
- "group_id" => group_id,
- "release_id" => release_id,
- "package_id" => package_id,
- "step2" => "1",
- "type_id" => type,
- "processor_id" => "8000", # Any
- "submit" => "Add This File"
- }
- end
-
- query = "?" + query_hash.map do |(name, value)|
- [name, URI.encode(value)].join("=")
- end.join("&")
-
- data = [
- "--" + boundary,
- "Content-Disposition: form-data; name=\"userfile\"; filename=\"#{basename}\"",
- "Content-Type: application/octet-stream",
- "Content-Transfer-Encoding: binary",
- "", file_data, ""
- ].join("\x0D\x0A")
-
- release_headers = headers.merge(
- "Content-Type" => "multipart/form-data; boundary=#{boundary}"
- )
-
- target = first_file ? "/frs/admin/qrs.php" : "/frs/admin/editrelease.php"
- http.post(target + query, data, release_headers)
- end
-
- if first_file then
- release_id = release_response.body[/release_id=(\d+)/, 1]
- raise("Couldn't get release id") unless release_id
- end
-
- first_file = false
- end
- end
-end \ No newline at end of file
diff --git a/vendor/plugins/acts_as_versioned/init.rb b/vendor/plugins/acts_as_versioned/init.rb
deleted file mode 100644
index 5937bbc7c..000000000
--- a/vendor/plugins/acts_as_versioned/init.rb
+++ /dev/null
@@ -1 +0,0 @@
-require 'acts_as_versioned' \ No newline at end of file
diff --git a/vendor/plugins/acts_as_versioned/lib/acts_as_versioned.rb b/vendor/plugins/acts_as_versioned/lib/acts_as_versioned.rb
deleted file mode 100644
index 5299e0dc7..000000000
--- a/vendor/plugins/acts_as_versioned/lib/acts_as_versioned.rb
+++ /dev/null
@@ -1,490 +0,0 @@
-# Copyright (c) 2005 Rick Olson
-#
-# 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 ActiveRecord #:nodoc:
- module Acts #:nodoc:
- # Specify this act if you want to save a copy of the row in a versioned table. This assumes there is a
- # versioned table ready and that your model has a version field. This works with optimistic locking if the lock_version
- # column is present as well.
- #
- # The class for the versioned model is derived the first time it is seen. Therefore, if you change your database schema you have to restart
- # your container for the changes to be reflected. In development mode this usually means restarting WEBrick.
- #
- # class Page < ActiveRecord::Base
- # # assumes pages_versions table
- # acts_as_versioned
- # end
- #
- # Example:
- #
- # page = Page.create(:title => 'hello world!')
- # page.version # => 1
- #
- # page.title = 'hello world'
- # page.save
- # page.version # => 2
- # page.versions.size # => 2
- #
- # page.revert_to(1) # using version number
- # page.title # => 'hello world!'
- #
- # page.revert_to(page.versions.last) # using versioned instance
- # page.title # => 'hello world'
- #
- # page.versions.earliest # efficient query to find the first version
- # page.versions.latest # efficient query to find the most recently created version
- #
- #
- # Simple Queries to page between versions
- #
- # page.versions.before(version)
- # page.versions.after(version)
- #
- # Access the previous/next versions from the versioned model itself
- #
- # version = page.versions.latest
- # version.previous # go back one version
- # version.next # go forward one version
- #
- # See ActiveRecord::Acts::Versioned::ClassMethods#acts_as_versioned for configuration options
- module Versioned
- CALLBACKS = [:set_new_version, :save_version, :save_version?]
- def self.included(base) # :nodoc:
- base.extend ClassMethods
- end
-
- module ClassMethods
- # == Configuration options
- #
- # * <tt>class_name</tt> - versioned model class name (default: PageVersion in the above example)
- # * <tt>table_name</tt> - versioned model table name (default: page_versions in the above example)
- # * <tt>foreign_key</tt> - foreign key used to relate the versioned model to the original model (default: page_id in the above example)
- # * <tt>inheritance_column</tt> - name of the column to save the model's inheritance_column value for STI. (default: versioned_type)
- # * <tt>version_column</tt> - name of the column in the model that keeps the version number (default: version)
- # * <tt>sequence_name</tt> - name of the custom sequence to be used by the versioned model.
- # * <tt>limit</tt> - number of revisions to keep, defaults to unlimited
- # * <tt>if</tt> - symbol of method to check before saving a new version. If this method returns false, a new version is not saved.
- # For finer control, pass either a Proc or modify Model#version_condition_met?
- #
- # acts_as_versioned :if => Proc.new { |auction| !auction.expired? }
- #
- # or...
- #
- # class Auction
- # def version_condition_met? # totally bypasses the <tt>:if</tt> option
- # !expired?
- # end
- # end
- #
- # * <tt>if_changed</tt> - Simple way of specifying attributes that are required to be changed before saving a model. This takes
- # either a symbol or array of symbols. WARNING - This will attempt to overwrite any attribute setters you may have.
- # Use this instead if you want to write your own attribute setters (and ignore if_changed):
- #
- # def name=(new_name)
- # write_changed_attribute :name, new_name
- # end
- #
- # * <tt>extend</tt> - Lets you specify a module to be mixed in both the original and versioned models. You can also just pass a block
- # to create an anonymous mixin:
- #
- # class Auction
- # acts_as_versioned do
- # def started?
- # !started_at.nil?
- # end
- # end
- # end
- #
- # or...
- #
- # module AuctionExtension
- # def started?
- # !started_at.nil?
- # end
- # end
- # class Auction
- # acts_as_versioned :extend => AuctionExtension
- # end
- #
- # Example code:
- #
- # @auction = Auction.find(1)
- # @auction.started?
- # @auction.versions.first.started?
- #
- # == Database Schema
- #
- # The model that you're versioning needs to have a 'version' attribute. The model is versioned
- # into a table called #{model}_versions where the model name is singlular. The _versions table should
- # contain all the fields you want versioned, the same version column, and a #{model}_id foreign key field.
- #
- # A lock_version field is also accepted if your model uses Optimistic Locking. If your table uses Single Table inheritance,
- # then that field is reflected in the versioned model as 'versioned_type' by default.
- #
- # Acts_as_versioned comes prepared with the ActiveRecord::Acts::Versioned::ActMethods::ClassMethods#create_versioned_table
- # method, perfect for a migration. It will also create the version column if the main model does not already have it.
- #
- # class AddVersions < ActiveRecord::Migration
- # def self.up
- # # create_versioned_table takes the same options hash
- # # that create_table does
- # Post.create_versioned_table
- # end
- #
- # def self.down
- # Post.drop_versioned_table
- # end
- # end
- #
- # == Changing What Fields Are Versioned
- #
- # By default, acts_as_versioned will version all but these fields:
- #
- # [self.primary_key, inheritance_column, 'version', 'lock_version', versioned_inheritance_column]
- #
- # You can add or change those by modifying #non_versioned_columns. Note that this takes strings and not symbols.
- #
- # class Post < ActiveRecord::Base
- # acts_as_versioned
- # self.non_versioned_columns << 'comments_count'
- # end
- #
- def acts_as_versioned(options = {}, &extension)
- # don't allow multiple calls
- return if self.included_modules.include?(ActiveRecord::Acts::Versioned::ActMethods)
-
- send :include, ActiveRecord::Acts::Versioned::ActMethods
-
- cattr_accessor :versioned_class_name, :versioned_foreign_key, :versioned_table_name, :versioned_inheritance_column,
- :version_column, :max_version_limit, :track_altered_attributes, :version_condition, :version_sequence_name, :non_versioned_columns,
- :version_association_options, :version_if_changed
-
- self.versioned_class_name = options[:class_name] || "Version"
- self.versioned_foreign_key = options[:foreign_key] || self.to_s.foreign_key
- self.versioned_table_name = options[:table_name] || "#{table_name_prefix}#{base_class.name.demodulize.underscore}_versions#{table_name_suffix}"
- self.versioned_inheritance_column = options[:inheritance_column] || "versioned_#{inheritance_column}"
- self.version_column = options[:version_column] || 'version'
- self.version_sequence_name = options[:sequence_name]
- self.max_version_limit = options[:limit].to_i
- self.version_condition = options[:if] || true
- self.non_versioned_columns = [self.primary_key, inheritance_column, 'version', 'lock_version', versioned_inheritance_column, 'created_at', 'created_on']
- self.version_association_options = {
- :class_name => "#{self.to_s}::#{versioned_class_name}",
- :foreign_key => versioned_foreign_key,
- :dependent => :delete_all
- }.merge(options[:association_options] || {})
-
- if block_given?
- extension_module_name = "#{versioned_class_name}Extension"
- silence_warnings do
- self.const_set(extension_module_name, Module.new(&extension))
- end
-
- options[:extend] = self.const_get(extension_module_name)
- end
-
- class_eval do
- has_many :versions, version_association_options do
- # finds earliest version of this record
- def earliest
- @earliest ||= find(:first, :order => 'version')
- end
-
- # find latest version of this record
- def latest
- @latest ||= find(:first, :order => 'version desc')
- end
- end
- before_save :set_new_version
- after_save :save_version
- after_save :clear_old_versions
-
- unless options[:if_changed].nil?
- self.track_altered_attributes = true
- options[:if_changed] = [options[:if_changed]] unless options[:if_changed].is_a?(Array)
- self.version_if_changed = options[:if_changed]
- end
-
- include options[:extend] if options[:extend].is_a?(Module)
- end
-
- # create the dynamic versioned model
- const_set(versioned_class_name, Class.new(ActiveRecord::Base)).class_eval do
- def self.reloadable? ; false ; end
- # find first version before the given version
- def self.before(version)
- find :first, :order => 'version desc',
- :conditions => ["#{original_class.versioned_foreign_key} = ? and version < ?", version.send(original_class.versioned_foreign_key), version.version]
- end
-
- # find first version after the given version.
- def self.after(version)
- find :first, :order => 'version',
- :conditions => ["#{original_class.versioned_foreign_key} = ? and version > ?", version.send(original_class.versioned_foreign_key), version.version]
- end
-
- def previous
- self.class.before(self)
- end
-
- def next
- self.class.after(self)
- end
-
- def versions_count
- page.version
- end
- end
-
- versioned_class.cattr_accessor :original_class
- versioned_class.original_class = self
- versioned_class.set_table_name versioned_table_name
- versioned_class.belongs_to self.to_s.demodulize.underscore.to_sym,
- :class_name => "::#{self.to_s}",
- :foreign_key => versioned_foreign_key
- versioned_class.send :include, options[:extend] if options[:extend].is_a?(Module)
- versioned_class.set_sequence_name version_sequence_name if version_sequence_name
- end
- end
-
- module ActMethods
- def self.included(base) # :nodoc:
- base.extend ClassMethods
- end
-
- # Saves a version of the model in the versioned table. This is called in the after_save callback by default
- def save_version
- if @saving_version
- @saving_version = nil
- rev = self.class.versioned_class.new
- clone_versioned_model(self, rev)
- rev.version = send(self.class.version_column)
- rev.send("#{self.class.versioned_foreign_key}=", id)
- rev.save
- end
- end
-
- # Clears old revisions if a limit is set with the :limit option in <tt>acts_as_versioned</tt>.
- # Override this method to set your own criteria for clearing old versions.
- def clear_old_versions
- return if self.class.max_version_limit == 0
- excess_baggage = send(self.class.version_column).to_i - self.class.max_version_limit
- if excess_baggage > 0
- self.class.versioned_class.delete_all ["version <= ? and #{self.class.versioned_foreign_key} = ?", excess_baggage, id]
- end
- end
-
- # Reverts a model to a given version. Takes either a version number or an instance of the versioned model
- def revert_to(version)
- if version.is_a?(self.class.versioned_class)
- return false unless version.send(self.class.versioned_foreign_key) == id and !version.new_record?
- else
- return false unless version = versions.find_by_version(version)
- end
- self.clone_versioned_model(version, self)
- send("#{self.class.version_column}=", version.version)
- true
- end
-
- # Reverts a model to a given version and saves the model.
- # Takes either a version number or an instance of the versioned model
- def revert_to!(version)
- revert_to(version) ? save_without_revision : false
- end
-
- # Temporarily turns off Optimistic Locking while saving. Used when reverting so that a new version is not created.
- def save_without_revision
- save_without_revision!
- true
- rescue
- false
- end
-
- def save_without_revision!
- without_locking do
- without_revision do
- save!
- end
- end
- end
-
- def altered?
- track_altered_attributes ? (version_if_changed.map(&:to_s) - changed).length < version_if_changed.length : changed?
- end
-
- # Clones a model. Used when saving a new version or reverting a model's version.
- def clone_versioned_model(orig_model, new_model)
- self.class.versioned_columns.each do |col|
- new_model.send("#{col.name}=", orig_model.send(col.name)) if orig_model.has_attribute?(col.name)
- end
-
- if orig_model.is_a?(self.class.versioned_class)
- new_model[new_model.class.inheritance_column] = orig_model[self.class.versioned_inheritance_column]
- elsif new_model.is_a?(self.class.versioned_class)
- new_model[self.class.versioned_inheritance_column] = orig_model[orig_model.class.inheritance_column]
- end
- end
-
- # Checks whether a new version shall be saved or not. Calls <tt>version_condition_met?</tt> and <tt>changed?</tt>.
- def save_version?
- version_condition_met? && altered?
- end
-
- # Checks condition set in the :if option to check whether a revision should be created or not. Override this for
- # custom version condition checking.
- def version_condition_met?
- case
- when version_condition.is_a?(Symbol)
- send(version_condition)
- when version_condition.respond_to?(:call) && (version_condition.arity == 1 || version_condition.arity == -1)
- version_condition.call(self)
- else
- version_condition
- end
- end
-
- # Executes the block with the versioning callbacks disabled.
- #
- # @foo.without_revision do
- # @foo.save
- # end
- #
- def without_revision(&block)
- self.class.without_revision(&block)
- end
-
- # Turns off optimistic locking for the duration of the block
- #
- # @foo.without_locking do
- # @foo.save
- # end
- #
- def without_locking(&block)
- self.class.without_locking(&block)
- end
-
- def empty_callback() end #:nodoc:
-
- protected
- # sets the new version before saving, unless you're using optimistic locking. In that case, let it take care of the version.
- def set_new_version
- @saving_version = new_record? || save_version?
- self.send("#{self.class.version_column}=", next_version) if new_record? || (!locking_enabled? && save_version?)
- end
-
- # Gets the next available version for the current record, or 1 for a new record
- def next_version
- (new_record? ? 0 : versions.calculate(:max, :version).to_i) + 1
- end
-
- module ClassMethods
- # Returns an array of columns that are versioned. See non_versioned_columns
- def versioned_columns
- @versioned_columns ||= columns.select { |c| !non_versioned_columns.include?(c.name) }
- end
-
- # Returns an instance of the dynamic versioned model
- def versioned_class
- const_get versioned_class_name
- end
-
- # Rake migration task to create the versioned table using options passed to acts_as_versioned
- def create_versioned_table(create_table_options = {})
- # create version column in main table if it does not exist
- if !self.content_columns.find { |c| %w(version lock_version).include? c.name }
- self.connection.add_column table_name, :version, :integer
- end
-
- self.connection.create_table(versioned_table_name, create_table_options) do |t|
- t.column versioned_foreign_key, :integer
- t.column :version, :integer
- end
-
- updated_col = nil
- self.versioned_columns.each do |col|
- updated_col = col if !updated_col && %(updated_at updated_on).include?(col.name)
- self.connection.add_column versioned_table_name, col.name, col.type,
- :limit => col.limit,
- :default => col.default,
- :scale => col.scale,
- :precision => col.precision
- end
-
- if type_col = self.columns_hash[inheritance_column]
- self.connection.add_column versioned_table_name, versioned_inheritance_column, type_col.type,
- :limit => type_col.limit,
- :default => type_col.default,
- :scale => type_col.scale,
- :precision => type_col.precision
- end
-
- if updated_col.nil?
- self.connection.add_column versioned_table_name, :updated_at, :timestamp
- end
- end
-
- # Rake migration task to drop the versioned table
- def drop_versioned_table
- self.connection.drop_table versioned_table_name
- end
-
- # Executes the block with the versioning callbacks disabled.
- #
- # Foo.without_revision do
- # @foo.save
- # end
- #
- def without_revision(&block)
- class_eval do
- CALLBACKS.each do |attr_name|
- alias_method "orig_#{attr_name}".to_sym, attr_name
- alias_method attr_name, :empty_callback
- end
- end
- block.call
- ensure
- class_eval do
- CALLBACKS.each do |attr_name|
- alias_method attr_name, "orig_#{attr_name}".to_sym
- end
- end
- end
-
- # Turns off optimistic locking for the duration of the block
- #
- # Foo.without_locking do
- # @foo.save
- # end
- #
- def without_locking(&block)
- current = ActiveRecord::Base.lock_optimistically
- ActiveRecord::Base.lock_optimistically = false if current
- result = block.call
- ActiveRecord::Base.lock_optimistically = true if current
- result
- end
- end
- end
- end
- end
-end
-
-ActiveRecord::Base.send :include, ActiveRecord::Acts::Versioned \ No newline at end of file
diff --git a/vendor/plugins/acts_as_versioned/test/abstract_unit.rb b/vendor/plugins/acts_as_versioned/test/abstract_unit.rb
deleted file mode 100644
index 269667ad0..000000000
--- a/vendor/plugins/acts_as_versioned/test/abstract_unit.rb
+++ /dev/null
@@ -1,48 +0,0 @@
-$:.unshift(File.dirname(__FILE__) + '/../../../rails/activesupport/lib')
-$:.unshift(File.dirname(__FILE__) + '/../../../rails/activerecord/lib')
-$:.unshift(File.dirname(__FILE__) + '/../lib')
-require 'test/unit'
-begin
- require 'active_support'
- require 'active_record'
- require 'active_record/fixtures'
-rescue LoadError
- require 'rubygems'
- retry
-end
-
-begin
- require 'ruby-debug'
- Debugger.start
-rescue LoadError
-end
-
-require 'acts_as_versioned'
-
-config = YAML::load(IO.read(File.dirname(__FILE__) + '/database.yml'))
-ActiveRecord::Base.logger = Logger.new(File.dirname(__FILE__) + "/debug.log")
-ActiveRecord::Base.configurations = {'test' => config[ENV['DB'] || 'sqlite3']}
-ActiveRecord::Base.establish_connection(ActiveRecord::Base.configurations['test'])
-
-load(File.dirname(__FILE__) + "/schema.rb")
-
-# set up custom sequence on widget_versions for DBs that support sequences
-if ENV['DB'] == 'postgresql'
- ActiveRecord::Base.connection.execute "DROP SEQUENCE widgets_seq;" rescue nil
- ActiveRecord::Base.connection.remove_column :widget_versions, :id
- ActiveRecord::Base.connection.execute "CREATE SEQUENCE widgets_seq START 101;"
- ActiveRecord::Base.connection.execute "ALTER TABLE widget_versions ADD COLUMN id INTEGER PRIMARY KEY DEFAULT nextval('widgets_seq');"
-end
-
-Test::Unit::TestCase.fixture_path = File.dirname(__FILE__) + "/fixtures/"
-$:.unshift(Test::Unit::TestCase.fixture_path)
-
-class Test::Unit::TestCase #:nodoc:
- # Turn off transactional fixtures if you're working with MyISAM tables in MySQL
- self.use_transactional_fixtures = true
-
- # Instantiated fixtures are slow, but give you @david where you otherwise would need people(:david)
- self.use_instantiated_fixtures = false
-
- # Add more helper methods to be used by all tests here...
-end \ No newline at end of file
diff --git a/vendor/plugins/acts_as_versioned/test/database.yml b/vendor/plugins/acts_as_versioned/test/database.yml
deleted file mode 100644
index 506e6bd37..000000000
--- a/vendor/plugins/acts_as_versioned/test/database.yml
+++ /dev/null
@@ -1,18 +0,0 @@
-sqlite:
- :adapter: sqlite
- :dbfile: acts_as_versioned_plugin.sqlite.db
-sqlite3:
- :adapter: sqlite3
- :dbfile: acts_as_versioned_plugin.sqlite3.db
-postgresql:
- :adapter: postgresql
- :username: postgres
- :password: postgres
- :database: acts_as_versioned_plugin_test
- :min_messages: ERROR
-mysql:
- :adapter: mysql
- :host: localhost
- :username: rails
- :password:
- :database: acts_as_versioned_plugin_test \ No newline at end of file
diff --git a/vendor/plugins/acts_as_versioned/test/fixtures/authors.yml b/vendor/plugins/acts_as_versioned/test/fixtures/authors.yml
deleted file mode 100644
index bd7a5aed6..000000000
--- a/vendor/plugins/acts_as_versioned/test/fixtures/authors.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-caged:
- id: 1
- name: caged
-mly:
- id: 2
- name: mly \ No newline at end of file
diff --git a/vendor/plugins/acts_as_versioned/test/fixtures/landmark.rb b/vendor/plugins/acts_as_versioned/test/fixtures/landmark.rb
deleted file mode 100644
index cb9b93057..000000000
--- a/vendor/plugins/acts_as_versioned/test/fixtures/landmark.rb
+++ /dev/null
@@ -1,3 +0,0 @@
-class Landmark < ActiveRecord::Base
- acts_as_versioned :if_changed => [ :name, :longitude, :latitude ]
-end
diff --git a/vendor/plugins/acts_as_versioned/test/fixtures/landmark_versions.yml b/vendor/plugins/acts_as_versioned/test/fixtures/landmark_versions.yml
deleted file mode 100644
index 2dbd54ed2..000000000
--- a/vendor/plugins/acts_as_versioned/test/fixtures/landmark_versions.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-washington:
- id: 1
- landmark_id: 1
- version: 1
- name: Washington, D.C.
- latitude: 38.895
- longitude: -77.036667
diff --git a/vendor/plugins/acts_as_versioned/test/fixtures/landmarks.yml b/vendor/plugins/acts_as_versioned/test/fixtures/landmarks.yml
deleted file mode 100644
index cf0639006..000000000
--- a/vendor/plugins/acts_as_versioned/test/fixtures/landmarks.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-washington:
- id: 1
- name: Washington, D.C.
- latitude: 38.895
- longitude: -77.036667
- doesnt_trigger_version: This is not important
- version: 1
diff --git a/vendor/plugins/acts_as_versioned/test/fixtures/locked_pages.yml b/vendor/plugins/acts_as_versioned/test/fixtures/locked_pages.yml
deleted file mode 100644
index 318e776cb..000000000
--- a/vendor/plugins/acts_as_versioned/test/fixtures/locked_pages.yml
+++ /dev/null
@@ -1,10 +0,0 @@
-welcome:
- id: 1
- title: Welcome to the weblog
- lock_version: 24
- type: LockedPage
-thinking:
- id: 2
- title: So I was thinking
- lock_version: 24
- type: SpecialLockedPage
diff --git a/vendor/plugins/acts_as_versioned/test/fixtures/locked_pages_revisions.yml b/vendor/plugins/acts_as_versioned/test/fixtures/locked_pages_revisions.yml
deleted file mode 100644
index 5c978e629..000000000
--- a/vendor/plugins/acts_as_versioned/test/fixtures/locked_pages_revisions.yml
+++ /dev/null
@@ -1,27 +0,0 @@
-welcome_1:
- id: 1
- page_id: 1
- title: Welcome to the weblg
- version: 23
- version_type: LockedPage
-
-welcome_2:
- id: 2
- page_id: 1
- title: Welcome to the weblog
- version: 24
- version_type: LockedPage
-
-thinking_1:
- id: 3
- page_id: 2
- title: So I was thinking!!!
- version: 23
- version_type: SpecialLockedPage
-
-thinking_2:
- id: 4
- page_id: 2
- title: So I was thinking
- version: 24
- version_type: SpecialLockedPage
diff --git a/vendor/plugins/acts_as_versioned/test/fixtures/migrations/1_add_versioned_tables.rb b/vendor/plugins/acts_as_versioned/test/fixtures/migrations/1_add_versioned_tables.rb
deleted file mode 100644
index 5007b16ad..000000000
--- a/vendor/plugins/acts_as_versioned/test/fixtures/migrations/1_add_versioned_tables.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-class AddVersionedTables < ActiveRecord::Migration
- def self.up
- create_table("things") do |t|
- t.column :title, :text
- t.column :price, :decimal, :precision => 7, :scale => 2
- t.column :type, :string
- end
- Thing.create_versioned_table
- end
-
- def self.down
- Thing.drop_versioned_table
- drop_table "things" rescue nil
- end
-end \ No newline at end of file
diff --git a/vendor/plugins/acts_as_versioned/test/fixtures/page.rb b/vendor/plugins/acts_as_versioned/test/fixtures/page.rb
deleted file mode 100644
index f133e351a..000000000
--- a/vendor/plugins/acts_as_versioned/test/fixtures/page.rb
+++ /dev/null
@@ -1,43 +0,0 @@
-class Page < ActiveRecord::Base
- belongs_to :author
- has_many :authors, :through => :versions, :order => 'name'
- belongs_to :revisor, :class_name => 'Author'
- has_many :revisors, :class_name => 'Author', :through => :versions, :order => 'name'
- acts_as_versioned :if => :feeling_good? do
- def self.included(base)
- base.cattr_accessor :feeling_good
- base.feeling_good = true
- base.belongs_to :author
- base.belongs_to :revisor, :class_name => 'Author'
- end
-
- def feeling_good?
- @@feeling_good == true
- end
- end
-end
-
-module LockedPageExtension
- def hello_world
- 'hello_world'
- end
-end
-
-class LockedPage < ActiveRecord::Base
- acts_as_versioned \
- :inheritance_column => :version_type,
- :foreign_key => :page_id,
- :table_name => :locked_pages_revisions,
- :class_name => 'LockedPageRevision',
- :version_column => :lock_version,
- :limit => 2,
- :if_changed => :title,
- :extend => LockedPageExtension
-end
-
-class SpecialLockedPage < LockedPage
-end
-
-class Author < ActiveRecord::Base
- has_many :pages
-end \ No newline at end of file
diff --git a/vendor/plugins/acts_as_versioned/test/fixtures/page_versions.yml b/vendor/plugins/acts_as_versioned/test/fixtures/page_versions.yml
deleted file mode 100644
index ef565fa4f..000000000
--- a/vendor/plugins/acts_as_versioned/test/fixtures/page_versions.yml
+++ /dev/null
@@ -1,16 +0,0 @@
-welcome_2:
- id: 1
- page_id: 1
- title: Welcome to the weblog
- body: Such a lovely day
- version: 24
- author_id: 1
- revisor_id: 1
-welcome_1:
- id: 2
- page_id: 1
- title: Welcome to the weblg
- body: Such a lovely day
- version: 23
- author_id: 2
- revisor_id: 2
diff --git a/vendor/plugins/acts_as_versioned/test/fixtures/pages.yml b/vendor/plugins/acts_as_versioned/test/fixtures/pages.yml
deleted file mode 100644
index 9f4ab546a..000000000
--- a/vendor/plugins/acts_as_versioned/test/fixtures/pages.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-welcome:
- id: 1
- title: Welcome to the weblog
- body: Such a lovely day
- version: 24
- author_id: 1
- revisor_id: 1
- created_on: "2008-01-01 00:00:00" \ No newline at end of file
diff --git a/vendor/plugins/acts_as_versioned/test/fixtures/widget.rb b/vendor/plugins/acts_as_versioned/test/fixtures/widget.rb
deleted file mode 100644
index 086ac2b40..000000000
--- a/vendor/plugins/acts_as_versioned/test/fixtures/widget.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-class Widget < ActiveRecord::Base
- acts_as_versioned :sequence_name => 'widgets_seq', :association_options => {
- :dependent => :nullify, :order => 'version desc'
- }
- non_versioned_columns << 'foo'
-end \ No newline at end of file
diff --git a/vendor/plugins/acts_as_versioned/test/migration_test.rb b/vendor/plugins/acts_as_versioned/test/migration_test.rb
deleted file mode 100644
index 47a7537ce..000000000
--- a/vendor/plugins/acts_as_versioned/test/migration_test.rb
+++ /dev/null
@@ -1,46 +0,0 @@
-require File.join(File.dirname(__FILE__), 'abstract_unit')
-
-if ActiveRecord::Base.connection.supports_migrations?
- class Thing < ActiveRecord::Base
- attr_accessor :version
- acts_as_versioned
- end
-
- class MigrationTest < Test::Unit::TestCase
- self.use_transactional_fixtures = false
- def teardown
- if ActiveRecord::Base.connection.respond_to?(:initialize_schema_information)
- ActiveRecord::Base.connection.initialize_schema_information
- ActiveRecord::Base.connection.update "UPDATE schema_info SET version = 0"
- else
- ActiveRecord::Base.connection.initialize_schema_migrations_table
- ActiveRecord::Base.connection.assume_migrated_upto_version(0)
- end
-
- Thing.connection.drop_table "things" rescue nil
- Thing.connection.drop_table "thing_versions" rescue nil
- Thing.reset_column_information
- end
-
- def test_versioned_migration
- assert_raises(ActiveRecord::StatementInvalid) { Thing.create :title => 'blah blah' }
- # take 'er up
- ActiveRecord::Migrator.up(File.dirname(__FILE__) + '/fixtures/migrations/')
- t = Thing.create :title => 'blah blah', :price => 123.45, :type => 'Thing'
- assert_equal 1, t.versions.size
-
- # check that the price column has remembered its value correctly
- assert_equal t.price, t.versions.first.price
- assert_equal t.title, t.versions.first.title
- assert_equal t[:type], t.versions.first[:type]
-
- # make sure that the precision of the price column has been preserved
- assert_equal 7, Thing::Version.columns.find{|c| c.name == "price"}.precision
- assert_equal 2, Thing::Version.columns.find{|c| c.name == "price"}.scale
-
- # now lets take 'er back down
- ActiveRecord::Migrator.down(File.dirname(__FILE__) + '/fixtures/migrations/')
- assert_raises(ActiveRecord::StatementInvalid) { Thing.create :title => 'blah blah' }
- end
- end
-end
diff --git a/vendor/plugins/acts_as_versioned/test/schema.rb b/vendor/plugins/acts_as_versioned/test/schema.rb
deleted file mode 100644
index 4e7e96319..000000000
--- a/vendor/plugins/acts_as_versioned/test/schema.rb
+++ /dev/null
@@ -1,80 +0,0 @@
-ActiveRecord::Schema.define(:version => 0) do
- create_table :pages, :force => true do |t|
- t.column :version, :integer
- t.column :title, :string, :limit => 255
- t.column :body, :text
- t.column :created_on, :datetime
- t.column :updated_on, :datetime
- t.column :author_id, :integer
- t.column :revisor_id, :integer
- end
-
- create_table :page_versions, :force => true do |t|
- t.column :page_id, :integer
- t.column :version, :integer
- t.column :title, :string, :limit => 255
- t.column :body, :text
- t.column :created_on, :datetime
- t.column :updated_on, :datetime
- t.column :author_id, :integer
- t.column :revisor_id, :integer
- end
-
- add_index :page_versions, [:page_id, :version], :unique => true
-
- create_table :authors, :force => true do |t|
- t.column :page_id, :integer
- t.column :name, :string
- end
-
- create_table :locked_pages, :force => true do |t|
- t.column :lock_version, :integer
- t.column :title, :string, :limit => 255
- t.column :type, :string, :limit => 255
- end
-
- create_table :locked_pages_revisions, :force => true do |t|
- t.column :page_id, :integer
- t.column :version, :integer
- t.column :title, :string, :limit => 255
- t.column :version_type, :string, :limit => 255
- t.column :updated_at, :datetime
- end
-
- add_index :locked_pages_revisions, [:page_id, :version], :unique => true
-
- create_table :widgets, :force => true do |t|
- t.column :name, :string, :limit => 50
- t.column :foo, :string
- t.column :version, :integer
- t.column :updated_at, :datetime
- end
-
- create_table :widget_versions, :force => true do |t|
- t.column :widget_id, :integer
- t.column :name, :string, :limit => 50
- t.column :version, :integer
- t.column :updated_at, :datetime
- end
-
- add_index :widget_versions, [:widget_id, :version], :unique => true
-
- create_table :landmarks, :force => true do |t|
- t.column :name, :string
- t.column :latitude, :float
- t.column :longitude, :float
- t.column :doesnt_trigger_version,:string
- t.column :version, :integer
- end
-
- create_table :landmark_versions, :force => true do |t|
- t.column :landmark_id, :integer
- t.column :name, :string
- t.column :latitude, :float
- t.column :longitude, :float
- t.column :doesnt_trigger_version,:string
- t.column :version, :integer
- end
-
- add_index :landmark_versions, [:landmark_id, :version], :unique => true
-end
diff --git a/vendor/plugins/acts_as_versioned/test/versioned_test.rb b/vendor/plugins/acts_as_versioned/test/versioned_test.rb
deleted file mode 100644
index 6ab9e739c..000000000
--- a/vendor/plugins/acts_as_versioned/test/versioned_test.rb
+++ /dev/null
@@ -1,352 +0,0 @@
-require File.join(File.dirname(__FILE__), 'abstract_unit')
-require File.join(File.dirname(__FILE__), 'fixtures/page')
-require File.join(File.dirname(__FILE__), 'fixtures/widget')
-
-class VersionedTest < Test::Unit::TestCase
- fixtures :pages, :page_versions, :locked_pages, :locked_pages_revisions, :authors, :landmarks, :landmark_versions
- set_fixture_class :page_versions => Page::Version
-
- def test_saves_versioned_copy
- p = Page.create! :title => 'first title', :body => 'first body'
- assert !p.new_record?
- assert_equal 1, p.versions.size
- assert_equal 1, p.version
- assert_instance_of Page.versioned_class, p.versions.first
- end
-
- def test_version_has_unique_created_at
- p = pages(:welcome)
- p.title = 'update me'
- p.save!
- assert_not_equal p.created_on, p.versions.latest.created_on
- end
-
- def test_saves_without_revision
- p = pages(:welcome)
- old_versions = p.versions.count
-
- p.save_without_revision
-
- p.without_revision do
- p.update_attributes :title => 'changed'
- end
-
- assert_equal old_versions, p.versions.count
- end
-
- def test_rollback_with_version_number
- p = pages(:welcome)
- assert_equal 24, p.version
- assert_equal 'Welcome to the weblog', p.title
-
- assert p.revert_to!(23), "Couldn't revert to 23"
- assert_equal 23, p.version
- assert_equal 'Welcome to the weblg', p.title
- end
-
- def test_versioned_class_name
- assert_equal 'Version', Page.versioned_class_name
- assert_equal 'LockedPageRevision', LockedPage.versioned_class_name
- end
-
- def test_versioned_class
- assert_equal Page::Version, Page.versioned_class
- assert_equal LockedPage::LockedPageRevision, LockedPage.versioned_class
- end
-
- def test_special_methods
- assert_nothing_raised { pages(:welcome).feeling_good? }
- assert_nothing_raised { pages(:welcome).versions.first.feeling_good? }
- assert_nothing_raised { locked_pages(:welcome).hello_world }
- assert_nothing_raised { locked_pages(:welcome).versions.first.hello_world }
- end
-
- def test_rollback_with_version_class
- p = pages(:welcome)
- assert_equal 24, p.version
- assert_equal 'Welcome to the weblog', p.title
-
- assert p.revert_to!(p.versions.find_by_version(23)), "Couldn't revert to 23"
- assert_equal 23, p.version
- assert_equal 'Welcome to the weblg', p.title
- end
-
- def test_rollback_fails_with_invalid_revision
- p = locked_pages(:welcome)
- assert !p.revert_to!(locked_pages(:thinking))
- end
-
- def test_saves_versioned_copy_with_options
- p = LockedPage.create! :title => 'first title'
- assert !p.new_record?
- assert_equal 1, p.versions.size
- assert_instance_of LockedPage.versioned_class, p.versions.first
- end
-
- def test_rollback_with_version_number_with_options
- p = locked_pages(:welcome)
- assert_equal 'Welcome to the weblog', p.title
- assert_equal 'LockedPage', p.versions.first.version_type
-
- assert p.revert_to!(p.versions.first.version), "Couldn't revert to 23"
- assert_equal 'Welcome to the weblg', p.title
- assert_equal 'LockedPage', p.versions.first.version_type
- end
-
- def test_rollback_with_version_class_with_options
- p = locked_pages(:welcome)
- assert_equal 'Welcome to the weblog', p.title
- assert_equal 'LockedPage', p.versions.first.version_type
-
- assert p.revert_to!(p.versions.first), "Couldn't revert to 1"
- assert_equal 'Welcome to the weblg', p.title
- assert_equal 'LockedPage', p.versions.first.version_type
- end
-
- def test_saves_versioned_copy_with_sti
- p = SpecialLockedPage.create! :title => 'first title'
- assert !p.new_record?
- assert_equal 1, p.versions.size
- assert_instance_of LockedPage.versioned_class, p.versions.first
- assert_equal 'SpecialLockedPage', p.versions.first.version_type
- end
-
- def test_rollback_with_version_number_with_sti
- p = locked_pages(:thinking)
- assert_equal 'So I was thinking', p.title
-
- assert p.revert_to!(p.versions.first.version), "Couldn't revert to 1"
- assert_equal 'So I was thinking!!!', p.title
- assert_equal 'SpecialLockedPage', p.versions.first.version_type
- end
-
- def test_lock_version_works_with_versioning
- p = locked_pages(:thinking)
- p2 = LockedPage.find(p.id)
-
- p.title = 'fresh title'
- p.save
- assert_equal 2, p.versions.size # limit!
-
- assert_raises(ActiveRecord::StaleObjectError) do
- p2.title = 'stale title'
- p2.save
- end
- end
-
- def test_version_if_condition
- p = Page.create! :title => "title"
- assert_equal 1, p.version
-
- Page.feeling_good = false
- p.save
- assert_equal 1, p.version
- Page.feeling_good = true
- end
-
- def test_version_if_condition2
- # set new if condition
- Page.class_eval do
- def new_feeling_good() title[0..0] == 'a'; end
- alias_method :old_feeling_good, :feeling_good?
- alias_method :feeling_good?, :new_feeling_good
- end
-
- p = Page.create! :title => "title"
- assert_equal 1, p.version # version does not increment
- assert_equal 1, p.versions.count
-
- p.update_attributes(:title => 'new title')
- assert_equal 1, p.version # version does not increment
- assert_equal 1, p.versions.count
-
- p.update_attributes(:title => 'a title')
- assert_equal 2, p.version
- assert_equal 2, p.versions.count
-
- # reset original if condition
- Page.class_eval { alias_method :feeling_good?, :old_feeling_good }
- end
-
- def test_version_if_condition_with_block
- # set new if condition
- old_condition = Page.version_condition
- Page.version_condition = Proc.new { |page| page.title[0..0] == 'b' }
-
- p = Page.create! :title => "title"
- assert_equal 1, p.version # version does not increment
- assert_equal 1, p.versions.count
-
- p.update_attributes(:title => 'a title')
- assert_equal 1, p.version # version does not increment
- assert_equal 1, p.versions.count
-
- p.update_attributes(:title => 'b title')
- assert_equal 2, p.version
- assert_equal 2, p.versions.count
-
- # reset original if condition
- Page.version_condition = old_condition
- end
-
- def test_version_no_limit
- p = Page.create! :title => "title", :body => 'first body'
- p.save
- p.save
- 5.times do |i|
- p.title = "title#{i}"
- p.save
- assert_equal "title#{i}", p.title
- assert_equal (i+2), p.version
- end
- end
-
- def test_version_max_limit
- p = LockedPage.create! :title => "title"
- p.update_attributes(:title => "title1")
- p.update_attributes(:title => "title2")
- 5.times do |i|
- p.title = "title#{i}"
- p.save
- assert_equal "title#{i}", p.title
- assert_equal (i+4), p.lock_version
- assert p.versions(true).size <= 2, "locked version can only store 2 versions"
- end
- end
-
- def test_track_altered_attributes_default_value
- assert !Page.track_altered_attributes
- assert LockedPage.track_altered_attributes
- assert SpecialLockedPage.track_altered_attributes
- end
-
- def test_track_altered_attributes
- p = LockedPage.create! :title => "title"
- assert_equal 1, p.lock_version
- assert_equal 1, p.versions(true).size
-
- p.title = 'title'
- assert !p.save_version?
- p.save
- assert_equal 2, p.lock_version # still increments version because of optimistic locking
- assert_equal 1, p.versions(true).size
-
- p.title = 'updated title'
- assert p.save_version?
- p.save
- assert_equal 3, p.lock_version
- assert_equal 1, p.versions(true).size # version 1 deleted
-
- p.title = 'updated title!'
- assert p.save_version?
- p.save
- assert_equal 4, p.lock_version
- assert_equal 2, p.versions(true).size # version 1 deleted
- end
-
- def test_find_versions
- assert_equal 1, locked_pages(:welcome).versions.find(:all, :conditions => ['title LIKE ?', '%weblog%']).size
- end
-
- def test_find_version
- assert_equal page_versions(:welcome_1), pages(:welcome).versions.find_by_version(23)
- end
-
- def test_with_sequence
- assert_equal 'widgets_seq', Widget.versioned_class.sequence_name
- 3.times { Widget.create! :name => 'new widget' }
- assert_equal 3, Widget.count
- assert_equal 3, Widget.versioned_class.count
- end
-
- def test_has_many_through
- assert_equal [authors(:caged), authors(:mly)], pages(:welcome).authors
- end
-
- def test_has_many_through_with_custom_association
- assert_equal [authors(:caged), authors(:mly)], pages(:welcome).revisors
- end
-
- def test_referential_integrity
- pages(:welcome).destroy
- assert_equal 0, Page.count
- assert_equal 0, Page::Version.count
- end
-
- def test_association_options
- association = Page.reflect_on_association(:versions)
- options = association.options
- assert_equal :delete_all, options[:dependent]
-
- association = Widget.reflect_on_association(:versions)
- options = association.options
- assert_equal :nullify, options[:dependent]
- assert_equal 'version desc', options[:order]
- assert_equal 'widget_id', options[:foreign_key]
-
- widget = Widget.create! :name => 'new widget'
- assert_equal 1, Widget.count
- assert_equal 1, Widget.versioned_class.count
- widget.destroy
- assert_equal 0, Widget.count
- assert_equal 1, Widget.versioned_class.count
- end
-
- def test_versioned_records_should_belong_to_parent
- page = pages(:welcome)
- page_version = page.versions.last
- assert_equal page, page_version.page
- end
-
- def test_unaltered_attributes
- landmarks(:washington).attributes = landmarks(:washington).attributes.except("id")
- assert !landmarks(:washington).changed?
- end
-
- def test_unchanged_string_attributes
- landmarks(:washington).attributes = landmarks(:washington).attributes.except("id").inject({}) { |params, (key, value)| params.update(key => value.to_s) }
- assert !landmarks(:washington).changed?
- end
-
- def test_should_find_earliest_version
- assert_equal page_versions(:welcome_1), pages(:welcome).versions.earliest
- end
-
- def test_should_find_latest_version
- assert_equal page_versions(:welcome_2), pages(:welcome).versions.latest
- end
-
- def test_should_find_previous_version
- assert_equal page_versions(:welcome_1), page_versions(:welcome_2).previous
- assert_equal page_versions(:welcome_1), pages(:welcome).versions.before(page_versions(:welcome_2))
- end
-
- def test_should_find_next_version
- assert_equal page_versions(:welcome_2), page_versions(:welcome_1).next
- assert_equal page_versions(:welcome_2), pages(:welcome).versions.after(page_versions(:welcome_1))
- end
-
- def test_should_find_version_count
- assert_equal 2, pages(:welcome).versions.size
- end
-
- def test_if_changed_creates_version_if_a_listed_column_is_changed
- landmarks(:washington).name = "Washington"
- assert landmarks(:washington).changed?
- assert landmarks(:washington).altered?
- end
-
- def test_if_changed_creates_version_if_all_listed_columns_are_changed
- landmarks(:washington).name = "Washington"
- landmarks(:washington).latitude = 1.0
- landmarks(:washington).longitude = 1.0
- assert landmarks(:washington).changed?
- assert landmarks(:washington).altered?
- end
-
- def test_if_changed_does_not_create_new_version_if_unlisted_column_is_changed
- landmarks(:washington).doesnt_trigger_version = "This should not trigger version"
- assert landmarks(:washington).changed?
- assert !landmarks(:washington).altered?
- end
-end \ No newline at end of file
diff --git a/vendor/plugins/acts_as_xapian/README.txt b/vendor/plugins/acts_as_xapian/README.txt
index 62cef2f24..a1d22ef3f 100644
--- a/vendor/plugins/acts_as_xapian/README.txt
+++ b/vendor/plugins/acts_as_xapian/README.txt
@@ -14,7 +14,7 @@ copied from the README.txt file.
Contents
========
-* a. Introduction to acts_as_xapian
+* a. Introduction to acts_as_xapian
* b. Installation
* c. Comparison to acts_as_solr (as on 24 April 2008)
* d. Documentation - indexing
@@ -33,14 +33,14 @@ alternative to acts_as_solr, acts_as_ferret, Ultrasphinx, acts_as_indexed,
acts_as_searchable or acts_as_tsearch.
acts_as_xapian is deployed in production on these websites.
-* "WhatDoTheyKnow":http://www.whatdotheyknow.com
+* "WhatDoTheyKnow":http://www.whatdotheyknow.com
* "MindBites":http://www.mindbites.com
-The section "c. Comparison to acts_as_solr" below will give you an idea of
+The section "c. Comparison to acts_as_solr" below will give you an idea of
acts_as_xapian's features.
acts_as_xapian was started by Francis Irving in May 2008 for search and email
-alerts in WhatDoTheyKnow, and so was supported by "mySociety":http://www.mysociety.org
+alerts in WhatDoTheyKnow, and so was supported by "mySociety":http://www.mysociety.org
and initially paid for by the "JRSST Charitable Trust":http://www.jrrt.org.uk/jrsstct.htm
@@ -52,11 +52,11 @@ this command within your Rails app.
git clone git://github.com/frabcus/acts_as_xapian.git vendor/plugins/acts_as_xapian
-Xapian 1.0.5 and associated Ruby bindings are also required.
+Xapian 1.0.5 and associated Ruby bindings are also required.
-Debian or Ubuntu - install the packages libxapian15 and libxapian-ruby1.8.
+Debian or Ubuntu - install the packages libxapian15 and libxapian-ruby1.8.
-Mac OSX - follow the instructions for installing from source on
+Mac OSX - follow the instructions for installing from source on
the "Installing Xapian":http://xapian.org/docs/install.html page - you need the
Xapian library and bindings (you don't need Omega).
@@ -102,7 +102,7 @@ Solr getting in the way whenever you want to use a new feature from Lucene.
* No Java - an advantage if you're more used to working in the rest of the
open source world. acts_as_xapian, it's pure Ruby and C++.
-* Xapian's awesome email list - the kids over at
+* Xapian's awesome email list - the kids over at
"xapian-discuss":http://lists.xapian.org/mailman/listinfo/xapian-discuss
are super helpful. Useful if you need to extend and improve acts_as_xapian. The
Ruby bindings are mature and well maintained as part of Xapian.
@@ -131,11 +131,11 @@ Here's how to add indexing to your Rails app:
Options must include:
-* :texts, an array of fields for indexing with full text search.
+* :texts, an array of fields for indexing with full text search.
e.g. :texts => [ :title, :body ]
-* :values, things which have a range of values for sorting, or for collapsing.
-Specify an array quadruple of [ field, identifier, prefix, type ] where
+* :values, things which have a range of values for sorting, or for collapsing.
+Specify an array quadruple of [ field, identifier, prefix, type ] where
** identifier is an arbitary numeric identifier for use in the Xapian database
** prefix is the part to use in search queries that goes before the :
** type can be any of :string, :number or :date
@@ -143,8 +143,8 @@ Specify an array quadruple of [ field, identifier, prefix, type ] where
e.g. :values => [ [ :created_at, 0, "created_at", :date ],
[ :size, 1, "size", :string ] ]
-* :terms, things which come with a prefix (before a :) in search queries.
-Specify an array triple of [ field, char, prefix ] where
+* :terms, things which come with a prefix (before a :) in search queries.
+Specify an array triple of [ field, char, prefix ] where
** char is an arbitary single upper case char used in the Xapian database, just
pick any single uppercase character, but use a different one for each prefix.
** prefix is the part to use in search queries that goes before the :
@@ -152,7 +152,7 @@ For example, if you were making Google and indexing to be able to later do a
query like "site:www.whatdotheyknow.com", then the prefix would be "site".
e.g. :terms => [ [ :variety, 'V', "variety" ] ]
-
+
A 'field' is a symbol referring to either an attribute or a function which
returns the text, date or number to index. Both 'identifier' and 'char' must be
the same for the same prefix in different models.
@@ -170,7 +170,7 @@ object isn't indexed
3. Call 'rake xapian:rebuild_index models="ModelName1 ModelName2"' to build the index
the first time (you must specify all your indexed models). It's put in a
-development/test/production dir in acts_as_xapian/xapiandbs. See f. Configuration
+development/test/production dir in acts_as_xapian/xapiandbs. See f. Configuration
below if you want to change this.
4. Then from a cron job or a daemon, or by hand regularly!, call 'rake xapian:update_index'
@@ -201,10 +201,10 @@ And then a hash of options:
* :sort_by_ascending - Default true (documents with higher values better/earlier), set to false for descending sort
* :collapse_by_prefix - Optionally, prefix of value to collapse by (i.e. only return most relevant result from group)
-Google like query syntax is as described in
+Google like query syntax is as described in
"Xapian::QueryParser Syntax":http://www.xapian.org/docs/queryparser.html
Queries can include prefix:value parts, according to what you indexed in the
-acts_as_xapian part above. You can also say things like model:InfoRequestEvent
+acts_as_xapian part above. You can also say things like model:InfoRequestEvent
to constrain by model in more complex ways than the :model parameter, or
modelid:InfoRequestEvent-100 to only find one specific object.
@@ -236,12 +236,12 @@ f. Configuration
================
If you want to customise the configuration of acts_as_xapian, it will look for
-a file called 'xapian.yml' under RAILS_ROOT/config. As is familiar from the
+a file called 'xapian.yml' under Rails.root/config. As is familiar from the
format of the database.yml file, separate :development, :test and :production
sections are expected.
The following options are available:
-* base_db_path - specifies the directory, relative to RAILS_ROOT, in which
+* base_db_path - specifies the directory, relative to Rails.root, in which
acts_as_xapian stores its search index databases. Default is the directory
xapiandbs within the acts_as_xapian directory.
@@ -264,7 +264,7 @@ temporarily add this to the end of your config/environment.rb
h. Support
==========
-Please ask any questions on the
+Please ask any questions on the
"acts_as_xapian Google Group":http://groups.google.com/group/acts_as_xapian
The official home page and repository for acts_as_xapian are the
diff --git a/vendor/plugins/acts_as_xapian/init.rb b/vendor/plugins/acts_as_xapian/init.rb
index 36b43ac0b..1e5b8557b 100644
--- a/vendor/plugins/acts_as_xapian/init.rb
+++ b/vendor/plugins/acts_as_xapian/init.rb
@@ -1,7 +1,7 @@
# acts_as_xapian/init.rb:
#
# Copyright (c) 2008 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
require 'acts_as_xapian'
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 67d6f3258..1e5df8de4 100644
--- a/vendor/plugins/acts_as_xapian/lib/acts_as_xapian.rb
+++ b/vendor/plugins/acts_as_xapian/lib/acts_as_xapian.rb
@@ -2,7 +2,7 @@
# Xapian full text search in Ruby on Rails.
#
# Copyright (c) 2008 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
#
# Documentation
# =============
@@ -88,16 +88,16 @@ module ActsAsXapian
return unless @@db_path.nil?
# barf if we can't figure out the environment
- environment = (ENV['RAILS_ENV'] or RAILS_ENV)
+ environment = (ENV['RAILS_ENV'] or Rails.env)
raise "Set RAILS_ENV, so acts_as_xapian can find the right Xapian database" if not environment
# check for a config file
- config_file = RAILS_ROOT + "/config/xapian.yml"
+ config_file = Rails.root.join("config","xapian.yml")
@@config = File.exists?(config_file) ? YAML.load_file(config_file)[environment] : {}
# figure out where the DBs should go
if config['base_db_path']
- db_parent_path = RAILS_ROOT + "/" + config['base_db_path']
+ db_parent_path = Rails.root.join(config['base_db_path'])
else
db_parent_path = File.join(File.dirname(__FILE__), '../xapiandbs/')
end
@@ -711,6 +711,9 @@ module ActsAsXapian
# We fork here, so each batch is run in a different process. This is
# because otherwise we get a memory "leak" and you can't rebuild very
# large databases (however long you have!)
+
+ ActiveRecord::Base.connection.disconnect!
+
pid = Process.fork # XXX this will only work on Unix, tough
if pid
Process.waitpid(pid)
@@ -718,11 +721,10 @@ module ActsAsXapian
raise "batch fork child failed, exiting also"
end
# 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)
+ ActiveRecord::Base.establish_connection
@@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
@@ -738,6 +740,8 @@ module ActsAsXapian
Kernel.exit! 0
end
+ ActiveRecord::Base.establish_connection
+
end
end
end
diff --git a/vendor/plugins/exception_notification/README b/vendor/plugins/exception_notification/README
deleted file mode 100644
index d5e343630..000000000
--- a/vendor/plugins/exception_notification/README
+++ /dev/null
@@ -1,144 +0,0 @@
-= 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
deleted file mode 100644
index b3ff82322..000000000
--- a/vendor/plugins/exception_notification/exception_notification.gemspec
+++ /dev/null
@@ -1,11 +0,0 @@
-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
deleted file mode 100644
index ef215f809..000000000
--- a/vendor/plugins/exception_notification/init.rb
+++ /dev/null
@@ -1 +0,0 @@
-require "exception_notification"
diff --git a/vendor/plugins/exception_notification/lib/exception_notification.rb b/vendor/plugins/exception_notification/lib/exception_notification.rb
deleted file mode 100644
index bf5975201..000000000
--- a/vendor/plugins/exception_notification/lib/exception_notification.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-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
deleted file mode 100644
index 6b9e236f7..000000000
--- a/vendor/plugins/exception_notification/lib/exception_notification/consider_local.rb
+++ /dev/null
@@ -1,31 +0,0 @@
-#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
deleted file mode 100644
index 19895e8db..000000000
--- a/vendor/plugins/exception_notification/lib/exception_notification/notifiable.rb
+++ /dev/null
@@ -1,66 +0,0 @@
-# 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
deleted file mode 100644
index 2cab3f963..000000000
--- a/vendor/plugins/exception_notification/lib/exception_notification/notifier.rb
+++ /dev/null
@@ -1,80 +0,0 @@
-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
deleted file mode 100644
index 942e1c527..000000000
--- a/vendor/plugins/exception_notification/lib/exception_notification/notifier_helper.rb
+++ /dev/null
@@ -1,67 +0,0 @@
-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
deleted file mode 100644
index e077f405b..000000000
--- a/vendor/plugins/exception_notification/test/exception_notifier_helper_test.rb
+++ /dev/null
@@ -1,62 +0,0 @@
-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
deleted file mode 100644
index 5831a1784..000000000
--- a/vendor/plugins/exception_notification/test/test_helper.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-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
deleted file mode 100644
index 7d13ba007..000000000
--- a/vendor/plugins/exception_notification/views/exception_notifier/_backtrace.rhtml
+++ /dev/null
@@ -1 +0,0 @@
-<%= @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
deleted file mode 100644
index 42dd803f1..000000000
--- a/vendor/plugins/exception_notification/views/exception_notifier/_environment.rhtml
+++ /dev/null
@@ -1,7 +0,0 @@
-<% 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
deleted file mode 100644
index e817847e4..000000000
--- a/vendor/plugins/exception_notification/views/exception_notifier/_inspect_model.rhtml
+++ /dev/null
@@ -1,16 +0,0 @@
-<% 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
deleted file mode 100644
index 25423093f..000000000
--- a/vendor/plugins/exception_notification/views/exception_notifier/_request.rhtml
+++ /dev/null
@@ -1,4 +0,0 @@
-* 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
deleted file mode 100644
index 308684885..000000000
--- a/vendor/plugins/exception_notification/views/exception_notifier/_session.rhtml
+++ /dev/null
@@ -1,2 +0,0 @@
-* 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
deleted file mode 100644
index 1ed5a3f2b..000000000
--- a/vendor/plugins/exception_notification/views/exception_notifier/_title.rhtml
+++ /dev/null
@@ -1,3 +0,0 @@
--------------------------------
-<%= 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
deleted file mode 100644
index 715c105bf..000000000
--- a/vendor/plugins/exception_notification/views/exception_notifier/exception_notification.rhtml
+++ /dev/null
@@ -1,6 +0,0 @@
-A <%= @exception.class %> occurred <%= @exception_source %>:
-
- <%= @exception.message %>
- <%= @backtrace.first %>
-
-<%= @sections.map { |section| render_section(section) }.join %>
diff --git a/vendor/plugins/globalize2/LICENSE b/vendor/plugins/globalize2/LICENSE
deleted file mode 100644
index 94a6b8160..000000000
--- a/vendor/plugins/globalize2/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-The MIT License
-
-Copyright (c) 2008, 2009 Joshua Harvey
-
-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. \ No newline at end of file
diff --git a/vendor/plugins/globalize2/README.textile b/vendor/plugins/globalize2/README.textile
deleted file mode 100644
index e47e9bf37..000000000
--- a/vendor/plugins/globalize2/README.textile
+++ /dev/null
@@ -1,86 +0,0 @@
-h1. Globalize2
-
-Globalize2 is the successor of Globalize for Rails.
-
-It is compatible with and builds on the new "I18n api in Ruby on Rails":http://guides.rubyonrails.org/i18n.html. and adds model translations to ActiveRecord.
-
-Globalize2 is much more lightweight and compatible than its predecessor was. Model translations in Globalize2 use default ActiveRecord features and do not limit any ActiveRecord functionality any more.
-
-h2. Requirements
-
-ActiveRecord
-I18n
-
-(or Rails > 2.2)
-
-h2. Installation
-
-To install Globalize2 with its default setup just use:
-
-<pre><code>
-script/plugin install git://github.com/joshmh/globalize2.git
-</code></pre>
-
-h2. Model translations
-
-Model translations allow you to translate your models' attribute values. E.g.
-
-<pre><code>
-class Post < ActiveRecord::Base
- translates :title, :text
-end
-</code></pre>
-
-Allows you to values for the attributes :title and :text per locale:
-
-<pre><code>
-I18n.locale = :en
-post.title # => Globalize2 rocks!
-
-I18n.locale = :he
-post.title # => גלובאלייז2 שולט!
-</code></pre>
-
-In order to make this work, you'll need to add the appropriate translation tables. Globalize2 comes with a handy helper method to help you do this. It's called @create_translation_table!@. Here's an example:
-
-<pre><code>
-class CreatePosts < ActiveRecord::Migration
- def self.up
- create_table :posts do |t|
- t.timestamps
- end
- Post.create_translation_table! :title => :string, :text => :text
- end
- def self.down
- drop_table :posts
- Post.drop_translation_table!
- end
-end
-</code></pre>
-
-Note that the ActiveRecord model @Post@ must already exist and have a @translates@ directive listing the translated fields.
-
-h2. Migration from Globalize
-
-See this script by Tomasz Stachewicz: http://gist.github.com/120867
-
-h2. Changes since Globalize2 v0.1.0
-
-* The association globalize_translations has been renamed to translations.
-
-h2. Alternative Solutions
-
-* "Veger's fork":http://github.com/veger/globalize2 - uses default AR schema for the default locale, delegates to the translations table for other locales only
-* "TranslatableColumns":http://github.com/iain/translatable_columns - have multiple languages of the same attribute in a model (Iain Hecker)
-* "localized_record":http://github.com/glennpow/localized_record - allows records to have localized attributes without any modifications to the database (Glenn Powell)
-* "model_translations":http://github.com/janne/model_translations - Minimal implementation of Globalize2 style model translations (Jan Andersson)
-
-h2. Related solutions
-
-* "globalize2_versioning":http://github.com/joshmh/globalize2_versioning - acts_as_versioned style versioning for Globalize2 (Joshua Harvey)
-* "i18n_multi_locales_validations":http://github.com/ZenCocoon/i18n_multi_locales_validations - multi-locales attributes validations to validates attributes from Globalize2 translations models (Sébastien Grosjean)
-* "Globalize2 Demo App":http://github.com/svenfuchs/globalize2-demo - demo application for Globalize2 (Sven Fuchs)</li>
-* "migrate_from_globalize1":http://gist.github.com/120867 - migrate model translations from Globalize1 to Globalize2 (Tomasz Stachewicz)</li>
-* "easy_globalize2_accessors":http://github.com/astropanic/easy_globalize2_accessors - easily access (read and write) globalize2-translated fields (astropanic, Tomasz Stachewicz)</li>
-* "globalize2-easy-translate":http://github.com/bsamman/globalize2-easy-translate - adds methods to easily access or set translated attributes to your model (bsamman)</li>
-* "batch_translations":http://github.com/alvarezrilla/batch_translations - allow saving multiple Globalize2 translations in the same request (Jose Alvarez Rilla)</li>
diff --git a/vendor/plugins/globalize2/Rakefile b/vendor/plugins/globalize2/Rakefile
deleted file mode 100644
index bc35dada4..000000000
--- a/vendor/plugins/globalize2/Rakefile
+++ /dev/null
@@ -1,39 +0,0 @@
-require 'rake'
-require 'rake/testtask'
-require 'rake/rdoctask'
-
-desc 'Default: run unit tests.'
-task :default => :test
-
-desc 'Test the globalize2 plugin.'
-Rake::TestTask.new(:test) do |t|
- t.libs << 'lib'
- t.pattern = 'test/**/*_test.rb'
- t.verbose = true
-end
-
-desc 'Generate documentation for the globalize2 plugin.'
-Rake::RDocTask.new(:rdoc) do |rdoc|
- rdoc.rdoc_dir = 'rdoc'
- rdoc.title = 'Globalize2'
- rdoc.options << '--line-numbers' << '--inline-source'
- rdoc.rdoc_files.include('README')
- rdoc.rdoc_files.include('lib/**/*.rb')
-end
-
-begin
- require 'jeweler'
- Jeweler::Tasks.new do |s|
- s.name = "globalize2"
- s.summary = "Rails I18n: de-facto standard library for ActiveRecord data translation"
- s.description = "Rails I18n: de-facto standard library for ActiveRecord data translation"
- s.email = "joshmh@gmail.com"
- s.homepage = "http://github.com/joshmh/globalize2"
- # s.rubyforge_project = ''
- s.authors = ["Sven Fuchs, Joshua Harvey, Clemens Kofler, John-Paul Bader"]
- # s.add_development_dependency ''
- end
- Jeweler::GemcutterTasks.new
-rescue LoadError
- puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
-end
diff --git a/vendor/plugins/globalize2/VERSION b/vendor/plugins/globalize2/VERSION
deleted file mode 100644
index 0c62199f1..000000000
--- a/vendor/plugins/globalize2/VERSION
+++ /dev/null
@@ -1 +0,0 @@
-0.2.1
diff --git a/vendor/plugins/globalize2/generators/db_backend.rb b/vendor/plugins/globalize2/generators/db_backend.rb
deleted file mode 100644
index e69de29bb..000000000
--- a/vendor/plugins/globalize2/generators/db_backend.rb
+++ /dev/null
diff --git a/vendor/plugins/globalize2/generators/templates/db_backend_migration.rb b/vendor/plugins/globalize2/generators/templates/db_backend_migration.rb
deleted file mode 100644
index 0f0261113..000000000
--- a/vendor/plugins/globalize2/generators/templates/db_backend_migration.rb
+++ /dev/null
@@ -1,25 +0,0 @@
-class ActsAsTaggableMigration < ActiveRecord::Migration
- def self.up
- create_table :globalize_translations do |t|
- t.string :locale, :null => false
- t.string :key, :null => false
- t.string :translation
- t.timestamps
- end
-
-# TODO: FINISH DOING MIGRATION -- stopped in the middle
-
- create_table :globalize_translations_map do |t|
- t.string :key, :null => false
- t.integer :translation_id, :null => false
- end
-
- add_index :taggings, :tag_id
- add_index :taggings, [:taggable_id, :taggable_type]
- end
-
- def self.down
- drop_table :globalize_translations
- drop_table :tags
- end
-end
diff --git a/vendor/plugins/globalize2/globalize2.gemspec b/vendor/plugins/globalize2/globalize2.gemspec
deleted file mode 100644
index 89021115e..000000000
--- a/vendor/plugins/globalize2/globalize2.gemspec
+++ /dev/null
@@ -1,81 +0,0 @@
-# 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{globalize2}
- s.version = "0.2.0"
-
- s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
- s.authors = ["Sven Fuchs, Joshua Harvey, Clemens Kofler, John-Paul Bader"]
- s.date = %q{2010-04-22}
- s.description = %q{Rails I18n: de-facto standard library for ActiveRecord data translation}
- s.email = %q{joshmh@gmail.com}
- s.extra_rdoc_files = [
- "LICENSE",
- "README.textile"
- ]
- s.files = [
- ".gitignore",
- "LICENSE",
- "README.textile",
- "Rakefile",
- "VERSION",
- "generators/db_backend.rb",
- "generators/templates/db_backend_migration.rb",
- "globalize2.gemspec",
- "init.rb",
- "lib/globalize.rb",
- "lib/globalize/active_record.rb",
- "lib/globalize/active_record/adapter.rb",
- "lib/globalize/active_record/attributes.rb",
- "lib/globalize/active_record/migration.rb",
- "lib/i18n/missing_translations_log_handler.rb",
- "lib/i18n/missing_translations_raise_handler.rb",
- "test/active_record/fallbacks_test.rb",
- "test/active_record/migration_test.rb",
- "test/active_record/sti_translated_test.rb",
- "test/active_record/translates_test.rb",
- "test/active_record/translation_class_test.rb",
- "test/active_record/validation_tests.rb",
- "test/active_record_test.rb",
- "test/all.rb",
- "test/data/models.rb",
- "test/data/no_globalize_schema.rb",
- "test/data/schema.rb",
- "test/i18n/missing_translations_test.rb",
- "test/test_helper.rb"
- ]
- s.homepage = %q{http://github.com/joshmh/globalize2}
- s.rdoc_options = ["--charset=UTF-8"]
- s.require_paths = ["lib"]
- s.rubygems_version = %q{1.3.6}
- s.summary = %q{Rails I18n: de-facto standard library for ActiveRecord data translation}
- s.test_files = [
- "test/active_record/fallbacks_test.rb",
- "test/active_record/migration_test.rb",
- "test/active_record/sti_translated_test.rb",
- "test/active_record/translates_test.rb",
- "test/active_record/translation_class_test.rb",
- "test/active_record/validation_tests.rb",
- "test/active_record_test.rb",
- "test/all.rb",
- "test/data/models.rb",
- "test/data/no_globalize_schema.rb",
- "test/data/schema.rb",
- "test/i18n/missing_translations_test.rb",
- "test/test_helper.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
- else
- end
- else
- end
-end
-
diff --git a/vendor/plugins/globalize2/init.rb b/vendor/plugins/globalize2/init.rb
deleted file mode 100644
index a4089251b..000000000
--- a/vendor/plugins/globalize2/init.rb
+++ /dev/null
@@ -1 +0,0 @@
-require 'globalize'
diff --git a/vendor/plugins/globalize2/lib/globalize.rb b/vendor/plugins/globalize2/lib/globalize.rb
deleted file mode 100644
index 67c1878ec..000000000
--- a/vendor/plugins/globalize2/lib/globalize.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-module Globalize
- autoload :ActiveRecord, 'globalize/active_record'
-
- class << self
- def fallbacks?
- I18n.respond_to?(:fallbacks)
- end
-
- def fallbacks(locale)
- fallbacks? ? I18n.fallbacks[locale] : [locale.to_sym]
- end
- end
-end
-
-ActiveRecord::Base.send(:include, Globalize::ActiveRecord)
diff --git a/vendor/plugins/globalize2/lib/globalize/active_record.rb b/vendor/plugins/globalize2/lib/globalize/active_record.rb
deleted file mode 100644
index 3095bfe28..000000000
--- a/vendor/plugins/globalize2/lib/globalize/active_record.rb
+++ /dev/null
@@ -1,238 +0,0 @@
-module Globalize
- class MigrationError < StandardError; end
- class MigrationMissingTranslatedField < MigrationError; end
- class BadMigrationFieldType < MigrationError; end
-
- module ActiveRecord
- autoload :Adapter, 'globalize/active_record/adapter'
- autoload :Attributes, 'globalize/active_record/attributes'
- autoload :Migration, 'globalize/active_record/migration'
-
- def self.included(base)
- base.extend ActMacro
- end
-
- class << self
- def build_translation_class(target, options)
- options[:table_name] ||= "#{target.table_name.singularize}_translations"
-
- klass = target.const_defined?(:Translation) ?
- target.const_get(:Translation) :
- target.const_set(:Translation, Class.new(::ActiveRecord::Base))
-
- klass.class_eval do
- set_table_name(options[:table_name])
- belongs_to target.name.underscore.gsub('/', '_')
- def locale; read_attribute(:locale).to_sym; end
- def locale=(locale); write_attribute(:locale, locale.to_s); end
- end
-
- klass
- end
- end
-
- module ActMacro
- def locale
- (defined?(@@locale) && @@locale)
- end
-
- def locale=(locale)
- @@locale = locale
- end
-
- def translates(*attr_names)
- return if translates?
- options = attr_names.extract_options!
-
- class_inheritable_accessor :translation_class, :translated_attribute_names
- class_inheritable_writer :required_attributes
- self.translation_class = ActiveRecord.build_translation_class(self, options)
- self.translated_attribute_names = attr_names.map(&:to_sym)
-
- include InstanceMethods
- extend ClassMethods, Migration
-
- after_save :save_translations!
- ActiveSupport::Deprecation.silence do
- # Silence the warning that :class_name is deprecated and will be
- # removed in Rails 3, since it clutters up e.g. test output, and
- # there is nothing obvious that we can replace it with in Rails 2.
-
- has_many :translations, :class_name => translation_class.name,
- :foreign_key => class_name.foreign_key,
- :dependent => :delete_all,
- :extend => HasManyExtensions
- end
-
- named_scope :with_translations, lambda { |locale|
- conditions = required_attributes.map do |attribute|
- "#{quoted_translation_table_name}.#{attribute} IS NOT NULL"
- end
- conditions << "#{quoted_translation_table_name}.locale = ?"
- { :include => :translations, :conditions => [conditions.join(' AND '), locale] }
- }
-
- attr_names.each { |attr_name| translated_attr_accessor(attr_name) }
- end
-
- def translates?
- included_modules.include?(InstanceMethods)
- end
- end
-
- module HasManyExtensions
- def by_locale(locale)
- first(:conditions => { :locale => locale.to_s })
- end
-
- def by_locales(locales)
- all(:conditions => { :locale => locales.map(&:to_s) })
- end
- end
-
- module ClassMethods
- delegate :set_translation_table_name, :to => :translation_class
-
- def with_locale(locale)
- begin
- previous_locale, self.locale = self.locale, locale
- result = yield
- ensure
- self.locale = previous_locale
- end
- result
- end
-
- def translation_table_name
- translation_class.table_name
- end
-
- def quoted_translation_table_name
- translation_class.quoted_table_name
- end
-
- def required_attributes
- @required_attributes ||= reflect_on_all_validations.select do |validation|
- validation.macro == :validates_presence_of && translated_attribute_names.include?(validation.name)
- end.map(&:name)
- end
-
- def respond_to?(method, *args, &block)
- method.to_s =~ /^find_by_(\w+)$/ && translated_attribute_names.include?($1.to_sym) || super
- end
-
- def method_missing(method, *args)
- if method.to_s =~ /^find_by_(\w+)$/ && translated_attribute_names.include?($1.to_sym)
- find_first_by_translated_attr_and_locales($1, args.first)
- elsif method.to_s =~ /^find_all_by_(\w+)$/ && translated_attribute_names.include?($1.to_sym)
- find_all_by_translated_attr_and_locales($1, args.first)
- else
- super
- end
- end
-
- protected
-
- def find_first_by_translated_attr_and_locales(name, value)
- query = "#{translated_attr_name(name)} = ? AND #{translated_attr_name('locale')} IN (?)"
- locales = Globalize.fallbacks(locale || I18n.locale).map(&:to_s)
- find(
- :first,
- :joins => :translations,
- :conditions => [query, value, locales],
- :readonly => false
- )
- end
-
- def find_all_by_translated_attr_and_locales(name, value)
- query = "#{translated_attr_name(name)} = ? AND #{translated_attr_name('locale')} IN (?)"
- locales = Globalize.fallbacks(locale || I18n.locale).map(&:to_s)
- find(
- :all,
- :joins => :translations,
- :conditions => [query, value, locales],
- :readonly => false
- )
- end
-
- def translated_attr_accessor(name)
- define_method "#{name}=", lambda { |value|
- globalize.write(self.class.locale || I18n.locale, name, value)
- self[name] = value
- }
- define_method name, lambda { |*args|
- globalize.fetch(args.first || self.class.locale || I18n.locale, name)
- }
- alias_method "#{name}_before_type_cast", name
- end
-
- def translated_attr_name(name)
- "#{translation_class.table_name}.#{name}"
- end
- end
-
- module InstanceMethods
- def globalize
- @globalize ||= Adapter.new self
- end
-
- def attributes
- self.attribute_names.inject({}) do |attrs, name|
- attrs[name] = read_attribute(name) ||
- (globalize.fetch(I18n.locale, name) rescue nil)
- attrs
- end
- end
-
- def attributes=(attributes, *args)
- if attributes.respond_to?(:delete) && locale = attributes.delete(:locale)
- self.class.with_locale(locale) { super }
- else
- super
- end
- end
-
- def attribute_names
- translated_attribute_names.map(&:to_s) + super
- end
-
- def available_locales
- translations.scoped(:select => 'DISTINCT locale').map(&:locale)
- end
-
- def translated_locales
- translations.map(&:locale)
- end
-
- def translated_attributes
- translated_attribute_names.inject({}) do |attributes, name|
- attributes.merge(name => send(name))
- end
- end
-
- def set_translations(options)
- options.keys.each do |locale|
- translation = translations.find_by_locale(locale.to_s) ||
- translations.build(:locale => locale.to_s)
- translation.update_attributes!(options[locale])
- end
- end
-
- def reload(options = nil)
- translated_attribute_names.each { |name| @attributes.delete(name.to_s) }
- globalize.reset
- super(options)
- end
-
- protected
-
- def save_translations!
- globalize.save_translations!
- end
- end
- end
-end
-
-def globalize_write(name, value)
- globalize.write(self.class.locale || I18n.locale, name, value)
-end
diff --git a/vendor/plugins/globalize2/lib/globalize/active_record/adapter.rb b/vendor/plugins/globalize2/lib/globalize/active_record/adapter.rb
deleted file mode 100644
index 12f89ec01..000000000
--- a/vendor/plugins/globalize2/lib/globalize/active_record/adapter.rb
+++ /dev/null
@@ -1,80 +0,0 @@
-module Globalize
- module ActiveRecord
- class Adapter
- # The cache caches attributes that already were looked up for read access.
- # The stash keeps track of new or changed values that need to be saved.
- attr_reader :record, :cache, :stash
-
- def initialize(record)
- @record = record
- @cache = Attributes.new
- @stash = Attributes.new
- end
-
- def fetch(locale, attr_name)
- cache.contains?(locale, attr_name) ?
- cache.read(locale, attr_name) :
- cache.write(locale, attr_name, fetch_attribute(locale, attr_name))
- end
-
- def write(locale, attr_name, value)
- stash.write(locale, attr_name, value)
- cache.write(locale, attr_name, value)
- end
-
- def save_translations!
- stash.each do |locale, attrs|
- translation = record.translations.find_or_initialize_by_locale(locale.to_s)
- attrs.each { |attr_name, value| translation[attr_name] = value }
- translation.save!
- end
- stash.clear
- end
-
- def reset
- cache.clear
- # stash.clear
- end
-
- protected
-
- def fetch_translation(locale)
- locale = locale.to_sym
- record.translations.loaded? ? record.translations.detect { |t| t.locale == locale } :
- record.translations.by_locale(locale)
- end
-
- def fetch_translations(locale)
- # only query if not already included with :include => translations
- record.translations.loaded? ? record.translations :
- record.translations.by_locales(Globalize.fallbacks(locale))
- end
-
- def fetch_attribute(locale, attr_name)
- translations = fetch_translations(locale)
- value, requested_locale = nil, locale
-
- Globalize.fallbacks(locale).each do |fallback|
- translation = translations.detect { |t| t.locale == fallback }
- value = translation && translation.send(attr_name)
- locale = fallback && break if value
- end
-
- set_metadata(value, :locale => locale, :requested_locale => requested_locale)
- value
- end
-
- def set_metadata(object, metadata)
- if object.respond_to?(:translation_metadata)
- object.translation_metadata.merge!(meta_data)
- end
- end
-
- def translation_metadata_accessor(object)
- return if obj.respond_to?(:translation_metadata)
- class << object; attr_accessor :translation_metadata end
- object.translation_metadata ||= {}
- end
- end
- end
-end
diff --git a/vendor/plugins/globalize2/lib/globalize/active_record/attributes.rb b/vendor/plugins/globalize2/lib/globalize/active_record/attributes.rb
deleted file mode 100644
index 7bd923ce2..000000000
--- a/vendor/plugins/globalize2/lib/globalize/active_record/attributes.rb
+++ /dev/null
@@ -1,25 +0,0 @@
-# Helper class for storing values per locale. Used by Globalize::Adapter
-# to stash and cache attribute values.
-module Globalize
- module ActiveRecord
- class Attributes < Hash
- def [](locale)
- locale = locale.to_sym
- self[locale] = {} unless has_key?(locale)
- self.fetch(locale)
- end
-
- def contains?(locale, attr_name)
- self[locale].has_key?(attr_name)
- end
-
- def read(locale, attr_name)
- self[locale][attr_name]
- end
-
- def write(locale, attr_name, value)
- self[locale][attr_name] = value
- end
- end
- end
-end
diff --git a/vendor/plugins/globalize2/lib/globalize/active_record/migration.rb b/vendor/plugins/globalize2/lib/globalize/active_record/migration.rb
deleted file mode 100644
index fa63aed8c..000000000
--- a/vendor/plugins/globalize2/lib/globalize/active_record/migration.rb
+++ /dev/null
@@ -1,44 +0,0 @@
-module Globalize
- module ActiveRecord
- module Migration
- def create_translation_table!(fields)
- translated_attribute_names.each do |f|
- raise MigrationMissingTranslatedField, "Missing translated field #{f}" unless fields[f]
- end
-
- fields.each do |name, type|
- if translated_attribute_names.include?(name) && ![:string, :text].include?(type)
- raise BadMigrationFieldType, "Bad field type for #{name}, should be :string or :text"
- end
- end
-
- self.connection.create_table(translation_table_name) do |t|
- t.references table_name.sub(/^#{table_name_prefix}/, "").singularize
- t.string :locale
- fields.each do |name, type|
- t.column name, type
- end
- t.timestamps
- end
-
- self.connection.add_index(
- translation_table_name,
- "#{table_name.sub(/^#{table_name_prefix}/, "").singularize}_id",
- :name => translation_index_name
- )
- end
-
- def translation_index_name
- require 'digest/sha1'
- # FIXME what's the max size of an index name?
- index_name = "index_#{translation_table_name}_on_#{self.table_name.singularize}_id"
- index_name.size < 50 ? index_name : "index_#{Digest::SHA1.hexdigest(index_name)}"
- end
-
- def drop_translation_table!
- self.connection.remove_index(translation_table_name, :name => translation_index_name) rescue nil
- self.connection.drop_table(translation_table_name)
- end
- end
- end
-end
diff --git a/vendor/plugins/globalize2/lib/i18n/missing_translations_log_handler.rb b/vendor/plugins/globalize2/lib/i18n/missing_translations_log_handler.rb
deleted file mode 100644
index 24c10890a..000000000
--- a/vendor/plugins/globalize2/lib/i18n/missing_translations_log_handler.rb
+++ /dev/null
@@ -1,41 +0,0 @@
-# A simple exception handler that behaves like the default exception handler
-# but additionally logs missing translations to a given log.
-#
-# Useful for identifying missing translations during testing.
-#
-# E.g.
-#
-# require 'globalize/i18n/missing_translations_log_handler'
-# I18n.missing_translations_logger = RAILS_DEFAULT_LOGGER
-# I18n.exception_handler = :missing_translations_log_handler
-#
-# To set up a different log file:
-#
-# logger = Logger.new("#{RAILS_ROOT}/log/missing_translations.log")
-# I18n.missing_translations_logger = logger
-
-module I18n
- @@missing_translations_logger = nil
-
- class << self
- def missing_translations_logger
- @@missing_translations_logger ||= begin
- require 'logger' unless defined?(Logger)
- Logger.new(STDOUT)
- end
- end
-
- def missing_translations_logger=(logger)
- @@missing_translations_logger = logger
- end
-
- def missing_translations_log_handler(exception, locale, key, options)
- if MissingTranslationData === exception
- missing_translations_logger.warn(exception.message)
- return exception.message
- else
- raise exception
- end
- end
- end
-end
diff --git a/vendor/plugins/globalize2/lib/i18n/missing_translations_raise_handler.rb b/vendor/plugins/globalize2/lib/i18n/missing_translations_raise_handler.rb
deleted file mode 100644
index 18237b151..000000000
--- a/vendor/plugins/globalize2/lib/i18n/missing_translations_raise_handler.rb
+++ /dev/null
@@ -1,25 +0,0 @@
-# A simple exception handler that behaves like the default exception handler
-# but also raises on missing translations.
-#
-# Useful for identifying missing translations during testing.
-#
-# E.g.
-#
-# require 'globalize/i18n/missing_translations_raise_handler'
-# I18n.exception_handler = :missing_translations_raise_handler
-module I18n
- class << self
- def missing_translations_raise_handler(exception, locale, key, options)
- raise exception
- end
- end
-end
-
-I18n.exception_handler = :missing_translations_raise_handler
-
-ActionView::Helpers::TranslationHelper.module_eval do
- def translate(key, options = {})
- I18n.translate(key, options)
- end
- alias :t :translate
-end
diff --git a/vendor/plugins/globalize2/test/active_record/fallbacks_test.rb b/vendor/plugins/globalize2/test/active_record/fallbacks_test.rb
deleted file mode 100644
index 449ec8b2b..000000000
--- a/vendor/plugins/globalize2/test/active_record/fallbacks_test.rb
+++ /dev/null
@@ -1,102 +0,0 @@
-require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
-require File.expand_path(File.dirname(__FILE__) + '/../data/models')
-
-if I18n.respond_to?(:fallbacks)
- class TranslatedTest < ActiveSupport::TestCase
- def setup
- I18n.locale = :'en-US'
- I18n.fallbacks.clear
- reset_db!
- ActiveRecord::Base.locale = nil
- end
-
- def teardown
- I18n.fallbacks.clear
- end
-
- test "keeping one field in new locale when other field is changed" do
- I18n.fallbacks.map 'de-DE' => [ 'en-US' ]
- post = Post.create :subject => 'foo'
- I18n.locale = 'de-DE'
- post.content = 'bar'
- assert_equal 'foo', post.subject
- end
-
- test "modifying non-required field in a new locale" do
- I18n.fallbacks.map 'de-DE' => [ 'en-US' ]
- post = Post.create :subject => 'foo'
- I18n.locale = 'de-DE'
- post.content = 'bar'
- assert post.save
- end
-
- test "resolves a simple fallback" do
- I18n.locale = 'de-DE'
- post = Post.create :subject => 'foo'
- I18n.locale = 'de'
- post.subject = 'baz'
- post.content = 'bar'
- post.save
- I18n.locale = 'de-DE'
- assert_equal 'foo', post.subject
- assert_equal 'bar', post.content
- end
-
- test "resolves a simple fallback without reloading" do
- I18n.locale = 'de-DE'
- post = Post.new :subject => 'foo'
- I18n.locale = 'de'
- post.subject = 'baz'
- post.content = 'bar'
- I18n.locale = 'de-DE'
- assert_equal 'foo', post.subject
- assert_equal 'bar', post.content
- end
-
- test "resolves a complex fallback without reloading" do
- I18n.fallbacks.map 'de' => %w(en he)
- I18n.locale = 'de'
- post = Post.new
- I18n.locale = 'en'
- post.subject = 'foo'
- I18n.locale = 'he'
- post.subject = 'baz'
- post.content = 'bar'
- I18n.locale = 'de'
- assert_equal 'foo', post.subject
- assert_equal 'bar', post.content
- end
-
- test 'fallbacks with lots of locale switching' do
- I18n.fallbacks.map :'de-DE' => [ :'en-US' ]
- post = Post.create :subject => 'foo'
-
- I18n.locale = :'de-DE'
- assert_equal 'foo', post.subject
-
- I18n.locale = :'en-US'
- post.update_attribute :subject, 'bar'
-
- I18n.locale = :'de-DE'
- assert_equal 'bar', post.subject
- end
-
- test 'fallbacks with lots of locale switching' do
- I18n.fallbacks.map :'de-DE' => [ :'en-US' ]
- child = Child.create :content => 'foo'
-
- I18n.locale = :'de-DE'
- assert_equal 'foo', child.content
-
- I18n.locale = :'en-US'
- child.update_attribute :content, 'bar'
-
- I18n.locale = :'de-DE'
- assert_equal 'bar', child.content
- end
- end
-end
-
-# TODO should validate_presence_of take fallbacks into account? maybe we need
-# an extra validation call, or more options for validate_presence_of.
-
diff --git a/vendor/plugins/globalize2/test/active_record/migration_test.rb b/vendor/plugins/globalize2/test/active_record/migration_test.rb
deleted file mode 100644
index 359d811f0..000000000
--- a/vendor/plugins/globalize2/test/active_record/migration_test.rb
+++ /dev/null
@@ -1,118 +0,0 @@
-require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
-require File.expand_path(File.dirname(__FILE__) + '/../data/models')
-
-class MigrationTest < ActiveSupport::TestCase
- def setup
- reset_db!
- Post.drop_translation_table!
- end
-
- test 'globalize table added' do
- assert !Post.connection.table_exists?(:post_translations)
- assert !Post.connection.index_exists?(:post_translations, :post_id)
-
- Post.create_translation_table!(:subject => :string, :content => :text)
- assert Post.connection.table_exists?(:post_translations)
- assert Post.connection.index_exists?(:post_translations, :post_id)
-
- columns = Post.connection.columns(:post_translations)
- assert locale = columns.detect { |c| c.name == 'locale' }
- assert_equal :string, locale.type
- assert subject = columns.detect { |c| c.name == 'subject' }
- assert_equal :string, subject.type
- assert content = columns.detect { |c| c.name == 'content' }
- assert_equal :text, content.type
- assert post_id = columns.detect { |c| c.name == 'post_id' }
- assert_equal :integer, post_id.type
- assert created_at = columns.detect { |c| c.name == 'created_at' }
- assert_equal :datetime, created_at.type
- assert updated_at = columns.detect { |c| c.name == 'updated_at' }
- assert_equal :datetime, updated_at.type
- end
-
- test 'globalize table dropped' do
- assert !Post.connection.table_exists?( :post_translations )
- assert !Post.connection.index_exists?( :post_translations, :post_id )
- Post.create_translation_table! :subject => :string, :content => :text
- assert Post.connection.table_exists?( :post_translations )
- assert Post.connection.index_exists?( :post_translations, :post_id )
- Post.drop_translation_table!
- assert !Post.connection.table_exists?( :post_translations )
- assert !Post.connection.index_exists?( :post_translations, :post_id )
- end
-
- test 'exception on missing field inputs' do
- assert_raise Globalize::MigrationMissingTranslatedField do
- Post.create_translation_table! :content => :text
- end
- end
-
- test 'exception on bad input type' do
- assert_raise Globalize::BadMigrationFieldType do
- Post.create_translation_table! :subject => :string, :content => :integer
- end
- end
-
- test "exception on bad input type isn't raised for untranslated fields" do
- assert_nothing_raised do
- Post.create_translation_table! :subject => :string, :content => :string, :views_count => :integer
- end
- end
-
- test 'create_translation_table! should not be called on non-translated models' do
- assert_raise NoMethodError do
- Blog.create_translation_table! :name => :string
- end
- end
-
- test 'drop_translation_table! should not be called on non-translated models' do
- assert_raise NoMethodError do
- Blog.drop_translation_table!
- end
- end
-
- test "translation_index_name returns a readable index name when it's not longer than 50 characters" do
- assert_equal 'index_post_translations_on_post_id', Post.send(:translation_index_name)
- end
-
- test "translation_index_name returns a hashed index name when it's longer than 50 characters" do
- class UltraLongModelNameWithoutProper < ActiveRecord::Base
- translates :foo
- end
- name = UltraLongModelNameWithoutProper.send(:translation_index_name)
- assert_match /^index_[a-z0-9]{40}$/, name
- end
-
- test 'globalize table added when table has long name' do
- UltraLongModelNameWithoutProper.create_translation_table!(
- :subject => :string, :content => :text
- )
-
- assert UltraLongModelNameWithoutProper.connection.table_exists?(
- :ultra_long_model_name_without_proper_translations
- )
- assert UltraLongModelNameWithoutProper.connection.index_exists?(
- :ultra_long_model_name_without_proper_translations,
- :name => UltraLongModelNameWithoutProper.send(
- :translation_index_name
- )
- )
- end
-
- test 'globalize table dropped when table has long name' do
- UltraLongModelNameWithoutProper.drop_translation_table!
- UltraLongModelNameWithoutProper.create_translation_table!(
- :subject => :string, :content => :text
- )
- UltraLongModelNameWithoutProper.drop_translation_table!
-
- assert !UltraLongModelNameWithoutProper.connection.table_exists?(
- :ultra_long_model_name_without_proper_translations
- )
- assert !UltraLongModelNameWithoutProper.connection.index_exists?(
- :ultra_long_model_name_without_proper_translations,
- :ultra_long_model_name_without_proper_id
- )
- end
-
-end
diff --git a/vendor/plugins/globalize2/test/active_record/sti_translated_test.rb b/vendor/plugins/globalize2/test/active_record/sti_translated_test.rb
deleted file mode 100644
index f529b8d6e..000000000
--- a/vendor/plugins/globalize2/test/active_record/sti_translated_test.rb
+++ /dev/null
@@ -1,49 +0,0 @@
-require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
-require File.expand_path(File.dirname(__FILE__) + '/../data/models')
-
-class StiTranslatedTest < ActiveSupport::TestCase
- def setup
- I18n.locale = :'en-US'
- reset_db!
- end
-
- test "works with simple dynamic finders" do
- foo = Child.create :content => 'foo'
- Child.create :content => 'bar'
- child = Child.find_by_content('foo')
- assert_equal foo, child
- end
-
- test 'change attribute on globalized model' do
- child = Child.create :content => 'foo'
- assert_equal [], child.changed
- child.content = 'bar'
- assert_equal [ 'content' ], child.changed
- child.content = 'baz'
- assert_member 'content', child.changed
- end
-
- test 'change attribute on globalized model after locale switching' do
- child = Child.create :content => 'foo'
- assert_equal [], child.changed
- child.content = 'bar'
- I18n.locale = :de
- assert_equal [ 'content' ], child.changed
- end
-
- test "saves all locales, even after locale switching" do
- child = Child.new :content => 'foo'
- I18n.locale = 'de-DE'
- child.content = 'bar'
- I18n.locale = 'he-IL'
- child.content = 'baz'
- child.save
- I18n.locale = 'en-US'
- child = Child.first
- assert_equal 'foo', child.content
- I18n.locale = 'de-DE'
- assert_equal 'bar', child.content
- I18n.locale = 'he-IL'
- assert_equal 'baz', child.content
- end
-end
diff --git a/vendor/plugins/globalize2/test/active_record/translates_test.rb b/vendor/plugins/globalize2/test/active_record/translates_test.rb
deleted file mode 100644
index 1831063fb..000000000
--- a/vendor/plugins/globalize2/test/active_record/translates_test.rb
+++ /dev/null
@@ -1,96 +0,0 @@
-require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
-require File.expand_path(File.dirname(__FILE__) + '/../data/models')
-
-class TranslatesTest < ActiveSupport::TestCase
- def setup
- I18n.locale = nil
- ActiveRecord::Base.locale = nil
- reset_db!
- end
-
- test 'defines a :locale accessors on ActiveRecord::Base' do
- ActiveRecord::Base.locale = :de
- assert_equal :de, ActiveRecord::Base.locale
- end
-
- test 'the :locale reader on ActiveRecord::Base does not default to I18n.locale (anymore)' do
- I18n.locale = :en
- assert_nil ActiveRecord::Base.locale
- end
-
- test 'ActiveRecord::Base.with_locale temporarily sets the given locale and yields the block' do
- I18n.locale = :en
- post = Post.with_locale(:de) do
- Post.create!(:subject => 'Titel', :content => 'Inhalt')
- end
- assert_nil Post.locale
- assert_equal :en, I18n.locale
-
- I18n.locale = :de
- assert_equal 'Titel', post.subject
- end
-
- test 'translation_class returns the Translation class' do
- assert_equal Post::Translation, Post.translation_class
- end
-
- test 'defines a has_many association on the model class' do
- assert_has_many Post, :translations
- end
-
- test 'defines a scope for retrieving locales that have complete translations' do
- post = Post.create!(:subject => 'subject', :content => 'content')
- assert_equal [:en], post.translated_locales
- end
-
- test 'sets the given attributes to translated_attribute_names' do
- assert_equal [:subject, :content], Post.translated_attribute_names
- end
-
- test 'defines accessors for the translated attributes' do
- post = Post.new
- assert post.respond_to?(:subject)
- assert post.respond_to?(:subject=)
- end
-
- test 'attribute reader without arguments will use the current locale on ActiveRecord::Base or I18n' do
- post = Post.with_locale(:de) do
- Post.create!(:subject => 'Titel', :content => 'Inhalt')
- end
- I18n.locale = :de
- assert_equal 'Titel', post.subject
-
- I18n.locale = :en
- ActiveRecord::Base.locale = :de
- assert_equal 'Titel', post.subject
- end
-
- test 'attribute reader when passed a locale will use the given locale' do
- post = Post.with_locale(:de) do
- Post.create!(:subject => 'Titel', :content => 'Inhalt')
- end
- assert_equal 'Titel', post.subject(:de)
- end
-
- test 'attribute reader will use the current locale on ActiveRecord::Base or I18n' do
- post = Post.with_locale(:en) do
- Post.create!(:subject => 'title', :content => 'content')
- end
- I18n.locale = :de
- post.subject = 'Titel'
- assert_equal 'Titel', post.subject
-
- ActiveRecord::Base.locale = :en
- post.subject = 'title'
- assert_equal 'title', post.subject
- end
-
- test "find_by_xx records have writable attributes" do
- Post.create :subject => "change me"
- p = Post.find_by_subject("change me")
- p.subject = "changed"
- assert_nothing_raised(ActiveRecord::ReadOnlyRecord) do
- p.save
- end
- end
-end
diff --git a/vendor/plugins/globalize2/test/active_record/translation_class_test.rb b/vendor/plugins/globalize2/test/active_record/translation_class_test.rb
deleted file mode 100644
index 1628416d7..000000000
--- a/vendor/plugins/globalize2/test/active_record/translation_class_test.rb
+++ /dev/null
@@ -1,30 +0,0 @@
-require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
-require File.expand_path(File.dirname(__FILE__) + '/../data/models')
-
-class TranlationClassTest < ActiveSupport::TestCase
- def setup
- reset_db!
- end
-
- test 'defines a Translation class nested in the model class' do
- assert Post.const_defined?(:Translation)
- end
-
- test 'defines a belongs_to association' do
- assert_belongs_to Post::Translation, :post
- end
-
- test 'defines a reader for :locale that always returns a symbol' do
- post = Post::Translation.new
- post.write_attribute('locale', 'de')
- assert_equal :de, post.locale
- end
-
- test 'defines a write for :locale that always writes a string' do
- post = Post::Translation.new
- post.locale = :de
- assert_equal 'de', post.read_attribute('locale')
- end
-end
-
-
diff --git a/vendor/plugins/globalize2/test/active_record/validation_tests.rb b/vendor/plugins/globalize2/test/active_record/validation_tests.rb
deleted file mode 100644
index 0148fa384..000000000
--- a/vendor/plugins/globalize2/test/active_record/validation_tests.rb
+++ /dev/null
@@ -1,75 +0,0 @@
-require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
-require File.expand_path(File.dirname(__FILE__) + '/../data/models')
-
-class ValidationTest < ActiveSupport::TestCase
- def setup
- reset_db!
- end
-
- def teardown
- Validatee.instance_variable_set(:@validate_callbacks, CallbackChain.new)
- end
-
- test "validates_presence_of" do
- Validatee.class_eval { validates_presence_of :string }
- assert !Validatee.new.valid?
- assert Validatee.new(:string => 'foo').valid?
- end
-
- test "validates_confirmation_of" do
- Validatee.class_eval { validates_confirmation_of :string }
- assert !Validatee.new(:string => 'foo', :string_confirmation => 'bar').valid?
- assert Validatee.new(:string => 'foo', :string_confirmation => 'foo').valid?
- end
-
- test "validates_acceptance_of" do
- Validatee.class_eval { validates_acceptance_of :string, :accept => '1' }
- assert !Validatee.new(:string => '0').valid?
- assert Validatee.new(:string => '1').valid?
- end
-
- test "validates_length_of (:is)" do
- Validatee.class_eval { validates_length_of :string, :is => 1 }
- assert !Validatee.new(:string => 'aa').valid?
- assert Validatee.new(:string => 'a').valid?
- end
-
- test "validates_format_of" do
- Validatee.class_eval { validates_format_of :string, :with => /^\d+$/ }
- assert !Validatee.new(:string => 'a').valid?
- assert Validatee.new(:string => '1').valid?
- end
-
- test "validates_inclusion_of" do
- Validatee.class_eval { validates_inclusion_of :string, :in => %(a) }
- assert !Validatee.new(:string => 'b').valid?
- assert Validatee.new(:string => 'a').valid?
- end
-
- test "validates_exclusion_of" do
- Validatee.class_eval { validates_exclusion_of :string, :in => %(b) }
- assert !Validatee.new(:string => 'b').valid?
- assert Validatee.new(:string => 'a').valid?
- end
-
- test "validates_numericality_of" do
- Validatee.class_eval { validates_numericality_of :string }
- assert !Validatee.new(:string => 'a').valid?
- assert Validatee.new(:string => '1').valid?
- end
-
- # This doesn't pass and Rails' validates_uniqueness_of implementation doesn't
- # seem to be extensible easily. One can work around that by either defining
- # a custom validation on the Validatee model itself, or by using validates_uniqueness_of
- # on Validatee::Translation.
- #
- # test "validates_uniqueness_of" do
- # Validatee.class_eval { validates_uniqueness_of :string }
- # Validatee.create!(:string => 'a')
- # assert !Validatee.new(:string => 'a').valid?
- # assert Validatee.new(:string => 'b').valid?
- # end
-
- # test "validates_associated" do
- # end
-end \ No newline at end of file
diff --git a/vendor/plugins/globalize2/test/active_record_test.rb b/vendor/plugins/globalize2/test/active_record_test.rb
deleted file mode 100644
index 38e247e17..000000000
--- a/vendor/plugins/globalize2/test/active_record_test.rb
+++ /dev/null
@@ -1,467 +0,0 @@
-require File.expand_path(File.dirname(__FILE__) + '/test_helper')
-require File.expand_path(File.dirname(__FILE__) + '/data/models')
-
-# Higher level tests.
-
-class ActiveRecordTest < ActiveSupport::TestCase
- def setup
- I18n.locale = :en
- reset_db!
- ActiveRecord::Base.locale = nil
- end
-
- def assert_translated(locale, record, names, expected)
- I18n.locale = locale
- assert_equal Array(expected), Array(names).map { |name| record.send(name) }
- end
-
- test "a translated record has translations" do
- assert_equal [], Post.new.translations
- end
-
- test "saves a translated version of the record for each locale" do
- post = Post.create(:subject => 'title')
- I18n.locale = :de
- post.update_attributes(:subject => 'Titel')
-
- assert_equal 2, post.translations.size
- assert_equal %w(de en), post.translations.map(&:locale).map(&:to_s).sort
- assert_equal %w(Titel title), post.translations.map(&:subject).sort
- end
-
- test "a translated record has German translations" do
- I18n.locale = :de
- post = Post.create(:subject => 'foo')
- assert_equal 1, post.translations.size
- assert_equal [:de], post.translations.map { |t| t.locale }
- end
-
- test "modifiying translated fields while switching locales" do
- post = Post.create(:subject => 'title', :content => 'content')
- assert_equal %w(title content), [post.subject, post.content]
-
- I18n.locale = :de
- post.subject, post.content = 'Titel', 'Inhalt'
-
- assert_translated(:de, post, [:subject, :content], %w(Titel Inhalt))
- assert_translated(:en, post, [:subject, :content], %w(title content))
- assert_translated(:de, post, [:subject, :content], %w(Titel Inhalt))
-
- post.save
- post.reload
-
- assert_translated(:en, post, [:subject, :content], %w(title content))
- assert_translated(:de, post, [:subject, :content], %w(Titel Inhalt))
- end
-
- test "attribute writers do return their argument" do
- value = Post.new.subject = 'foo'
- assert_equal 'foo', value
- end
-
- test "update_attribute succeeds with valid values" do
- post = Post.create(:subject => 'foo', :content => 'bar')
- post.update_attribute(:subject, 'baz')
- assert_equal 'baz', Post.first.subject
- end
-
- test "update_attributes fails with invalid values" do
- post = Post.create(:subject => 'foo', :content => 'bar')
- assert !post.update_attributes(:subject => '')
- assert_not_nil post.reload.attributes['subject']
- assert_equal 'foo', post.subject
- end
-
- test "passing the locale to create uses the given locale" do
- post = Post.create(:subject => 'Titel', :content => 'Inhalt', :locale => :de)
- assert_equal :en, I18n.locale
- assert_nil ActiveRecord::Base.locale
-
- I18n.locale = :de
- assert_equal 'Titel', post.subject
- end
-
- test "passing the locale to attributes= uses the given locale" do
- post = Post.create(:subject => 'title', :content => 'content')
- post.update_attributes(:subject => 'Titel', :content => 'Inhalt', :locale => :de)
- post.reload
-
- assert_equal :en, I18n.locale
- assert_nil ActiveRecord::Base.locale
-
- assert_equal 'title', post.subject
- I18n.locale = :de
- assert_equal 'Titel', post.subject
- end
-
- test 'reload works' do
- post = Post.create(:subject => 'foo', :content => 'bar')
- post.subject = 'baz'
- post.reload
- assert_equal 'foo', post.subject
- end
-
- test "returns nil if no translations are found (unsaved record)" do
- post = Post.new(:subject => 'foo')
- assert_equal 'foo', post.subject
- assert_nil post.content
- end
-
- test "returns nil if no translations are found (saved record)" do
- post = Post.create(:subject => 'foo')
- post.reload
- assert_equal 'foo', post.subject
- assert_nil post.content
- end
-
- test "finds a German post" do
- post = Post.create(:subject => 'foo (en)', :content => 'bar')
- I18n.locale = :de
- post = Post.first
- post.subject = 'baz (de)'
- post.save
- assert_equal 'baz (de)', Post.first.subject
- I18n.locale = :en
- assert_equal 'foo (en)', Post.first.subject
- end
-
- test "saves an English post and loads correctly" do
- post = Post.create(:subject => 'foo', :content => 'bar')
- assert post.save
- post = Post.first
- assert_equal 'foo', post.subject
- assert_equal 'bar', post.content
- end
-
- test "returns the value for the correct locale, after locale switching" do
- post = Post.create(:subject => 'foo')
- I18n.locale = :de
- post.subject = 'bar'
- post.save
- I18n.locale = :en
- post = Post.first
- assert_equal 'foo', post.subject
- I18n.locale = :de
- assert_equal 'bar', post.subject
- end
-
- test "returns the value for the correct locale, after locale switching, without saving" do
- post = Post.create :subject => 'foo'
- I18n.locale = :de
- post.subject = 'bar'
- I18n.locale = :en
- assert_equal 'foo', post.subject
- I18n.locale = :de
- assert_equal 'bar', post.subject
- end
-
- test "saves all locales, even after locale switching" do
- post = Post.new :subject => 'foo'
- I18n.locale = :de
- post.subject = 'bar'
- I18n.locale = :he
- post.subject = 'baz'
- post.save
- I18n.locale = :en
- post = Post.first
- assert_equal 'foo', post.subject
- I18n.locale = :de
- assert_equal 'bar', post.subject
- I18n.locale = :he
- assert_equal 'baz', post.subject
- end
-
- test "works with associations" do
- blog = Blog.create
- post1 = blog.posts.create(:subject => 'foo')
-
- I18n.locale = :de
- post2 = blog.posts.create(:subject => 'bar')
- assert_equal 2, blog.posts.size
-
- I18n.locale = :en
- assert_equal 'foo', blog.posts.first.subject
- assert_nil blog.posts.last.subject
-
- I18n.locale = :de
- assert_equal 'bar', blog.posts.last.subject
- end
-
- test "works with simple dynamic finders" do
- foo = Post.create(:subject => 'foo')
- Post.create(:subject => 'bar')
- post = Post.find_by_subject('foo')
- assert_equal foo, post
- end
-
- test 'change attribute on globalized model' do
- post = Post.create(:subject => 'foo', :content => 'bar')
- assert_equal [], post.changed
- post.subject = 'baz'
- assert_equal ['subject'], post.changed
- post.content = 'quux'
- assert_member 'subject', post.changed
- assert_member 'content', post.changed
- end
-
- test 'change attribute on globalized model after locale switching' do
- post = Post.create(:subject => 'foo', :content => 'bar')
- assert_equal [], post.changed
- post.subject = 'baz'
- I18n.locale = :de
- assert_equal ['subject'], post.changed
- end
-
- test 'complex writing and stashing' do
- post = Post.create(:subject => 'foo', :content => 'bar')
- post.subject = nil
- assert_nil post.subject
- assert !post.valid?
- post.subject = 'stashed_foo'
- assert_equal 'stashed_foo', post.subject
- end
-
- test 'translated class locale setting' do
- assert ActiveRecord::Base.respond_to?(:locale)
- assert_equal :en, I18n.locale
- assert_nil ActiveRecord::Base.locale
-
- I18n.locale = :de
- assert_equal :de, I18n.locale
- assert_nil ActiveRecord::Base.locale
-
- ActiveRecord::Base.locale = :es
- assert_equal :de, I18n.locale
- assert_equal :es, ActiveRecord::Base.locale
-
- I18n.locale = :fr
- assert_equal :fr, I18n.locale
- assert_equal :es, ActiveRecord::Base.locale
- end
-
- test "untranslated class responds to locale" do
- assert Blog.respond_to?(:locale)
- end
-
- test "to ensure locales in different classes are the same" do
- ActiveRecord::Base.locale = :de
- assert_equal :de, ActiveRecord::Base.locale
- assert_equal :de, Parent.locale
-
- Parent.locale = :es
- assert_equal :es, ActiveRecord::Base.locale
- assert_equal :es, Parent.locale
- end
-
- test "attribute saving goes by content locale and not global locale" do
- ActiveRecord::Base.locale = :de
- assert_equal :en, I18n.locale
- Post.create :subject => 'foo'
- assert_equal :de, Post.first.translations.first.locale
- end
-
- test "attribute loading goes by content locale and not global locale" do
- post = Post.create(:subject => 'foo')
- assert_nil ActiveRecord::Base.locale
-
- ActiveRecord::Base.locale = :de
- assert_equal :en, I18n.locale
- post.update_attribute(:subject, 'foo [de]')
- assert_equal 'foo [de]', Post.first.subject
-
- ActiveRecord::Base.locale = :en
- assert_equal 'foo', Post.first.subject
- end
-
- test "access content locale before setting" do
- Globalize::ActiveRecord::ActMacro.class_eval "remove_class_variable(:@@locale)"
- assert_nothing_raised { ActiveRecord::Base.locale }
- end
-
- test "available_locales" do
- Post.locale = :de
- post = Post.create(:subject => 'foo')
- Post.locale = :es
- post.update_attribute(:subject, 'bar')
- Post.locale = :fr
- post.update_attribute(:subject, 'baz')
- assert_equal [:de, :es, :fr], post.available_locales
- assert_equal [:de, :es, :fr], Post.first.available_locales
- end
-
- test "saving record correctly after post-save reload" do
- reloader = Reloader.create(:content => 'foo')
- assert_equal 'foo', reloader.content
- end
-
- test "including translations" do
- I18n.locale = :de
- Post.create(:subject => "Foo1", :content => "Bar1")
- Post.create(:subject => "Foo2", :content => "Bar2")
-
- class << Post
- def translations_included
- self.all(:include => :translations)
- end
- end
-
- default = Post.all.map { |x| [x.subject, x.content] }
- with_include = Post.translations_included.map { |x| [x.subject, x.content] }
- assert_equal default, with_include
- end
-
- test "setting multiple translations at once with options hash" do
- Post.locale = :de
- post = Post.create(:subject => "foo1", :content => "foo1")
- Post.locale = :en
- post.update_attributes(:subject => "bar1", :content => "bar1")
-
- options = { :de => {:subject => "foo2", :content => "foo2"},
- :en => {:subject => "bar2", :content => "bar2"} }
- post.set_translations options
- post.reload
-
- assert ["bar2", "bar2"], [post.subject, post.content]
- Post.locale = :de
- assert ["foo2", "foo2"], [post.subject, post.content]
- end
-
- test "setting only one translation with set_translations" do
- Post.locale = :de
- post = Post.create(:subject => "foo1", :content => "foo1")
- Post.locale = :en
- post.update_attributes(:subject => "bar1", :content => "bar1")
-
- options = { :en => { :subject => "bar2", :content => "bar2" } }
- post.set_translations options
- post.reload
-
- assert ["bar2", "bar2"], [post.subject, post.content]
- Post.locale = :de
- assert ["foo1", "foo1"], [post.subject, post.content]
- end
-
- test "setting only selected attributes with set_translations" do
- Post.locale = :de
- post = Post.create(:subject => "foo1", :content => "foo1")
- Post.locale = :en
- post.update_attributes(:subject => "bar1", :content => "bar1")
-
- options = { :de => { :content => "foo2" }, :en => { :subject => "bar2" } }
- post.set_translations options
- post.reload
-
- assert ["bar2", "bar1"], [post.subject, post.content]
- Post.locale = :de
- assert ["foo1", "foo2"], [post.subject, post.content]
- end
-
- test "setting invalid attributes raises ArgumentError" do
- Post.locale = :de
- post = Post.create(:subject => "foo1", :content => "foo1")
- Post.locale = :en
- post.update_attributes(:subject => "bar1", :content => "bar1")
-
- options = { :de => {:fake => "foo2"} }
- exception = assert_raise(ActiveRecord::UnknownAttributeError) do
- post.set_translations options
- end
- assert_equal "unknown attribute: fake", exception.message
- end
-
- test "reload accepting find options" do
- p = Post.create(:subject => "Foo", :content => "Bar")
- assert p.reload(:readonly => true, :lock => true)
- assert_raise(ArgumentError) { p.reload(:foo => :bar) }
- end
-
- test "dependent destroy of translation" do
- p = Post.create(:subject => "Foo", :content => "Bar")
- assert_equal 1, PostTranslation.count
- p.destroy
- assert_equal 0, PostTranslation.count
- end
-
- test "translating subclass of untranslated comment model" do
- translated_comment = TranslatedComment.create(:post => @post)
- assert_nothing_raised { translated_comment.translations }
- end
-
- test "modifiying translated comments works as expected" do
- I18n.locale = :en
- translated_comment = TranslatedComment.create(:post => @post, :content => 'foo')
- assert_equal 'foo', translated_comment.content
-
- I18n.locale = :de
- translated_comment.content = 'bar'
- assert translated_comment.save
- assert_equal 'bar', translated_comment.content
-
- I18n.locale = :en
- assert_equal 'foo', translated_comment.content
-
- assert_equal 2, translated_comment.translations.size
- end
-
- test "can create a proxy class for a namespaced model" do
- assert_nothing_raised do
- module Foo
- module Bar
- class Baz < ActiveRecord::Base
- translates :bumm
- end
- end
- end
- end
- end
-
- test "attribute translated before type cast" do
- Post.locale = :en
- post = Post.create(:subject => 'foo', :content => 'bar')
- Post.locale = :de
- post.update_attribute(:subject, "German foo")
- assert_equal 'German foo', post.subject_before_type_cast
- Post.locale = :en
- assert_equal 'foo', post.subject_before_type_cast
- end
-
- test "don't override existing translation class" do
- assert PostTranslation.new.respond_to?(:existing_method)
- end
-
- test "has_many and named scopes work with globalize" do
- blog = Blog.create
- assert_nothing_raised { blog.posts.foobar }
- end
-
- test "required_attribuets don't include non-translated attributes" do
- validations = [
- stub(:name => :name, :macro => :validates_presence_of),
- stub(:name => :email, :macro => :validates_presence_of)
- ]
- User.expects(:reflect_on_all_validations => validations)
- assert_equal [:name], User.required_attributes
- end
-
- test "attribute_names returns translated and regular attribute names" do
- Post.create :subject => "foo", :content => "bar"
- assert_equal Post.last.attribute_names.sort, %w[blog_id content id subject]
- end
-
- test "attributes returns translated and regular attributes" do
- Post.create :subject => "foo", :content => "bar"
- assert_equal Post.last.attributes.keys.sort, %w[blog_id content id subject]
- end
-
- test "to_xml includes translated fields" do
- Post.create :subject => "foo", :content => "bar"
- assert Post.last.to_xml =~ /subject/
- assert Post.last.to_xml =~ /content/
- end
-end
-
-# TODO error checking for fields that exist in main table, don't exist in
-# proxy table, aren't strings or text
-#
-# TODO allow finding by translated attributes in conditions?
-# TODO generate advanced dynamic finders?
diff --git a/vendor/plugins/globalize2/test/all.rb b/vendor/plugins/globalize2/test/all.rb
deleted file mode 100644
index ff467a176..000000000
--- a/vendor/plugins/globalize2/test/all.rb
+++ /dev/null
@@ -1,2 +0,0 @@
-files = Dir[File.dirname(__FILE__) + '/**/*_test.rb']
-files.each { |file| require file } \ No newline at end of file
diff --git a/vendor/plugins/globalize2/test/data/models.rb b/vendor/plugins/globalize2/test/data/models.rb
deleted file mode 100644
index 5408d6e23..000000000
--- a/vendor/plugins/globalize2/test/data/models.rb
+++ /dev/null
@@ -1,56 +0,0 @@
-#require 'ruby2ruby'
-#require 'parse_tree'
-#require 'parse_tree_extensions'
-#require 'pp'
-
-class PostTranslation < ActiveRecord::Base
- def existing_method ; end
-end
-
-class Post < ActiveRecord::Base
- translates :subject, :content
- validates_presence_of :subject
- named_scope :foobar, :conditions => { :title => "foobar" }
-end
-
-class Blog < ActiveRecord::Base
- has_many :posts, :order => 'id ASC'
-end
-
-class Parent < ActiveRecord::Base
- translates :content
-end
-
-class Child < Parent
-end
-
-class Comment < ActiveRecord::Base
- validates_presence_of :content
- belongs_to :post
-end
-
-class TranslatedComment < Comment
- translates :content
-end
-
-class UltraLongModelNameWithoutProper < ActiveRecord::Base
- translates :subject, :content
- validates_presence_of :subject
-end
-
-class Reloader < Parent
- after_create :do_reload
-
- def do_reload
- reload
- end
-end
-
-class Validatee < ActiveRecord::Base
- translates :string
-end
-
-class User < ActiveRecord::Base
- translates :name
- validates_presence_of :name, :email
-end
diff --git a/vendor/plugins/globalize2/test/data/no_globalize_schema.rb b/vendor/plugins/globalize2/test/data/no_globalize_schema.rb
deleted file mode 100644
index 379455ddb..000000000
--- a/vendor/plugins/globalize2/test/data/no_globalize_schema.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-# This schema creates tables without columns for the translated fields
-ActiveRecord::Schema.define do
- create_table :blogs, :force => true do |t|
- t.string :name
- end
-
- create_table :posts, :force => true do |t|
- t.references :blog
- end
-end
-
diff --git a/vendor/plugins/globalize2/test/data/schema.rb b/vendor/plugins/globalize2/test/data/schema.rb
deleted file mode 100644
index 910dd0855..000000000
--- a/vendor/plugins/globalize2/test/data/schema.rb
+++ /dev/null
@@ -1,55 +0,0 @@
-ActiveRecord::Schema.define do
- create_table :blogs, :force => true do |t|
- t.string :description
- end
-
- create_table :posts, :force => true do |t|
- t.references :blog
- end
-
- create_table :post_translations, :force => true do |t|
- t.string :locale
- t.references :post
- t.string :subject
- t.text :content
- end
-
- create_table :parents, :force => true do |t|
- end
-
- create_table :parent_translations, :force => true do |t|
- t.string :locale
- t.references :parent
- t.text :content
- t.string :type
- end
-
- create_table :comments, :force => true do |t|
- t.references :post
- end
-
- create_table :comment_translations, :force => true do |t|
- t.string :locale
- t.references :comment
- t.string :subject
- t.text :content
- end
-
- create_table :validatees, :force => true do |t|
- end
-
- create_table :validatee_translations, :force => true do |t|
- t.string :locale
- t.references :validatee
- t.string :string
- end
-
- create_table :users, :force => true do |t|
- t.string :email
- end
-
- create_table :users_translations, :force => true do |t|
- t.references :user
- t.string :name
- end
-end
diff --git a/vendor/plugins/globalize2/test/i18n/missing_translations_test.rb b/vendor/plugins/globalize2/test/i18n/missing_translations_test.rb
deleted file mode 100644
index 5d0ecd6fc..000000000
--- a/vendor/plugins/globalize2/test/i18n/missing_translations_test.rb
+++ /dev/null
@@ -1,36 +0,0 @@
-require File.dirname(__FILE__) + '/../test_helper'
-require 'i18n/missing_translations_log_handler'
-
-class MissingTranslationsTest < ActiveSupport::TestCase
- test "defines I18n.missing_translations_logger accessor" do
- assert I18n.respond_to?(:missing_translations_logger)
- end
-
- test "defines I18n.missing_translations_logger= writer" do
- assert I18n.respond_to?(:missing_translations_logger=)
- end
-end
-
-class TestLogger < String
- def warn(msg) self.concat msg; end
-end
-
-class LogMissingTranslationsTest < ActiveSupport::TestCase
- def setup
- @locale, @key, @options = :en, :foo, {}
- @exception = I18n::MissingTranslationData.new(@locale, @key, @options)
-
- @logger = TestLogger.new
- I18n.missing_translations_logger = @logger
- end
-
- test "still returns the exception message for MissingTranslationData exceptions" do
- result = I18n.send(:missing_translations_log_handler, @exception, @locale, @key, @options)
- assert_equal 'translation missing: en, foo', result
- end
-
- test "logs the missing translation to I18n.missing_translations_logger" do
- I18n.send(:missing_translations_log_handler, @exception, @locale, @key, @options)
- assert_equal 'translation missing: en, foo', @logger
- end
-end
diff --git a/vendor/plugins/globalize2/test/test_helper.rb b/vendor/plugins/globalize2/test/test_helper.rb
deleted file mode 100644
index 99a5d3950..000000000
--- a/vendor/plugins/globalize2/test/test_helper.rb
+++ /dev/null
@@ -1,76 +0,0 @@
-$LOAD_PATH << File.expand_path( File.dirname(__FILE__) + '/../lib' )
-
-require 'rubygems'
-require 'test/unit'
-require 'active_record'
-require 'active_support'
-require 'active_support/test_case'
-require 'mocha'
-require 'globalize'
-# require 'validation_reflection'
-
-config = { :adapter => 'sqlite3', :database => ':memory:' }
-ActiveRecord::Base.establish_connection(config)
-
-class ActiveSupport::TestCase
- def reset_db!(schema_path = nil)
- schema_path ||= File.expand_path(File.dirname(__FILE__) + '/data/schema.rb')
- ActiveRecord::Migration.verbose = false
- ActiveRecord::Base.silence { load(schema_path) }
- end
-
- def assert_member(item, array)
- assert_block "Item #{item} is not in array #{array}" do
- array.member?(item)
- end
- end
-
- def assert_belongs_to(model, associated)
- assert model.reflect_on_all_associations(:belongs_to).detect { |association|
- association.name.to_s == associated.to_s
- }
- end
-
- def assert_has_many(model, associated)
- assert model.reflect_on_all_associations(:has_many).detect { |association|
- association.name.to_s == associated.to_s
- }
- end
-end
-
-module ActiveRecord
- module ConnectionAdapters
- class AbstractAdapter
- def index_exists?(table_name, column_name)
- indexes(table_name).any? { |index| index.name == index_name(table_name, column_name) }
- end
- end
- end
-end
-
-# module ActiveRecord
-# class BaseWithoutTable < Base
-# self.abstract_class = true
-#
-# def create_or_update
-# errors.empty?
-# end
-#
-# class << self
-# def columns()
-# @columns ||= []
-# end
-#
-# def column(name, sql_type = nil, default = nil, null = true)
-# columns << ActiveRecord::ConnectionAdapters::Column.new(name.to_s, default, sql_type.to_s, null)
-# reset_column_information
-# end
-#
-# # Do not reset @columns
-# def reset_column_information
-# read_methods.each { |name| undef_method(name) }
-# @column_names = @columns_hash = @content_columns = @dynamic_methods_hash = @read_methods = nil
-# end
-# end
-# end
-# end \ No newline at end of file
diff --git a/vendor/plugins/has_tag_string/lib/has_tag_string.rb b/vendor/plugins/has_tag_string/lib/has_tag_string.rb
index b982bc3a0..4022faaac 100644
--- a/vendor/plugins/has_tag_string/lib/has_tag_string.rb
+++ b/vendor/plugins/has_tag_string/lib/has_tag_string.rb
@@ -4,7 +4,7 @@
# followed by a colon - e.g. url:http://www.flourish.org
#
# Copyright (c) 2010 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
module HasTagString
# Represents one tag of one model.
diff --git a/vendor/plugins/rails_xss/MIT-LICENSE b/vendor/plugins/rails_xss/MIT-LICENSE
deleted file mode 100644
index ed44a7bde..000000000
--- a/vendor/plugins/rails_xss/MIT-LICENSE
+++ /dev/null
@@ -1,20 +0,0 @@
-Copyright (c) 2009 Koziarski Software Ltd.
-
-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/plugins/rails_xss/README.markdown b/vendor/plugins/rails_xss/README.markdown
deleted file mode 100644
index 1222ef38d..000000000
--- a/vendor/plugins/rails_xss/README.markdown
+++ /dev/null
@@ -1,91 +0,0 @@
-RailsXss
-========
-
-This plugin replaces the default ERB template handlers with erubis, and switches the behaviour to escape by default rather than requiring you to escape. This is consistent with the behaviour in Rails 3.0.
-
-Strings now have a notion of "html safe", which is false by default. Whenever rails copies a string into the response body it checks whether or not the string is safe, safe strings are copied verbatim into the response body, but unsafe strings are escaped first.
-
-All the XSS-proof helpers like link_to and form_tag now return safe strings, and will continue to work unmodified. If you have your own helpers which return strings you *know* are safe, you will need to explicitly tell rails that they're safe. For an example, take the following helper.
-
-
- def some_helper
- (1..5).map do |i|
- "<li>#{i}</li>"
- end.join("\n")
- end
-
-With this plugin installed, the html will be escaped. So you will need to do one of the following:
-
-1) Use the raw helper in your template. raw will ensure that your string is copied verbatim into the response body.
-
- <%= raw some_helper %>
-
-2) Mark the string as safe in the helper itself:
-
- def some_helper
- (1..5).map do |i|
- "<li>#{i}</li>"
- end.join("\n").html_safe
- end
-
-3) Use the `safe_helper` meta programming method (WARNING: This is not supported by Rails 3, so if you're planning to
-eventually upgrade your app this alternative is not recommended):
-
- module ApplicationHelper
- def some_helper
- #...
- end
- safe_helper :some_helper # not supported by Rails 3
- end
-
-Example
--------
-
-BEFORE:
-
- <%= params[:own_me] %> => XSS attack
- <%=h params[:own_me] %> => No XSS
- <%= @blog_post.content %> => Displays the HTML
-
-AFTER:
-
- <%= params[:own_me] %> => No XSS
- <%=h params[:own_me] %> => No XSS (same result)
- <%= @blog_post.content %> => *escapes* the HTML
- <%= raw @blog_post.content %> => Displays the HTML
-
-
-Gotchas
----
-
-#### textilize and simple_format do *not* return safe strings
-
-Both these methods support arbitrary HTML and are *not* safe to embed directly in your document. You'll need to do something like:
-
- <%= sanitize(textilize(@blog_post.content_textile)) %>
-
-#### Safe strings aren't magic.
-
-Once a string has been marked as safe, the only operations which will maintain that HTML safety are String#<<, String#concat and String#+. All other operations are safety ignorant so it's still probably possible to break your app if you're doing something like
-
- value = something_safe
- value.gsub!(/a/, params[:own_me])
-
-Don't do that.
-
-#### String interpolation won't be safe, even when it 'should' be
-
- value = "#{something_safe}#{something_else_safe}"
- value.html_safe? # => false
-
-This is intended functionality and can't be fixed.
-
-Getting Started
-===============
-
-1. Install rails 2.3.8 or higher, or freeze rails from 2-3-stable.
-2. Install erubis (gem install erubis)
-3. Install this plugin (ruby script/plugin install git://github.com/rails/rails_xss.git)
-4. Report anything that breaks.
-
-Copyright (c) 2009 Koziarski Software Ltd, released under the MIT license. For full details see MIT-LICENSE included in this distribution.
diff --git a/vendor/plugins/rails_xss/Rakefile b/vendor/plugins/rails_xss/Rakefile
deleted file mode 100644
index 929ecbb81..000000000
--- a/vendor/plugins/rails_xss/Rakefile
+++ /dev/null
@@ -1,23 +0,0 @@
-require 'rake'
-require 'rake/testtask'
-require 'rake/rdoctask'
-
-desc 'Default: run unit tests.'
-task :default => :test
-
-desc 'Test the rails_xss plugin.'
-Rake::TestTask.new(:test) do |t|
- t.libs << 'lib'
- t.libs << 'test'
- t.pattern = 'test/**/*_test.rb'
- t.verbose = true
-end
-
-desc 'Generate documentation for the rails_xss plugin.'
-Rake::RDocTask.new(:rdoc) do |rdoc|
- rdoc.rdoc_dir = 'rdoc'
- rdoc.title = 'RailsXss'
- rdoc.options << '--line-numbers' << '--inline-source'
- rdoc.rdoc_files.include('README')
- rdoc.rdoc_files.include('lib/**/*.rb')
-end
diff --git a/vendor/plugins/rails_xss/init.rb b/vendor/plugins/rails_xss/init.rb
deleted file mode 100644
index 533eb1f36..000000000
--- a/vendor/plugins/rails_xss/init.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-unless $gems_rake_task
- if Rails::VERSION::MAJOR >= 3
- $stderr.puts "You don't need to install rails_xss as a plugin for Rails 3 and after."
- elsif Rails::VERSION::MAJOR <= 2 && Rails::VERSION::MINOR <= 3 && Rails::VERSION::TINY <= 7
- $stderr.puts "rails_xss requires Rails 2.3.8 or later. Please upgrade to enable automatic HTML safety."
- else
- require 'rails_xss'
- end
-end
diff --git a/vendor/plugins/rails_xss/lib/rails_xss.rb b/vendor/plugins/rails_xss/lib/rails_xss.rb
deleted file mode 100644
index 46d1b9a4a..000000000
--- a/vendor/plugins/rails_xss/lib/rails_xss.rb
+++ /dev/null
@@ -1,3 +0,0 @@
-require 'rails_xss/erubis'
-require 'rails_xss/action_view'
-require 'rails_xss/string_ext'
diff --git a/vendor/plugins/rails_xss/lib/rails_xss/action_view.rb b/vendor/plugins/rails_xss/lib/rails_xss/action_view.rb
deleted file mode 100644
index c3f5e47df..000000000
--- a/vendor/plugins/rails_xss/lib/rails_xss/action_view.rb
+++ /dev/null
@@ -1,111 +0,0 @@
-module ActionView
- class Base
- def self.xss_safe?
- true
- end
-
- module WithSafeOutputBuffer
- # Rails version of with_output_buffer uses '' as the default buf
- def with_output_buffer(buf = ActiveSupport::SafeBuffer.new) #:nodoc:
- super buf
- end
- end
-
- include WithSafeOutputBuffer
- end
-
- module Helpers
- module CaptureHelper
- def content_for(name, content = nil, &block)
- ivar = "@content_for_#{name}"
- content = capture(&block) if block_given?
- instance_variable_set(ivar, "#{instance_variable_get(ivar)}#{ERB::Util.h(content)}".html_safe)
- nil
- end
- end
-
- module TextHelper
- def concat(string, unused_binding = nil)
- if unused_binding
- ActiveSupport::Deprecation.warn("The binding argument of #concat is no longer needed. Please remove it from your views and helpers.", caller)
- end
-
- output_buffer.concat(string)
- end
-
- def simple_format(text, html_options={})
- start_tag = tag('p', html_options, true)
- text = ERB::Util.h(text).to_str.dup
- text.gsub!(/\r\n?/, "\n") # \r\n and \r -> \n
- text.gsub!(/\n\n+/, "</p>\n\n#{start_tag}") # 2+ newline -> paragraph
- text.gsub!(/([^\n]\n)(?=[^\n])/, '\1<br />') # 1 newline -> br
- text.insert 0, start_tag
- text.html_safe.safe_concat("</p>")
- end
- end
-
- module TagHelper
- private
- def content_tag_string_with_escaping(name, content, options, escape = true)
- content_tag_string_without_escaping(name, escape ? ERB::Util.h(content) : content, options, escape)
- end
- alias_method_chain :content_tag_string, :escaping
- end
-
- module UrlHelper
- def link_to(*args, &block)
- if block_given?
- options = args.first || {}
- html_options = args.second
- concat(link_to(capture(&block), options, html_options))
- else
- name = args.first
- options = args.second || {}
- html_options = args.third
-
- url = url_for(options)
-
- if html_options
- html_options = html_options.stringify_keys
- href = html_options['href']
- convert_options_to_javascript!(html_options, url)
- tag_options = tag_options(html_options)
- else
- tag_options = nil
- end
-
- href_attr = "href=\"#{url}\"" unless href
- "<a #{href_attr}#{tag_options}>#{ERB::Util.h(name || url)}</a>".html_safe
- end
- end
- end
-
- module JavaScriptHelper
- def escape_javascript(javascript)
- if javascript
- javascript.gsub(/(\\|<\/|\r\n|[\n\r"'])/) {|match| JS_ESCAPE_MAP[match] }
- else
- ''
- end
- end
- end
- end
-end
-
-module RailsXss
- module SafeHelpers
- def safe_helper(*names)
- names.each do |helper_method_name|
- aliased_target, punctuation = helper_method_name.to_s.sub(/([?!=])$/, ''), $1
- module_eval <<-END
- def #{aliased_target}_with_xss_safety#{punctuation}(*args, &block)
- raw(#{aliased_target}_without_xss_safety#{punctuation}(*args, &block))
- end
- END
- alias_method_chain helper_method_name, :xss_safety
- end
- end
- end
-end
-
-Module.class_eval { include RailsXss::SafeHelpers }
diff --git a/vendor/plugins/rails_xss/lib/rails_xss/erubis.rb b/vendor/plugins/rails_xss/lib/rails_xss/erubis.rb
deleted file mode 100644
index b8a239483..000000000
--- a/vendor/plugins/rails_xss/lib/rails_xss/erubis.rb
+++ /dev/null
@@ -1,41 +0,0 @@
-# stop erubis from printing it's version number all the time
-old_stdout = $stdout
-File.open("/dev/null", "w") do |f|
- $stdout = f
- require 'erubis/helpers/rails_helper'
- $stdout = old_stdout
-end
-
-module RailsXss
- class Erubis < ::Erubis::Eruby
- def add_preamble(src)
- src << "@output_buffer = ActiveSupport::SafeBuffer.new;"
- end
-
- def add_text(src, text)
- return if text.empty?
- src << "@output_buffer.safe_concat('" << escape_text(text) << "');"
- end
-
- BLOCK_EXPR = /\s+(do|\{)(\s*\|[^|]*\|)?\s*\Z/
-
- def add_expr_literal(src, code)
- if code =~ BLOCK_EXPR
- src << "@output_buffer.safe_concat((" << $1 << ").to_s);"
- else
- src << '@output_buffer << ((' << code << ').to_s);'
- end
- end
-
- def add_expr_escaped(src, code)
- src << '@output_buffer << ' << escaped_expr(code) << ';'
- end
-
- def add_postamble(src)
- src << '@output_buffer.to_s'
- end
- end
-end
-
-Erubis::Helpers::RailsHelper.engine_class = RailsXss::Erubis
-Erubis::Helpers::RailsHelper.show_src = false
diff --git a/vendor/plugins/rails_xss/lib/rails_xss/string_ext.rb b/vendor/plugins/rails_xss/lib/rails_xss/string_ext.rb
deleted file mode 100644
index ee32e47c8..000000000
--- a/vendor/plugins/rails_xss/lib/rails_xss/string_ext.rb
+++ /dev/null
@@ -1,65 +0,0 @@
-require 'active_support/deprecation'
-
-ActiveSupport::SafeBuffer.class_eval do
- def concat(value)
- if value.html_safe?
- super(value)
- else
- super(ERB::Util.h(value))
- end
- end
- alias << concat
- UNSAFE_STRING_METHODS = ["capitalize", "chomp", "chop", "delete", "downcase", "gsub", "lstrip", "next", "reverse", "rstrip", "slice", "squeeze", "strip", "sub", "succ", "swapcase", "tr", "tr_s", "upcase"].freeze
-
- for unsafe_method in UNSAFE_STRING_METHODS
- class_eval <<-EOT, __FILE__, __LINE__ + 1
- def #{unsafe_method}(*args)
- super.to_str
- end
-
- def #{unsafe_method}!(*args)
- raise TypeError, "Cannot modify SafeBuffer in place"
- end
- EOT
- end
-end
-
-class String
- def html_safe?
- defined?(@_rails_html_safe)
- end
-
- def html_safe!
- ActiveSupport::Deprecation.warn("Use html_safe with your strings instead of html_safe! See http://yehudakatz.com/2010/02/01/safebuffers-and-rails-3-0/ for the full story.", caller)
- @_rails_html_safe = true
- self
- end
-
- def add_with_safety(other)
- result = add_without_safety(other)
- if html_safe? && also_html_safe?(other)
- result.html_safe!
- else
- result
- end
- end
- alias_method :add_without_safety, :+
- alias_method :+, :add_with_safety
-
- def concat_with_safety(other_or_fixnum)
- result = concat_without_safety(other_or_fixnum)
- unless html_safe? && also_html_safe?(other_or_fixnum)
- remove_instance_variable(:@_rails_html_safe) if defined?(@_rails_html_safe)
- end
- result
- end
-
- alias_method_chain :concat, :safety
- undef_method :<<
- alias_method :<<, :concat_with_safety
-
- private
- def also_html_safe?(other)
- other.respond_to?(:html_safe?) && other.html_safe?
- end
-end
diff --git a/vendor/plugins/rails_xss/lib/tasks/rails_xss_tasks.rake b/vendor/plugins/rails_xss/lib/tasks/rails_xss_tasks.rake
deleted file mode 100644
index b8659f089..000000000
--- a/vendor/plugins/rails_xss/lib/tasks/rails_xss_tasks.rake
+++ /dev/null
@@ -1,4 +0,0 @@
-# desc "Explaining what the task does"
-# task :rails_xss do
-# # Task goes here
-# end
diff --git a/vendor/plugins/rails_xss/test/active_record_helper_test.rb b/vendor/plugins/rails_xss/test/active_record_helper_test.rb
deleted file mode 100644
index 728ec0ac6..000000000
--- a/vendor/plugins/rails_xss/test/active_record_helper_test.rb
+++ /dev/null
@@ -1,74 +0,0 @@
-require 'test_helper'
-
-class ActiveRecordHelperTest < ActionView::TestCase
- silence_warnings do
- Post = Struct.new("Post", :title, :author_name, :body, :secret, :written_on)
- Post.class_eval do
- alias_method :title_before_type_cast, :title unless respond_to?(:title_before_type_cast)
- alias_method :body_before_type_cast, :body unless respond_to?(:body_before_type_cast)
- alias_method :author_name_before_type_cast, :author_name unless respond_to?(:author_name_before_type_cast)
- end
- end
-
- def setup_post
- @post = Post.new
- def @post.errors
- Class.new {
- def on(field)
- case field.to_s
- when "author_name"
- "can't be empty"
- when "body"
- true
- else
- false
- end
- end
- def empty?() false end
- def count() 1 end
- def full_messages() [ "Author name can't be empty" ] end
- }.new
- end
-
- def @post.new_record?() true end
- def @post.to_param() nil end
-
- def @post.column_for_attribute(attr_name)
- Post.content_columns.select { |column| column.name == attr_name }.first
- end
-
- silence_warnings do
- def Post.content_columns() [ Column.new(:string, "title", "Title"), Column.new(:text, "body", "Body") ] end
- end
-
- @post.title = "Hello World"
- @post.author_name = ""
- @post.body = "Back to the hill and over it again!"
- @post.secret = 1
- @post.written_on = Date.new(2004, 6, 15)
- end
-
- def setup
- setup_post
-
- @response = ActionController::TestResponse.new
-
- @controller = Object.new
- def @controller.url_for(options)
- options = options.symbolize_keys
-
- [options[:action], options[:id].to_param].compact.join('/')
- end
- end
-
- def test_text_field_with_errors_is_safe
- assert text_field("post", "author_name").html_safe?
- end
-
- def test_text_field_with_errors
- assert_dom_equal(
- %(<div class="fieldWithErrors"><input id="post_author_name" name="post[author_name]" size="30" type="text" value="" /></div>),
- text_field("post", "author_name")
- )
- end
-end
diff --git a/vendor/plugins/rails_xss/test/asset_tag_helper_test.rb b/vendor/plugins/rails_xss/test/asset_tag_helper_test.rb
deleted file mode 100644
index f58feda3d..000000000
--- a/vendor/plugins/rails_xss/test/asset_tag_helper_test.rb
+++ /dev/null
@@ -1,49 +0,0 @@
-require 'test_helper'
-
-class AssetTagHelperTest < ActionView::TestCase
- def setup
- @controller = Class.new do
- attr_accessor :request
- def url_for(*args) "http://www.example.com" end
- end.new
- end
-
- def test_auto_discovery_link_tag
- assert_dom_equal(%(<link href="http://www.example.com" rel="Not so alternate" title="ATOM" type="application/atom+xml" />),
- auto_discovery_link_tag(:atom, {}, {:rel => "Not so alternate"}))
- end
-
- def test_javascript_include_tag_with_blank_asset_id
- ENV["RAILS_ASSET_ID"] = ""
- assert_dom_equal(%(<script src="/javascripts/test.js" type="text/javascript"></script>\n<script src="/javascripts/prototype.js" type="text/javascript"></script>\n<script src="/javascripts/effects.js" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js" type="text/javascript"></script>\n<script src="/javascripts/controls.js" type="text/javascript"></script>\n<script src="/javascripts/application.js" type="text/javascript"></script>),
- javascript_include_tag("test", :defaults))
- end
-
- def test_javascript_include_tag_with_given_asset_id
- ENV["RAILS_ASSET_ID"] = "1"
- assert_dom_equal(%(<script src="/javascripts/prototype.js?1" type="text/javascript"></script>\n<script src="/javascripts/effects.js?1" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js?1" type="text/javascript"></script>\n<script src="/javascripts/controls.js?1" type="text/javascript"></script>\n<script src="/javascripts/application.js?1" type="text/javascript"></script>),
- javascript_include_tag(:defaults))
- ENV["RAILS_ASSET_ID"] = ""
- end
-
- def test_javascript_include_tag_is_html_safe
- assert javascript_include_tag(:defaults).html_safe?
- assert javascript_include_tag("prototype").html_safe?
- end
-
- def test_stylesheet_link_tag
- assert_dom_equal(%(<link href="http://www.example.com/styles/style.css" media="screen" rel="stylesheet" type="text/css" />),
- stylesheet_link_tag("http://www.example.com/styles/style"))
- end
-
- def test_stylesheet_link_tag_is_html_safe
- assert stylesheet_link_tag('dir/file').html_safe?
- assert stylesheet_link_tag('dir/other/file', 'dir/file2').html_safe?
- assert stylesheet_tag('dir/file', {}).html_safe?
- end
-
- def test_image_tag
- assert_dom_equal(%(<img alt="Mouse" onmouseover="this.src='/images/mouse_over.png'" onmouseout="this.src='/images/mouse.png'" src="/images/mouse.png" />),
- image_tag("mouse.png", :mouseover => image_path("mouse_over.png")))
- end
-end
diff --git a/vendor/plugins/rails_xss/test/caching_test.rb b/vendor/plugins/rails_xss/test/caching_test.rb
deleted file mode 100644
index 3ea41e8b5..000000000
--- a/vendor/plugins/rails_xss/test/caching_test.rb
+++ /dev/null
@@ -1,54 +0,0 @@
-require 'test_helper'
-
-CACHE_DIR = 'test_cache'
-# Don't change '/../temp/' cavalierly or you might hose something you don't want hosed
-FILE_STORE_PATH = File.join(File.dirname(__FILE__), '/../temp/', CACHE_DIR)
-ActionController::Base.page_cache_directory = FILE_STORE_PATH
-ActionController::Base.cache_store = :file_store, FILE_STORE_PATH
-
-class FragmentCachingTestController < ActionController::Base
- def some_action; end;
-end
-
-class FragmentCachingTest < ActionController::TestCase
- def setup
- ActionController::Base.perform_caching = true
- @store = ActiveSupport::Cache::MemoryStore.new
- ActionController::Base.cache_store = @store
- @controller = FragmentCachingTestController.new
- @params = {:controller => 'posts', :action => 'index'}
- @request = ActionController::TestRequest.new
- @response = ActionController::TestResponse.new
- @controller.params = @params
- @controller.request = @request
- @controller.response = @response
- @controller.send(:initialize_current_url)
- @controller.send(:initialize_template_class, @response)
- @controller.send(:assign_shortcuts, @request, @response)
- end
-
- def test_fragment_for
- @store.write('views/expensive', 'fragment content')
- fragment_computed = false
-
- buffer = 'generated till now -> '.html_safe
- @controller.fragment_for(buffer, 'expensive') { fragment_computed = true }
-
- assert !fragment_computed
- assert_equal 'generated till now -> fragment content', buffer
- end
-
- def test_html_safety
- assert_nil @store.read('views/name')
- content = 'value'.html_safe
- assert_equal content, @controller.write_fragment('name', content)
-
- cached = @store.read('views/name')
- assert_equal content, cached
- assert_equal String, cached.class
-
- html_safe = @controller.read_fragment('name')
- assert_equal content, html_safe
- assert html_safe.html_safe?
- end
-end
diff --git a/vendor/plugins/rails_xss/test/content_for_test.rb b/vendor/plugins/rails_xss/test/content_for_test.rb
deleted file mode 100644
index 45ba6762c..000000000
--- a/vendor/plugins/rails_xss/test/content_for_test.rb
+++ /dev/null
@@ -1,39 +0,0 @@
-require 'test_helper'
-
-class ContentForTest < ActionView::TestCase
-
- def test_content_for_should_yield_html_safe_string
- content_for(:testing, "Some <p>html</p>")
- content = instance_variable_get(:"@content_for_testing")
- assert content.html_safe?
- end
-
- def test_content_for_should_escape_content
- content_for(:testing, "Some <p>html</p>")
- content = instance_variable_get(:"@content_for_testing")
- expected = %{Some &lt;p&gt;html&lt;/p&gt;}
- assert_dom_equal expected, content
- end
-
- def test_content_for_should_not_escape_html_safe_content
- content_for(:testing, "Some <p>html</p>".html_safe)
- content = instance_variable_get(:"@content_for_testing")
- expected = %{Some <p>html</p>}
- assert_dom_equal expected, content
- end
-
- def test_content_for_should_escape_content_from_block
- content_for(:testing){ "Some <p>html</p>" }
- content = instance_variable_get(:"@content_for_testing")
- expected = %{Some &lt;p&gt;html&lt;/p&gt;}
- assert_dom_equal expected, content
- end
-
- def test_content_for_should_not_escape_html_safe_content_from_block
- content_for(:testing){ "Some <p>html</p>".html_safe }
- content = instance_variable_get(:"@content_for_testing")
- expected = %{Some <p>html</p>}
- assert_dom_equal expected, content
- end
-
-end
diff --git a/vendor/plugins/rails_xss/test/date_helper_test.rb b/vendor/plugins/rails_xss/test/date_helper_test.rb
deleted file mode 100644
index daf010274..000000000
--- a/vendor/plugins/rails_xss/test/date_helper_test.rb
+++ /dev/null
@@ -1,29 +0,0 @@
-require 'test_helper'
-
-class DateHelperTest < ActionView::TestCase
- silence_warnings do
- Post = Struct.new("Post", :id, :written_on, :updated_at)
- end
-
- def test_select_html_safety
- assert select_day(16).html_safe?
- assert select_month(8).html_safe?
- assert select_year(Time.mktime(2003, 8, 16, 8, 4, 18)).html_safe?
- assert select_minute(Time.mktime(2003, 8, 16, 8, 4, 18)).html_safe?
- assert select_second(Time.mktime(2003, 8, 16, 8, 4, 18)).html_safe?
-
- assert select_minute(8, :use_hidden => true).html_safe?
- assert select_month(8, :prompt => 'Choose month').html_safe?
-
- assert select_time(Time.mktime(2003, 8, 16, 8, 4, 18), {}, :class => 'selector').html_safe?
- assert select_date(Time.mktime(2003, 8, 16), :date_separator => " / ", :start_year => 2003, :end_year => 2005, :prefix => "date[first]").html_safe?
- end
-
- def test_object_select_html_safety
- @post = Post.new
- @post.written_on = Date.new(2004, 6, 15)
-
- assert date_select("post", "written_on", :default => Time.local(2006, 9, 19, 15, 16, 35), :include_blank => true).html_safe?
- assert time_select("post", "written_on", :ignore_date => true).html_safe?
- end
-end
diff --git a/vendor/plugins/rails_xss/test/deprecated_output_safety_test.rb b/vendor/plugins/rails_xss/test/deprecated_output_safety_test.rb
deleted file mode 100644
index e16f7ce0d..000000000
--- a/vendor/plugins/rails_xss/test/deprecated_output_safety_test.rb
+++ /dev/null
@@ -1,112 +0,0 @@
-require 'test_helper'
-
-class DeprecatedOutputSafetyTest < ActiveSupport::TestCase
- def setup
- @string = "hello"
- end
-
- test "A string can be marked safe using html_safe!" do
- assert_deprecated do
- @string.html_safe!
- assert @string.html_safe?
- end
- end
-
- test "Marking a string safe returns the string using html_safe!" do
- assert_deprecated do
- assert_equal @string, @string.html_safe!
- end
- end
-
- test "Adding a safe string to another safe string returns a safe string using html_safe!" do
- assert_deprecated do
- @other_string = "other".html_safe!
- @string.html_safe!
- @combination = @other_string + @string
-
- assert_equal "otherhello", @combination
- assert @combination.html_safe?
- end
- end
-
- test "Adding an unsafe string to a safe string returns an unsafe string using html_safe!" do
- assert_deprecated do
- @other_string = "other".html_safe!
- @combination = @other_string + "<foo>"
- @other_combination = @string + "<foo>"
-
- assert_equal "other<foo>", @combination
- assert_equal "hello<foo>", @other_combination
-
- assert !@combination.html_safe?
- assert !@other_combination.html_safe?
- end
- end
-
- test "Concatting safe onto unsafe yields unsafe using html_safe!" do
- assert_deprecated do
- @other_string = "other"
- @string.html_safe!
-
- @other_string.concat(@string)
- assert !@other_string.html_safe?
- end
- end
-
- test "Concatting unsafe onto safe yields unsafe using html_safe!" do
- assert_deprecated do
- @other_string = "other".html_safe!
- string = @other_string.concat("<foo>")
- assert_equal "other<foo>", string
- assert !string.html_safe?
- end
- end
-
- test "Concatting safe onto safe yields safe using html_safe!" do
- assert_deprecated do
- @other_string = "other".html_safe!
- @string.html_safe!
-
- @other_string.concat(@string)
- assert @other_string.html_safe?
- end
- end
-
- test "Concatting safe onto unsafe with << yields unsafe using html_safe!" do
- assert_deprecated do
- @other_string = "other"
- @string.html_safe!
-
- @other_string << @string
- assert !@other_string.html_safe?
- end
- end
-
- test "Concatting unsafe onto safe with << yields unsafe using html_safe!" do
- assert_deprecated do
- @other_string = "other".html_safe!
- string = @other_string << "<foo>"
- assert_equal "other<foo>", string
- assert !string.html_safe?
- end
- end
-
- test "Concatting safe onto safe with << yields safe using html_safe!" do
- assert_deprecated do
- @other_string = "other".html_safe!
- @string.html_safe!
-
- @other_string << @string
- assert @other_string.html_safe?
- end
- end
-
- test "Concatting a fixnum to safe always yields safe using html_safe!" do
- assert_deprecated do
- @string.html_safe!
- @string.concat(13)
- assert_equal "hello".concat(13), @string
- assert @string.html_safe?
- end
- end
-end
diff --git a/vendor/plugins/rails_xss/test/erb_util_test.rb b/vendor/plugins/rails_xss/test/erb_util_test.rb
deleted file mode 100644
index 9a04d38e6..000000000
--- a/vendor/plugins/rails_xss/test/erb_util_test.rb
+++ /dev/null
@@ -1,36 +0,0 @@
-require 'test_helper'
-
-class ErbUtilTest < Test::Unit::TestCase
- include ERB::Util
-
- ERB::Util::HTML_ESCAPE.each do |given, expected|
- define_method "test_html_escape_#{expected.gsub(/\W/, '')}" do
- assert_equal expected, html_escape(given)
- end
-
- unless given == '"'
- define_method "test_json_escape_#{expected.gsub(/\W/, '')}" do
- assert_equal ERB::Util::JSON_ESCAPE[given], json_escape(given)
- end
- end
- end
-
- def test_html_escape_is_html_safe
- escaped = h("<p>")
- assert_equal "&lt;p&gt;", escaped
- assert escaped.html_safe?
- end
-
- def test_html_escape_passes_html_escpe_unmodified
- escaped = h("<p>".html_safe)
- assert_equal "<p>", escaped
- assert escaped.html_safe?
- end
-
- def test_rest_in_ascii
- (0..127).to_a.map {|int| int.chr }.each do |chr|
- next if %w(& " < >).include?(chr)
- assert_equal chr, html_escape(chr)
- end
- end
-end
diff --git a/vendor/plugins/rails_xss/test/form_helper_test.rb b/vendor/plugins/rails_xss/test/form_helper_test.rb
deleted file mode 100644
index e5580d26c..000000000
--- a/vendor/plugins/rails_xss/test/form_helper_test.rb
+++ /dev/null
@@ -1,1447 +0,0 @@
-require 'test_helper'
-
-silence_warnings do
- Post = Struct.new(:title, :author_name, :body, :secret, :written_on, :cost)
- Post.class_eval do
- alias_method :title_before_type_cast, :title unless respond_to?(:title_before_type_cast)
- alias_method :body_before_type_cast, :body unless respond_to?(:body_before_type_cast)
- alias_method :author_name_before_type_cast, :author_name unless respond_to?(:author_name_before_type_cast)
- alias_method :secret?, :secret
-
- def new_record=(boolean)
- @new_record = boolean
- end
-
- def new_record?
- @new_record
- end
-
- attr_accessor :author
- def author_attributes=(attributes); end
-
- attr_accessor :comments
- def comments_attributes=(attributes); end
-
- attr_accessor :tags
- def tags_attributes=(attributes); end
- end
-
- class Comment
- attr_reader :id
- attr_reader :post_id
- def initialize(id = nil, post_id = nil); @id, @post_id = id, post_id end
- def save; @id = 1; @post_id = 1 end
- def new_record?; @id.nil? end
- def to_param; @id; end
- def name
- @id.nil? ? "new #{self.class.name.downcase}" : "#{self.class.name.downcase} ##{@id}"
- end
-
- attr_accessor :relevances
- def relevances_attributes=(attributes); end
-
- end
-
- class Tag
- attr_reader :id
- attr_reader :post_id
- def initialize(id = nil, post_id = nil); @id, @post_id = id, post_id end
- def save; @id = 1; @post_id = 1 end
- def new_record?; @id.nil? end
- def to_param; @id; end
- def value
- @id.nil? ? "new #{self.class.name.downcase}" : "#{self.class.name.downcase} ##{@id}"
- end
-
- attr_accessor :relevances
- def relevances_attributes=(attributes); end
-
- end
-
- class CommentRelevance
- attr_reader :id
- attr_reader :comment_id
- def initialize(id = nil, comment_id = nil); @id, @comment_id = id, comment_id end
- def save; @id = 1; @comment_id = 1 end
- def new_record?; @id.nil? end
- def to_param; @id; end
- def value
- @id.nil? ? "new #{self.class.name.downcase}" : "#{self.class.name.downcase} ##{@id}"
- end
- end
-
- class TagRelevance
- attr_reader :id
- attr_reader :tag_id
- def initialize(id = nil, tag_id = nil); @id, @tag_id = id, tag_id end
- def save; @id = 1; @tag_id = 1 end
- def new_record?; @id.nil? end
- def to_param; @id; end
- def value
- @id.nil? ? "new #{self.class.name.downcase}" : "#{self.class.name.downcase} ##{@id}"
- end
- end
-
- class Author < Comment
- attr_accessor :post
- def post_attributes=(attributes); end
- end
-end
-
-class FormHelperTest < ActionView::TestCase
- tests ActionView::Helpers::FormHelper
-
- def setup
- super
-
- # Create "label" locale for testing I18n label helpers
- I18n.backend.store_translations 'label', {
- :helpers => {
- :label => {
- :post => {
- :body => "Write entire text here"
- }
- }
- }
- }
-
- @post = Post.new
- @comment = Comment.new
- def @post.errors()
- Class.new{
- def on(field); "can't be empty" if field == "author_name"; end
- def empty?() false end
- def count() 1 end
- def full_messages() [ "Author name can't be empty" ] end
- }.new
- end
- def @post.id; 123; end
- def @post.id_before_type_cast; 123; end
- def @post.to_param; '123'; end
-
- @post.title = "Hello World"
- @post.author_name = ""
- @post.body = "Back to the hill and over it again!"
- @post.secret = 1
- @post.written_on = Date.new(2004, 6, 15)
-
- def Post.human_attribute_name(attribute)
- attribute.to_s == "cost" ? "Total cost" : attribute.to_s.humanize
- end
-
- @controller = Class.new do
- attr_reader :url_for_options
- def url_for(options)
- @url_for_options = options
- "http://www.example.com"
- end
- end
- @controller = @controller.new
- end
-
- def test_label
- assert_dom_equal('<label for="post_title">Title</label>', label("post", "title"))
- assert_dom_equal('<label for="post_title">The title goes here</label>', label("post", "title", "The title goes here"))
- assert_dom_equal(
- '<label class="title_label" for="post_title">Title</label>',
- label("post", "title", nil, :class => 'title_label')
- )
- assert_dom_equal('<label for="post_secret">Secret?</label>', label("post", "secret?"))
- end
-
- def test_label_with_symbols
- assert_dom_equal('<label for="post_title">Title</label>', label(:post, :title))
- assert_dom_equal('<label for="post_secret">Secret?</label>', label(:post, :secret?))
- end
-
- def test_label_with_locales_strings
- old_locale, I18n.locale = I18n.locale, :label
- assert_dom_equal('<label for="post_body">Write entire text here</label>', label("post", "body"))
- ensure
- I18n.locale = old_locale
- end
-
- def test_label_with_human_attribute_name
- old_locale, I18n.locale = I18n.locale, :label
- assert_dom_equal('<label for="post_cost">Total cost</label>', label(:post, :cost))
- ensure
- I18n.locale = old_locale
- end
-
- def test_label_with_locales_symbols
- old_locale, I18n.locale = I18n.locale, :label
- assert_dom_equal('<label for="post_body">Write entire text here</label>', label(:post, :body))
- ensure
- I18n.locale = old_locale
- end
-
- def test_label_with_for_attribute_as_symbol
- assert_dom_equal('<label for="my_for">Title</label>', label(:post, :title, nil, :for => "my_for"))
- end
-
- def test_label_with_for_attribute_as_string
- assert_dom_equal('<label for="my_for">Title</label>', label(:post, :title, nil, "for" => "my_for"))
- end
-
- def test_label_with_id_attribute_as_symbol
- assert_dom_equal('<label for="post_title" id="my_id">Title</label>', label(:post, :title, nil, :id => "my_id"))
- end
-
- def test_label_with_id_attribute_as_string
- assert_dom_equal('<label for="post_title" id="my_id">Title</label>', label(:post, :title, nil, "id" => "my_id"))
- end
-
- def test_label_with_for_and_id_attributes_as_symbol
- assert_dom_equal('<label for="my_for" id="my_id">Title</label>', label(:post, :title, nil, :for => "my_for", :id => "my_id"))
- end
-
- def test_label_with_for_and_id_attributes_as_string
- assert_dom_equal('<label for="my_for" id="my_id">Title</label>', label(:post, :title, nil, "for" => "my_for", "id" => "my_id"))
- end
-
- def test_label_for_radio_buttons_with_value
- assert_dom_equal('<label for="post_title_great_title">The title goes here</label>', label("post", "title", "The title goes here", :value => "great_title"))
- assert_dom_equal('<label for="post_title_great_title">The title goes here</label>', label("post", "title", "The title goes here", :value => "great title"))
- end
-
- def test_text_field
- assert_dom_equal(
- '<input id="post_title" name="post[title]" size="30" type="text" value="Hello World" />', text_field("post", "title")
- )
- assert_dom_equal(
- '<input id="post_title" name="post[title]" size="30" type="password" value="Hello World" />', password_field("post", "title")
- )
- assert_dom_equal(
- '<input id="person_name" name="person[name]" size="30" type="password" />', password_field("person", "name")
- )
- end
-
- def test_text_field_with_escapes
- @post.title = "<b>Hello World</b>"
- assert_dom_equal(
- '<input id="post_title" name="post[title]" size="30" type="text" value="&lt;b&gt;Hello World&lt;/b&gt;" />', text_field("post", "title")
- )
- end
-
- def test_text_field_with_html_entities
- @post.title = "The HTML Entity for & is &amp;"
- assert_dom_equal(
- '<input id="post_title" name="post[title]" size="30" type="text" value="The HTML Entity for &amp; is &amp;amp;" />',
- text_field("post", "title")
- )
- end
-
- def test_text_field_with_options
- expected = '<input id="post_title" name="post[title]" size="35" type="text" value="Hello World" />'
- assert_dom_equal expected, text_field("post", "title", "size" => 35)
- assert_dom_equal expected, text_field("post", "title", :size => 35)
- end
-
- def test_text_field_assuming_size
- expected = '<input id="post_title" maxlength="35" name="post[title]" size="35" type="text" value="Hello World" />'
- assert_dom_equal expected, text_field("post", "title", "maxlength" => 35)
- assert_dom_equal expected, text_field("post", "title", :maxlength => 35)
- end
-
- def test_text_field_removing_size
- expected = '<input id="post_title" maxlength="35" name="post[title]" type="text" value="Hello World" />'
- assert_dom_equal expected, text_field("post", "title", "maxlength" => 35, "size" => nil)
- assert_dom_equal expected, text_field("post", "title", :maxlength => 35, :size => nil)
- end
-
- def test_text_field_doesnt_change_param_values
- object_name = 'post[]'
- expected = '<input id="post_123_title" name="post[123][title]" size="30" type="text" value="Hello World" />'
- assert_equal expected, text_field(object_name, "title")
- assert_equal object_name, "post[]"
- end
-
- def test_hidden_field
- assert_dom_equal '<input id="post_title" name="post[title]" type="hidden" value="Hello World" />',
- hidden_field("post", "title")
- assert_dom_equal '<input id="post_secret" name="post[secret]" type="hidden" value="1" />',
- hidden_field("post", "secret?")
- end
-
- def test_hidden_field_with_escapes
- @post.title = "<b>Hello World</b>"
- assert_dom_equal '<input id="post_title" name="post[title]" type="hidden" value="&lt;b&gt;Hello World&lt;/b&gt;" />',
- hidden_field("post", "title")
- end
-
- def test_hidden_field_with_options
- assert_dom_equal '<input id="post_title" name="post[title]" type="hidden" value="Something Else" />',
- hidden_field("post", "title", :value => "Something Else")
- end
-
- def test_check_box
- assert_dom_equal(
- '<input name="post[secret]" type="hidden" value="0" /><input checked="checked" id="post_secret" name="post[secret]" type="checkbox" value="1" />',
- check_box("post", "secret")
- )
- @post.secret = 0
- assert_dom_equal(
- '<input name="post[secret]" type="hidden" value="0" /><input id="post_secret" name="post[secret]" type="checkbox" value="1" />',
- check_box("post", "secret")
- )
- assert_dom_equal(
- '<input name="post[secret]" type="hidden" value="0" /><input checked="checked" id="post_secret" name="post[secret]" type="checkbox" value="1" />',
- check_box("post", "secret" ,{"checked"=>"checked"})
- )
- @post.secret = true
- assert_dom_equal(
- '<input name="post[secret]" type="hidden" value="0" /><input checked="checked" id="post_secret" name="post[secret]" type="checkbox" value="1" />',
- check_box("post", "secret")
- )
- assert_dom_equal(
- '<input name="post[secret]" type="hidden" value="0" /><input checked="checked" id="post_secret" name="post[secret]" type="checkbox" value="1" />',
- check_box("post", "secret?")
- )
-
- @post.secret = ['0']
- assert_dom_equal(
- '<input name="post[secret]" type="hidden" value="0" /><input id="post_secret" name="post[secret]" type="checkbox" value="1" />',
- check_box("post", "secret")
- )
- @post.secret = ['1']
- assert_dom_equal(
- '<input name="post[secret]" type="hidden" value="0" /><input checked="checked" id="post_secret" name="post[secret]" type="checkbox" value="1" />',
- check_box("post", "secret")
- )
- end
-
- def test_check_box_with_explicit_checked_and_unchecked_values
- @post.secret = "on"
- assert_dom_equal(
- '<input name="post[secret]" type="hidden" value="off" /><input checked="checked" id="post_secret" name="post[secret]" type="checkbox" value="on" />',
- check_box("post", "secret", {}, "on", "off")
- )
- end
-
- def test_checkbox_disabled_still_submits_checked_value
- assert_dom_equal(
- '<input name="post[secret]" type="hidden" value="1" /><input checked="checked" disabled="disabled" id="post_secret" name="post[secret]" type="checkbox" value="1" />',
- check_box("post", "secret", { :disabled => :true })
- )
- end
-
- def test_radio_button
- assert_dom_equal('<input checked="checked" id="post_title_hello_world" name="post[title]" type="radio" value="Hello World" />',
- radio_button("post", "title", "Hello World")
- )
- assert_dom_equal('<input id="post_title_goodbye_world" name="post[title]" type="radio" value="Goodbye World" />',
- radio_button("post", "title", "Goodbye World")
- )
- assert_dom_equal('<input id="item_subobject_title_inside_world" name="item[subobject][title]" type="radio" value="inside world"/>',
- radio_button("item[subobject]", "title", "inside world")
- )
- end
-
- def test_radio_button_is_checked_with_integers
- assert_dom_equal('<input checked="checked" id="post_secret_1" name="post[secret]" type="radio" value="1" />',
- radio_button("post", "secret", "1")
- )
- end
-
- def test_radio_button_respects_passed_in_id
- assert_dom_equal('<input checked="checked" id="foo" name="post[secret]" type="radio" value="1" />',
- radio_button("post", "secret", "1", :id=>"foo")
- )
- end
-
- def test_radio_button_with_booleans
- assert_dom_equal('<input id="post_secret_true" name="post[secret]" type="radio" value="true" />',
- radio_button("post", "secret", true)
- )
-
- assert_dom_equal('<input id="post_secret_false" name="post[secret]" type="radio" value="false" />',
- radio_button("post", "secret", false)
- )
- end
-
- def test_text_area
- assert_dom_equal(
- '<textarea cols="40" id="post_body" name="post[body]" rows="20">Back to the hill and over it again!</textarea>',
- text_area("post", "body")
- )
- end
-
- def test_text_area_with_escapes
- @post.body = "Back to <i>the</i> hill and over it again!"
- assert_dom_equal(
- '<textarea cols="40" id="post_body" name="post[body]" rows="20">Back to &lt;i&gt;the&lt;/i&gt; hill and over it again!</textarea>',
- text_area("post", "body")
- )
- end
-
- def test_text_area_with_alternate_value
- assert_dom_equal(
- '<textarea cols="40" id="post_body" name="post[body]" rows="20">Testing alternate values.</textarea>',
- text_area("post", "body", :value => 'Testing alternate values.')
- )
- end
-
- def test_text_area_with_html_entities
- @post.body = "The HTML Entity for & is &amp;"
- assert_dom_equal(
- '<textarea cols="40" id="post_body" name="post[body]" rows="20">The HTML Entity for &amp; is &amp;amp;</textarea>',
- text_area("post", "body")
- )
- end
-
- def test_text_area_with_size_option
- assert_dom_equal(
- '<textarea cols="183" id="post_body" name="post[body]" rows="820">Back to the hill and over it again!</textarea>',
- text_area("post", "body", :size => "183x820")
- )
- end
-
- def test_explicit_name
- assert_dom_equal(
- '<input id="post_title" name="dont guess" size="30" type="text" value="Hello World" />', text_field("post", "title", "name" => "dont guess")
- )
- assert_dom_equal(
- '<textarea cols="40" id="post_body" name="really!" rows="20">Back to the hill and over it again!</textarea>',
- text_area("post", "body", "name" => "really!")
- )
- assert_dom_equal(
- '<input name="i mean it" type="hidden" value="0" /><input checked="checked" id="post_secret" name="i mean it" type="checkbox" value="1" />',
- check_box("post", "secret", "name" => "i mean it")
- )
- assert_dom_equal text_field("post", "title", "name" => "dont guess"),
- text_field("post", "title", :name => "dont guess")
- assert_dom_equal text_area("post", "body", "name" => "really!"),
- text_area("post", "body", :name => "really!")
- assert_dom_equal check_box("post", "secret", "name" => "i mean it"),
- check_box("post", "secret", :name => "i mean it")
- end
-
- def test_explicit_id
- assert_dom_equal(
- '<input id="dont guess" name="post[title]" size="30" type="text" value="Hello World" />', text_field("post", "title", "id" => "dont guess")
- )
- assert_dom_equal(
- '<textarea cols="40" id="really!" name="post[body]" rows="20">Back to the hill and over it again!</textarea>',
- text_area("post", "body", "id" => "really!")
- )
- assert_dom_equal(
- '<input name="post[secret]" type="hidden" value="0" /><input checked="checked" id="i mean it" name="post[secret]" type="checkbox" value="1" />',
- check_box("post", "secret", "id" => "i mean it")
- )
- assert_dom_equal text_field("post", "title", "id" => "dont guess"),
- text_field("post", "title", :id => "dont guess")
- assert_dom_equal text_area("post", "body", "id" => "really!"),
- text_area("post", "body", :id => "really!")
- assert_dom_equal check_box("post", "secret", "id" => "i mean it"),
- check_box("post", "secret", :id => "i mean it")
- end
-
- def test_auto_index
- pid = @post.id
- assert_dom_equal(
- "<label for=\"post_#{pid}_title\">Title</label>",
- label("post[]", "title")
- )
- assert_dom_equal(
- "<input id=\"post_#{pid}_title\" name=\"post[#{pid}][title]\" size=\"30\" type=\"text\" value=\"Hello World\" />", text_field("post[]","title")
- )
- assert_dom_equal(
- "<textarea cols=\"40\" id=\"post_#{pid}_body\" name=\"post[#{pid}][body]\" rows=\"20\">Back to the hill and over it again!</textarea>",
- text_area("post[]", "body")
- )
- assert_dom_equal(
- "<input name=\"post[#{pid}][secret]\" type=\"hidden\" value=\"0\" /><input checked=\"checked\" id=\"post_#{pid}_secret\" name=\"post[#{pid}][secret]\" type=\"checkbox\" value=\"1\" />",
- check_box("post[]", "secret")
- )
- assert_dom_equal(
-"<input checked=\"checked\" id=\"post_#{pid}_title_hello_world\" name=\"post[#{pid}][title]\" type=\"radio\" value=\"Hello World\" />",
- radio_button("post[]", "title", "Hello World")
- )
- assert_dom_equal("<input id=\"post_#{pid}_title_goodbye_world\" name=\"post[#{pid}][title]\" type=\"radio\" value=\"Goodbye World\" />",
- radio_button("post[]", "title", "Goodbye World")
- )
- end
-
- def test_form_for
- form_for(:post, @post, :html => { :id => 'create-post' }) do |f|
- concat f.label(:title)
- concat f.text_field(:title)
- concat f.text_area(:body)
- concat f.check_box(:secret)
- concat f.submit('Create post')
- end
-
- expected =
- "<form action='http://www.example.com' id='create-post' method='post'>" +
- "<label for='post_title'>Title</label>" +
- "<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" +
- "<textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
- "<input name='post[secret]' type='hidden' value='0' />" +
- "<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />" +
- "<input name='commit' id='post_submit' type='submit' value='Create post' />" +
- "</form>"
-
- assert_dom_equal expected, output_buffer
- end
-
- def test_form_for_with_method
- form_for(:post, @post, :html => { :id => 'create-post', :method => :put }) do |f|
- concat f.text_field(:title)
- concat f.text_area(:body)
- concat f.check_box(:secret)
- end
-
- expected =
- "<form action='http://www.example.com' id='create-post' method='post'>" +
- "<div style='margin:0;padding:0;display:inline'><input name='_method' type='hidden' value='put' /></div>" +
- "<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" +
- "<textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
- "<input name='post[secret]' type='hidden' value='0' />" +
- "<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />" +
- "</form>"
-
- assert_dom_equal expected, output_buffer
- end
-
- def test_form_for_without_object
- form_for(:post, :html => { :id => 'create-post' }) do |f|
- concat f.text_field(:title)
- concat f.text_area(:body)
- concat f.check_box(:secret)
- end
-
- expected =
- "<form action='http://www.example.com' id='create-post' method='post'>" +
- "<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" +
- "<textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
- "<input name='post[secret]' type='hidden' value='0' />" +
- "<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />" +
- "</form>"
-
- assert_dom_equal expected, output_buffer
- end
-
- def test_form_for_with_index
- form_for("post[]", @post) do |f|
- concat f.label(:title)
- concat f.text_field(:title)
- concat f.text_area(:body)
- concat f.check_box(:secret)
- end
-
- expected =
- "<form action='http://www.example.com' method='post'>" +
- "<label for=\"post_123_title\">Title</label>" +
- "<input name='post[123][title]' size='30' type='text' id='post_123_title' value='Hello World' />" +
- "<textarea name='post[123][body]' id='post_123_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
- "<input name='post[123][secret]' type='hidden' value='0' />" +
- "<input name='post[123][secret]' checked='checked' type='checkbox' id='post_123_secret' value='1' />" +
- "</form>"
-
- assert_dom_equal expected, output_buffer
- end
-
- def test_form_for_with_nil_index_option_override
- form_for("post[]", @post, :index => nil) do |f|
- concat f.text_field(:title)
- concat f.text_area(:body)
- concat f.check_box(:secret)
- end
-
- expected =
- "<form action='http://www.example.com' method='post'>" +
- "<input name='post[][title]' size='30' type='text' id='post__title' value='Hello World' />" +
- "<textarea name='post[][body]' id='post__body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
- "<input name='post[][secret]' type='hidden' value='0' />" +
- "<input name='post[][secret]' checked='checked' type='checkbox' id='post__secret' value='1' />" +
- "</form>"
-
- assert_dom_equal expected, output_buffer
- end
-
- def test_nested_fields_for
- form_for(:post, @post) do |f|
- f.fields_for(:comment, @post) do |c|
- concat c.text_field(:title)
- end
- end
-
- expected = "<form action='http://www.example.com' method='post'>" +
- "<input name='post[comment][title]' size='30' type='text' id='post_comment_title' value='Hello World' />" +
- "</form>"
-
- assert_dom_equal expected, output_buffer
- end
-
- def test_nested_fields_for_with_nested_collections
- form_for('post[]', @post) do |f|
- concat f.text_field(:title)
- f.fields_for('comment[]', @comment) do |c|
- concat c.text_field(:name)
- end
- end
-
- expected = "<form action='http://www.example.com' method='post'>" +
- "<input name='post[123][title]' size='30' type='text' id='post_123_title' value='Hello World' />" +
- "<input name='post[123][comment][][name]' size='30' type='text' id='post_123_comment__name' value='new comment' />" +
- "</form>"
-
- assert_dom_equal expected, output_buffer
- end
-
- def test_nested_fields_for_with_index_and_parent_fields
- form_for('post', @post, :index => 1) do |c|
- concat c.text_field(:title)
- c.fields_for('comment', @comment, :index => 1) do |r|
- concat r.text_field(:name)
- end
- end
-
- expected = "<form action='http://www.example.com' method='post'>" +
- "<input name='post[1][title]' size='30' type='text' id='post_1_title' value='Hello World' />" +
- "<input name='post[1][comment][1][name]' size='30' type='text' id='post_1_comment_1_name' value='new comment' />" +
- "</form>"
-
- assert_dom_equal expected, output_buffer
- end
-
- def test_form_for_with_index_and_nested_fields_for
- form_for(:post, @post, :index => 1) do |f|
- f.fields_for(:comment, @post) do |c|
- concat c.text_field(:title)
- end
- end
-
- expected = "<form action='http://www.example.com' method='post'>" +
- "<input name='post[1][comment][title]' size='30' type='text' id='post_1_comment_title' value='Hello World' />" +
- "</form>"
-
- assert_dom_equal expected, output_buffer
- end
-
- def test_nested_fields_for_with_index_on_both
- form_for(:post, @post, :index => 1) do |f|
- f.fields_for(:comment, @post, :index => 5) do |c|
- concat c.text_field(:title)
- end
- end
-
- expected = "<form action='http://www.example.com' method='post'>" +
- "<input name='post[1][comment][5][title]' size='30' type='text' id='post_1_comment_5_title' value='Hello World' />" +
- "</form>"
-
- assert_dom_equal expected, output_buffer
- end
-
- def test_nested_fields_for_with_auto_index
- form_for("post[]", @post) do |f|
- f.fields_for(:comment, @post) do |c|
- concat c.text_field(:title)
- end
- end
-
- expected = "<form action='http://www.example.com' method='post'>" +
- "<input name='post[123][comment][title]' size='30' type='text' id='post_123_comment_title' value='Hello World' />" +
- "</form>"
-
- assert_dom_equal expected, output_buffer
- end
-
- def test_nested_fields_for_with_index_radio_button
- form_for(:post, @post) do |f|
- f.fields_for(:comment, @post, :index => 5) do |c|
- concat c.radio_button(:title, "hello")
- end
- end
-
- expected = "<form action='http://www.example.com' method='post'>" +
- "<input name='post[comment][5][title]' type='radio' id='post_comment_5_title_hello' value='hello' />" +
- "</form>"
-
- assert_dom_equal expected, output_buffer
- end
-
- def test_nested_fields_for_with_auto_index_on_both
- form_for("post[]", @post) do |f|
- f.fields_for("comment[]", @post) do |c|
- concat c.text_field(:title)
- end
- end
-
- expected = "<form action='http://www.example.com' method='post'>" +
- "<input name='post[123][comment][123][title]' size='30' type='text' id='post_123_comment_123_title' value='Hello World' />" +
- "</form>"
-
- assert_dom_equal expected, output_buffer
- end
-
- def test_nested_fields_for_with_index_and_auto_index
- form_for("post[]", @post) do |f|
- f.fields_for(:comment, @post, :index => 5) do |c|
- concat c.text_field(:title)
- end
- end
-
- form_for(:post, @post, :index => 1) do |f|
- f.fields_for("comment[]", @post) do |c|
- concat c.text_field(:title)
- end
- end
-
- expected = "<form action='http://www.example.com' method='post'>" +
- "<input name='post[123][comment][5][title]' size='30' type='text' id='post_123_comment_5_title' value='Hello World' />" +
- "</form>" +
- "<form action='http://www.example.com' method='post'>" +
- "<input name='post[1][comment][123][title]' size='30' type='text' id='post_1_comment_123_title' value='Hello World' />" +
- "</form>"
-
- assert_dom_equal expected, output_buffer
- end
-
- def test_nested_fields_for_with_a_new_record_on_a_nested_attributes_one_to_one_association
- @post.author = Author.new
-
- form_for(:post, @post) do |f|
- concat f.text_field(:title)
- f.fields_for(:author) do |af|
- concat af.text_field(:name)
- end
- end
-
- expected = '<form action="http://www.example.com" method="post">' +
- '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
- '<input id="post_author_attributes_name" name="post[author_attributes][name]" size="30" type="text" value="new author" />' +
- '</form>'
-
- assert_dom_equal expected, output_buffer
- end
-
- def test_nested_fields_for_with_explicitly_passed_object_on_a_nested_attributes_one_to_one_association
- form_for(:post, @post) do |f|
- f.fields_for(:author, Author.new(123)) do |af|
- assert_not_nil af.object
- assert_equal 123, af.object.id
- end
- end
- end
-
- def test_nested_fields_for_with_an_existing_record_on_a_nested_attributes_one_to_one_association
- @post.author = Author.new(321)
-
- form_for(:post, @post) do |f|
- concat f.text_field(:title)
- f.fields_for(:author) do |af|
- concat af.text_field(:name)
- end
- end
-
- expected = '<form action="http://www.example.com" method="post">' +
- '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
- '<input id="post_author_attributes_name" name="post[author_attributes][name]" size="30" type="text" value="author #321" />' +
- '<input id="post_author_attributes_id" name="post[author_attributes][id]" type="hidden" value="321" />' +
- '</form>'
-
- assert_dom_equal expected, output_buffer
- end
-
- def test_nested_fields_for_with_existing_records_on_a_nested_attributes_one_to_one_association_with_explicit_hidden_field_placement
- @post.author = Author.new(321)
-
- form_for(:post, @post) do |f|
- concat f.text_field(:title)
- f.fields_for(:author) do |af|
- concat af.hidden_field(:id)
- concat af.text_field(:name)
- end
- end
-
- expected = '<form action="http://www.example.com" method="post">' +
- '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
- '<input id="post_author_attributes_id" name="post[author_attributes][id]" type="hidden" value="321" />' +
- '<input id="post_author_attributes_name" name="post[author_attributes][name]" size="30" type="text" value="author #321" />' +
- '</form>'
-
- assert_dom_equal expected, output_buffer
- end
-
- def test_nested_fields_for_with_existing_records_on_a_nested_attributes_collection_association
- @post.comments = Array.new(2) { |id| Comment.new(id + 1) }
-
- form_for(:post, @post) do |f|
- concat f.text_field(:title)
- @post.comments.each do |comment|
- f.fields_for(:comments, comment) do |cf|
- concat cf.text_field(:name)
- end
- end
- end
-
- expected = '<form action="http://www.example.com" method="post">' +
- '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
- '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" size="30" type="text" value="comment #1" />' +
- '<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="1" />' +
- '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" size="30" type="text" value="comment #2" />' +
- '<input id="post_comments_attributes_1_id" name="post[comments_attributes][1][id]" type="hidden" value="2" />' +
- '</form>'
-
- assert_dom_equal expected, output_buffer
- end
-
- def test_nested_fields_for_with_existing_records_on_a_nested_attributes_collection_association_with_explicit_hidden_field_placement
- @post.comments = Array.new(2) { |id| Comment.new(id + 1) }
-
- form_for(:post, @post) do |f|
- concat f.text_field(:title)
- @post.comments.each do |comment|
- f.fields_for(:comments, comment) do |cf|
- concat cf.hidden_field(:id)
- concat cf.text_field(:name)
- end
- end
- end
-
- expected = '<form action="http://www.example.com" method="post">' +
- '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
- '<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="1" />' +
- '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" size="30" type="text" value="comment #1" />' +
- '<input id="post_comments_attributes_1_id" name="post[comments_attributes][1][id]" type="hidden" value="2" />' +
- '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" size="30" type="text" value="comment #2" />' +
- '</form>'
-
- assert_dom_equal expected, output_buffer
- end
-
- def test_nested_fields_for_with_new_records_on_a_nested_attributes_collection_association
- @post.comments = [Comment.new, Comment.new]
-
- form_for(:post, @post) do |f|
- concat f.text_field(:title)
- @post.comments.each do |comment|
- f.fields_for(:comments, comment) do |cf|
- concat cf.text_field(:name)
- end
- end
- end
-
- expected = '<form action="http://www.example.com" method="post">' +
- '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
- '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" size="30" type="text" value="new comment" />' +
- '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" size="30" type="text" value="new comment" />' +
- '</form>'
-
- assert_dom_equal expected, output_buffer
- end
-
- def test_nested_fields_for_with_existing_and_new_records_on_a_nested_attributes_collection_association
- @post.comments = [Comment.new(321), Comment.new]
-
- form_for(:post, @post) do |f|
- concat f.text_field(:title)
- @post.comments.each do |comment|
- f.fields_for(:comments, comment) do |cf|
- concat cf.text_field(:name)
- end
- end
- end
-
- expected = '<form action="http://www.example.com" method="post">' +
- '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
- '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" size="30" type="text" value="comment #321" />' +
- '<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="321" />' +
- '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" size="30" type="text" value="new comment" />' +
- '</form>'
-
- assert_dom_equal expected, output_buffer
- end
-
- def test_nested_fields_for_with_an_empty_supplied_attributes_collection
- form_for(:post, @post) do |f|
- concat f.text_field(:title)
- f.fields_for(:comments, []) do |cf|
- concat cf.text_field(:name)
- end
- end
-
- expected = '<form action="http://www.example.com" method="post">' +
- '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
- '</form>'
-
- assert_dom_equal expected, output_buffer
- end
-
- def test_nested_fields_for_with_existing_records_on_a_supplied_nested_attributes_collection
- @post.comments = Array.new(2) { |id| Comment.new(id + 1) }
-
- form_for(:post, @post) do |f|
- concat f.text_field(:title)
- f.fields_for(:comments, @post.comments) do |cf|
- concat cf.text_field(:name)
- end
- end
-
- expected = '<form action="http://www.example.com" method="post">' +
- '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
- '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" size="30" type="text" value="comment #1" />' +
- '<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="1" />' +
- '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" size="30" type="text" value="comment #2" />' +
- '<input id="post_comments_attributes_1_id" name="post[comments_attributes][1][id]" type="hidden" value="2" />' +
- '</form>'
-
- assert_dom_equal expected, output_buffer
- end
-
- def test_nested_fields_for_on_a_nested_attributes_collection_association_yields_only_builder
- @post.comments = [Comment.new(321), Comment.new]
- yielded_comments = []
-
- form_for(:post, @post) do |f|
- concat f.text_field(:title)
- f.fields_for(:comments) do |cf|
- concat cf.text_field(:name)
- yielded_comments << cf.object
- end
- end
-
- expected = '<form action="http://www.example.com" method="post">' +
- '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
- '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" size="30" type="text" value="comment #321" />' +
- '<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="321" />' +
- '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" size="30" type="text" value="new comment" />' +
- '</form>'
-
- assert_dom_equal expected, output_buffer
- assert_equal yielded_comments, @post.comments
- end
-
- def test_nested_fields_for_with_child_index_option_override_on_a_nested_attributes_collection_association
- @post.comments = []
-
- form_for(:post, @post) do |f|
- f.fields_for(:comments, Comment.new(321), :child_index => 'abc') do |cf|
- concat cf.text_field(:name)
- end
- end
-
- expected = '<form action="http://www.example.com" method="post">' +
- '<input id="post_comments_attributes_abc_name" name="post[comments_attributes][abc][name]" size="30" type="text" value="comment #321" />' +
- '<input id="post_comments_attributes_abc_id" name="post[comments_attributes][abc][id]" type="hidden" value="321" />' +
- '</form>'
-
- assert_dom_equal expected, output_buffer
- end
-
- def test_nested_fields_uses_unique_indices_for_different_collection_associations
- @post.comments = [Comment.new(321)]
- @post.tags = [Tag.new(123), Tag.new(456)]
- @post.comments[0].relevances = []
- @post.tags[0].relevances = []
- @post.tags[1].relevances = []
- form_for(:post, @post) do |f|
- f.fields_for(:comments, @post.comments[0]) do |cf|
- concat cf.text_field(:name)
- cf.fields_for(:relevances, CommentRelevance.new(314)) do |crf|
- concat crf.text_field(:value)
- end
- end
- f.fields_for(:tags, @post.tags[0]) do |tf|
- concat tf.text_field(:value)
- tf.fields_for(:relevances, TagRelevance.new(3141)) do |trf|
- concat trf.text_field(:value)
- end
- end
- f.fields_for('tags', @post.tags[1]) do |tf|
- concat tf.text_field(:value)
- tf.fields_for(:relevances, TagRelevance.new(31415)) do |trf|
- concat trf.text_field(:value)
- end
- end
- end
-
- expected = '<form action="http://www.example.com" method="post">' +
- '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" size="30" type="text" value="comment #321" />' +
- '<input id="post_comments_attributes_0_relevances_attributes_0_value" name="post[comments_attributes][0][relevances_attributes][0][value]" size="30" type="text" value="commentrelevance #314" />' +
- '<input id="post_comments_attributes_0_relevances_attributes_0_id" name="post[comments_attributes][0][relevances_attributes][0][id]" type="hidden" value="314" />' +
- '<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="321" />' +
- '<input id="post_tags_attributes_0_value" name="post[tags_attributes][0][value]" size="30" type="text" value="tag #123" />' +
- '<input id="post_tags_attributes_0_relevances_attributes_0_value" name="post[tags_attributes][0][relevances_attributes][0][value]" size="30" type="text" value="tagrelevance #3141" />' +
- '<input id="post_tags_attributes_0_relevances_attributes_0_id" name="post[tags_attributes][0][relevances_attributes][0][id]" type="hidden" value="3141" />' +
- '<input id="post_tags_attributes_0_id" name="post[tags_attributes][0][id]" type="hidden" value="123" />' +
- '<input id="post_tags_attributes_1_value" name="post[tags_attributes][1][value]" size="30" type="text" value="tag #456" />' +
- '<input id="post_tags_attributes_1_relevances_attributes_0_value" name="post[tags_attributes][1][relevances_attributes][0][value]" size="30" type="text" value="tagrelevance #31415" />' +
- '<input id="post_tags_attributes_1_relevances_attributes_0_id" name="post[tags_attributes][1][relevances_attributes][0][id]" type="hidden" value="31415" />' +
- '<input id="post_tags_attributes_1_id" name="post[tags_attributes][1][id]" type="hidden" value="456" />' +
- '</form>'
-
- assert_dom_equal expected, output_buffer
- end
-
- def test_fields_for
- fields_for(:post, @post) do |f|
- concat f.text_field(:title)
- concat f.text_area(:body)
- concat f.check_box(:secret)
- end
-
- expected =
- "<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" +
- "<textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
- "<input name='post[secret]' type='hidden' value='0' />" +
- "<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />"
-
- assert_dom_equal expected, output_buffer
- end
-
- def test_fields_for_with_index
- fields_for("post[]", @post) do |f|
- concat f.text_field(:title)
- concat f.text_area(:body)
- concat f.check_box(:secret)
- end
-
- expected =
- "<input name='post[123][title]' size='30' type='text' id='post_123_title' value='Hello World' />" +
- "<textarea name='post[123][body]' id='post_123_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
- "<input name='post[123][secret]' type='hidden' value='0' />" +
- "<input name='post[123][secret]' checked='checked' type='checkbox' id='post_123_secret' value='1' />"
-
- assert_dom_equal expected, output_buffer
- end
-
- def test_fields_for_with_nil_index_option_override
- fields_for("post[]", @post, :index => nil) do |f|
- concat f.text_field(:title)
- concat f.text_area(:body)
- concat f.check_box(:secret)
- end
-
- expected =
- "<input name='post[][title]' size='30' type='text' id='post__title' value='Hello World' />" +
- "<textarea name='post[][body]' id='post__body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
- "<input name='post[][secret]' type='hidden' value='0' />" +
- "<input name='post[][secret]' checked='checked' type='checkbox' id='post__secret' value='1' />"
-
- assert_dom_equal expected, output_buffer
- end
-
- def test_fields_for_with_index_option_override
- fields_for("post[]", @post, :index => "abc") do |f|
- concat f.text_field(:title)
- concat f.text_area(:body)
- concat f.check_box(:secret)
- end
-
- expected =
- "<input name='post[abc][title]' size='30' type='text' id='post_abc_title' value='Hello World' />" +
- "<textarea name='post[abc][body]' id='post_abc_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
- "<input name='post[abc][secret]' type='hidden' value='0' />" +
- "<input name='post[abc][secret]' checked='checked' type='checkbox' id='post_abc_secret' value='1' />"
-
- assert_dom_equal expected, output_buffer
- end
-
- def test_fields_for_without_object
- fields_for(:post) do |f|
- concat f.text_field(:title)
- concat f.text_area(:body)
- concat f.check_box(:secret)
- end
-
- expected =
- "<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" +
- "<textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
- "<input name='post[secret]' type='hidden' value='0' />" +
- "<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />"
-
- assert_dom_equal expected, output_buffer
- end
-
- def test_fields_for_with_only_object
- fields_for(@post) do |f|
- concat f.text_field(:title)
- concat f.text_area(:body)
- concat f.check_box(:secret)
- end
-
- expected =
- "<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" +
- "<textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
- "<input name='post[secret]' type='hidden' value='0' />" +
- "<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />"
-
- assert_dom_equal expected, output_buffer
- end
-
- def test_fields_for_object_with_bracketed_name
- fields_for("author[post]", @post) do |f|
- concat f.label(:title)
- concat f.text_field(:title)
- end
-
- assert_dom_equal "<label for=\"author_post_title\">Title</label>" +
- "<input name='author[post][title]' size='30' type='text' id='author_post_title' value='Hello World' />",
- output_buffer
- end
-
- def test_fields_for_object_with_bracketed_name_and_index
- fields_for("author[post]", @post, :index => 1) do |f|
- concat f.label(:title)
- concat f.text_field(:title)
- end
-
- assert_dom_equal "<label for=\"author_post_1_title\">Title</label>" +
- "<input name='author[post][1][title]' size='30' type='text' id='author_post_1_title' value='Hello World' />",
- output_buffer
- end
-
- def test_form_builder_does_not_have_form_for_method
- assert ! ActionView::Helpers::FormBuilder.instance_methods.include?('form_for')
- end
-
- def test_form_for_and_fields_for
- form_for(:post, @post, :html => { :id => 'create-post' }) do |post_form|
- concat post_form.text_field(:title)
- concat post_form.text_area(:body)
-
- fields_for(:parent_post, @post) do |parent_fields|
- concat parent_fields.check_box(:secret)
- end
- end
-
- expected =
- "<form action='http://www.example.com' id='create-post' method='post'>" +
- "<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" +
- "<textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
- "<input name='parent_post[secret]' type='hidden' value='0' />" +
- "<input name='parent_post[secret]' checked='checked' type='checkbox' id='parent_post_secret' value='1' />" +
- "</form>"
-
- assert_dom_equal expected, output_buffer
- end
-
- def test_form_for_and_fields_for_with_object
- form_for(:post, @post, :html => { :id => 'create-post' }) do |post_form|
- concat post_form.text_field(:title)
- concat post_form.text_area(:body)
-
- post_form.fields_for(@comment) do |comment_fields|
- concat comment_fields.text_field(:name)
- end
- end
-
- expected =
- "<form action='http://www.example.com' id='create-post' method='post'>" +
- "<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" +
- "<textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
- "<input name='post[comment][name]' type='text' id='post_comment_name' value='new comment' size='30' />" +
- "</form>"
-
- assert_dom_equal expected, output_buffer
- end
-
- class LabelledFormBuilder < ActionView::Helpers::FormBuilder
- (field_helpers - %w(hidden_field)).each do |selector|
- src, line = <<-END_SRC, __LINE__ + 1
- def #{selector}(field, *args, &proc)
- ("<label for='\#{field}'>\#{field.to_s.humanize}:</label> " + super + "<br/>").html_safe
- end
- END_SRC
- class_eval src, __FILE__, line
- end
- end
-
- def test_form_for_with_labelled_builder
- form_for(:post, @post, :builder => LabelledFormBuilder) do |f|
- concat f.text_field(:title)
- concat f.text_area(:body)
- concat f.check_box(:secret)
- end
-
- expected =
- "<form action='http://www.example.com' method='post'>" +
- "<label for='title'>Title:</label> <input name='post[title]' size='30' type='text' id='post_title' value='Hello World' /><br/>" +
- "<label for='body'>Body:</label> <textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea><br/>" +
- "<label for='secret'>Secret:</label> <input name='post[secret]' type='hidden' value='0' /><input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' /><br/>" +
- "</form>"
-
- assert_dom_equal expected, output_buffer
- end
-
- def test_default_form_builder
- old_default_form_builder, ActionView::Base.default_form_builder =
- ActionView::Base.default_form_builder, LabelledFormBuilder
-
- form_for(:post, @post) do |f|
- concat f.text_field(:title)
- concat f.text_area(:body)
- concat f.check_box(:secret)
- end
-
- expected =
- "<form action='http://www.example.com' method='post'>" +
- "<label for='title'>Title:</label> <input name='post[title]' size='30' type='text' id='post_title' value='Hello World' /><br/>" +
- "<label for='body'>Body:</label> <textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea><br/>" +
- "<label for='secret'>Secret:</label> <input name='post[secret]' type='hidden' value='0' /><input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' /><br/>" +
- "</form>"
-
- assert_dom_equal expected, output_buffer
- ensure
- ActionView::Base.default_form_builder = old_default_form_builder
- end
-
- def test_default_form_builder_with_active_record_helpers
- form_for(:post, @post) do |f|
- concat f.error_message_on('author_name')
- concat f.error_messages
- end
-
- expected = %(<form action='http://www.example.com' method='post'>) +
- %(<div class='formError'>can't be empty</div>) +
- %(<div class="errorExplanation" id="errorExplanation"><h2>1 error prohibited this post from being saved</h2><p>There were problems with the following fields:</p><ul><li>Author name can't be empty</li></ul></div>) +
- %(</form>)
-
- assert_dom_equal expected, output_buffer
-
- end
-
- def test_default_form_builder_no_instance_variable
- post = @post
- @post = nil
-
- form_for(:post, post) do |f|
- concat f.error_message_on('author_name')
- concat f.error_messages
- end
-
- expected = %(<form action='http://www.example.com' method='post'>) +
- %(<div class='formError'>can't be empty</div>) +
- %(<div class="errorExplanation" id="errorExplanation"><h2>1 error prohibited this post from being saved</h2><p>There were problems with the following fields:</p><ul><li>Author name can't be empty</li></ul></div>) +
- %(</form>)
-
- assert_dom_equal expected, output_buffer
-
- end
-
- def test_default_form_builder_without_object
-
- form_for(:post) do |f|
- concat f.error_message_on('author_name')
- concat f.error_messages
- end
-
- expected = %(<form action='http://www.example.com' method='post'>) +
- %(<div class='formError'>can't be empty</div>) +
- %(<div class="errorExplanation" id="errorExplanation"><h2>1 error prohibited this post from being saved</h2><p>There were problems with the following fields:</p><ul><li>Author name can't be empty</li></ul></div>) +
- %(</form>)
-
- assert_dom_equal expected, output_buffer
-
- end
-
- # Perhaps this test should be moved to prototype helper tests.
- def test_remote_form_for_with_labelled_builder
- self.extend ActionView::Helpers::PrototypeHelper
-
- remote_form_for(:post, @post, :builder => LabelledFormBuilder) do |f|
- concat f.text_field(:title)
- concat f.text_area(:body)
- concat f.check_box(:secret)
- end
-
- expected =
- %(<form action="http://www.example.com" onsubmit="new Ajax.Request('http://www.example.com', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); return false;" method="post">) +
- "<label for='title'>Title:</label> <input name='post[title]' size='30' type='text' id='post_title' value='Hello World' /><br/>" +
- "<label for='body'>Body:</label> <textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea><br/>" +
- "<label for='secret'>Secret:</label> <input name='post[secret]' type='hidden' value='0' /><input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' /><br/>" +
- "</form>"
-
- assert_dom_equal expected, output_buffer
- end
-
- def test_fields_for_with_labelled_builder
- fields_for(:post, @post, :builder => LabelledFormBuilder) do |f|
- concat f.text_field(:title)
- concat f.text_area(:body)
- concat f.check_box(:secret)
- end
-
- expected =
- "<label for='title'>Title:</label> <input name='post[title]' size='30' type='text' id='post_title' value='Hello World' /><br/>" +
- "<label for='body'>Body:</label> <textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea><br/>" +
- "<label for='secret'>Secret:</label> <input name='post[secret]' type='hidden' value='0' /><input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' /><br/>"
-
- assert_dom_equal expected, output_buffer
- end
-
- def test_form_for_with_labelled_builder_with_nested_fields_for_without_options_hash
- klass = nil
-
- form_for(:post, @post, :builder => LabelledFormBuilder) do |f|
- f.fields_for(:comments, Comment.new) do |nested_fields|
- klass = nested_fields.class
- ''
- end
- end
-
- assert_equal LabelledFormBuilder, klass
- end
-
- def test_form_for_with_labelled_builder_with_nested_fields_for_with_options_hash
- klass = nil
-
- form_for(:post, @post, :builder => LabelledFormBuilder) do |f|
- f.fields_for(:comments, Comment.new, :index => 'foo') do |nested_fields|
- klass = nested_fields.class
- ''
- end
- end
-
- assert_equal LabelledFormBuilder, klass
- end
-
- class LabelledFormBuilderSubclass < LabelledFormBuilder; end
-
- def test_form_for_with_labelled_builder_with_nested_fields_for_with_custom_builder
- klass = nil
-
- form_for(:post, @post, :builder => LabelledFormBuilder) do |f|
- f.fields_for(:comments, Comment.new, :builder => LabelledFormBuilderSubclass) do |nested_fields|
- klass = nested_fields.class
- ''
- end
- end
-
- assert_equal LabelledFormBuilderSubclass, klass
- end
-
- def test_form_for_with_html_options_adds_options_to_form_tag
- form_for(:post, @post, :html => {:id => 'some_form', :class => 'some_class'}) do |f| end
- expected = "<form action=\"http://www.example.com\" class=\"some_class\" id=\"some_form\" method=\"post\"></form>"
-
- assert_dom_equal expected, output_buffer
- end
-
- def test_form_for_with_string_url_option
- form_for(:post, @post, :url => 'http://www.otherdomain.com') do |f| end
-
- assert_equal '<form action="http://www.otherdomain.com" method="post"></form>', output_buffer
- end
-
- def test_form_for_with_hash_url_option
- form_for(:post, @post, :url => {:controller => 'controller', :action => 'action'}) do |f| end
-
- assert_equal 'controller', @controller.url_for_options[:controller]
- assert_equal 'action', @controller.url_for_options[:action]
- end
-
- def test_form_for_with_record_url_option
- form_for(:post, @post, :url => @post) do |f| end
-
- expected = "<form action=\"/posts/123\" method=\"post\"></form>"
- assert_equal expected, output_buffer
- end
-
- def test_form_for_with_existing_object
- form_for(@post) do |f| end
-
- expected = "<form action=\"/posts/123\" class=\"edit_post\" id=\"edit_post_123\" method=\"post\"><div style=\"margin:0;padding:0;display:inline\"><input name=\"_method\" type=\"hidden\" value=\"put\" /></div></form>"
- assert_equal expected, output_buffer
- end
-
- def test_form_for_with_new_object
- post = Post.new
- post.new_record = true
- def post.id() nil end
-
- form_for(post) do |f| end
-
- expected = "<form action=\"/posts\" class=\"new_post\" id=\"new_post\" method=\"post\"></form>"
- assert_equal expected, output_buffer
- end
-
- def test_form_for_with_existing_object_in_list
- @post.new_record = false
- @comment.save
-
- form_for([@post, @comment]) {}
-
- expected = %(<form action="#{comment_path(@post, @comment)}" class="edit_comment" id="edit_comment_1" method="post"><div style="margin:0;padding:0;display:inline"><input name="_method" type="hidden" value="put" /></div></form>)
- assert_dom_equal expected, output_buffer
- end
-
- def test_form_for_with_new_object_in_list
- @post.new_record = false
-
- form_for([@post, @comment]) {}
-
- expected = %(<form action="#{comments_path(@post)}" class="new_comment" id="new_comment" method="post"></form>)
- assert_dom_equal expected, output_buffer
- end
-
- def test_form_for_with_existing_object_and_namespace_in_list
- @post.new_record = false
- @comment.save
-
- form_for([:admin, @post, @comment]) {}
-
- expected = %(<form action="#{admin_comment_path(@post, @comment)}" class="edit_comment" id="edit_comment_1" method="post"><div style="margin:0;padding:0;display:inline"><input name="_method" type="hidden" value="put" /></div></form>)
- assert_dom_equal expected, output_buffer
- end
-
- def test_form_for_with_new_object_and_namespace_in_list
- @post.new_record = false
-
- form_for([:admin, @post, @comment]) {}
-
- expected = %(<form action="#{admin_comments_path(@post)}" class="new_comment" id="new_comment" method="post"></form>)
- assert_dom_equal expected, output_buffer
- end
-
- def test_form_for_with_existing_object_and_custom_url
- form_for(@post, :url => "/super_posts") do |f| end
-
- expected = "<form action=\"/super_posts\" class=\"edit_post\" id=\"edit_post_123\" method=\"post\"><div style=\"margin:0;padding:0;display:inline\"><input name=\"_method\" type=\"hidden\" value=\"put\" /></div></form>"
- assert_equal expected, output_buffer
- end
-
- def test_remote_form_for_with_html_options_adds_options_to_form_tag
- self.extend ActionView::Helpers::PrototypeHelper
-
- remote_form_for(:post, @post, :html => {:id => 'some_form', :class => 'some_class'}) do |f| end
- expected = "<form action=\"http://www.example.com\" class=\"some_class\" id=\"some_form\" method=\"post\" onsubmit=\"new Ajax.Request('http://www.example.com', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); return false;\"></form>"
-
- assert_dom_equal expected, output_buffer
- end
-
- protected
- def comments_path(post)
- "/posts/#{post.id}/comments"
- end
- alias_method :post_comments_path, :comments_path
-
- def comment_path(post, comment)
- "/posts/#{post.id}/comments/#{comment.id}"
- end
- alias_method :post_comment_path, :comment_path
-
- def admin_comments_path(post)
- "/admin/posts/#{post.id}/comments"
- end
- alias_method :admin_post_comments_path, :admin_comments_path
-
- def admin_comment_path(post, comment)
- "/admin/posts/#{post.id}/comments/#{comment.id}"
- end
- alias_method :admin_post_comment_path, :admin_comment_path
-
- def posts_path
- "/posts"
- end
-
- def post_path(post)
- "/posts/#{post.id}"
- end
-
- def protect_against_forgery?
- false
- end
-end
diff --git a/vendor/plugins/rails_xss/test/form_tag_helper_test.rb b/vendor/plugins/rails_xss/test/form_tag_helper_test.rb
deleted file mode 100644
index 41eeceeb3..000000000
--- a/vendor/plugins/rails_xss/test/form_tag_helper_test.rb
+++ /dev/null
@@ -1,354 +0,0 @@
-require 'test_helper'
-
-class FormTagHelperTest < ActionView::TestCase
- def setup
- @controller = Class.new do
- def url_for(options)
- "http://www.example.com"
- end
- end
- @controller = @controller.new
- end
-
- VALID_HTML_ID = /^[A-Za-z][-_:.A-Za-z0-9]*$/ # see http://www.w3.org/TR/html4/types.html#type-name
-
- def test_check_box_tag
- actual = check_box_tag "admin"
- expected = %(<input id="admin" name="admin" type="checkbox" value="1" />)
- assert_dom_equal expected, actual
- end
-
- def test_check_box_tag_id_sanitized
- label_elem = root_elem(check_box_tag("project[2][admin]"))
- assert_match VALID_HTML_ID, label_elem['id']
- end
-
- def test_form_tag
- actual = form_tag
- expected = %(<form action="http://www.example.com" method="post">)
- assert_dom_equal expected, actual
- end
-
- def test_form_tag_multipart
- actual = form_tag({}, { 'multipart' => true })
- expected = %(<form action="http://www.example.com" enctype="multipart/form-data" method="post">)
- assert_dom_equal expected, actual
- end
-
- def test_form_tag_with_method_put
- actual = form_tag({}, { :method => :put })
- expected = %(<form action="http://www.example.com" method="post"><div style='margin:0;padding:0;display:inline'><input type="hidden" name="_method" value="put" /></div>)
- assert_dom_equal expected, actual
- end
-
- def test_form_tag_with_method_delete
- actual = form_tag({}, { :method => :delete })
- expected = %(<form action="http://www.example.com" method="post"><div style='margin:0;padding:0;display:inline'><input type="hidden" name="_method" value="delete" /></div>)
- assert_dom_equal expected, actual
- end
-
- def test_form_tag_with_block_in_erb
- __in_erb_template = ''
- form_tag("http://example.com") { concat "Hello world!" }
-
- expected = %(<form action="http://example.com" method="post">Hello world!</form>)
- assert_dom_equal expected, output_buffer
- end
-
- def test_form_tag_with_block_and_method_in_erb
- __in_erb_template = ''
- form_tag("http://example.com", :method => :put) { concat "Hello world!" }
-
- expected = %(<form action="http://example.com" method="post"><div style='margin:0;padding:0;display:inline'><input type="hidden" name="_method" value="put" /></div>Hello world!</form>)
- assert_dom_equal expected, output_buffer
- end
-
- def test_hidden_field_tag
- actual = hidden_field_tag "id", 3
- expected = %(<input id="id" name="id" type="hidden" value="3" />)
- assert_dom_equal expected, actual
- end
-
- def test_hidden_field_tag_id_sanitized
- input_elem = root_elem(hidden_field_tag("item[][title]"))
- assert_match VALID_HTML_ID, input_elem['id']
- end
-
- def test_file_field_tag
- assert_dom_equal "<input name=\"picsplz\" type=\"file\" id=\"picsplz\" />", file_field_tag("picsplz")
- end
-
- def test_file_field_tag_with_options
- assert_dom_equal "<input name=\"picsplz\" type=\"file\" id=\"picsplz\" class=\"pix\"/>", file_field_tag("picsplz", :class => "pix")
- end
-
- def test_password_field_tag
- actual = password_field_tag
- expected = %(<input id="password" name="password" type="password" />)
- assert_dom_equal expected, actual
- end
-
- def test_radio_button_tag
- actual = radio_button_tag "people", "david"
- expected = %(<input id="people_david" name="people" type="radio" value="david" />)
- assert_dom_equal expected, actual
-
- actual = radio_button_tag("num_people", 5)
- expected = %(<input id="num_people_5" name="num_people" type="radio" value="5" />)
- assert_dom_equal expected, actual
-
- actual = radio_button_tag("gender", "m") + radio_button_tag("gender", "f")
- expected = %(<input id="gender_m" name="gender" type="radio" value="m" /><input id="gender_f" name="gender" type="radio" value="f" />)
- assert_dom_equal expected, actual
-
- actual = radio_button_tag("opinion", "-1") + radio_button_tag("opinion", "1")
- expected = %(<input id="opinion_-1" name="opinion" type="radio" value="-1" /><input id="opinion_1" name="opinion" type="radio" value="1" />)
- assert_dom_equal expected, actual
-
- actual = radio_button_tag("person[gender]", "m")
- expected = %(<input id="person_gender_m" name="person[gender]" type="radio" value="m" />)
- assert_dom_equal expected, actual
- end
-
- def test_select_tag
- actual = select_tag "people", "<option>david</option>".html_safe
- expected = %(<select id="people" name="people"><option>david</option></select>)
- assert_dom_equal expected, actual
- end
-
- def test_select_tag_with_multiple
- actual = select_tag "colors", "<option>Red</option><option>Blue</option><option>Green</option>".html_safe, :multiple => :true
- expected = %(<select id="colors" multiple="multiple" name="colors"><option>Red</option><option>Blue</option><option>Green</option></select>)
- assert_dom_equal expected, actual
- end
-
- def test_select_tag_disabled
- actual = select_tag "places", "<option>Home</option><option>Work</option><option>Pub</option>".html_safe, :disabled => :true
- expected = %(<select id="places" disabled="disabled" name="places"><option>Home</option><option>Work</option><option>Pub</option></select>)
- assert_dom_equal expected, actual
- end
-
- def test_select_tag_id_sanitized
- input_elem = root_elem(select_tag("project[1]people", "<option>david</option>"))
- assert_match VALID_HTML_ID, input_elem['id']
- end
-
- def test_select_tag_with_array_options
- assert_deprecated /array/ do
- select_tag "people", ["<option>david</option>"]
- end
- end
-
- def test_text_area_tag_size_string
- actual = text_area_tag "body", "hello world", "size" => "20x40"
- expected = %(<textarea cols="20" id="body" name="body" rows="40">hello world</textarea>)
- assert_dom_equal expected, actual
- end
-
- def test_text_area_tag_size_symbol
- actual = text_area_tag "body", "hello world", :size => "20x40"
- expected = %(<textarea cols="20" id="body" name="body" rows="40">hello world</textarea>)
- assert_dom_equal expected, actual
- end
-
- def test_text_area_tag_should_disregard_size_if_its_given_as_an_integer
- actual = text_area_tag "body", "hello world", :size => 20
- expected = %(<textarea id="body" name="body">hello world</textarea>)
- assert_dom_equal expected, actual
- end
-
- def test_text_area_tag_id_sanitized
- input_elem = root_elem(text_area_tag("item[][description]"))
- assert_match VALID_HTML_ID, input_elem['id']
- end
-
- def test_text_area_tag_escape_content
- actual = text_area_tag "body", "<b>hello world</b>", :size => "20x40"
- expected = %(<textarea cols="20" id="body" name="body" rows="40">&lt;b&gt;hello world&lt;/b&gt;</textarea>)
- assert_dom_equal expected, actual
- end
-
- def test_text_area_tag_unescaped_content
- actual = text_area_tag "body", "<b>hello world</b>", :size => "20x40", :escape => false
- expected = %(<textarea cols="20" id="body" name="body" rows="40"><b>hello world</b></textarea>)
- assert_dom_equal expected, actual
- end
-
- def test_text_area_tag_unescaped_nil_content
- actual = text_area_tag "body", nil, :escape => false
- expected = %(<textarea id="body" name="body"></textarea>)
- assert_dom_equal expected, actual
- end
-
- def test_text_field_tag
- actual = text_field_tag "title", "Hello!"
- expected = %(<input id="title" name="title" type="text" value="Hello!" />)
- assert_dom_equal expected, actual
- end
-
- def test_text_field_tag_class_string
- actual = text_field_tag "title", "Hello!", "class" => "admin"
- expected = %(<input class="admin" id="title" name="title" type="text" value="Hello!" />)
- assert_dom_equal expected, actual
- end
-
- def test_text_field_tag_size_symbol
- actual = text_field_tag "title", "Hello!", :size => 75
- expected = %(<input id="title" name="title" size="75" type="text" value="Hello!" />)
- assert_dom_equal expected, actual
- end
-
- def test_text_field_tag_size_string
- actual = text_field_tag "title", "Hello!", "size" => "75"
- expected = %(<input id="title" name="title" size="75" type="text" value="Hello!" />)
- assert_dom_equal expected, actual
- end
-
- def test_text_field_tag_maxlength_symbol
- actual = text_field_tag "title", "Hello!", :maxlength => 75
- expected = %(<input id="title" name="title" maxlength="75" type="text" value="Hello!" />)
- assert_dom_equal expected, actual
- end
-
- def test_text_field_tag_maxlength_string
- actual = text_field_tag "title", "Hello!", "maxlength" => "75"
- expected = %(<input id="title" name="title" maxlength="75" type="text" value="Hello!" />)
- assert_dom_equal expected, actual
- end
-
- def test_text_field_disabled
- actual = text_field_tag "title", "Hello!", :disabled => :true
- expected = %(<input id="title" name="title" disabled="disabled" type="text" value="Hello!" />)
- assert_dom_equal expected, actual
- end
-
- def test_text_field_tag_with_multiple_options
- actual = text_field_tag "title", "Hello!", :size => 70, :maxlength => 80
- expected = %(<input id="title" name="title" size="70" maxlength="80" type="text" value="Hello!" />)
- assert_dom_equal expected, actual
- end
-
- def test_text_field_tag_id_sanitized
- input_elem = root_elem(text_field_tag("item[][title]"))
- assert_match VALID_HTML_ID, input_elem['id']
- end
-
- def test_label_tag_without_text
- actual = label_tag "title"
- expected = %(<label for="title">Title</label>)
- assert_dom_equal expected, actual
- end
-
- def test_label_tag_with_symbol
- actual = label_tag :title
- expected = %(<label for="title">Title</label>)
- assert_dom_equal expected, actual
- end
-
- def test_label_tag_with_text
- actual = label_tag "title", "My Title"
- expected = %(<label for="title">My Title</label>)
- assert_dom_equal expected, actual
- end
-
- def test_label_tag_class_string
- actual = label_tag "title", "My Title", "class" => "small_label"
- expected = %(<label for="title" class="small_label">My Title</label>)
- assert_dom_equal expected, actual
- end
-
- def test_label_tag_id_sanitized
- label_elem = root_elem(label_tag("item[title]"))
- assert_match VALID_HTML_ID, label_elem['for']
- end
-
- def test_boolean_options
- assert_dom_equal %(<input checked="checked" disabled="disabled" id="admin" name="admin" readonly="readonly" type="checkbox" value="1" />), check_box_tag("admin", 1, true, 'disabled' => true, :readonly => "yes")
- assert_dom_equal %(<input checked="checked" id="admin" name="admin" type="checkbox" value="1" />), check_box_tag("admin", 1, true, :disabled => false, :readonly => nil)
- assert_dom_equal %(<input type="checkbox" />), tag(:input, :type => "checkbox", :checked => false)
- assert_dom_equal %(<select id="people" multiple="multiple" name="people[]"><option>david</option></select>), select_tag("people", "<option>david</option>".html_safe, :multiple => true)
- assert_dom_equal %(<select id="people_" multiple="multiple" name="people[]"><option>david</option></select>), select_tag("people[]", "<option>david</option>".html_safe, :multiple => true)
- assert_dom_equal %(<select id="people" name="people"><option>david</option></select>), select_tag("people", "<option>david</option>".html_safe, :multiple => nil)
- end
-
- def test_stringify_symbol_keys
- actual = text_field_tag "title", "Hello!", :id => "admin"
- expected = %(<input id="admin" name="title" type="text" value="Hello!" />)
- assert_dom_equal expected, actual
- end
-
- def test_submit_tag
- assert_dom_equal(
- %(<input name='commit' onclick="if (window.hiddenCommit) { window.hiddenCommit.setAttribute('value', this.value); }else { hiddenCommit = document.createElement('input');hiddenCommit.type = 'hidden';hiddenCommit.value = this.value;hiddenCommit.name = this.name;this.form.appendChild(hiddenCommit); }this.setAttribute('originalValue', this.value);this.disabled = true;this.value='Saving...';alert('hello!');result = (this.form.onsubmit ? (this.form.onsubmit() ? this.form.submit() : false) : this.form.submit());if (result == false) { this.value = this.getAttribute('originalValue');this.disabled = false; }return result;" type="submit" value="Save" />),
- submit_tag("Save", :disable_with => "Saving...", :onclick => "alert('hello!')")
- )
- end
-
- def test_submit_tag_with_no_onclick_options
- assert_dom_equal(
- %(<input name='commit' onclick="if (window.hiddenCommit) { window.hiddenCommit.setAttribute('value', this.value); }else { hiddenCommit = document.createElement('input');hiddenCommit.type = 'hidden';hiddenCommit.value = this.value;hiddenCommit.name = this.name;this.form.appendChild(hiddenCommit); }this.setAttribute('originalValue', this.value);this.disabled = true;this.value='Saving...';result = (this.form.onsubmit ? (this.form.onsubmit() ? this.form.submit() : false) : this.form.submit());if (result == false) { this.value = this.getAttribute('originalValue');this.disabled = false; }return result;" type="submit" value="Save" />),
- submit_tag("Save", :disable_with => "Saving...")
- )
- end
-
- def test_submit_tag_with_confirmation
- assert_dom_equal(
- %(<input name='commit' type='submit' value='Save' onclick="if (!confirm('Are you sure?')) return false; return true;"/>),
- submit_tag("Save", :confirm => "Are you sure?")
- )
- end
-
- def test_submit_tag_with_confirmation_and_with_disable_with
- assert_dom_equal(
- %(<input name="commit" onclick="if (!confirm('Are you sure?')) return false; if (window.hiddenCommit) { window.hiddenCommit.setAttribute('value', this.value); }else { hiddenCommit = document.createElement('input');hiddenCommit.type = 'hidden';hiddenCommit.value = this.value;hiddenCommit.name = this.name;this.form.appendChild(hiddenCommit); }this.setAttribute('originalValue', this.value);this.disabled = true;this.value='Saving...';result = (this.form.onsubmit ? (this.form.onsubmit() ? this.form.submit() : false) : this.form.submit());if (result == false) { this.value = this.getAttribute('originalValue');this.disabled = false; }return result;" type="submit" value="Save" />),
- submit_tag("Save", :disable_with => "Saving...", :confirm => "Are you sure?")
- )
- end
-
- def test_image_submit_tag_with_confirmation
- assert_dom_equal(
- %(<input type="image" src="/images/save.gif" onclick="return confirm('Are you sure?');"/>),
- image_submit_tag("save.gif", :confirm => "Are you sure?")
- )
- end
-
- def test_pass
- assert_equal 1, 1
- end
-
- def test_field_set_tag_in_erb
- __in_erb_template = ''
- field_set_tag("Your details") { concat "Hello world!" }
-
- expected = %(<fieldset><legend>Your details</legend>Hello world!</fieldset>)
- assert_dom_equal expected, output_buffer
-
- self.output_buffer = ''.html_safe
- field_set_tag { concat "Hello world!" }
-
- expected = %(<fieldset>Hello world!</fieldset>)
- assert_dom_equal expected, output_buffer
-
- self.output_buffer = ''.html_safe
- field_set_tag('') { concat "Hello world!" }
-
- expected = %(<fieldset>Hello world!</fieldset>)
- assert_dom_equal expected, output_buffer
-
- self.output_buffer = ''.html_safe
- field_set_tag('', :class => 'format') { concat "Hello world!" }
-
- expected = %(<fieldset class="format">Hello world!</fieldset>)
- assert_dom_equal expected, output_buffer
- end
-
- def protect_against_forgery?
- false
- end
-
- private
-
- def root_elem(rendered_content)
- HTML::Document.new(rendered_content).root.children[0]
- end
-end
diff --git a/vendor/plugins/rails_xss/test/javascript_helper_test.rb b/vendor/plugins/rails_xss/test/javascript_helper_test.rb
deleted file mode 100644
index 691d97a15..000000000
--- a/vendor/plugins/rails_xss/test/javascript_helper_test.rb
+++ /dev/null
@@ -1,10 +0,0 @@
-require 'test_helper'
-
-class JavascriptHelperTest < ActionView::TestCase
- def test_escape_javascript_with_safebuffer
- given = %('quoted' "double-quoted" new-line:\n </closed>)
- expect = %(\\'quoted\\' \\"double-quoted\\" new-line:\\n <\\/closed>)
- assert_equal expect, escape_javascript(given)
- assert_equal expect, escape_javascript(ActiveSupport::SafeBuffer.new(given))
- end
-end
diff --git a/vendor/plugins/rails_xss/test/output_escaping_test.rb b/vendor/plugins/rails_xss/test/output_escaping_test.rb
deleted file mode 100644
index 8b6f8b83c..000000000
--- a/vendor/plugins/rails_xss/test/output_escaping_test.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-require 'test_helper'
-
-class OutputEscapingTest < ActiveSupport::TestCase
-
- test "escape_html shouldn't die when passed nil" do
- assert ERB::Util.h(nil).blank?
- end
-
- test "escapeHTML should escape strings" do
- assert_equal "&lt;&gt;&quot;", ERB::Util.h("<>\"")
- end
-
- test "escapeHTML shouldn't touch explicitly safe strings" do
- # TODO this seems easier to compose and reason about, but
- # this should be verified
- assert_equal "<", ERB::Util.h("<".html_safe)
- end
-
-end
diff --git a/vendor/plugins/rails_xss/test/output_safety_test.rb b/vendor/plugins/rails_xss/test/output_safety_test.rb
deleted file mode 100644
index 2e376477d..000000000
--- a/vendor/plugins/rails_xss/test/output_safety_test.rb
+++ /dev/null
@@ -1,115 +0,0 @@
-require 'test_helper'
-
-class OutputSafetyTest < ActiveSupport::TestCase
- def setup
- @string = "hello"
- @object = Class.new(Object) do
- def to_s
- "other"
- end
- end.new
- end
-
- test "A string is unsafe by default" do
- assert !@string.html_safe?
- end
-
- test "A string can be marked safe" do
- string = @string.html_safe
- assert string.html_safe?
- end
-
- test "Marking a string safe returns the string" do
- assert_equal @string, @string.html_safe
- end
-
- test "A fixnum is safe by default" do
- assert 5.html_safe?
- end
-
- test "An object is unsafe by default" do
- assert !@object.html_safe?
- end
-
- test "Adding an object to a safe string returns a safe string" do
- string = @string.html_safe
- string << @object
-
- assert_equal "helloother", string
- assert string.html_safe?
- end
-
- test "Adding a safe string to another safe string returns a safe string" do
- @other_string = "other".html_safe
- string = @string.html_safe
- @combination = @other_string + string
-
- assert_equal "otherhello", @combination
- assert @combination.html_safe?
- end
-
- test "Adding an unsafe string to a safe string escapes it and returns a safe string" do
- @other_string = "other".html_safe
- @combination = @other_string + "<foo>"
- @other_combination = @string + "<foo>"
-
- assert_equal "other&lt;foo&gt;", @combination
- assert_equal "hello<foo>", @other_combination
-
- assert @combination.html_safe?
- assert !@other_combination.html_safe?
- end
-
- test "Concatting safe onto unsafe yields unsafe" do
- @other_string = "other"
-
- string = @string.html_safe
- @other_string.concat(string)
- assert !@other_string.html_safe?
- end
-
- test "Concatting unsafe onto safe yields escaped safe" do
- @other_string = "other".html_safe
- string = @other_string.concat("<foo>")
- assert_equal "other&lt;foo&gt;", string
- assert string.html_safe?
- end
-
- test "Concatting safe onto safe yields safe" do
- @other_string = "other".html_safe
- string = @string.html_safe
-
- @other_string.concat(string)
- assert @other_string.html_safe?
- end
-
- test "Concatting safe onto unsafe with << yields unsafe" do
- @other_string = "other"
- string = @string.html_safe
-
- @other_string << string
- assert !@other_string.html_safe?
- end
-
- test "Concatting unsafe onto safe with << yields escaped safe" do
- @other_string = "other".html_safe
- string = @other_string << "<foo>"
- assert_equal "other&lt;foo&gt;", string
- assert string.html_safe?
- end
-
- test "Concatting safe onto safe with << yields safe" do
- @other_string = "other".html_safe
- string = @string.html_safe
-
- @other_string << string
- assert @other_string.html_safe?
- end
-
- test "Concatting a fixnum to safe always yields safe" do
- string = @string.html_safe
- string = string.concat(13)
- assert_equal "hello".concat(13), string
- assert string.html_safe?
- end
-end
diff --git a/vendor/plugins/rails_xss/test/rails_xss_test.rb b/vendor/plugins/rails_xss/test/rails_xss_test.rb
deleted file mode 100644
index b6268bafd..000000000
--- a/vendor/plugins/rails_xss/test/rails_xss_test.rb
+++ /dev/null
@@ -1,23 +0,0 @@
-require 'test_helper'
-
-class RailsXssTest < ActiveSupport::TestCase
- test "ERB::Util.h should mark its return value as safe and escape it" do
- escaped = ERB::Util.h("<p>")
- assert_equal "&lt;p&gt;", escaped
- assert escaped.html_safe?
- end
-
- test "ERB::Util.h should leave previously safe strings alone " do
- # TODO this seems easier to compose and reason about, but
- # this should be verified
- escaped = ERB::Util.h("<p>".html_safe)
- assert_equal "<p>", escaped
- assert escaped.html_safe?
- end
-
- test "ERB::Util.h should not implode when passed a non-string" do
- assert_nothing_raised do
- assert_equal "1", ERB::Util.h(1)
- end
- end
-end
diff --git a/vendor/plugins/rails_xss/test/raw_output_helper_test.rb b/vendor/plugins/rails_xss/test/raw_output_helper_test.rb
deleted file mode 100644
index 2a67f976e..000000000
--- a/vendor/plugins/rails_xss/test/raw_output_helper_test.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-require 'test_helper'
-
-class RawOutputHelperTest < ActionView::TestCase
-
- def setup
- @string = "hello"
- end
-
- test "raw returns the safe string" do
- result = raw(@string)
- assert_equal @string, result
- assert result.html_safe?
- end
-
- test "raw handles nil values correctly" do
- assert_equal "", raw(nil)
- end
-end
diff --git a/vendor/plugins/rails_xss/test/safe_buffer_test.rb b/vendor/plugins/rails_xss/test/safe_buffer_test.rb
deleted file mode 100644
index a0a2eccee..000000000
--- a/vendor/plugins/rails_xss/test/safe_buffer_test.rb
+++ /dev/null
@@ -1,51 +0,0 @@
-require 'test_helper'
-
-class SafeBufferTest < ActiveSupport::TestCase
- def setup
- @buffer = ActiveSupport::SafeBuffer.new
- end
-
- test "Should look like a string" do
- assert @buffer.is_a?(String)
- assert_equal "", @buffer
- end
-
- test "Should escape a raw string which is passed to them" do
- @buffer << "<script>"
- assert_equal "&lt;script&gt;", @buffer
- end
-
- test "Should NOT escape a safe value passed to it" do
- @buffer << "<script>".html_safe
- assert_equal "<script>", @buffer
- end
-
- test "Should not mess with an innocuous string" do
- @buffer << "Hello"
- assert_equal "Hello", @buffer
- end
-
- test "Should not mess with a previously escape test" do
- @buffer << ERB::Util.html_escape("<script>")
- assert_equal "&lt;script&gt;", @buffer
- end
-
- test "Should be considered safe" do
- assert @buffer.html_safe?
- end
-
- test "Should return a safe buffer when calling to_s" do
- new_buffer = @buffer.to_s
- assert_equal ActiveSupport::SafeBuffer, new_buffer.class
- end
-
- test "Should not return a safe buffer when using sub" do
- assert !@buffer.sub('', "asdf").html_safe?
- end
-
- test "Should raise argument error when using sub!" do
- assert_raise TypeError do
- @buffer.sub!('', "asdf")
- end
- end
-end
diff --git a/vendor/plugins/rails_xss/test/tag_helper_test.rb b/vendor/plugins/rails_xss/test/tag_helper_test.rb
deleted file mode 100644
index 2a4280943..000000000
--- a/vendor/plugins/rails_xss/test/tag_helper_test.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-require 'test_helper'
-
-class TagHelperTest < ActionView::TestCase
-
- def test_content_tag
- assert_equal "<a href=\"create\">Create</a>", content_tag("a", "Create", "href" => "create")
- assert content_tag("a", "Create", "href" => "create").html_safe?
- assert_equal content_tag("a", "Create", "href" => "create"),
- content_tag("a", "Create", :href => "create")
- assert_equal "<p>&lt;script&gt;evil_js&lt;/script&gt;</p>",
- content_tag(:p, '<script>evil_js</script>')
- assert_equal "<p><script>evil_js</script></p>",
- content_tag(:p, '<script>evil_js</script>', nil, false)
- end
-
- def test_tag_honors_html_safe_for_param_values
- ['1&amp;2', '1 &lt; 2', '&#8220;test&#8220;'].each do |escaped|
- assert_equal %(<a href="#{escaped}" />), tag('a', :href => escaped.html_safe)
- end
- end
-end
diff --git a/vendor/plugins/rails_xss/test/test_helper.rb b/vendor/plugins/rails_xss/test/test_helper.rb
deleted file mode 100644
index d9594e446..000000000
--- a/vendor/plugins/rails_xss/test/test_helper.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-abort 'RAILS_ROOT=/path/to/rails/2.3/app rake test' unless ENV['RAILS_ROOT']
-require File.expand_path('config/environment', ENV['RAILS_ROOT'])
-require File.expand_path('../../init', __FILE__)
-require 'active_support/test_case'
-require 'action_view/test_case'
-require 'test/unit'
diff --git a/vendor/plugins/rails_xss/test/text_helper_test.rb b/vendor/plugins/rails_xss/test/text_helper_test.rb
deleted file mode 100644
index b74ae547c..000000000
--- a/vendor/plugins/rails_xss/test/text_helper_test.rb
+++ /dev/null
@@ -1,30 +0,0 @@
-require 'test_helper'
-
-class TextHelperTest < ActionView::TestCase
-
- def setup
- @controller = Class.new do
- attr_accessor :request
- def url_for(*args) "http://www.example.com" end
- end.new
- end
-
- def test_simple_format_with_escaping_html_options
- assert_dom_equal(%(<p class="intro">It's nice to have options.</p>),
- simple_format("It's nice to have options.", :class=>"intro"))
- end
-
- def test_simple_format_should_not_escape_safe_content
- assert_dom_equal(%(<p>This is <script>safe_js</script>.</p>),
- simple_format('This is <script>safe_js</script>.'.html_safe))
- end
-
- def test_simple_format_escapes_unsafe_content
- assert_dom_equal(%(<p>This is &lt;script&gt;evil_js&lt;/script&gt;.</p>),
- simple_format('This is <script>evil_js</script>.'))
- end
-
- def test_truncate_should_not_be_html_safe
- assert !truncate("Hello World!", :length => 12).html_safe?
- end
-end
diff --git a/vendor/plugins/rails_xss/test/url_for_test.rb b/vendor/plugins/rails_xss/test/url_for_test.rb
deleted file mode 100644
index b13451bfb..000000000
--- a/vendor/plugins/rails_xss/test/url_for_test.rb
+++ /dev/null
@@ -1,39 +0,0 @@
-require 'test_helper'
-
-class UrlHelperTest < ActionView::TestCase
-
- def abcd(hash = {})
- hash_for(:a => :b, :c => :d).merge(hash)
- end
-
- def hash_for(opts = {})
- {:controller => "foo", :action => "bar"}.merge(opts)
- end
-
- def test_url_for_does_not_escape_urls_if_explicitly_stated
- assert_equal "/foo/bar?a=b&c=d", url_for(abcd(:escape => false))
- end
-
- def test_link_tag_with_img
- link = link_to("<img src='/favicon.jpg' />".html_safe, "/")
- expected = %{<a href="/"><img src='/favicon.jpg' /></a>}
- assert_dom_equal expected, link
- end
-
- def test_link_to_should_not_escape_content_for_html_safe
- link = link_to("Some <p>html</p>".html_safe, "/")
- expected = %{<a href="/">Some <p>html</p></a>}
- assert_dom_equal link, expected
- end
-
- def test_link_to_escapes_content_for_non_safe
- link = link_to("Some <p>html</p>", "/")
- expected = %{<a href="/">Some &lt;p&gt;html&lt;/p&gt;</a>}
- assert_dom_equal link, expected
- end
-
- def test_url_for_escaping_is_safety_aware
- assert url_for(abcd(:escape => true)).html_safe?, "escaped urls should be html_safe?"
- assert !url_for(abcd(:escape => false)).html_safe?, "non-escaped urls should not be html_safe?"
- end
-end
diff --git a/vendor/plugins/strip_attributes/lib/strip_attributes.rb b/vendor/plugins/strip_attributes/lib/strip_attributes.rb
index 70f414654..bb93aa9a7 100644
--- a/vendor/plugins/strip_attributes/lib/strip_attributes.rb
+++ b/vendor/plugins/strip_attributes/lib/strip_attributes.rb
@@ -3,10 +3,12 @@ module StripAttributes
# XXX this differs from official StripAttributes, as it doesn't make blank cells null.
def strip_attributes!(options = nil)
before_validation do |record|
- attributes = StripAttributes.narrow(record.attributes, options)
- attributes.each do |attr, value|
+ attribute_names = StripAttributes.narrow(record.attribute_names, options)
+
+ attribute_names.each do |attribute_name|
+ value = record[attribute_name]
if value.respond_to?(:strip)
- record[attr] = (value.nil?) ? nil : value.strip
+ record[attribute_name] = (value.nil?) ? nil : value.strip
end
end
end
@@ -14,16 +16,16 @@ module StripAttributes
# Necessary because Rails has removed the narrowing of attributes using :only
# and :except on Base#attributes
- def self.narrow(attributes, options)
+ def self.narrow(attribute_names, options)
if options.nil?
- attributes
+ attribute_names
else
if except = options[:except]
except = Array(except).collect { |attribute| attribute.to_s }
- attributes.except(*except)
+ attribute_names - except
elsif only = options[:only]
only = Array(only).collect { |attribute| attribute.to_s }
- attributes.slice(*only)
+ attribute_names & only
else
raise ArgumentError, "Options does not specify :except or :only (#{options.keys.inspect})"
end
diff --git a/vendor/plugins/strip_attributes/test/strip_attributes_test.rb b/vendor/plugins/strip_attributes/test/strip_attributes_test.rb
index 95754fca7..8158dc664 100644
--- a/vendor/plugins/strip_attributes/test/strip_attributes_test.rb
+++ b/vendor/plugins/strip_attributes/test/strip_attributes_test.rb
@@ -49,7 +49,7 @@ class StripAttributesTest < Test::Unit::TestCase
assert_equal "foo", record.foo
assert_equal "bar", record.bar
assert_equal "biz", record.biz
- assert_nil record.baz
+ assert_equal "", record.baz
end
def test_should_strip_only_one_field
@@ -76,7 +76,7 @@ class StripAttributesTest < Test::Unit::TestCase
assert_equal "\tfoo", record.foo
assert_equal "bar", record.bar
assert_equal "biz", record.biz
- assert_nil record.baz
+ assert_equal "", record.baz
end
def test_should_strip_all_except_three_fields
@@ -85,6 +85,6 @@ class StripAttributesTest < Test::Unit::TestCase
assert_equal "\tfoo", record.foo
assert_equal "bar \t ", record.bar
assert_equal "\tbiz ", record.biz
- assert_nil record.baz
+ assert_equal "", record.baz
end
end
diff --git a/vendor/rails-locales b/vendor/rails-locales
deleted file mode 160000
-Subproject 7b769690775e9705f82da75aee3435e8dadebec