├── log
└── .keep
├── app
├── mailers
│ ├── .keep
│ ├── application_mailer.rb
│ └── alert_mailer.rb
├── models
│ ├── .keep
│ ├── concerns
│ │ └── .keep
│ ├── office.rb
│ ├── bill.rb
│ ├── application_record.rb
│ ├── watch.rb
│ ├── electorate.rb
│ └── api_statistic.rb
├── assets
│ ├── images
│ │ ├── .keep
│ │ ├── op-logo.png
│ │ ├── ua-logo.png
│ │ ├── civio-logo.png
│ │ ├── crta-logo.png
│ │ ├── data-logo.png
│ │ ├── efa-logo.png
│ │ ├── pmg-logo.png
│ │ ├── mysociety-logo.png
│ │ ├── open-forum-logo.png
│ │ ├── open-north-logo.png
│ │ ├── openpolis-logo.png
│ │ ├── avatars
│ │ │ ├── emmaaargh.jpg
│ │ │ ├── hey_maze.jpg
│ │ │ ├── sarah_wilson.jpg
│ │ │ ├── daniel_ferguson.jpg
│ │ │ └── alice_in_covid_land.jpg
│ │ ├── regards-citoyens-logo.png
│ │ ├── tvfy_general_social_card.png
│ │ ├── theyvoteforyou_logo_200x200.jpg
│ │ ├── theyvoteforyou_logo_600x600.jpg
│ │ ├── check-green.svg
│ │ ├── cross-red.svg
│ │ └── generic-person.svg
│ ├── javascripts
│ │ ├── global.js
│ │ ├── bootstrap.js
│ │ ├── swag.js
│ │ ├── policies.js
│ │ ├── divisions.js
│ │ └── application.js
│ ├── stylesheets
│ │ ├── global
│ │ │ ├── _footer.scss
│ │ │ ├── _history-list.scss
│ │ │ ├── _tables.scss
│ │ │ ├── _alerts.scss
│ │ │ ├── _banners.scss
│ │ │ ├── _history-notice.scss
│ │ │ ├── _utilities.scss
│ │ │ ├── _swag.scss
│ │ │ ├── _social-share.scss
│ │ │ └── _variables.scss
│ │ ├── policies
│ │ │ ├── _policies-new.scss
│ │ │ ├── _policies.scss
│ │ │ └── _policies-list.scss
│ │ ├── members
│ │ │ ├── _members.scss
│ │ │ └── _member-list-compact.scss
│ │ ├── divisions
│ │ │ ├── _divisions.scss
│ │ │ ├── _division-motion.scss
│ │ │ └── _division-show.scss
│ │ ├── people_distances
│ │ │ └── _people_distances.scss
│ │ └── users
│ │ │ └── _welcome.scss
│ └── config
│ │ └── manifest.js
├── lib
│ ├── assets
│ │ └── .keep
│ ├── house.rb
│ ├── check_resource_exists.rb
│ ├── templates
│ │ └── erb
│ │ │ └── scaffold
│ │ │ └── _form.html.erb
│ ├── data_loader
│ │ └── debates_xml.rb
│ ├── party.rb
│ └── card_screenshotter
│ │ └── policies.rb
├── controllers
│ ├── concerns
│ │ └── .keep
│ ├── help_controller.rb
│ ├── registrations_controller.rb
│ ├── api
│ │ └── v1
│ │ │ ├── policies_controller.rb
│ │ │ ├── people_controller.rb
│ │ │ ├── divisions_controller.rb
│ │ │ └── application_controller.rb
│ ├── users_controller.rb
│ ├── admin
│ │ └── application_controller.rb
│ └── confirmations_controller.rb
├── helpers
│ ├── help_helper.rb
│ ├── home_helper.rb
│ ├── people_helper.rb
│ ├── electorates_helper.rb
│ ├── api
│ │ └── v1
│ │ │ ├── people_helper.rb
│ │ │ ├── policies_helper.rb
│ │ │ └── divisions_helper.rb
│ ├── card_helper.rb
│ ├── users_helper.rb
│ └── votes_helper.rb
├── views
│ ├── api
│ │ └── v1
│ │ │ ├── offices
│ │ │ └── _office.json.jbuilder
│ │ │ ├── people
│ │ │ ├── index.json.jbuilder
│ │ │ ├── _person.json.jbuilder
│ │ │ ├── _docs_index.md
│ │ │ └── show.json.jbuilder
│ │ │ ├── policies
│ │ │ ├── index.json.jbuilder
│ │ │ ├── _policy.json.jbuilder
│ │ │ └── show.json.jbuilder
│ │ │ ├── divisions
│ │ │ ├── index.json.jbuilder
│ │ │ ├── _division.json.jbuilder
│ │ │ └── show.json.jbuilder
│ │ │ ├── bills
│ │ │ └── _bill.json.jbuilder
│ │ │ ├── votes
│ │ │ └── _vote.json.jbuilder
│ │ │ └── members
│ │ │ └── _member.json.jbuilder
│ ├── help
│ │ ├── faq
│ │ │ ├── _rebellion.md
│ │ │ ├── _summaries.md
│ │ │ ├── _division.md
│ │ │ ├── _decisions.md
│ │ │ ├── _policies_license.md
│ │ │ └── _rebel.md
│ │ ├── style_guide.html.haml
│ │ └── research.html.haml
│ ├── alert_mailer
│ │ ├── _policy_updated_subject.text.erb
│ │ ├── policy_updated.text.erb
│ │ └── policy_updated.html.haml
│ ├── home
│ │ ├── error500.html.haml
│ │ ├── error404.html.haml
│ │ ├── _panel1.md
│ │ ├── _panel3.md
│ │ ├── _panel2.md
│ │ ├── _policies.html.haml
│ │ ├── about.html.haml
│ │ ├── _search_form.html.haml
│ │ ├── history.html.haml
│ │ └── _no_search_results.html.haml
│ ├── people_distances
│ │ ├── _comparison_all_same.html.haml
│ │ ├── _comparison_all_different.html.haml
│ │ ├── _comparison_different_and_same.html.haml
│ │ ├── _policies_intro.html.haml
│ │ ├── _comparison_block.html.haml
│ │ ├── _member.html.haml
│ │ ├── _summary_vote_numbers.html.haml
│ │ └── _divisions_same.html.haml
│ ├── policies
│ │ ├── how_the_number_is_calculated
│ │ │ ├── _cells.html.haml
│ │ │ └── _not_enough.html.haml
│ │ ├── _draft_warning.html.haml
│ │ ├── _division_edit_instructions.html.haml
│ │ ├── _not_a_crystal_ball_warning.html.haml
│ │ ├── _new_policy_outro.md
│ │ ├── _how_the_number_is_calculated.html.haml
│ │ ├── history.html.haml
│ │ ├── _policy.html.haml
│ │ └── _vote_summary_table.html.haml
│ ├── members
│ │ ├── _interesting_votes.html.haml
│ │ ├── friends.html.haml
│ │ ├── member_not_found.html.haml
│ │ ├── _recent_votes.html.haml
│ │ ├── _summary.html.haml
│ │ ├── _policy_comparisons_block.html.haml
│ │ └── _policy_comparisons.html.haml
│ ├── users
│ │ ├── confirm.html.haml
│ │ └── show.html.haml
│ ├── divisions
│ │ ├── _pagination.html.haml
│ │ ├── _summary_whip_vote.html.haml
│ │ ├── _summary_whip_absent.html.haml
│ │ ├── _divisions.html.haml
│ │ ├── _external_links.html.haml
│ │ ├── _summary_whip.html.haml
│ │ ├── _header.html.haml
│ │ ├── index_with_member.html.haml
│ │ └── _summary_table.html.haml
│ ├── devise
│ │ ├── mailer
│ │ │ ├── confirmation_instructions.text.erb
│ │ │ ├── reset_password_instructions.text.erb
│ │ │ ├── confirmation_instructions.html.haml
│ │ │ └── reset_password_instructions.html.haml
│ │ ├── passwords
│ │ │ ├── edit.html.haml
│ │ │ └── new.html.haml
│ │ ├── confirmations
│ │ │ └── new.html.haml
│ │ └── sessions
│ │ │ └── new.html.haml
│ ├── layouts
│ │ ├── _bootstrap_flash.html.haml
│ │ ├── _history_notice.html.haml
│ │ ├── _history_list.html.haml
│ │ └── card_layout.html.haml
│ ├── application
│ │ ├── _honeybadger_javascript.html.haml
│ │ ├── _swag.html.haml
│ │ ├── _plausible_analytics.html.haml
│ │ ├── _social_share.html.haml
│ │ └── _logged_in_user_menu.html.haml
│ └── feeds
│ │ └── mpdream_info.xml.builder
├── jobs
│ ├── calculate_policy_person_distances_job.rb
│ ├── alert_watches_job.rb
│ └── application_job.rb
└── policies
│ ├── division_policy.rb
│ ├── policy_policy.rb
│ ├── policy_division_policy.rb
│ └── application_policy.rb
├── lib
└── tasks
│ └── .keep
├── .ruby-version
├── vendor
└── assets
│ ├── javascripts
│ └── .keep
│ └── stylesheets
│ ├── .keep
│ └── bootstrap-accessibility.css
├── .hound.yml
├── .rspec
├── Procfile
├── bin
├── dev
├── rake
├── rails
├── brakeman
├── rubocop
├── rspec
├── yarn
├── pry
├── ri
├── haml
├── mina
├── racc
├── rdoc
├── sdoc
├── thor
├── tilt
├── cap
├── guard
├── ldiff
├── rackup
├── capify
├── coderay
├── foreman
├── launchy
├── listen
├── bootsnap
├── htmldiff
├── httparty
├── nokogiri
├── skylight
├── _guard-core
├── redcarpet
├── ruby-parse
├── sdoc-merge
├── sprockets
├── stackprof
├── ruby-rewrite
├── ruby_parse
├── honeybadger
├── mongrel_rpm
├── update
├── reverse_markdown
├── elastic_ruby_console
├── stackprof-flamegraph.pl
├── stackprof-gprof2dot.py
└── ruby_parse_extract_error
├── Procfile.ansible
├── Procfile.production
├── public
├── googled564325686c043cb.html
├── icon.png
├── favicon.ico
├── apple-touch-icon-precomposed.png
└── icon.svg
├── config
├── honeybadger.yml
├── database.travis.yml
├── skylight.yml.example
├── spring.rb
├── environment.rb
├── initializers
│ ├── session_store.rb
│ ├── mime_types.rb
│ ├── mini_profiler.rb
│ ├── elasticsearch.rb
│ ├── devise_async.rb
│ ├── application_controller_renderer.rb
│ ├── invisible_captcha.rb
│ ├── admin_access.rb
│ ├── filter_parameter_logging.rb
│ ├── flipper.rb
│ ├── cors.rb
│ ├── assets.rb
│ ├── permissions_policy.rb
│ ├── wrap_parameters.rb
│ ├── backtrace_silencers.rb
│ ├── inflections.rb
│ └── markdown_handler.rb
├── deploy
│ ├── ukraine_dev.rb
│ ├── ukraine_production.rb
│ ├── staging.rb
│ ├── production.rb
│ └── development.rb
├── boot.rb
├── cable.yml
├── database.yml.example
└── credentials
│ └── production.yml.enc
├── .github
├── FUNDING.yml
├── CODEOWNERS
├── dependabot.yml
└── stale.yml
├── spec
├── factories
│ ├── persons.rb
│ ├── votes.rb
│ ├── policy_divisions.rb
│ ├── division_infos.rb
│ ├── member_infos.rb
│ ├── people_distances.rb
│ ├── users.rb
│ ├── wiki_motions.rb
│ ├── policy_person_distances.rb
│ ├── policies.rb
│ ├── whips.rb
│ ├── offices.rb
│ ├── divisions.rb
│ └── members.rb
├── devise
│ └── regression
│ │ ├── confirmation.txt
│ │ └── reset.txt
├── requests
│ └── help_controller_spec.rb
├── mailers
│ └── regression
│ │ └── alert_mailer
│ │ ├── email1.txt
│ │ └── email2.txt
├── fixtures
│ └── static_pages
│ │ └── feeds
│ │ └── mpdream-info.xml__id=1.xml
├── models
│ └── policy_division_spec.rb
└── features
│ └── user_profile_spec.rb
├── design_docs
├── TVFY General Social Card.ai
└── principles.md
├── local_dev
├── roles
│ ├── app
│ │ ├── templates
│ │ │ ├── settings.yml
│ │ │ ├── secrets.yml
│ │ │ └── database.yml
│ │ └── vars
│ │ │ └── main.yml
│ ├── docker
│ │ ├── templates
│ │ │ └── docker.list
│ │ └── vars
│ │ │ └── main.yml
│ └── ruby
│ │ └── vars
│ │ └── main.yml
├── playbook.yml
└── ansible.cfg
├── config.ru
├── db
└── migrate
│ ├── 20140822005440_rename_pw_mp_table.rb
│ ├── 20211223010947_add_admin_to_users.rb
│ ├── 20220217035040_add_policies_name_unique_index.rb
│ ├── 20140822032917_rename_pw_vote_table.rb
│ ├── 20140829025542_drop_sort_orders_table.rb
│ ├── 20141009090336_add_title_to_bills.rb
│ ├── 20220124013958_drop_edit_date_in_wiki_motions.rb
│ ├── 20140822032540_rename_pw_dyn_user_table.rb
│ ├── 20140822041718_rename_pw_moffice_table.rb
│ ├── 20140823223520_rename_mp_id_in_votes.rb
│ ├── 20140825021413_rename_user_id_in_users.rb
│ ├── 20220224001347_add_extra_large_image_url_to_people.rb
│ ├── 20140822034125_rename_pw_cache_whip_table.rb
│ ├── 20140822040612_rename_pw_division_table.rb
│ ├── 20140827093105_remove_pw_cache_divwiki_table.rb
│ ├── 20140822012602_rename_pw_dyn_dreammp_table.rb
│ ├── 20140823231135_rename_dream_id_in_policies.rb
│ ├── 20140825022650_rename_person_in_members.rb
│ ├── 20140825023720_rename_person_in_offices.rb
│ ├── 20140827031535_remove_user_name_from_users.rb
│ ├── 20140822064958_rename_division_id_column.rb
│ ├── 20140822070958_rename_mp_id_column_in_members.rb
│ ├── 20140823230610_rename_moffice_id_in_offices.rb
│ ├── 20220201015710_make_user_name_required_in_schema_to_match_model.rb
│ ├── 20140822010234_rename_pw_cache_mpinfo_table.rb
│ ├── 20140822041229_rename_pw_constituency_table.rb
│ ├── 20140825022036_rename_wiki_id_in_wiki_motions.rb
│ ├── 20140923072111_rename_real_name_to_name_in_users.rb
│ ├── 20140822011111_rename_pw_dyn_dreamvote_table.rb
│ ├── 20140822034625_rename_pw_dyn_wiki_motion_table.rb
│ ├── 20140822035700_rename_pw_cache_divinfo_table.rb
│ ├── 20140829021006_remove_vote_from_votes.rb
│ ├── 20140917033854_add_object_changes_to_versions.rb
│ ├── 20140923074703_remove_active_policy_id_from_users.rb
│ ├── 20141008013017_remove_notes_from_divisions.rb
│ ├── 20140822055520_rename_pw_vote_sortorder_table.rb
│ ├── 20140829023041_rename_vote_without_tell_in_votes.rb
│ ├── 20141001030502_change_policy_description_to_text.rb
│ ├── 20140822081103_rename_mp_id_column_in_member_infos.rb
│ ├── 20140824000144_rename_dream_id_in_policy_divisions.rb
│ ├── 20140924013708_add_markdown_to_divisions.rb
│ ├── 20141007052651_make_markdown_default_in_divisions.rb
│ ├── 20141021033254_add_api_key_to_users.rb
│ ├── 20140917033028_add_policy_id_to_versions.rb
│ ├── 20141008012425_add_bill_to_divisions.rb
│ ├── 20140822002749_rename_pw_cache_realreal_distance_table.rb
│ ├── 20140825024918_rename_person_in_policy_member_distances.rb
│ ├── 20140825025958_rename_policy_member_distances_table.rb
│ ├── 20140616062909_change_password_to_legacy_password_on_users.rb
│ ├── 20140825020429_rename_dream_id_in_policy_member_distances.rb
│ ├── 20141018235020_add_division_id_to_versions.rb
│ ├── 20140822012134_rename_pw_cache_dreamreal_distance_table.rb
│ ├── 20141001075857_add_images_urls_to_people.rb
│ ├── 20140907063906_add_further_index_to_divisions.rb
│ ├── 20140823224359_rename_mp_ids_in_member_distances.rb
│ ├── 20141121043312_create_watches.rb
│ ├── 20140923073138_remove_unused_columns_in_users.rb
│ ├── 20140823225659_make_cons_id_primary_key_in_electorates.rb
│ ├── 20220305211148_remove_unused_columns_on_divisions.rb
│ ├── 20141017005318_remove_limits_on_house_fields.rb
│ ├── 20141021184859_create_api_statistics.rb
│ ├── 20140828053926_rename_division_date_number_name_in_divisions.rb
│ ├── 20140905062045_remove_limits_from_fields_on_offices.rb
│ ├── 20140928235604_create_people.rb
│ ├── 20220202004503_add_staff_option_to_users.rb
│ ├── 20141001030631_change_division_binary_columns_to_text.rb
│ ├── 20140828080040_remove_division_date_number_house_from_wiki_motions.rb
│ ├── 20141008030623_multiple_bills_in_divisions.rb
│ ├── 20140917011343_create_versions.rb
│ ├── 20140828062935_add_division_id_to_policy_divisions.rb
│ ├── 20220413041820_create_people_distances.rb
│ ├── 20140828074700_add_division_id_to_wiki_motions.rb
│ ├── 20150617030311_convert_tables_to_utf8_character_set.rb
│ ├── 20140821075351_drop_unused_tables_in_rails.rb
│ ├── 20140828071906_drop_division_date_number_house_in_policy_divisions.rb
│ ├── 20140930212321_add_timestamps_to_all_tables.rb
│ ├── 20211223050627_create_flipper_tables.rb
│ ├── 20140822004101_add_primary_keys.rb
│ ├── 20220421041242_drop_member_distances.rb
│ ├── 20140828083134_add_vote_without_tell_to_votes.rb
│ ├── 20220217004002_convert_users_text_fields_to_string.rb
│ └── 20140623022321_add_confirmable_to_devise.rb
├── Rakefile
└── Makefile
/log/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/app/mailers/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/app/models/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/lib/tasks/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.ruby-version:
--------------------------------------------------------------------------------
1 | 3.4.4
2 |
--------------------------------------------------------------------------------
/app/assets/images/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/app/lib/assets/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/app/models/concerns/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/app/controllers/concerns/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/vendor/assets/javascripts/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/vendor/assets/stylesheets/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.hound.yml:
--------------------------------------------------------------------------------
1 | ruby:
2 | config_file: .rubocop.yml
3 |
--------------------------------------------------------------------------------
/.rspec:
--------------------------------------------------------------------------------
1 | --color
2 | --format Fuubar
3 | --profile
4 |
--------------------------------------------------------------------------------
/Procfile:
--------------------------------------------------------------------------------
1 | web: bundle exec rails server
2 | mailcatcher: mailcatcher
3 |
--------------------------------------------------------------------------------
/bin/dev:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | exec "./bin/rails", "server", *ARGV
3 |
--------------------------------------------------------------------------------
/Procfile.ansible:
--------------------------------------------------------------------------------
1 | worker: bundle exec rake jobs:work RAILS_ENV=production
2 |
--------------------------------------------------------------------------------
/Procfile.production:
--------------------------------------------------------------------------------
1 | worker: rvm . do bundle exec rake jobs:work RAILS_ENV=production
2 |
--------------------------------------------------------------------------------
/public/googled564325686c043cb.html:
--------------------------------------------------------------------------------
1 | google-site-verification: googled564325686c043cb.html
--------------------------------------------------------------------------------
/app/assets/javascripts/global.js:
--------------------------------------------------------------------------------
1 | $(function() {
2 | return $("img.lazy").lazyload();
3 | });
4 |
--------------------------------------------------------------------------------
/app/helpers/help_helper.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module HelpHelper
4 | end
5 |
--------------------------------------------------------------------------------
/app/helpers/home_helper.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module HomeHelper
4 | end
5 |
--------------------------------------------------------------------------------
/public/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/openaustralia/theyvoteforyou/HEAD/public/icon.png
--------------------------------------------------------------------------------
/app/assets/stylesheets/global/_footer.scss:
--------------------------------------------------------------------------------
1 | @import "footer-main";
2 | @import "author-projects";
3 |
--------------------------------------------------------------------------------
/app/helpers/people_helper.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module PeopleHelper
4 | end
5 |
--------------------------------------------------------------------------------
/config/honeybadger.yml:
--------------------------------------------------------------------------------
1 | ---
2 | api_key: "<%= Rails.application.credentials.honeybadger&.api_key %>"
3 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/openaustralia/theyvoteforyou/HEAD/public/favicon.ico
--------------------------------------------------------------------------------
/app/assets/javascripts/bootstrap.js:
--------------------------------------------------------------------------------
1 | jQuery(function() {
2 | return $(".has-tooltip").tooltip();
3 | });
4 |
--------------------------------------------------------------------------------
/app/helpers/electorates_helper.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module ElectoratesHelper
4 | end
5 |
--------------------------------------------------------------------------------
/config/database.travis.yml:
--------------------------------------------------------------------------------
1 | test:
2 | adapter: mysql2
3 | database: publicwhip_test
4 | username: root
5 |
--------------------------------------------------------------------------------
/bin/rake:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | require_relative "../config/boot"
3 | require "rake"
4 | Rake.application.run
5 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | custom: ['https://www.oaf.org.au/donate/']
4 |
--------------------------------------------------------------------------------
/app/assets/images/op-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/openaustralia/theyvoteforyou/HEAD/app/assets/images/op-logo.png
--------------------------------------------------------------------------------
/app/assets/images/ua-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/openaustralia/theyvoteforyou/HEAD/app/assets/images/ua-logo.png
--------------------------------------------------------------------------------
/app/assets/stylesheets/global/_history-list.scss:
--------------------------------------------------------------------------------
1 | .change-policy-name ~ .change-action {
2 | margin-left: 1em;
3 | }
4 |
--------------------------------------------------------------------------------
/app/views/api/v1/offices/_office.json.jbuilder:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | json.position office.position
4 |
--------------------------------------------------------------------------------
/spec/factories/persons.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | FactoryBot.define do
4 | factory :person
5 | end
6 |
--------------------------------------------------------------------------------
/app/assets/images/civio-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/openaustralia/theyvoteforyou/HEAD/app/assets/images/civio-logo.png
--------------------------------------------------------------------------------
/app/assets/images/crta-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/openaustralia/theyvoteforyou/HEAD/app/assets/images/crta-logo.png
--------------------------------------------------------------------------------
/app/assets/images/data-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/openaustralia/theyvoteforyou/HEAD/app/assets/images/data-logo.png
--------------------------------------------------------------------------------
/app/assets/images/efa-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/openaustralia/theyvoteforyou/HEAD/app/assets/images/efa-logo.png
--------------------------------------------------------------------------------
/app/assets/images/pmg-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/openaustralia/theyvoteforyou/HEAD/app/assets/images/pmg-logo.png
--------------------------------------------------------------------------------
/app/mailers/application_mailer.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class ApplicationMailer < ActionMailer::Base
4 | end
5 |
--------------------------------------------------------------------------------
/app/models/office.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Office < ApplicationRecord
4 | belongs_to :person
5 | end
6 |
--------------------------------------------------------------------------------
/config/skylight.yml.example:
--------------------------------------------------------------------------------
1 | ---
2 | # The authentication token for the application.
3 | authentication: xxxxxxxxxxxxxxxxxxxxx
4 |
--------------------------------------------------------------------------------
/app/assets/images/mysociety-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/openaustralia/theyvoteforyou/HEAD/app/assets/images/mysociety-logo.png
--------------------------------------------------------------------------------
/app/assets/images/open-forum-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/openaustralia/theyvoteforyou/HEAD/app/assets/images/open-forum-logo.png
--------------------------------------------------------------------------------
/app/assets/images/open-north-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/openaustralia/theyvoteforyou/HEAD/app/assets/images/open-north-logo.png
--------------------------------------------------------------------------------
/app/assets/images/openpolis-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/openaustralia/theyvoteforyou/HEAD/app/assets/images/openpolis-logo.png
--------------------------------------------------------------------------------
/app/assets/javascripts/swag.js:
--------------------------------------------------------------------------------
1 | $('.alert.swag').on('closed.bs.alert', function () {
2 | document.cookie='tvfy_swag=false;Path=/'
3 | })
--------------------------------------------------------------------------------
/app/assets/stylesheets/global/_tables.scss:
--------------------------------------------------------------------------------
1 | th {
2 | font-weight: normal;
3 | }
4 |
5 | .rebel {
6 | color: $color-rebel;
7 | }
8 |
--------------------------------------------------------------------------------
/app/assets/stylesheets/policies/_policies-new.scss:
--------------------------------------------------------------------------------
1 | #tips {
2 | ul {
3 | padding-left: 0;
4 | list-style: none;
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/app/views/api/v1/people/index.json.jbuilder:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | json.array! @people, partial: "person", as: :person
4 |
--------------------------------------------------------------------------------
/app/views/help/faq/_rebellion.md:
--------------------------------------------------------------------------------
1 | "Rebellion" figures record the number of rebel votes
2 | (see [What are “Rebel Voters”?](#rebel)).
3 |
--------------------------------------------------------------------------------
/app/assets/config/manifest.js:
--------------------------------------------------------------------------------
1 | //= link_tree ../images
2 | //= link_directory ../javascripts .js
3 | //= link_directory ../stylesheets .css
4 |
--------------------------------------------------------------------------------
/app/assets/images/avatars/emmaaargh.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/openaustralia/theyvoteforyou/HEAD/app/assets/images/avatars/emmaaargh.jpg
--------------------------------------------------------------------------------
/app/assets/images/avatars/hey_maze.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/openaustralia/theyvoteforyou/HEAD/app/assets/images/avatars/hey_maze.jpg
--------------------------------------------------------------------------------
/app/assets/stylesheets/policies/_policies.scss:
--------------------------------------------------------------------------------
1 | @import "policies-list";
2 | @import "policies-new";
3 | @import "policy-voter-comparision";
4 |
--------------------------------------------------------------------------------
/app/models/bill.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Bill < ApplicationRecord
4 | has_and_belongs_to_many :divisions
5 | end
6 |
--------------------------------------------------------------------------------
/app/views/api/v1/policies/index.json.jbuilder:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | json.array! @policies, partial: "policy", as: :policy
4 |
--------------------------------------------------------------------------------
/design_docs/TVFY General Social Card.ai:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/openaustralia/theyvoteforyou/HEAD/design_docs/TVFY General Social Card.ai
--------------------------------------------------------------------------------
/public/apple-touch-icon-precomposed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/openaustralia/theyvoteforyou/HEAD/public/apple-touch-icon-precomposed.png
--------------------------------------------------------------------------------
/app/assets/images/avatars/sarah_wilson.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/openaustralia/theyvoteforyou/HEAD/app/assets/images/avatars/sarah_wilson.jpg
--------------------------------------------------------------------------------
/app/views/alert_mailer/_policy_updated_subject.text.erb:
--------------------------------------------------------------------------------
1 | Policy “<%= policy.name_with_for %>” updated on <%= Rails.configuration.project_name %>
2 |
--------------------------------------------------------------------------------
/app/views/api/v1/divisions/index.json.jbuilder:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | json.array! @divisions, partial: "division", as: :division
4 |
--------------------------------------------------------------------------------
/app/assets/images/regards-citoyens-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/openaustralia/theyvoteforyou/HEAD/app/assets/images/regards-citoyens-logo.png
--------------------------------------------------------------------------------
/config/spring.rb:
--------------------------------------------------------------------------------
1 | %w(
2 | .ruby-version
3 | .rbenv-vars
4 | tmp/restart.txt
5 | tmp/caching-dev.txt
6 | ).each { |path| Spring.watch(path) }
7 |
--------------------------------------------------------------------------------
/local_dev/roles/app/templates/settings.yml:
--------------------------------------------------------------------------------
1 | # Optionally change the address of the elasticsearch service
2 | elasticsearch_url: http://localhost:9200
3 |
--------------------------------------------------------------------------------
/public/icon.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/app/assets/images/avatars/daniel_ferguson.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/openaustralia/theyvoteforyou/HEAD/app/assets/images/avatars/daniel_ferguson.jpg
--------------------------------------------------------------------------------
/app/assets/images/tvfy_general_social_card.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/openaustralia/theyvoteforyou/HEAD/app/assets/images/tvfy_general_social_card.png
--------------------------------------------------------------------------------
/app/assets/stylesheets/members/_members.scss:
--------------------------------------------------------------------------------
1 | @import "members/member-show";
2 | @import "members/member-list";
3 | @import "members/member-list-compact";
4 |
--------------------------------------------------------------------------------
/app/assets/images/avatars/alice_in_covid_land.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/openaustralia/theyvoteforyou/HEAD/app/assets/images/avatars/alice_in_covid_land.jpg
--------------------------------------------------------------------------------
/app/assets/images/theyvoteforyou_logo_200x200.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/openaustralia/theyvoteforyou/HEAD/app/assets/images/theyvoteforyou_logo_200x200.jpg
--------------------------------------------------------------------------------
/app/assets/images/theyvoteforyou_logo_600x600.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/openaustralia/theyvoteforyou/HEAD/app/assets/images/theyvoteforyou_logo_600x600.jpg
--------------------------------------------------------------------------------
/app/helpers/api/v1/people_helper.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module Api
4 | module V1
5 | module PeopleHelper
6 | end
7 | end
8 | end
9 |
--------------------------------------------------------------------------------
/app/models/application_record.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class ApplicationRecord < ActiveRecord::Base
4 | self.abstract_class = true
5 | end
6 |
--------------------------------------------------------------------------------
/spec/factories/votes.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | FactoryBot.define do
4 | factory :vote do
5 | member
6 | division
7 | end
8 | end
9 |
--------------------------------------------------------------------------------
/app/helpers/api/v1/policies_helper.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module Api
4 | module V1
5 | module PoliciesHelper
6 | end
7 | end
8 | end
9 |
--------------------------------------------------------------------------------
/bin/rails:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | APP_PATH = File.expand_path("../config/application", __dir__)
3 | require_relative "../config/boot"
4 | require "rails/commands"
5 |
--------------------------------------------------------------------------------
/local_dev/roles/app/vars/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | docker_compose_dir: '{{ work_base_dir }}/docker-compose'
3 | docker_compose_path: '{{ docker_compose_dir }}/docker-compose.yml'
--------------------------------------------------------------------------------
/app/helpers/api/v1/divisions_helper.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module Api
4 | module V1
5 | module DivisionsHelper
6 | end
7 | end
8 | end
9 |
--------------------------------------------------------------------------------
/app/models/watch.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Watch < ApplicationRecord
4 | belongs_to :watchable, polymorphic: true
5 | belongs_to :user
6 | end
7 |
--------------------------------------------------------------------------------
/config/environment.rb:
--------------------------------------------------------------------------------
1 | # Load the Rails application.
2 | require_relative "application"
3 |
4 | # Initialize the Rails application.
5 | Rails.application.initialize!
6 |
--------------------------------------------------------------------------------
/app/models/electorate.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | # TODO: I think this is completely unused. Remove from schema
4 | class Electorate < ApplicationRecord
5 | end
6 |
--------------------------------------------------------------------------------
/bin/brakeman:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | require "rubygems"
3 | require "bundler/setup"
4 |
5 | ARGV.unshift("--ensure-latest")
6 |
7 | load Gem.bin_path("brakeman", "brakeman")
8 |
--------------------------------------------------------------------------------
/app/views/api/v1/bills/_bill.json.jbuilder:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | json.id bill.id
4 | json.official_id bill.official_id
5 | json.title bill.title
6 | json.url bill.url
7 |
--------------------------------------------------------------------------------
/config.ru:
--------------------------------------------------------------------------------
1 | # This file is used by Rack-based servers to start the application.
2 |
3 | require_relative "config/environment"
4 |
5 | run Rails.application
6 | Rails.application.load_server
7 |
--------------------------------------------------------------------------------
/config/initializers/session_store.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | Rails.application.config.session_store :cookie_store, key: '_publicwhip_session'
4 |
--------------------------------------------------------------------------------
/app/views/api/v1/votes/_vote.json.jbuilder:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | json.vote vote.vote
4 | json.member do
5 | json.partial! "api/v1/members/member", member: vote.member
6 | end
7 |
--------------------------------------------------------------------------------
/config/deploy/ukraine_dev.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | set :domain, "theyvoteforyou.org.au.dev"
4 | set :repository, "https://github.com/opora/publicwhip.git"
5 | set :branch, "develop"
6 |
--------------------------------------------------------------------------------
/app/views/home/error500.html.haml:
--------------------------------------------------------------------------------
1 | - content_for :title, "We're sorry, but something went wrong"
2 | .page-header
3 | %h1= yield :title
4 | %p Try again and contact us if you're still having problems.
5 |
--------------------------------------------------------------------------------
/app/views/people_distances/_comparison_all_same.html.haml:
--------------------------------------------------------------------------------
1 | = render "comparison_block", person_distance: person_distance, policies: policies, title: "Always voted the same way on", label: :"always-same"
2 |
--------------------------------------------------------------------------------
/app/views/policies/how_the_number_is_calculated/_cells.html.haml:
--------------------------------------------------------------------------------
1 | %td= fraction_to_percentage_display(Distance.score(type))
2 | %td= Distance.weights(type)
3 | %td= policy_person_distance.no_votes(type)
4 |
--------------------------------------------------------------------------------
/config/initializers/mime_types.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Add new mime types for use in respond_to blocks:
4 | # Mime::Type.register "text/richtext", :rtf
5 |
--------------------------------------------------------------------------------
/config/deploy/ukraine_production.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | set :domain, "li1413-108.members.linode.com"
4 | set :repository, "https://github.com/opora/publicwhip.git"
5 | set :branch, "develop"
6 |
--------------------------------------------------------------------------------
/db/migrate/20140822005440_rename_pw_mp_table.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class RenamePwMpTable < ActiveRecord::Migration
4 | def change
5 | rename_table :pw_mp, :members
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/db/migrate/20211223010947_add_admin_to_users.rb:
--------------------------------------------------------------------------------
1 | class AddAdminToUsers < ActiveRecord::Migration[5.0]
2 | def change
3 | add_column :users, :admin, :boolean, null: false, default: false
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/db/migrate/20220217035040_add_policies_name_unique_index.rb:
--------------------------------------------------------------------------------
1 | class AddPoliciesNameUniqueIndex < ActiveRecord::Migration[6.0]
2 | def change
3 | add_index :policies, :name, unique: true
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/local_dev/playbook.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - hosts: all
3 | tasks:
4 | - import_role:
5 | name: docker
6 | - import_role:
7 | name: ruby
8 | - import_role:
9 | name: app
10 |
--------------------------------------------------------------------------------
/app/assets/stylesheets/divisions/_divisions.scss:
--------------------------------------------------------------------------------
1 | @import "division-show";
2 | @import "division-motion";
3 | @import "division-votes-table";
4 | @import "division-list";
5 | @import "division-comparison-table";
6 |
--------------------------------------------------------------------------------
/app/views/members/_interesting_votes.html.haml:
--------------------------------------------------------------------------------
1 | = render "members/rebellious_divisions", member: member
2 |
3 | - if member.person.free_votes_with_whip > 0
4 | = render "members/free_divisions", member: member
5 |
--------------------------------------------------------------------------------
/app/views/people_distances/_comparison_all_different.html.haml:
--------------------------------------------------------------------------------
1 | = render "comparison_block", person_distance: person_distance, policies: policies, title: "Always voted differently on", label: :"always-different"
2 |
--------------------------------------------------------------------------------
/db/migrate/20140822032917_rename_pw_vote_table.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class RenamePwVoteTable < ActiveRecord::Migration
4 | def change
5 | rename_table :pw_vote, :votes
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/db/migrate/20140829025542_drop_sort_orders_table.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class DropSortOrdersTable < ActiveRecord::Migration
4 | def change
5 | drop_table :vote_sortorders
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/db/migrate/20141009090336_add_title_to_bills.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class AddTitleToBills < ActiveRecord::Migration
4 | def change
5 | add_column :bills, :title, :text
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/spec/factories/policy_divisions.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | FactoryBot.define do
4 | factory :policy_division do
5 | policy
6 | division
7 | vote { "aye" }
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/app/views/home/error404.html.haml:
--------------------------------------------------------------------------------
1 | - content_for :title, "Sorry, that page wasn't found"
2 | .page-header
3 | %h1= yield :title
4 | %p Check the address and contact us if you still can't find what you were looking for.
5 |
--------------------------------------------------------------------------------
/db/migrate/20220124013958_drop_edit_date_in_wiki_motions.rb:
--------------------------------------------------------------------------------
1 | class DropEditDateInWikiMotions < ActiveRecord::Migration[5.0]
2 | def change
3 | remove_column :wiki_motions, :edit_date, :datetime
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/app/views/people_distances/_comparison_different_and_same.html.haml:
--------------------------------------------------------------------------------
1 | = render "comparison_block", person_distance: person_distance, policies: policies, title: "Voted a mixture of the same and differently on", label: :mixture
2 |
--------------------------------------------------------------------------------
/db/migrate/20140822032540_rename_pw_dyn_user_table.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class RenamePwDynUserTable < ActiveRecord::Migration
4 | def change
5 | rename_table :pw_dyn_user, :users
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/db/migrate/20140822041718_rename_pw_moffice_table.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class RenamePwMofficeTable < ActiveRecord::Migration
4 | def change
5 | rename_table :pw_moffice, :offices
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/db/migrate/20140823223520_rename_mp_id_in_votes.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class RenameMpIdInVotes < ActiveRecord::Migration
4 | def change
5 | rename_column :votes, :mp_id, :member_id
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/db/migrate/20140825021413_rename_user_id_in_users.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class RenameUserIdInUsers < ActiveRecord::Migration
4 | def change
5 | rename_column :users, :user_id, :id
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/db/migrate/20220224001347_add_extra_large_image_url_to_people.rb:
--------------------------------------------------------------------------------
1 | class AddExtraLargeImageUrlToPeople < ActiveRecord::Migration[6.0]
2 | def change
3 | add_column :people, :extra_large_image_url, :text
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/.github/CODEOWNERS:
--------------------------------------------------------------------------------
1 | # This file is used to define code owners for this repository.
2 | # See https://docs.github.com/en/github/creating-cloning-and-archiving-repositories/about-code-owners
3 |
4 | * @openaustralia/code-reviewers
5 |
--------------------------------------------------------------------------------
/app/views/users/confirm.html.haml:
--------------------------------------------------------------------------------
1 | - content_for :title, 'Confirm your email address'
2 |
3 | .single-message.thin-page
4 | %p.loud
5 | Great, now
6 | %strong check your inbox
7 | for your confirmation email.
8 |
--------------------------------------------------------------------------------
/db/migrate/20140822034125_rename_pw_cache_whip_table.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class RenamePwCacheWhipTable < ActiveRecord::Migration
4 | def change
5 | rename_table :pw_cache_whip, :whips
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/db/migrate/20140822040612_rename_pw_division_table.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class RenamePwDivisionTable < ActiveRecord::Migration
4 | def change
5 | rename_table :pw_division, :divisions
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/db/migrate/20140827093105_remove_pw_cache_divwiki_table.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class RemovePwCacheDivwikiTable < ActiveRecord::Migration
4 | def change
5 | drop_table :pw_cache_divwiki
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/config/boot.rb:
--------------------------------------------------------------------------------
1 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)
2 |
3 | require "bundler/setup" # Set up gems listed in the Gemfile.
4 | require "bootsnap/setup" # Speed up boot time by caching expensive operations.
5 |
--------------------------------------------------------------------------------
/db/migrate/20140822012602_rename_pw_dyn_dreammp_table.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class RenamePwDynDreammpTable < ActiveRecord::Migration
4 | def change
5 | rename_table :pw_dyn_dreammp, :policies
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/db/migrate/20140823231135_rename_dream_id_in_policies.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class RenameDreamIdInPolicies < ActiveRecord::Migration
4 | def change
5 | rename_column :policies, :dream_id, :id
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/db/migrate/20140825022650_rename_person_in_members.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class RenamePersonInMembers < ActiveRecord::Migration
4 | def change
5 | rename_column :members, :person, :person_id
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/db/migrate/20140825023720_rename_person_in_offices.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class RenamePersonInOffices < ActiveRecord::Migration
4 | def change
5 | rename_column :offices, :person, :person_id
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/db/migrate/20140827031535_remove_user_name_from_users.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class RemoveUserNameFromUsers < ActiveRecord::Migration
4 | def change
5 | remove_column :users, :user_name, :text
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/app/views/divisions/_pagination.html.haml:
--------------------------------------------------------------------------------
1 | %nav.index-pagination
2 | %ul.pagination
3 | - years.reverse.each do |year|
4 | = nav_link(year, { date: year }, "Divisions held in #{year}", (date_start && date_start.year == year))
5 |
--------------------------------------------------------------------------------
/db/migrate/20140822064958_rename_division_id_column.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class RenameDivisionIdColumn < ActiveRecord::Migration
4 | def change
5 | rename_column :divisions, :division_id, :id
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/db/migrate/20140822070958_rename_mp_id_column_in_members.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class RenameMpIdColumnInMembers < ActiveRecord::Migration
4 | def change
5 | rename_column :members, :mp_id, :id
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/db/migrate/20140823230610_rename_moffice_id_in_offices.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class RenameMofficeIdInOffices < ActiveRecord::Migration
4 | def change
5 | rename_column :offices, :moffice_id, :id
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/db/migrate/20220201015710_make_user_name_required_in_schema_to_match_model.rb:
--------------------------------------------------------------------------------
1 | class MakeUserNameRequiredInSchemaToMatchModel < ActiveRecord::Migration[6.0]
2 | def change
3 | change_column_null :users, :name, false
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/db/migrate/20140822010234_rename_pw_cache_mpinfo_table.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class RenamePwCacheMpinfoTable < ActiveRecord::Migration
4 | def change
5 | rename_table :pw_cache_mpinfo, :member_infos
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/db/migrate/20140822041229_rename_pw_constituency_table.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class RenamePwConstituencyTable < ActiveRecord::Migration
4 | def change
5 | rename_table :pw_constituency, :electorates
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/db/migrate/20140825022036_rename_wiki_id_in_wiki_motions.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class RenameWikiIdInWikiMotions < ActiveRecord::Migration
4 | def change
5 | rename_column :wiki_motions, :wiki_id, :id
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/db/migrate/20140923072111_rename_real_name_to_name_in_users.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class RenameRealNameToNameInUsers < ActiveRecord::Migration
4 | def change
5 | rename_column :users, :real_name, :name
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/app/assets/stylesheets/global/_alerts.scss:
--------------------------------------------------------------------------------
1 | .alert-container {
2 | .alert {
3 | margin-bottom: 0;
4 | border: 0;
5 | }
6 | }
7 |
8 | .alert-postnote {
9 | border-radius: 0;
10 | border-left: .5em solid $gray-lighter;
11 | }
12 |
--------------------------------------------------------------------------------
/db/migrate/20140822011111_rename_pw_dyn_dreamvote_table.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class RenamePwDynDreamvoteTable < ActiveRecord::Migration
4 | def change
5 | rename_table :pw_dyn_dreamvote, :policy_divisions
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/db/migrate/20140822034625_rename_pw_dyn_wiki_motion_table.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class RenamePwDynWikiMotionTable < ActiveRecord::Migration
4 | def change
5 | rename_table :pw_dyn_wiki_motion, :wiki_motions
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/db/migrate/20140822035700_rename_pw_cache_divinfo_table.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class RenamePwCacheDivinfoTable < ActiveRecord::Migration
4 | def change
5 | rename_table :pw_cache_divinfo, :division_infos
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/db/migrate/20140829021006_remove_vote_from_votes.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class RemoveVoteFromVotes < ActiveRecord::Migration
4 | def change
5 | remove_column :votes, :vote, :string, limit: 10, null: false
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/db/migrate/20140917033854_add_object_changes_to_versions.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class AddObjectChangesToVersions < ActiveRecord::Migration
4 | def change
5 | add_column :versions, :object_changes, :text
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/db/migrate/20140923074703_remove_active_policy_id_from_users.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class RemoveActivePolicyIdFromUsers < ActiveRecord::Migration
4 | def change
5 | remove_columns :users, :active_policy_id
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/db/migrate/20141008013017_remove_notes_from_divisions.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class RemoveNotesFromDivisions < ActiveRecord::Migration
4 | def change
5 | remove_column :divisions, :notes, :text, null: false
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/config/cable.yml:
--------------------------------------------------------------------------------
1 | development:
2 | adapter: async
3 |
4 | test:
5 | adapter: test
6 |
7 | production:
8 | adapter: redis
9 | url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %>
10 | channel_prefix: publicwhip_production
11 |
--------------------------------------------------------------------------------
/db/migrate/20140822055520_rename_pw_vote_sortorder_table.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class RenamePwVoteSortorderTable < ActiveRecord::Migration
4 | def change
5 | rename_table :pw_vote_sortorder, :vote_sortorders
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/db/migrate/20140829023041_rename_vote_without_tell_in_votes.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class RenameVoteWithoutTellInVotes < ActiveRecord::Migration
4 | def change
5 | rename_column :votes, :vote_without_tell, :vote
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/db/migrate/20141001030502_change_policy_description_to_text.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class ChangePolicyDescriptionToText < ActiveRecord::Migration
4 | def change
5 | change_column :policies, :description, :text
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/app/helpers/card_helper.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module CardHelper
4 | def get_hostname(url)
5 | uri = URI(url)
6 | uri.hostname
7 | end
8 |
9 | def remove_slash(link)
10 | link.sub("//", "/")
11 | end
12 | end
13 |
--------------------------------------------------------------------------------
/app/views/people_distances/_policies_intro.html.haml:
--------------------------------------------------------------------------------
1 | %h2 How do their votes on policies compare?
2 | %p.compare-policies-intro
3 | Policies are groups of votes related to an issue.
4 | We only show policies where we have enough information on both people.
5 |
--------------------------------------------------------------------------------
/config/initializers/mini_profiler.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | # Config for mini profiler
4 | # https://github.com/MiniProfiler/rack-mini-profiler#configuration-options
5 | # Rack::MiniProfiler.config.start_hidden = true if Rails.env.development?
6 |
--------------------------------------------------------------------------------
/db/migrate/20140822081103_rename_mp_id_column_in_member_infos.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class RenameMpIdColumnInMemberInfos < ActiveRecord::Migration
4 | def change
5 | rename_column :member_infos, :mp_id, :member_id
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/db/migrate/20140824000144_rename_dream_id_in_policy_divisions.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class RenameDreamIdInPolicyDivisions < ActiveRecord::Migration
4 | def change
5 | rename_column :policy_divisions, :dream_id, :policy_id
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/db/migrate/20140924013708_add_markdown_to_divisions.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class AddMarkdownToDivisions < ActiveRecord::Migration
4 | def change
5 | add_column :divisions, :markdown, :boolean, null: false, default: false
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/local_dev/roles/docker/templates/docker.list:
--------------------------------------------------------------------------------
1 |
2 | # {{ ansible_managed }}
3 | # Docker Ubuntu apt repo
4 |
5 | deb [arch={{ docker_ubuntu_apt_arch }} signed-by={{ docker_ubuntu_gpg_keyring_path }}] {{ docker_ubuntu_apt_url }} {{ docker_ubuntu_apt_dist }} stable
6 |
--------------------------------------------------------------------------------
/app/lib/house.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class House
4 | class << self
5 | def australian
6 | %w[representatives senate]
7 | end
8 |
9 | def valid?(name)
10 | australian.include?(name)
11 | end
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/app/views/api/v1/policies/_policy.json.jbuilder:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | json.id policy.id
4 | json.name policy.name
5 | json.description policy.description
6 | json.provisional policy.provisional?
7 | json.last_edited_at policy.last_edited_at.iso8601
8 |
--------------------------------------------------------------------------------
/config/initializers/elasticsearch.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | # To reduce log noise
4 | Ethon.logger = Logger.new(nil)
5 |
6 | ENV["ELASTICSEARCH_URL"] = Rails.application.credentials.elasticsearch.url if Rails.application.credentials.elasticsearch&.url
7 |
--------------------------------------------------------------------------------
/db/migrate/20141007052651_make_markdown_default_in_divisions.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class MakeMarkdownDefaultInDivisions < ActiveRecord::Migration
4 | def change
5 | change_column :divisions, :markdown, :boolean, default: true
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/db/migrate/20141021033254_add_api_key_to_users.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class AddApiKeyToUsers < ActiveRecord::Migration
4 | def change
5 | add_column :users, :api_key, :string
6 | add_index :users, :api_key, unique: true
7 | end
8 | end
9 |
--------------------------------------------------------------------------------
/spec/devise/regression/confirmation.txt:
--------------------------------------------------------------------------------
1 | Matthew Landauer, you are one step away from creating your account on They Vote For You
2 |
3 | Please confirm your account email by clicking the link below:
4 |
5 | http://pw.org.au/users/confirmation?confirmation_token=abc123
6 |
--------------------------------------------------------------------------------
/app/jobs/calculate_policy_person_distances_job.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class CalculatePolicyPersonDistancesJob < ApplicationJob
4 | queue_as :default
5 |
6 | def perform(policy)
7 | policy.calculate_person_distances!
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/app/views/home/_panel1.md:
--------------------------------------------------------------------------------
1 | ## Discover & Share
2 |
3 | Discover how your [representatives in parliament](<%= members_path %>) vote on
4 | [issues you care about](<%= policies_path %>). You might be surprised by what you find.
5 | Share this with others and spread the word.
6 |
--------------------------------------------------------------------------------
/config/deploy/staging.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | set :branch, :main
4 | set :deploy_to, "/srv/www/staging"
5 |
6 | role :app, %w[deploy@theyvoteforyou.org.au]
7 | role :web, %w[deploy@theyvoteforyou.org.au]
8 | role :db, %w[deploy@theyvoteforyou.org.au]
9 |
--------------------------------------------------------------------------------
/db/migrate/20140917033028_add_policy_id_to_versions.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class AddPolicyIdToVersions < ActiveRecord::Migration
4 | def change
5 | add_column :versions, :policy_id, :integer
6 | add_index :versions, :policy_id
7 | end
8 | end
9 |
--------------------------------------------------------------------------------
/db/migrate/20141008012425_add_bill_to_divisions.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class AddBillToDivisions < ActiveRecord::Migration
4 | def change
5 | add_column :divisions, :bill_id, :string
6 | add_column :divisions, :bill_url, :text
7 | end
8 | end
9 |
--------------------------------------------------------------------------------
/app/controllers/help_controller.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class HelpController < ApplicationController
4 | def faq; end
5 |
6 | def data; end
7 |
8 | def research; end
9 |
10 | def licencing; end
11 |
12 | def style_guide; end
13 | end
14 |
--------------------------------------------------------------------------------
/config/deploy/production.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | set :branch, :main
4 | set :deploy_to, "/srv/www/production"
5 |
6 | role :app, %w[deploy@theyvoteforyou.org.au]
7 | role :web, %w[deploy@theyvoteforyou.org.au]
8 | role :db, %w[deploy@theyvoteforyou.org.au]
9 |
--------------------------------------------------------------------------------
/db/migrate/20140822002749_rename_pw_cache_realreal_distance_table.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class RenamePwCacheRealrealDistanceTable < ActiveRecord::Migration
4 | def change
5 | rename_table :pw_cache_realreal_distance, :member_distances
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/db/migrate/20140825024918_rename_person_in_policy_member_distances.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class RenamePersonInPolicyMemberDistances < ActiveRecord::Migration
4 | def change
5 | rename_column :policy_member_distances, :person, :person_id
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/db/migrate/20140825025958_rename_policy_member_distances_table.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class RenamePolicyMemberDistancesTable < ActiveRecord::Migration
4 | def change
5 | rename_table :policy_member_distances, :policy_person_distances
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/local_dev/roles/app/templates/secrets.yml:
--------------------------------------------------------------------------------
1 | development:
2 | secret_key_base: '{{ rails_dev_secret_key_base }}'
3 | secret_key: '{{ rails_dev_secret_key }}'
4 |
5 | test:
6 | secret_key_base: '{{ rails_test_secret_key_base }}'
7 | secret_key: '{{ rails_test_secret_key }}'
8 |
--------------------------------------------------------------------------------
/app/lib/check_resource_exists.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require "net/http"
4 |
5 | class CheckResourceExists
6 | def self.call(url)
7 | uri = URI(url)
8 | res = Net::HTTP.get_response(uri)
9 | res.is_a? Net::HTTPSuccess
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/db/migrate/20140616062909_change_password_to_legacy_password_on_users.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class ChangePasswordToLegacyPasswordOnUsers < ActiveRecord::Migration
4 | def change
5 | rename_column :pw_dyn_user, :password, :legacy_password
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/db/migrate/20140825020429_rename_dream_id_in_policy_member_distances.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class RenameDreamIdInPolicyMemberDistances < ActiveRecord::Migration
4 | def change
5 | rename_column :policy_member_distances, :dream_id, :policy_id
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/db/migrate/20141018235020_add_division_id_to_versions.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class AddDivisionIdToVersions < ActiveRecord::Migration
4 | def change
5 | add_column :versions, :division_id, :integer
6 | add_index :versions, :division_id
7 | end
8 | end
9 |
--------------------------------------------------------------------------------
/config/initializers/devise_async.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 | # Supported options: :resque, :sidekiq, :delayed_job, :queue_classic, :torquebox, :backburner
3 | # TODO: Re-enable devise_async once upgraded Devise to 4.x and Rails to 5.x
4 | # Devise::Async.backend = :delayed_job
5 |
--------------------------------------------------------------------------------
/db/migrate/20140822012134_rename_pw_cache_dreamreal_distance_table.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class RenamePwCacheDreamrealDistanceTable < ActiveRecord::Migration
4 | def change
5 | rename_table :pw_cache_dreamreal_distance, :policy_member_distances
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/db/migrate/20141001075857_add_images_urls_to_people.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class AddImagesUrlsToPeople < ActiveRecord::Migration
4 | def change
5 | add_column :people, :small_image_url, :text
6 | add_column :people, :large_image_url, :text
7 | end
8 | end
9 |
--------------------------------------------------------------------------------
/app/views/home/_panel3.md:
--------------------------------------------------------------------------------
1 | ## Use the data
2 |
3 | This is a free and [open source](<%= help_licencing_path %>) public resource. Everything here can be reused in your own project. Use [our API](<%= help_data_path %>) to remix, play and tell your stories about how they vote to change our laws.
4 |
--------------------------------------------------------------------------------
/config/deploy/development.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | set :branch, :main
4 | set :deploy_to, "/srv/www/production"
5 |
6 | role :app, %w[deploy@theyvoteforyou.org.au.test]
7 | role :web, %w[deploy@theyvoteforyou.org.au.test]
8 | role :db, %w[deploy@theyvoteforyou.org.au.test]
9 |
--------------------------------------------------------------------------------
/local_dev/ansible.cfg:
--------------------------------------------------------------------------------
1 | [defaults]
2 | retry_files_enabled = False
3 | deprecation_warnings = True
4 | interpreter_python = /opt/ansible-venv/bin/python
5 |
6 | [privilege_escalation]
7 | become = True
8 | become_method = sudo
9 | become_user = vagrant
10 | become_ask_pass = False
11 |
--------------------------------------------------------------------------------
/config/initializers/application_controller_renderer.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # ActiveSupport::Reloader.to_prepare do
4 | # ApplicationController.renderer.defaults.merge!(
5 | # http_host: 'example.org',
6 | # https: false
7 | # )
8 | # end
9 |
--------------------------------------------------------------------------------
/config/initializers/invisible_captcha.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | InvisibleCaptcha.setup do |config|
4 | # Set this to true for development so a human can see
5 | # the honeypot field
6 | config.visual_honeypots = false
7 | config.timestamp_enabled = !Rails.env.test?
8 | end
9 |
--------------------------------------------------------------------------------
/spec/factories/division_infos.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | FactoryBot.define do
4 | factory :division_info do
5 | division
6 | rebellions { 0 }
7 | tells { 0 }
8 | turnout { 0 }
9 | possible_turnout { 0 }
10 | aye_majority { 0 }
11 | end
12 | end
13 |
--------------------------------------------------------------------------------
/spec/factories/member_infos.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | FactoryBot.define do
4 | factory :member_info do
5 | member
6 | rebellions { 0 }
7 | tells { 0 }
8 | votes_attended { 0 }
9 | votes_possible { 0 }
10 | aye_majority { 0 }
11 | end
12 | end
13 |
--------------------------------------------------------------------------------
/db/migrate/20140907063906_add_further_index_to_divisions.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class AddFurtherIndexToDivisions < ActiveRecord::Migration
4 | def change
5 | change_column :divisions, :clock_time, :string
6 | add_index :divisions, %i[id date clock_time]
7 | end
8 | end
9 |
--------------------------------------------------------------------------------
/app/views/home/_panel2.md:
--------------------------------------------------------------------------------
1 | ## Make it better
2 |
3 | People like you are making votes in Parliament easier to use by [summarising divisions](<%= help_research_path %>) and editing [policies](<%= policies_path %>), just like Wikipedia. Fix-up mistakes or add something new—if you see something, do something.
4 |
--------------------------------------------------------------------------------
/bin/rubocop:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | require "rubygems"
3 | require "bundler/setup"
4 |
5 | # explicit rubocop config increases performance slightly while avoiding config confusion.
6 | ARGV.unshift("--config", File.expand_path("../.rubocop.yml", __dir__))
7 |
8 | load Gem.bin_path("rubocop", "rubocop")
9 |
--------------------------------------------------------------------------------
/spec/factories/people_distances.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | FactoryBot.define do
4 | factory :people_distance do
5 | person1 factory: %i[person]
6 | person2 factory: %i[person]
7 | nvotessame { 0 }
8 | nvotesdiffer { 0 }
9 | distance_b { 0 }
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/app/views/api/v1/members/_member.json.jbuilder:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | json.id member.id
4 | json.person do
5 | json.id member.person_id
6 | end
7 | json.first_name member.first_name
8 | json.last_name member.last_name
9 | json.electorate member.electorate
10 | json.party member.party
11 |
--------------------------------------------------------------------------------
/Rakefile:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | # Add your own tasks in files placed in lib/tasks ending in .rake,
4 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
5 |
6 | require File.expand_path("config/application", __dir__)
7 |
8 | Publicwhip::Application.load_tasks
9 |
--------------------------------------------------------------------------------
/app/views/devise/mailer/confirmation_instructions.text.erb:
--------------------------------------------------------------------------------
1 | <%= @resource.name %>, you are one step away from creating your account on <%= Rails.configuration.project_name %>
2 |
3 | Please confirm your account email by clicking the link below:
4 |
5 | <%= confirmation_url(@resource, confirmation_token: @token) %>
6 |
--------------------------------------------------------------------------------
/db/migrate/20140823224359_rename_mp_ids_in_member_distances.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class RenameMpIdsInMemberDistances < ActiveRecord::Migration
4 | def change
5 | rename_column :member_distances, :mp_id1, :member1_id
6 | rename_column :member_distances, :mp_id2, :member2_id
7 | end
8 | end
9 |
--------------------------------------------------------------------------------
/db/migrate/20141121043312_create_watches.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class CreateWatches < ActiveRecord::Migration
4 | def change
5 | create_table :watches do |t|
6 | t.integer :watchable_id
7 | t.string :watchable_type
8 | t.integer :user_id
9 | end
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/app/jobs/alert_watches_job.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class AlertWatchesJob < ApplicationJob
4 | queue_as :default
5 |
6 | def perform(policy, version)
7 | policy.watches.each do |watch|
8 | AlertMailer.policy_updated(policy, version, watch.user).deliver
9 | end
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/app/views/policies/_draft_warning.html.haml:
--------------------------------------------------------------------------------
1 | - if policy.provisional?
2 | .row.alert.alert-danger{role: "alert"}
3 | %span.fi-alert
4 | %strong Warning!
5 | Don't share this. It's a
6 | %strong draft
7 | which means someone is still working on it and
8 | it may be
9 | %strong wildly innaccurate
10 |
--------------------------------------------------------------------------------
/app/assets/stylesheets/global/_banners.scss:
--------------------------------------------------------------------------------
1 | .banner-heading,
2 | .banner-action {
3 | float: none;
4 | clear: both;
5 |
6 | @media (min-width: $screen-sm-min) {
7 | margin-left: auto;
8 | margin-right: auto;
9 | }
10 | }
11 |
12 | .banner-action {
13 | label {
14 | font-weight: normal;
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/db/migrate/20140923073138_remove_unused_columns_in_users.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class RemoveUnusedColumnsInUsers < ActiveRecord::Migration
4 | def change
5 | remove_columns :users, :legacy_password, :remote_addr, :confirm_hash, :confirm_return_url,
6 | :is_confirmed, :reg_date
7 | end
8 | end
9 |
--------------------------------------------------------------------------------
/app/views/members/friends.html.haml:
--------------------------------------------------------------------------------
1 | - content_for :title do
2 | Compare
3 | = @member.name
4 | with someone else
5 | - set_meta_tags description: "See how #{@member.name} voted compared with other people"
6 |
7 | = render "member_page_header", member: @member
8 | = render "possible_friends", person: @member.person, all_friends: true
9 |
--------------------------------------------------------------------------------
/app/controllers/registrations_controller.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class RegistrationsController < Devise::RegistrationsController
4 | invisible_captcha only: :create, honeypot: :title, scope: :user
5 |
6 | protected
7 |
8 | def after_inactive_sign_up_path_for(_resource)
9 | user_confirm_path
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/spec/factories/users.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | FactoryBot.define do
4 | factory :user do
5 | sequence(:email) { |n| "henare#{n}@oaf.org.au" }
6 | password { "password" }
7 | name { "Henare Degan" }
8 |
9 | factory :confirmed_user do
10 | confirmed_at { Time.zone.now }
11 | end
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/config/initializers/admin_access.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | # Only admins can access flipper (the feature flag panel)
4 | class CanAccessFlipperUI
5 | def self.matches?(request)
6 | current_user = request.env["warden"].user
7 | current_user.present? && current_user.respond_to?(:admin?) && current_user.admin?
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/db/migrate/20140823225659_make_cons_id_primary_key_in_electorates.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class MakeConsIdPrimaryKeyInElectorates < ActiveRecord::Migration
4 | def change
5 | remove_column :electorates, :id
6 | rename_column :electorates, :cons_id, :id
7 | change_column :electorates, :id, :primary_key
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/spec/factories/wiki_motions.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | FactoryBot.define do
4 | factory :wiki_motion do
5 | title { "An edited division" }
6 | description { "This division relates to all sorts of interesting things." }
7 | created_at { Time.zone.local(2014, 1, 1, 1, 1, 1) }
8 | user
9 | division
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/app/jobs/application_job.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class ApplicationJob < ActiveJob::Base
4 | # Automatically retry jobs that encountered a deadlock
5 | # retry_on ActiveRecord::Deadlocked
6 |
7 | # Most jobs are safe to ignore if the underlying records are no longer available
8 | # discard_on ActiveJob::DeserializationError
9 | end
10 |
--------------------------------------------------------------------------------
/db/migrate/20220305211148_remove_unused_columns_on_divisions.rb:
--------------------------------------------------------------------------------
1 | class RemoveUnusedColumnsOnDivisions < ActiveRecord::Migration[6.0]
2 | def change
3 | remove_column :divisions, :valid, :boolean
4 | remove_column :divisions, :markdown, :boolean, default: true, null: false
5 | remove_column :divisions, :source_gid, :text, null: false
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/spec/devise/regression/reset.txt:
--------------------------------------------------------------------------------
1 | Matthew Landauer, someone has requested a link to change your password. You can do this through the link below.
2 |
3 | http://pw.org.au/users/password/edit?reset_password_token=abc123
4 |
5 | If you didn't request this, please ignore this email.
6 |
7 | Your password won't change until you access the link above and create a new one.
8 |
--------------------------------------------------------------------------------
/app/assets/stylesheets/members/_member-list-compact.scss:
--------------------------------------------------------------------------------
1 | .member-list-compact {
2 | .member-item {
3 | @include clearfix;
4 | }
5 |
6 | .member-link {
7 | .policy-comparision-block & {
8 | color: $text-color;
9 | }
10 | }
11 |
12 | .member-photo {
13 | float: left;
14 | clear: left;
15 | margin-right: .5em;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/app/helpers/users_helper.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module UsersHelper
4 | def name_with_badge(user)
5 | out = []
6 | out << link_to_unless_current(user.name, user)
7 | if user.staff
8 | out << " "
9 | out << content_tag(:span, "staff", class: %w[label label-default staff])
10 | end
11 | safe_join(out)
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/spec/factories/policy_person_distances.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | FactoryBot.define do
4 | factory :policy_person_distance do
5 | policy
6 | person
7 | nvotessame { 0 }
8 | nvotessamestrong { 0 }
9 | nvotesdiffer { 0 }
10 | nvotesdifferstrong { 0 }
11 | nvotesabsent { 0 }
12 | nvotesabsentstrong { 0 }
13 | end
14 | end
15 |
--------------------------------------------------------------------------------
/app/controllers/api/v1/policies_controller.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module Api
4 | module V1
5 | class PoliciesController < Api::V1::ApplicationController
6 | def index
7 | @policies = Policy.order(:id).all
8 | end
9 |
10 | def show
11 | @policy = Policy.find(params[:id])
12 | end
13 | end
14 | end
15 | end
16 |
--------------------------------------------------------------------------------
/db/migrate/20141017005318_remove_limits_on_house_fields.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class RemoveLimitsOnHouseFields < ActiveRecord::Migration
4 | def change
5 | change_column :divisions, :house, :string, limit: nil
6 | change_column :electorates, :house, :string, limit: nil
7 | change_column :members, :house, :string, limit: nil
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/db/migrate/20141021184859_create_api_statistics.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class CreateApiStatistics < ActiveRecord::Migration
4 | def change
5 | create_table :api_statistics do |t|
6 | t.string :ip_address
7 | t.text :query
8 | t.text :user_agent
9 | t.integer :user_id
10 |
11 | t.timestamps
12 | end
13 | end
14 | end
15 |
--------------------------------------------------------------------------------
/app/controllers/api/v1/people_controller.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module Api
4 | module V1
5 | class PeopleController < Api::V1::ApplicationController
6 | def index
7 | @people = Person.current.includes(:members)
8 | end
9 |
10 | def show
11 | @person = Person.find(params[:id])
12 | end
13 | end
14 | end
15 | end
16 |
--------------------------------------------------------------------------------
/spec/factories/policies.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | FactoryBot.define do
4 | factory :policy do
5 | sequence(:name) { |n| "the existence of test policies #{n}" }
6 | description { "there should be fabulous test policies" }
7 | private { 0 }
8 | user
9 |
10 | factory :provisional_policy do
11 | private { 2 }
12 | end
13 | end
14 | end
15 |
--------------------------------------------------------------------------------
/spec/requests/help_controller_spec.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require "spec_helper"
4 | # Compare results of rendering pages via rails and via the old php app
5 |
6 | describe HelpController, type: :request do
7 | include HTMLCompareHelper
8 | include_context "with fixtures"
9 |
10 | it "#research" do
11 | compare_static("/help/research")
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/app/views/members/member_not_found.html.haml:
--------------------------------------------------------------------------------
1 | - content_for :title, 'Representative or Senator not found'
2 | %h1= yield :title
3 |
4 | No Representative or Senator found. If you entered a postcode, please make
5 | sure it is correct. Or you can
6 | = link_to "browse All Representatives", members_path(house: "representatives")
7 | or #{link_to "browse all Senators", members_path(house: "senate")}.
8 |
--------------------------------------------------------------------------------
/db/migrate/20140828053926_rename_division_date_number_name_in_divisions.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class RenameDivisionDateNumberNameInDivisions < ActiveRecord::Migration
4 | def change
5 | rename_column :divisions, :division_date, :date
6 | rename_column :divisions, :division_number, :number
7 | rename_column :divisions, :division_name, :name
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/db/migrate/20140905062045_remove_limits_from_fields_on_offices.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class RemoveLimitsFromFieldsOnOffices < ActiveRecord::Migration
4 | def change
5 | change_column :offices, :dept, :string, limit: nil
6 | change_column :offices, :position, :string, limit: nil
7 | change_column :offices, :responsibility, :string, limit: nil
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/app/views/devise/mailer/reset_password_instructions.text.erb:
--------------------------------------------------------------------------------
1 | <%= @resource.name %>, someone has requested a link to change your password. You can do this through the link below.
2 |
3 | <%= edit_password_url(@resource, reset_password_token: @token) %>
4 |
5 | If you didn't request this, please ignore this email.
6 |
7 | Your password won't change until you access the link above and create a new one.
8 |
--------------------------------------------------------------------------------
/db/migrate/20140928235604_create_people.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class CreatePeople < ActiveRecord::Migration
4 | def change
5 | create_table :people, &:timestamps
6 | # Create all the people
7 | Person.reset_column_information
8 | Member.group(:person_id).pluck(:person_id).each do |person_id|
9 | Person.create!(id: person_id)
10 | end
11 | end
12 | end
13 |
--------------------------------------------------------------------------------
/db/migrate/20220202004503_add_staff_option_to_users.rb:
--------------------------------------------------------------------------------
1 | class AddStaffOptionToUsers < ActiveRecord::Migration[6.0]
2 | def change
3 | # Used to show to the public whether a user is currently (or a past) staff member of the OpenAustralia Foundation
4 | # This is to add extra weight to edits made by those people
5 | add_column :users, :staff, :boolean, null: false, default: false
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/spec/factories/whips.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | FactoryBot.define do
4 | factory :whip do
5 | division
6 | sequence(:party) { |n| "Party #{n}" }
7 | aye_votes { 0 }
8 | aye_tells { 0 }
9 | no_votes { 0 }
10 | no_tells { 0 }
11 | both_votes { 0 }
12 | abstention_votes { 0 }
13 | possible_votes { 0 }
14 | whip_guess { "unknown" }
15 | end
16 | end
17 |
--------------------------------------------------------------------------------
/app/models/api_statistic.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class ApiStatistic < ApplicationRecord
4 | belongs_to :user
5 |
6 | def self.log(request)
7 | create!(
8 | user: User.find_by(api_key: request.query_parameters["key"]),
9 | ip_address: request.remote_ip,
10 | query: request.fullpath,
11 | user_agent: request.headers["User-Agent"]
12 | )
13 | end
14 | end
15 |
--------------------------------------------------------------------------------
/db/migrate/20141001030631_change_division_binary_columns_to_text.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class ChangeDivisionBinaryColumnsToText < ActiveRecord::Migration
4 | def change
5 | change_column :divisions, :source_url, :text
6 | change_column :divisions, :debate_url, :text
7 | change_column :divisions, :motion, :text
8 | change_column :divisions, :notes, :text
9 | end
10 | end
11 |
--------------------------------------------------------------------------------
/app/views/divisions/_summary_whip_vote.html.haml:
--------------------------------------------------------------------------------
1 | %tr.member-row{class: member_row_class(vote, whip)}
2 | %th.cell-name
3 | = link_to vote.member.name, member_path_simple(vote.member)
4 | %span.text-muted.member-electorate= vote.member.electorate
5 | %small.post-title.text-muted= vote.member.party_name if whip.whipless? || whip.possible_votes == 1
6 | %td.cell-vote= vote_display vote.vote
7 | %td.cell-toggler
8 |
--------------------------------------------------------------------------------
/app/views/layouts/_bootstrap_flash.html.haml:
--------------------------------------------------------------------------------
1 | - flash.each do |name, msg|
2 | - if msg.is_a?(String)
3 | %div{class: "alert-container alert-" + (name.to_s == "notice" ? "success" : "danger")}
4 | %div{class: "container alert alert-" + (name.to_s == "notice" ? "success" : "danger")}
5 | %button.close(type="button" data-dismiss="alert" aria-hidden="true") ×
6 | %div{id: "flash_#{name}"}= msg
7 |
--------------------------------------------------------------------------------
/spec/factories/offices.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | FactoryBot.define do
4 | factory :office do
5 | # TODO: Get rid of dept and responsibility in the schema
6 | dept { "" }
7 | responsibility { "" }
8 | position { "Minister for ponies" }
9 | # TODO: Make person_id null: false in the schema
10 | # We are pretending this has already been done here
11 | person
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/app/views/policies/_division_edit_instructions.html.haml:
--------------------------------------------------------------------------------
1 | %p
2 | To select votes for this policy,
3 | = link_to "search", search_path
4 | or
5 | = link_to "browse", divisions_path
6 | for divisions. On the page for each division you can choose how somebody
7 | supporting this policy would have voted. If you haven't edited a policy
8 | before please #{link_to "read about how policies work", help_faq_path(anchor: "policies")}.
9 |
--------------------------------------------------------------------------------
/app/views/policies/_not_a_crystal_ball_warning.html.haml:
--------------------------------------------------------------------------------
1 | .row.alert.alert-warning{role: "alert"}
2 | %span.fi-flag
3 | %strong
4 | Be careful!
5 | Without a magic crystal ball, there's no way to predict with absolute certainty what representatives will do in future, no matter what they promise you now or how they voted in the past.
6 | Nonetheless, exploring how they voted before can help you decide who to support in an election.
7 |
--------------------------------------------------------------------------------
/config/initializers/filter_parameter_logging.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Configure parameters to be partially matched (e.g. passw matches password) and filtered from the log file.
4 | # Use this to limit dissemination of sensitive information.
5 | # See the ActiveSupport::ParameterFilter documentation for supported notations and behaviors.
6 | Rails.application.config.filter_parameters += [:password]
7 |
--------------------------------------------------------------------------------
/app/assets/stylesheets/global/_history-notice.scss:
--------------------------------------------------------------------------------
1 | .history-notice {
2 | padding: .2em 0;
3 | color: $gray;
4 | background-color: $gray-lighter;
5 | font-size: $font-size-supporting;
6 |
7 | @media (min-width: $screen-sm-min) {
8 | padding: .2em 0;
9 | font-size: $font-size-small;
10 | }
11 |
12 | p {
13 | margin-bottom: 0;
14 | }
15 |
16 | a {
17 | color: $gray;
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/app/lib/templates/erb/scaffold/_form.html.erb:
--------------------------------------------------------------------------------
1 | <%%= simple_form_for(@<%= singular_table_name %>) do |f| %>
2 | <%%= f.error_notification %>
3 |
4 |
5 | <%- attributes.each do |attribute| -%>
6 | <%%= f.<%= attribute.reference? ? :association : :input %> :<%= attribute.name %> %>
7 | <%- end -%>
8 |
9 |
10 |
11 | <%%= f.button :submit %>
12 |
13 | <%% end %>
14 |
--------------------------------------------------------------------------------
/app/views/api/v1/people/_person.json.jbuilder:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | json.id person.id
4 | json.latest_member do
5 | json.id person.latest_member.id
6 | json.name do
7 | json.first person.latest_member.first_name
8 | json.last person.latest_member.last_name
9 | end
10 | json.electorate person.latest_member.electorate
11 | json.house person.latest_member.house
12 | json.party person.latest_member.party
13 | end
14 |
--------------------------------------------------------------------------------
/app/views/help/faq/_summaries.md:
--------------------------------------------------------------------------------
1 | When you click on a link for a [division](/divisions), you will be taken to a summary that
2 | will either contain an edited description of the division or a message letting you know that one needs to written.
3 |
4 | Currently, the divisions with edited summaries are those that are relevant to one of
5 | the [Policies](/policies). See our [Research](/help/research) page to find out more about how the
6 | summaries are edited.
7 |
--------------------------------------------------------------------------------
/db/migrate/20140828080040_remove_division_date_number_house_from_wiki_motions.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class RemoveDivisionDateNumberHouseFromWikiMotions < ActiveRecord::Migration
4 | def change
5 | remove_column :wiki_motions, :division_date, :date, null: false
6 | remove_column :wiki_motions, :division_number, :integer, null: false
7 | remove_column :wiki_motions, :house, :string, limit: 8, null: false
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/db/migrate/20141008030623_multiple_bills_in_divisions.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class MultipleBillsInDivisions < ActiveRecord::Migration
4 | def change
5 | remove_column :divisions, :bill_id, :string
6 | remove_column :divisions, :bill_url, :text
7 | create_table :bills do |t|
8 | t.string :official_id
9 | t.text :url
10 | t.timestamps
11 | end
12 | create_join_table :divisions, :bills
13 | end
14 | end
15 |
--------------------------------------------------------------------------------
/app/views/application/_honeybadger_javascript.html.haml:
--------------------------------------------------------------------------------
1 | - if Rails.application.credentials.honeybadger&.javascript_api_key
2 | = javascript_include_tag "//js.honeybadger.io/v3.0/honeybadger.min.js"
3 | -# We're using a different API key for the js front end to what's used by the backend
4 | :javascript
5 | Honeybadger.configure({
6 | apiKey: '#{Rails.application.credentials.honeybadger.javascript_api_key}',
7 | environment: '#{Rails.env}'
8 | });
9 |
--------------------------------------------------------------------------------
/app/views/policies/_new_policy_outro.md:
--------------------------------------------------------------------------------
1 | After a policy is created you will be able to associate it with divisions and select how a supporter of the policy would have voted. <%= inline_project_name %> compares the real votes of MPs to your selections and calculates the voting record for the policy. [Find out more about the process](/help/faq#policies).
2 |
3 | Remember, all policies are public. They are a shared resource to be edited and updated by anyone (like Wikipedia).
4 |
--------------------------------------------------------------------------------
/config/initializers/flipper.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | Flipper::UI.configure do |config|
4 | config.descriptions_source = lambda do |_keys|
5 | # This should be a complete list of all features being currently used in the codebase
6 | {
7 | }
8 | end
9 |
10 | # Defaults to false. Set to true to show feature descriptions on the list
11 | # page as well as the view page.
12 | config.show_feature_description_in_list = true
13 | end
14 |
--------------------------------------------------------------------------------
/app/lib/data_loader/debates_xml.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module DataLoader
4 | class DebatesXml
5 | def initialize(xml_document, house)
6 | @xml_document = xml_document
7 | raise "Debate data missing" unless @xml_document.at(:debates)
8 |
9 | @house = house
10 | end
11 |
12 | def divisions
13 | @xml_document.search(:division).map { |division| DivisionXml.new(division, @house) }
14 | end
15 | end
16 | end
17 |
--------------------------------------------------------------------------------
/config/database.yml.example:
--------------------------------------------------------------------------------
1 | # Copy this to database.yml and edit
2 |
3 | development:
4 | adapter: mysql2
5 | database: pw
6 | username: pw
7 | password:
8 |
9 | # Warning: The database defined as "test" will be erased and
10 | # re-generated from your development database when you run "rake".
11 | # Do not set this db to the same as development or production.
12 | test:
13 | adapter: mysql2
14 | database: pw_test
15 | username: pw_test
16 | password:
17 |
--------------------------------------------------------------------------------
/app/views/divisions/_summary_whip_absent.html.haml:
--------------------------------------------------------------------------------
1 | %tr.member-row{class: [('collapse party-member-row' unless whip.whipless? || whip.possible_votes == 1), ('member-row-' + whip.party.parameterize)]}
2 | %th.cell-name
3 | = link_to member.name, member_path_simple(member)
4 | %span.text-muted.member-electorate= member.electorate
5 | %small.post-title.text-muted= member.party_name if whip.whipless? || whip.possible_votes == 1
6 | %td.cell-vote Absent
7 | %td.cell-toggler
8 |
--------------------------------------------------------------------------------
/bin/rspec:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | # frozen_string_literal: true
3 | #
4 | # This file was generated by Bundler.
5 | #
6 | # The application 'rspec' is installed as part of a gem, and
7 | # this file is here to facilitate running it.
8 | #
9 |
10 | require "pathname"
11 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
12 | Pathname.new(__FILE__).realpath)
13 |
14 | require "rubygems"
15 | require "bundler/setup"
16 |
17 | load Gem.bin_path("rspec-core", "rspec")
18 |
--------------------------------------------------------------------------------
/app/views/divisions/_divisions.html.haml:
--------------------------------------------------------------------------------
1 | - if divisions.to_a.empty?
2 | - if members.count == 1
3 | %p
4 | No votes listed as
5 | = member_type_party_place_sentence(members.first)
6 | - else
7 | %p No votes listed
8 |
9 | - else
10 | %ol.divisions-list.list-unstyled{class: active_house_for_list_class(house)}
11 | - divisions.each do |division|
12 | = render partial: 'divisions/division', locals: {members: members, house: house, division: division}
13 |
--------------------------------------------------------------------------------
/app/views/home/_policies.html.haml:
--------------------------------------------------------------------------------
1 | - # Refactor: this is identical to a partial in policies, execept for the header level
2 | %ul.list-unstyled
3 | - policies.each do |policy|
4 | %li
5 | %h3
6 | = link_to capitalise_initial_character(policy.name_with_for), policy
7 | %small
8 | = pluralize(policy.divisions.count, "division")
9 | - if policy.unedited_motions_count != 0
10 | %em= "(#{policy.unedited_motions_count} unedited)"
11 |
--------------------------------------------------------------------------------
/app/views/home/about.html.haml:
--------------------------------------------------------------------------------
1 | - content_for :title, "About"
2 | - set_meta_tags description: default_meta_description
3 |
4 | - content_for :header do
5 | .section-header.clearfix
6 | .page-header.container
7 | %h1= yield :title
8 | %p.lead
9 | Forget what politicians say. What truly matters is what they do. And what they do is vote, to write our laws which affect us all.
10 |
11 | .row
12 | .col-md-8
13 | = render "about"
14 |
--------------------------------------------------------------------------------
/app/helpers/votes_helper.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module VotesHelper
4 | def vote_words(vote)
5 | if vote
6 | if vote.rebellion?
7 | "voted #{vote_display(vote.vote)}, rebelling against the #{vote.party_name}"
8 | elsif vote.free_vote?
9 | "voted #{vote_display(vote.vote)} in this free vote"
10 | else
11 | "voted #{vote_display(vote.vote)}"
12 | end
13 | else
14 | "was absent"
15 | end
16 | end
17 | end
18 |
--------------------------------------------------------------------------------
/app/assets/stylesheets/policies/_policies-list.scss:
--------------------------------------------------------------------------------
1 | .policies-list {
2 | .policy-title {
3 | font-weight: normal;
4 | padding-left: 0;
5 | }
6 |
7 | .policy-subscriber-count {
8 | padding-left: 0;
9 | margin-bottom: 0;
10 | }
11 |
12 | .policy-data {
13 | margin-top: 0;
14 | }
15 |
16 | .policy-edit-notice, .object-secondary .policy-subscriber-count {
17 | &:before {
18 | content: "\00a0\25CF\00a0";
19 | color: #aaa;
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/app/views/policies/_how_the_number_is_calculated.html.haml:
--------------------------------------------------------------------------------
1 | %section.page-section#ratioexpl
2 | %h2
3 | How
4 | "#{policy_agreement_summary(policy_person_distance)}"
5 | is worked out
6 |
7 | - if policy_person_distance.category == :not_enough
8 | = render "policies/how_the_number_is_calculated/not_enough", policy_person_distance: policy_person_distance
9 | - else
10 | = render "policies/how_the_number_is_calculated/other", policy_person_distance: policy_person_distance
11 |
--------------------------------------------------------------------------------
/db/migrate/20140917011343_create_versions.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class CreateVersions < ActiveRecord::Migration
4 | def change
5 | create_table :versions do |t|
6 | t.string :item_type, null: false
7 | t.integer :item_id, null: false
8 | t.string :event, null: false
9 | t.string :whodunnit
10 | t.text :object
11 | t.datetime :created_at
12 | end
13 | add_index :versions, %i[item_type item_id]
14 | end
15 | end
16 |
--------------------------------------------------------------------------------
/app/views/api/v1/divisions/_division.json.jbuilder:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | json.id division.id
4 | json.house division.house
5 | json.name division.name
6 | json.date division.date
7 | json.number division.number
8 | json.clock_time(division.clock_time&.strip)
9 | json.aye_votes division.aye_votes
10 | json.no_votes division.no_votes
11 | json.possible_turnout division.division_info.possible_turnout
12 | json.rebellions division.division_info.rebellions
13 | json.edited division.edited?
14 |
--------------------------------------------------------------------------------
/app/views/divisions/_external_links.html.haml:
--------------------------------------------------------------------------------
1 | %nav.division-external-links.page-section
2 | %h2.h5 External links
3 | %ul.list-unstyled.object-list-compact
4 | %li.object-item= link_to "Debate in Parliament", division.debate_url, title: "Links to debate shown at www.openaustralia.org"
5 | %li.object-item= link_to "Hansard source", division.source_url, title: "The original record of vote as reported by Hansard"
6 | - division.bills.each do |bill|
7 | %li.object-item= link_to bill.title, bill.url
8 |
--------------------------------------------------------------------------------
/local_dev/roles/docker/vars/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | docker_ubuntu_gpg_url: 'https://download.docker.com/linux/ubuntu/gpg'
3 | docker_ubuntu_gpg_text_path: '/tmp/docker-archive-keyring.gpg'
4 | docker_ubuntu_gpg_keyring_path: '/usr/share/keyrings/docker-archive-keyring.gpg'
5 | docker_ubuntu_apt_url: 'https://download.docker.com/linux/ubuntu'
6 | docker_ubuntu_apt_arch: 'amd64' # {{ ansible_architecture | lower }} - this gives 'x86_64', which is not valid
7 | docker_ubuntu_apt_dist: '{{ ansible_distribution_release | lower }}'
8 |
--------------------------------------------------------------------------------
/app/views/help/faq/_division.md:
--------------------------------------------------------------------------------
1 | A division is a formal vote on a motion in the House of Representatives or the Senate. A motion is
2 | a formal proposal put to the House or Senate to take action of some kind.
3 |
4 | When a division is called on a particular motion, Members of Parliament (MPs) in the House of
5 | Representatives or Senators in the Senate divide themselves into two groups: one that votes
6 | Yes and one that votes No. Each political party has whips who try to persuade their members
7 | to vote along party lines.
8 |
--------------------------------------------------------------------------------
/app/views/home/_search_form.html.haml:
--------------------------------------------------------------------------------
1 | %form.form-inline.search{action: search_path, name: "pw"}
2 | .input-group.col-sm-12.col-md-8.col-lg-7
3 | %label.sr-only{for: "query"} Search
4 | %input.form-control#query{type: "search", autosave: "#{Rails.configuration.project_name}", autofocus: (params[:query].blank? ? true : false), maxlength: "256", name: "query", value: "#{params[:query] if !params[:query].blank?}"}/
5 | .input-group-btn
6 | %input.btn.btn-primary{name: "button", type: "submit", value: "Search"}/
7 |
--------------------------------------------------------------------------------
/app/views/help/style_guide.html.haml:
--------------------------------------------------------------------------------
1 | - content_for :title, "Style Guide"
2 | - set_meta_tags description: "A guide to the style to use when contributing to #{Rails.configuration.project_name}."
3 |
4 |
5 | - content_for :header do
6 | .section-header.clearfix
7 | .page-header.container
8 | %h1= yield :title
9 | %p.lead #{inline_project_name} is for everyone. It should be easy for everyone to find out how their MP votes in Parliament.
10 |
11 | .row
12 | .col-md-8
13 | =render "help/style_guide_copy"
14 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 |
2 | init-submodules:
3 | git submodule update --init --recursive
4 |
5 | install-ruby:
6 | rbenv install < .ruby-version
7 |
8 | deploy-production:
9 | bundle exec cap production deploy
10 | deploy-staging:
11 | bundle exec cap staging deploy
12 |
13 | dev-services-up:
14 | COMPOSE_PROJECT_NAME=theyvoteforyou-dev docker compose -f docker-stack/dev/docker-compose.yml up --build -d
15 | test-services-up:
16 | COMPOSE_PROJECT_NAME=theyvoteforyou-test docker compose -f docker-stack/test/docker-compose.yml up --build -d
17 |
--------------------------------------------------------------------------------
/app/assets/images/check-green.svg:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/app/views/help/faq/_decisions.md:
--------------------------------------------------------------------------------
1 | <%= inline_project_name %> is concerned with the voting patterns of politicians, which means it is limited to
2 | formal votes (known as divisions, see [What is a division?](#division)). This is because
3 | politicians’ names and how they voted are only recorded in the official record of Parliament
4 | (known as the Hansard) when a division occurs.
5 |
6 | Unfortunately, most decisions in Parliament are not made by division
7 | (see [When does a division occur?](#division-occur)) and so do not appear on this site.
8 |
--------------------------------------------------------------------------------
/app/views/help/research.html.haml:
--------------------------------------------------------------------------------
1 | - content_for :title, "Parliamentary Research"
2 | - set_meta_tags description: "A guide on how to contribute to #{Rails.configuration.project_name} by researching policies and divisions."
3 |
4 | - content_for :header do
5 | .section-header.clearfix
6 | .page-header.container
7 | %h1= yield :title
8 | %p.lead
9 | A guide on how to contribute to #{inline_project_name} by researching policies and divisions.
10 |
11 | .row
12 | .col-md-8
13 | = render "help/research_copy"
14 |
--------------------------------------------------------------------------------
/config/initializers/cors.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Avoid CORS issues when API is called from the frontend app.
4 | # Handle Cross-Origin Resource Sharing (CORS) in order to accept cross-origin Ajax requests.
5 |
6 | # Read more: https://github.com/cyu/rack-cors
7 |
8 | Rails.application.config.middleware.insert_before 0, Rack::Cors do
9 | allow do
10 | origins "*"
11 | # Only allow GET requests on the API
12 | resource "*", headers: :any, methods: [:get]
13 | end
14 | end
15 |
--------------------------------------------------------------------------------
/spec/factories/divisions.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | FactoryBot.define do
4 | factory :division do
5 | date { Date.new(2014, 1, 1) }
6 | sequence(:number) { |n| n }
7 | house { "representatives" }
8 | name { "Some division" }
9 | motion { "I move that this division be very, very interesting" }
10 | source_url { "http://parlinfo.aph.gov.au/foobar" }
11 | debate_url { "http://parlinfo.aph.gov.au/bazbar" }
12 | debate_gid { "uk.org.publicwhip/representatives/2014-01-1.1.1" }
13 | end
14 | end
15 |
--------------------------------------------------------------------------------
/spec/mailers/regression/alert_mailer/email1.txt:
--------------------------------------------------------------------------------
1 | For red being a nice colour
2 | http://pw.org.au/policies/50
3 |
4 | Created policy “red being a nice colour” with description “there should be fabulous test policies”.
5 |
6 | By Wibble at 12:00AM - 01 Jan 2020
7 | http://pw.org.au/users/200
8 |
9 | ------------------------------------------------------
10 |
11 | Visit the policy page to unsubscribe from this policy:
12 | http://pw.org.au/policies/50
13 |
14 | View all your subscriptions:
15 | http://pw.org.au/users/100/subscriptions
16 |
--------------------------------------------------------------------------------
/app/views/members/_recent_votes.html.haml:
--------------------------------------------------------------------------------
1 | %section.page-section#recent-votes
2 | %h2 Recent Votes
3 |
4 | %p
5 | Recent votes in parliament that this
6 | = member_type(member.house)
7 | could have attended.
8 |
9 | - member.person.members.order(entered_house: :desc).each do |member|
10 | = render "divisions/divisions", members: [member], divisions: member.divisions_they_could_have_attended.limit(3), house: nil
11 |
12 | =link_to "View all votes", member_divisions_path_simple(member), class: 'btn btn-default btn-sm'
13 |
--------------------------------------------------------------------------------
/app/mailers/alert_mailer.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class AlertMailer < ApplicationMailer
4 | default from: "#{Rails.configuration.project_name} <#{Rails.configuration.contact_email}>"
5 | layout "email"
6 | helper PoliciesHelper, DivisionsHelper, PathHelper
7 |
8 | def policy_updated(policy, version, user)
9 | @policy = policy
10 | @version = version
11 | @user = user
12 |
13 | mail to: user.email, subject: render_to_string(partial: "policy_updated_subject", locals: { policy: @policy }).strip
14 | end
15 | end
16 |
--------------------------------------------------------------------------------
/app/views/help/faq/_policies_license.md:
--------------------------------------------------------------------------------
1 | Policy information is licensed under the [Creative Commons Attribution 4.0 International](http://creativecommons.org/licenses/by/4.0/) license.
2 | This allows the information to be used and shared by anyone as long as they attribute its source.
3 | This ensures its widest possible use.
4 |
5 | Anyone who contributes to the creation or editing of a policy is also agreeing to their contribution
6 | being licensed under the [Creative Commons Attribution 4.0 International](http://creativecommons.org/licenses/by/4.0/) license.
7 |
--------------------------------------------------------------------------------
/app/views/users/show.html.haml:
--------------------------------------------------------------------------------
1 | - content_for :title, @user.name
2 |
3 | %h2
4 | - if @you
5 | Your recent contributions
6 | - else
7 | Recent contributions by
8 | = @user.name
9 |
10 | - if !@you && @user.staff
11 | %p
12 | = @user.name
13 | is an OpenAustralia Foundation staff member
14 |
15 | - if @history.empty?
16 | %p No contributions… yet :)
17 | - else
18 | = render partial: "layouts/history_list", locals: { policy: @policy, history: @history }
19 |
20 | %p See other #{link_to 'recent changes', history_path}.
21 |
--------------------------------------------------------------------------------
/spec/mailers/regression/alert_mailer/email2.txt:
--------------------------------------------------------------------------------
1 | For red being a nice colour
2 | http://pw.org.au/policies/50
3 |
4 | Changed text on related division: An edited division
5 | http://pw.org.au/divisions/representatives/2014-01-01/1
6 |
7 | By Wibble at 01:01AM - 01 Jan 2014
8 | http://pw.org.au/users/200
9 |
10 | ------------------------------------------------------
11 |
12 | Visit the policy page to unsubscribe from this policy:
13 | http://pw.org.au/policies/50
14 |
15 | View all your subscriptions:
16 | http://pw.org.au/users/100/subscriptions
17 |
--------------------------------------------------------------------------------
/app/assets/images/cross-red.svg:
--------------------------------------------------------------------------------
1 |
9 |
--------------------------------------------------------------------------------
/app/views/members/_summary.html.haml:
--------------------------------------------------------------------------------
1 | %p.member-description
2 | - if !member.person.current_offices.empty?
3 | = member.name
4 | is
5 | -# TODO: The UK uses extra Offices data like department so this will need to be expanded
6 | %span.role= member.person.current_offices.map{|o| content_tag(:em, o.position) }.to_sentence(two_words_connector: ", and ").html_safe + "."
7 |
8 | - # TODO: add back in the rebellion and attendance rate for previous membership.
9 | - if member.person.members.size > 1
10 | = member_history_sentence(member)
11 |
--------------------------------------------------------------------------------
/app/views/people_distances/_comparison_block.html.haml:
--------------------------------------------------------------------------------
1 | - unless policies.empty?
2 | .policy-comparision-block.col-md-7{class: "compare-#{label}"}
3 | .row
4 | %h3.policy-comparision-position.col-xs-9= title
5 | .row
6 | %ul.policy-comparision-list.object-list-compact.list-unstyled.col-xs-12
7 | - policies.each do |policy|
8 | %li.policy-comparision-policy.object-item
9 | = link_to capitalise_initial_character(policy.name), compare_member_policy_path_simple(person_distance, policy), class: "policy-title"
10 |
--------------------------------------------------------------------------------
/app/views/application/_swag.html.haml:
--------------------------------------------------------------------------------
1 | -# TODO: Make buy experience work without leaving the site
2 | - unless cookies[:tvfy_swag] == "false"
3 | = link_to "https://swag.theyvoteforyou.org.au/products/short-sleeve-t-shirt" do
4 | .swag.alert.fade.in
5 | %button.close{"aria-label": "Close", "data-dismiss": "alert", type: "button"}
6 | %span{"aria-hidden": "true"} ×
7 | = image_tag "tshirt.svg"
8 | .swag-text
9 | Because nothing says "I care about being informed" like a killer t-shirt.
10 | %strong Get it now!
11 |
12 |
--------------------------------------------------------------------------------
/config/initializers/assets.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Version of your assets, change this if you want to expire all your assets.
4 | Rails.application.config.assets.version = "1.0"
5 |
6 | # Add additional assets to the asset load path.
7 | # Rails.application.config.assets.paths << Emoji.images_path
8 |
9 | # Precompile additional assets.
10 | # application.js, application.css, and all non-JS/CSS in the app/assets
11 | # folder are already added.
12 | Rails.application.config.assets.precompile += %w( email.css )
13 |
--------------------------------------------------------------------------------
/app/views/devise/passwords/edit.html.haml:
--------------------------------------------------------------------------------
1 | - content_for :title, 'Change your password'
2 |
3 | %h2= yield :title
4 |
5 | = form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :put }) do |f|
6 | = devise_error_messages!
7 | = f.hidden_field :reset_password_token
8 | .form-group
9 | = f.label :password, "New password"
10 | = f.password_field :password, autofocus: true, autocomplete: "off", class: "form-control"
11 |
12 | = f.submit "Change my password", class: "btn btn-default"
13 | = render "devise/shared/links"
14 |
--------------------------------------------------------------------------------
/app/views/people_distances/_member.html.haml:
--------------------------------------------------------------------------------
1 | - if member.show_large_image?
2 | = link_to member_path_simple(member), class: "pull-left" do
3 | = image_tag(member.large_image_url, alt: "Photo of #{member.name}", size: member.large_image_size, class: "media-object photo")
4 | .media-body
5 | %h2.media-heading
6 | %span.fn= link_to_unless_current member.name, member_path_simple(member)
7 | %p.member-role.lead
8 | = member_type_party_place_sentence(member)
9 | %span.member-period
10 | = formatted_date_range(member.date_range, format: :short)
11 |
--------------------------------------------------------------------------------
/config/initializers/permissions_policy.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Define an application-wide HTTP permissions policy. For further
4 | # information see: https://developers.google.com/web/updates/2018/06/feature-policy
5 |
6 | # Rails.application.config.permissions_policy do |policy|
7 | # policy.camera :none
8 | # policy.gyroscope :none
9 | # policy.microphone :none
10 | # policy.usb :none
11 | # policy.fullscreen :self
12 | # policy.payment :self, "https://secure.example.com"
13 | # end
14 |
--------------------------------------------------------------------------------
/local_dev/roles/ruby/vars/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | ruby_rbenv_git_url: 'https://github.com/rbenv/rbenv.git'
3 | ruby_rbenv_path: '/home/vagrant/.rbenv'
4 | ruby_rbenv_plugins_path: '{{ ruby_rbenv_path }}/plugins'
5 |
6 | ruby_rbenv_bash_path: '/home/vagrant/.bashrc'
7 |
8 | ruby_rbenv_build_git_url: 'https://github.com/rbenv/ruby-build.git'
9 | ruby_rbenv_build_path: '{{ ruby_rbenv_plugins_path }}/ruby-build'
10 |
11 | ruby_rbenv_doctor_url: 'https://github.com/rbenv/rbenv-installer/raw/HEAD/bin/rbenv-doctor'
12 | ruby_rbenv_doctor_path: '/home/vagrant/rbenv-doctor.sh'
13 |
--------------------------------------------------------------------------------
/db/migrate/20140828062935_add_division_id_to_policy_divisions.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class AddDivisionIdToPolicyDivisions < ActiveRecord::Migration
4 | def change
5 | add_column :policy_divisions, :division_id, :integer
6 | PolicyDivision.reset_column_information
7 | PolicyDivision.all.find_each do |pd|
8 | division = Division.find_by!(date: pd.read_attribute(:division_date), number: pd.read_attribute(:division_number), house: pd.read_attribute(:house))
9 | pd.update!(division_id: division.id)
10 | end
11 | end
12 | end
13 |
--------------------------------------------------------------------------------
/app/assets/images/generic-person.svg:
--------------------------------------------------------------------------------
1 |
2 |
7 |
--------------------------------------------------------------------------------
/config/initializers/wrap_parameters.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # This file contains settings for ActionController::ParamsWrapper which
4 | # is enabled by default.
5 |
6 | # Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array.
7 | ActiveSupport.on_load(:action_controller) do
8 | wrap_parameters format: [:json]
9 | end
10 |
11 | # To enable root element in JSON for ActiveRecord objects.
12 | # ActiveSupport.on_load(:active_record) do
13 | # self.include_root_in_json = true
14 | # end
15 |
--------------------------------------------------------------------------------
/db/migrate/20220413041820_create_people_distances.rb:
--------------------------------------------------------------------------------
1 | class CreatePeopleDistances < ActiveRecord::Migration[6.0]
2 | def change
3 | create_table :people_distances do |t|
4 | t.integer :person1_id, null: false
5 | t.integer :person2_id, null: false
6 | t.integer :nvotessame, null: false
7 | t.integer :nvotesdiffer, null: false
8 | t.float :distance_b, null: false
9 | t.timestamps
10 |
11 | t.index :person1_id
12 | t.index :person2_id
13 | t.index [:person1_id, :person2_id], unique: true
14 | end
15 | end
16 | end
17 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | # To get started with Dependabot version updates, you'll need to specify which
2 | # package ecosystems to update and where the package manifests are located.
3 | # Please see the documentation for all configuration options:
4 | # https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
5 |
6 | version: 2
7 | updates:
8 | - package-ecosystem: bundler # See documentation for possible values
9 | directory: "/" # Location of package manifests
10 | schedule:
11 | interval: "weekly"
12 |
--------------------------------------------------------------------------------
/app/assets/stylesheets/people_distances/_people_distances.scss:
--------------------------------------------------------------------------------
1 | .policy-comparision-block {
2 | &.compare-always-same {
3 | border-top-color: $color-for3;
4 | color: $color-for3;
5 | }
6 |
7 | &.compare-mixture {
8 | border-top-color: $color-mixed-position;
9 | color: $color-mixed-position;
10 | }
11 |
12 | &.compare-always-different {
13 | border-top-color: $color-against3;
14 | color: $color-against3;
15 | }
16 | }
17 |
18 | .compare-policies-intro {
19 | margin-bottom: 2em;
20 | }
21 |
22 | .btn.compare-others {
23 | margin-bottom: 2em;
24 | }
25 |
--------------------------------------------------------------------------------
/app/views/home/history.html.haml:
--------------------------------------------------------------------------------
1 | - content_for :title, 'Recent edits'
2 | - set_meta_tags description: "Recent edits to divisions and policies by the #{Rails.configuration.project_name} community."
3 | - content_for :header do
4 | .section-header.clearfix
5 | .page-header.container
6 | %h1 All edits made in the last week
7 |
8 | - if @history.empty?
9 | %p None yet… you can kick things off and see your name here by #{link_to "summarising divisions", help_research_path}.
10 | - else
11 | = render partial: "layouts/history_list", locals: { policy: @policy, history: @history }
12 |
--------------------------------------------------------------------------------
/spec/fixtures/static_pages/feeds/mpdream-info.xml__id=1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/config/initializers/backtrace_silencers.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces.
4 | # Rails.backtrace_cleaner.add_silencer { |line| /my_noisy_library/.match?(line) }
5 |
6 | # You can also remove all the silencers if you're trying to debug a problem that might stem from framework code
7 | # by setting BACKTRACE=1 before calling your invocation, like "BACKTRACE=1 ./bin/rails runner 'MyClass.perform'".
8 | Rails.backtrace_cleaner.remove_silencers! if ENV["BACKTRACE"]
9 |
--------------------------------------------------------------------------------
/db/migrate/20140828074700_add_division_id_to_wiki_motions.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class AddDivisionIdToWikiMotions < ActiveRecord::Migration
4 | def change
5 | add_column :wiki_motions, :division_id, :integer
6 | add_index :wiki_motions, :division_id
7 | WikiMotion.reset_column_information
8 | WikiMotion.all.find_each do |w|
9 | division = Division.find_by!(date: w.division_date, number: w.division_number, house: w.house)
10 | # I don't want callbacks called
11 | w.update_attribute(:division_id, division.id)
12 | end
13 | end
14 | end
15 |
--------------------------------------------------------------------------------
/app/assets/javascripts/policies.js:
--------------------------------------------------------------------------------
1 | // Place all the behaviors and hooks related to the matching controller here.
2 | // All this logic will automatically be available in application.js.
3 |
4 | $(function() {
5 | $(".policy-name, .policy-comparision-position").widowFix({
6 | letterLimit: 10,
7 | prevLimit: 11
8 | });
9 | if ((typeof changeSubscribeButtons !== "undefined" && changeSubscribeButtons !== null) && document.getElementsByClassName("subscribe-button-form-unsubscribe").length > 0) {
10 | return changeSubscribeButtons("Subscribed", "subscribe-button-active");
11 | }
12 | });
13 |
--------------------------------------------------------------------------------
/app/assets/stylesheets/global/_utilities.scss:
--------------------------------------------------------------------------------
1 | .lazy {
2 | display: none !important;
3 |
4 | .has-js & {
5 | display: inherit !important;
6 | }
7 | }
8 |
9 | /**
10 | * Breakpoint definition for JS - see https://github.com/JoshBarr/on-media-query
11 | * used by onmediaquery.js
12 | */
13 |
14 | body:after {
15 | display: none;
16 |
17 | content: 'small';
18 |
19 | @media (min-width: $screen-md-min) {
20 | content: 'wide';
21 | }
22 | }
23 |
24 | html {
25 | font-family: 'small';
26 |
27 | @media (min-width: $screen-md-min) {
28 | font-family: 'wide';
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/app/views/divisions/_summary_whip.html.haml:
--------------------------------------------------------------------------------
1 | = render 'summary_whip_header', whip: whip
2 |
3 | -# Show members in this party that are present in this division
4 | - votes.select {|vote| vote.member.party == whip.party}.each do |vote|
5 | = render 'summary_whip_vote', vote: vote, whip: whip
6 |
7 | - # TODO: Order by minority within party (e.g. rebels first) then majority, then absent
8 | -# Show members in this party that are absent in this division
9 | - members_vote_null.select {|member| member.party == whip.party}.each do |member|
10 | = render 'summary_whip_absent', member: member, whip: whip
11 |
--------------------------------------------------------------------------------
/db/migrate/20150617030311_convert_tables_to_utf8_character_set.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class ConvertTablesToUtf8CharacterSet < ActiveRecord::Migration
4 | def up
5 | ActiveRecord::Base.connection.tables.each do |table_name|
6 | ActiveRecord::Base.connection.execute "ALTER TABLE #{table_name} CONVERT TO CHARACTER SET utf8"
7 | end
8 | end
9 |
10 | def down
11 | ActiveRecord::Base.connection.tables.each do |table_name|
12 | ActiveRecord::Base.connection.execute "ALTER TABLE #{table_name} CONVERT TO CHARACTER SET latin1"
13 | end
14 | end
15 | end
16 |
--------------------------------------------------------------------------------
/bin/yarn:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | APP_ROOT = File.expand_path('..', __dir__)
3 | Dir.chdir(APP_ROOT) do
4 | yarn = ENV["PATH"].split(File::PATH_SEPARATOR).
5 | select { |dir| File.expand_path(dir) != __dir__ }.
6 | product(["yarn", "yarn.cmd", "yarn.ps1"]).
7 | map { |dir, file| File.expand_path(file, dir) }.
8 | find { |file| File.executable?(file) }
9 |
10 | if yarn
11 | exec yarn, *ARGV
12 | else
13 | $stderr.puts "Yarn executable was not detected in the system."
14 | $stderr.puts "Download Yarn at https://yarnpkg.com/en/docs/install"
15 | exit 1
16 | end
17 | end
18 |
--------------------------------------------------------------------------------
/spec/factories/members.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | FactoryBot.define do
4 | factory :member do
5 | gid { "uk.org.publicwhip/lord/100156" }
6 | source_gid { "" }
7 | first_name { "Christine" }
8 | last_name { "Milne" }
9 | sequence(:title) { |n| "Title #{n}" }
10 | constituency { "Newtown" }
11 | party { "Australian Greens" }
12 | house { "representatives" }
13 | entered_house { "2005-07-01" }
14 | left_house { "9999-12-31" }
15 | entered_reason { "general_election" }
16 | left_reason { "still_in_office" }
17 | person
18 | end
19 | end
20 |
--------------------------------------------------------------------------------
/app/assets/javascripts/divisions.js:
--------------------------------------------------------------------------------
1 | // Place all the behaviors and hooks related to the matching controller here.
2 | // All this logic will automatically be available in application.js.
3 |
4 | $(function() {
5 | $("form.edit_division a#preview_link").on("shown.bs.tab", function(e) {
6 | return $("#preview").html(marked($("#edit textarea").val()));
7 | });
8 | $(".division-title").widowFix({
9 | letterLimit: 10,
10 | prevLimit: 11
11 | });
12 | return $(".voter-table-toggle-members").click(function() {
13 | return $(this).toggleClass("voter-table-toggle-members-active");
14 | });
15 | });
16 |
--------------------------------------------------------------------------------
/app/views/divisions/_header.html.haml:
--------------------------------------------------------------------------------
1 | - content_for :title do
2 | = truncate(division.name, length: 180)
3 |
4 | .page-header.division-header.row
5 | %nav.header-actions.col-md-1.col-lg-2
6 | - if policy(division).edit?
7 | = link_to "Edit", edit_division_path_simple(division), title: "Change title and summary of this division", class: "link-division-edit btn btn-default btn-xs"
8 |
9 | %h1.division-title.col-md-11.col-lg-10.long-title
10 | %small.pre-title= division_date_and_time(division) + " – " + division.house_name
11 | = link_to_unless_current yield(:title), division_path_simple(division)
12 |
--------------------------------------------------------------------------------
/app/views/layouts/_history_notice.html.haml:
--------------------------------------------------------------------------------
1 | .history-notice
2 | %p.container
3 | -if division
4 | = link_to "Division last edited #{relative_time division.wiki_motion.created_at}", history_division_path_simple(division), title: "View the edit history of this division."
5 | -elsif policy
6 | = link_to "Policy last edited #{time_ago_in_words(policy.last_edited_at)} ago", history_policy_path(policy), title: "View the edit history of this policy."
7 | by
8 | -if division
9 | = name_with_badge(division.wiki_motion.user)
10 | -elsif policy
11 | = name_with_badge(policy.last_edited_by)
12 |
--------------------------------------------------------------------------------
/app/views/application/_plausible_analytics.html.haml:
--------------------------------------------------------------------------------
1 | - if Rails.env.production?
2 | -# plausible.io analytics
3 | -# In planningalerts.org.au we implemented a thing where the pageview path was given as a rails route path effectively bundling all
4 | -# similar pages together. We can't do that here yet because the implementation in planningalerts requires request.route_uri_pattern
5 | -# which is only available from rails 7.1. So, for the time being just do the simple thing
6 | -# TODO: Upgrade to rails 7.1 or above
7 | = javascript_include_tag "/js/script.outbound-links.js", defer: true, data: {domain: "theyvoteforyou.org.au"}
8 |
--------------------------------------------------------------------------------
/app/views/feeds/mpdream_info.xml.builder:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | xml.instruct! :xml, version: "1.0", encoding: "ISO-8859-1"
4 | xml.publicwhip do
5 | @policy_person_distances.each do |pmd|
6 | xml.memberinfo("id" => "uk.org.publicwhip/member/#{pmd['member_id']}",
7 | "public_whip_dreammp#{@policy.id}_distance" => number_with_precision(pmd["distance_a"], precision: 99, strip_insignificant_zeros: true),
8 | "public_whip_dreammp#{@policy.id}_both_voted" => pmd["both_voted"],
9 | "public_whip_dreammp#{@policy.id}_absent" => pmd["absent"])
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/db/migrate/20140821075351_drop_unused_tables_in_rails.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class DropUnusedTablesInRails < ActiveRecord::Migration
4 | def change
5 | drop_table :pw_cache_attendrank_today
6 | drop_table :pw_cache_divdiv_distance
7 | drop_table :pw_cache_dreaminfo
8 | drop_table :pw_cache_partyinfo
9 | drop_table :pw_cache_rebelrank_today
10 | drop_table :pw_candidate
11 | drop_table :pw_dyn_aggregate_dreammp
12 | drop_table :pw_dyn_auditlog
13 | drop_table :pw_dyn_newsletter
14 | drop_table :pw_dyn_newsletters_sent
15 | drop_table :pw_logincoming
16 | end
17 | end
18 |
--------------------------------------------------------------------------------
/app/views/devise/mailer/confirmation_instructions.html.haml:
--------------------------------------------------------------------------------
1 | - content_for :subject, "Confirm your email address"
2 |
3 | %tr
4 | %td.content-block
5 | #{@resource.name}, you are one step away from creating your account on
6 | %em= Rails.configuration.project_name
7 | %tr
8 | %td.content-block
9 | Please confirm your email address by clicking the link below
10 | %tr
11 | %td.content-block
12 | = link_to "Confirm email address", confirmation_url(@resource, confirmation_token: @token), class: "btn-primary"
13 | %tr
14 | %td.content-block
15 | — The
16 | %em= Rails.configuration.project_name
17 | team
18 |
--------------------------------------------------------------------------------
/local_dev/roles/app/templates/database.yml:
--------------------------------------------------------------------------------
1 | # Database connections
2 |
3 | development:
4 | adapter: mysql2
5 | pool: 5
6 | host: '127.0.0.1'
7 | port: 3306
8 | database: pw
9 | username: root
10 | password: '{{ mysql_root_password }}'
11 |
12 | # Warning: The database defined as "test" will be erased and
13 | # re-generated from your development database when you run "rake".
14 | # Do not set this db to the same as development or production.
15 | test:
16 | adapter: mysql2
17 | pool: 5
18 | host: '127.0.0.1'
19 | port: 3306
20 | database: pw_test
21 | username: root
22 | password: '{{ mysql_root_password }}'
23 |
--------------------------------------------------------------------------------
/app/views/api/v1/people/_docs_index.md:
--------------------------------------------------------------------------------
1 | <% if current_user %>
2 | GET <%= link_to api_v1_people_url(format: "json", key: current_user.api_key), api_v1_people_url(format: "json", key: current_user.api_key) %>
3 | <% else %>
4 | GET <%= api_v1_people_url(format: "json", key: "foo").gsub("foo", "[api_key]") %>
5 | <% end %>
6 |
7 | This returns basic information about each person who is currently a member of parliament. It
8 | includes their name, electorate, party and whether they are in the House of Representatives or the
9 | Senate.
10 |
11 | To get more detailed information about a person use the `id` to do the following:
12 |
--------------------------------------------------------------------------------
/app/views/divisions/index_with_member.html.haml:
--------------------------------------------------------------------------------
1 | - content_for :title do
2 | Voting Record —
3 | = @member.full_name2
4 | - set_meta_tags description: "A list of all votes in parliament that #{@member.full_name_no_electorate} could have attended."
5 |
6 | = render "members/member_page_header", member: @member
7 |
8 | %h2#divisions
9 | Divisions
10 | %small #{divisions_period(@date_range, @date_start)}
11 |
12 | %p Divisions #{@member.full_name_no_electorate} could have attended.
13 |
14 | = render "divisions", members: [@member], divisions: @divisions, house: @house
15 | = render "pagination", years: @years, date_start: @date_start
16 |
--------------------------------------------------------------------------------
/app/views/home/_no_search_results.html.haml:
--------------------------------------------------------------------------------
1 | - if postcode
2 | %h2
3 | Postcode
4 | %strong= postcode
5 | not found
6 |
7 | %p Sorry, we couldn't find that postcode.
8 | %p
9 | If you’re sure this postcode exists please
10 | = mail_to Rails.configuration.contact_email, "contact us"
11 | to let us know.
12 | - else
13 | %h2 No results found
14 | %p
15 | Sorry, we couldn't find any people, policies or divisions relevant to your search term
16 | %strong “#{params[:query]}”.
17 | %p
18 | Suggestions:
19 |
20 | %ul
21 | %li check the spelling
22 | %li try some more general or alternate terms
23 |
--------------------------------------------------------------------------------
/db/migrate/20140828071906_drop_division_date_number_house_in_policy_divisions.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class DropDivisionDateNumberHouseInPolicyDivisions < ActiveRecord::Migration
4 | def change
5 | remove_index :policy_divisions, name: "division_date_2"
6 | add_index :policy_divisions, %i[division_id policy_id], unique: true
7 | add_index :policy_divisions, :division_id
8 | remove_column :policy_divisions, :division_date, :date, null: false
9 | remove_column :policy_divisions, :division_number, :integer, null: false
10 | remove_column :policy_divisions, :house, :string, limit: 8, null: false
11 | end
12 | end
13 |
--------------------------------------------------------------------------------
/app/views/alert_mailer/policy_updated.text.erb:
--------------------------------------------------------------------------------
1 | <%= capitalise_initial_character(@policy.name_with_for) %>
2 | <%= policy_url(@policy) %>
3 |
4 | <% if @version.kind_of?(WikiMotion) %>
5 | Changed text on related division: <%= @version.division.name %>
6 | <%= division_url_simple(@version.division) %>
7 | <% else %>
8 | <%= version_sentence_text(@version) %>
9 | <% end %>
10 |
11 | <%= version_attribution_text(@version) %>
12 |
13 | ------------------------------------------------------
14 |
15 | Visit the policy page to unsubscribe from this policy:
16 | <%= policy_url(@policy) %>
17 |
18 | View all your subscriptions:
19 | <%= user_subscriptions_url(@user) %>
20 |
--------------------------------------------------------------------------------
/app/assets/stylesheets/users/_welcome.scss:
--------------------------------------------------------------------------------
1 | .welcome {
2 | text-align: center;
3 |
4 | .subscriptions-list-intro {
5 | @media (max-width: $screen-md-max) {
6 | text-align: left;
7 | }
8 | }
9 |
10 | .subscriptions-list {
11 | text-align: left;
12 |
13 | @media (min-width: $screen-sm-min) {
14 | margin-top: 30px;
15 | }
16 | }
17 | }
18 |
19 | .welcome-intro {
20 | text-align: center;
21 |
22 | @media (min-width: $screen-xs-min) {
23 | margin-bottom: 30px;
24 | }
25 |
26 | @media (min-width: $screen-md-min) {
27 | margin-top: 60px;
28 | }
29 | }
30 |
31 | .staff.label {
32 | padding-top: 0.5em;
33 | }
34 |
--------------------------------------------------------------------------------
/app/controllers/users_controller.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class UsersController < ApplicationController
4 | before_action :authenticate_user!, only: %i[subscriptions welcome]
5 |
6 | def show
7 | @user = User.find(params[:id])
8 | @you = current_user && @user == current_user
9 | @history = @user.recent_changes(20)
10 | end
11 |
12 | def subscriptions
13 | @user = User.find(params[:id])
14 | end
15 |
16 | def confirm
17 | # Remove Devise flash
18 | flash.delete(:notice)
19 | end
20 |
21 | def welcome
22 | @policies = current_user.unwatched_policies.published.sample(3)
23 | flash.delete(:notice)
24 | end
25 | end
26 |
--------------------------------------------------------------------------------
/db/migrate/20140930212321_add_timestamps_to_all_tables.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class AddTimestampsToAllTables < ActiveRecord::Migration
4 | def change
5 | add_timestamps :division_infos
6 | add_timestamps :divisions
7 | add_timestamps :electorates
8 | add_timestamps :member_distances
9 | add_timestamps :member_infos
10 | add_timestamps :members
11 | add_timestamps :offices
12 | add_timestamps :policies
13 | add_timestamps :policy_divisions
14 | add_timestamps :policy_person_distances
15 | add_timestamps :users
16 | add_timestamps :votes
17 | add_timestamps :whips
18 | add_timestamps :wiki_motions
19 | end
20 | end
21 |
--------------------------------------------------------------------------------
/app/assets/stylesheets/global/_swag.scss:
--------------------------------------------------------------------------------
1 | .swag {
2 | background-color: #101c37;
3 | color: white;
4 | padding: 10px;
5 | text-align: center;
6 | font-size: 20px;
7 | line-height: 26px;
8 | margin-bottom: 0;
9 | border: 0;
10 | border-radius: 0;
11 | :hover {
12 | text-decoration: underline;
13 | }
14 |
15 | .swag-text {
16 | text-align: left;
17 | display: inline-block;
18 | max-width: 280px;
19 | vertical-align: middle;
20 | }
21 |
22 | button.close {
23 | color: white;
24 | opacity: 0.8;
25 | :hover, :focus {
26 | // TODO: Do something designed rather than fairly arbitrary
27 | opacity: 0.6;
28 | }
29 | };
30 | }
31 |
--------------------------------------------------------------------------------
/app/lib/party.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Party
4 | attr_accessor :name
5 |
6 | def initialize(params)
7 | @name = params[:name]
8 | end
9 |
10 | def long_name
11 | case name
12 | when "SPK"
13 | "Speaker"
14 | when "CWM"
15 | "Deputy Speaker"
16 | when "PRES"
17 | "President"
18 | when "DPRES"
19 | "Deputy President"
20 | else
21 | name
22 | end
23 | end
24 |
25 | # Does this party not have a whip?
26 | def whipless?
27 | %w[XB Other None SPK CWM DCWM PRES DPRES].include?(name) ||
28 | name[0..2] == "Ind"
29 | end
30 |
31 | def subject_to_whip?
32 | !whipless?
33 | end
34 | end
35 |
--------------------------------------------------------------------------------
/app/views/layouts/_history_list.html.haml:
--------------------------------------------------------------------------------
1 | %ul.row.list-unstyled
2 | - history.each do |version|
3 | %li.object-item
4 | - if version.kind_of?(WikiMotion)
5 | %p
6 | Changed text on
7 | = link_to version.division.name, division_path_simple(version.division)
8 |
9 | - else
10 | - if !policy
11 | %p.change-policy-name
12 | On policy
13 | = link_to version_policy(version).name, version_policy(version)
14 |
15 | = version_sentence(version)
16 |
17 | %p.small.object-primary.text-muted
18 | = name_with_badge(version_author(version))
19 | = time_ago_in_words(version.created_at)
20 | ago
21 |
--------------------------------------------------------------------------------
/app/views/devise/passwords/new.html.haml:
--------------------------------------------------------------------------------
1 | - content_for :title, 'Password reset'
2 |
3 | .thin-page
4 | %h1.long-title= yield :title
5 |
6 | %p Enter your email and we’ll send you intructions to reset your password
7 |
8 | = form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :post }) do |f|
9 | = devise_error_messages!
10 | .form-group
11 | = f.label :email
12 | = f.email_field :email, autofocus: true, class: "form-control", required: "required"
13 |
14 | = f.submit "Reset password", class: "btn btn-primary btn-wide"
15 |
16 | %ul.form-secondary.nav.nav-pills
17 | %li= link_to 'Back to log in', new_user_session_path, class: "btn-xs"
18 |
--------------------------------------------------------------------------------
/app/views/layouts/card_layout.html.haml:
--------------------------------------------------------------------------------
1 |
2 | !!! 5
3 | %html.no-js(lang="en")
4 | %head
5 | %meta(charset="utf-8")
6 | %meta(name="viewport" content="width=device-width, initial-scale=1")
7 | %meta{:name => "robots", :content => "noindex"}
8 | %title
9 | - if content_for? :title
10 | = yield :title
11 | = "— #{Rails.configuration.project_name}"
12 | - else
13 | #{Rails.configuration.project_name} — How does your MP vote?
14 |
15 | = stylesheet_link_tag "//code.cdn.mozilla.net/fonts/fira.css"
16 | = stylesheet_link_tag "application"
17 |
18 | = csrf_meta_tag
19 | = display_meta_tags
20 | %body{class: "social_media_cards"}
21 | = yield
--------------------------------------------------------------------------------
/app/policies/division_policy.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class DivisionPolicy < ApplicationPolicy
4 | def update?
5 | user&.staff?
6 | end
7 |
8 | # NOTE: Up to Pundit v2.3.1, the inheritance was declared as
9 | # `Scope < Scope` rather than `Scope < ApplicationPolicy::Scope`.
10 | # In most cases the behavior will be identical, but if updating existing
11 | # code, beware of possible changes to the ancestors:
12 | # https://gist.github.com/Burgestrand/4b4bc22f31c8a95c425fc0e30d7ef1f5
13 |
14 | class Scope < ApplicationPolicy::Scope
15 | # NOTE: Be explicit about which records you allow access to!
16 | # def resolve
17 | # scope.all
18 | # end
19 | end
20 | end
21 |
--------------------------------------------------------------------------------
/db/migrate/20211223050627_create_flipper_tables.rb:
--------------------------------------------------------------------------------
1 | class CreateFlipperTables < ActiveRecord::Migration[5.0]
2 | def self.up
3 | create_table :flipper_features do |t|
4 | t.string :key, null: false
5 | t.timestamps null: false
6 | end
7 | add_index :flipper_features, :key, unique: true
8 |
9 | create_table :flipper_gates do |t|
10 | t.string :feature_key, null: false
11 | t.string :key, null: false
12 | t.string :value
13 | t.timestamps null: false
14 | end
15 | add_index :flipper_gates, [:feature_key, :key, :value], unique: true
16 | end
17 |
18 | def self.down
19 | drop_table :flipper_gates
20 | drop_table :flipper_features
21 | end
22 | end
23 |
--------------------------------------------------------------------------------
/app/views/api/v1/divisions/show.json.jbuilder:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | json.partial! "division", division: @division
4 |
5 | # Extra information that isn't in the summary
6 | json.summary @division.motion
7 | json.votes @division.votes.order(:vote).includes(:member), partial: "api/v1/votes/vote", as: :vote
8 |
9 | json.policy_divisions do
10 | json.array! @division.policy_divisions.includes(:policy) do |pd|
11 | json.policy do
12 | json.partial! "api/v1/policies/policy", policy: pd.policy
13 | end
14 | json.vote PolicyDivision.vote_without_strong(pd.vote)
15 | json.strong pd.strong_vote?
16 | end
17 | end
18 |
19 | json.bills @division.bills, partial: "api/v1/bills/bill", as: :bill
20 |
--------------------------------------------------------------------------------
/db/migrate/20140822004101_add_primary_keys.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class AddPrimaryKeys < ActiveRecord::Migration
4 | def change
5 | add_column :member_distances, :id, :primary_key
6 | add_column :pw_cache_divinfo, :id, :primary_key
7 | add_column :pw_cache_divwiki, :id, :primary_key
8 | add_column :pw_cache_dreamreal_distance, :id, :primary_key
9 | add_column :pw_cache_mpinfo, :id, :primary_key
10 | add_column :pw_cache_whip, :id, :primary_key
11 | add_column :pw_constituency, :id, :primary_key
12 | add_column :pw_dyn_dreamvote, :id, :primary_key
13 | add_column :pw_vote, :id, :primary_key
14 | add_column :pw_vote_sortorder, :id, :primary_key
15 | end
16 | end
17 |
--------------------------------------------------------------------------------
/app/assets/stylesheets/divisions/_division-motion.scss:
--------------------------------------------------------------------------------
1 | .division-edit-notice.page-section {
2 | margin-top: 1em;
3 |
4 | @media (min-width: $screen-sm-min) {
5 | margin-top: 0;
6 | }
7 | }
8 |
9 | .motion-source-info {
10 | border-top: 1px solid #E7E7E7;
11 | }
12 |
13 | .division-outcome-summary {
14 | &.division-outcome-passed {
15 | color: $color-vote-for;
16 | }
17 |
18 | &.division-outcome-not-passed {
19 | color: $color-vote-against;
20 | }
21 | }
22 |
23 | .motion-title,
24 | .motion-title + .division-edit-link,
25 | .division-outcome-summary,
26 | .division-outcome-score {
27 | display: inline-block;
28 | }
29 |
30 | .motion-title + .division-edit-link {
31 | margin-left: 1em;
32 | }
33 |
--------------------------------------------------------------------------------
/app/controllers/api/v1/divisions_controller.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module Api
4 | module V1
5 | class DivisionsController < Api::V1::ApplicationController
6 | def index
7 | @divisions = Division.order(date: :desc, house: :desc, number: :desc).includes(:wiki_motions, :whips, :division_info).limit(100)
8 | @divisions = @divisions.where(date: (params[:start_date])..) if params[:start_date]
9 | @divisions = @divisions.where(date: ..(params[:end_date])) if params[:end_date]
10 | @divisions = @divisions.where(house: params[:house]) if params[:house]
11 | end
12 |
13 | def show
14 | @division = Division.find(params[:id])
15 | end
16 | end
17 | end
18 | end
19 |
--------------------------------------------------------------------------------
/config/initializers/inflections.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Add new inflection rules using the following format. Inflections
4 | # are locale specific, and you may define rules for as many different
5 | # locales as you wish. All of these examples are active by default:
6 | # ActiveSupport::Inflector.inflections(:en) do |inflect|
7 | # inflect.plural /^(ox)$/i, "\\1en"
8 | # inflect.singular /^(ox)en/i, "\\1"
9 | # inflect.irregular "person", "people"
10 | # inflect.uncountable %w( fish sheep )
11 | # end
12 |
13 | # These inflection rules are supported but not enabled by default:
14 | # ActiveSupport::Inflector.inflections(:en) do |inflect|
15 | # inflect.acronym "RESTful"
16 | # end
17 |
--------------------------------------------------------------------------------
/app/assets/stylesheets/global/_social-share.scss:
--------------------------------------------------------------------------------
1 | %inline-icon {
2 | margin-right: 3px;
3 | display: inline-block;
4 | font-size: 24px;
5 | vertical-align: middle;
6 | }
7 |
8 | .social-share {
9 | z-index: 1;
10 | ul {
11 | display: inline;
12 | }
13 | }
14 |
15 | .social-share-heading {
16 | margin: 0 10px 0 0;
17 | display: inline-block;
18 | color: #aaa;
19 | }
20 |
21 | .share-link {
22 | margin-left: 2px;
23 | color: #888;
24 |
25 | i {
26 | @extend %inline-icon;
27 | color: #aaa;
28 |
29 | &.fi-social-facebook {
30 | padding: 0 0 2px 0;
31 | }
32 | }
33 |
34 | &:hover,
35 | &:focus {
36 | text-decoration: none;
37 | i {
38 | color: inherit;
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/config/initializers/markdown_handler.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require "redcarpet"
4 |
5 | class BootstrapTableRenderer < Redcarpet::Render::HTML
6 | def table(header, body)
7 | ""
8 | end
9 | end
10 |
11 | module MarkdownHandler
12 | def self.erb
13 | @erb ||= ActionView::Template.registered_template_handler(:erb)
14 | end
15 |
16 | def self.call(template, source)
17 | compiled_source = erb.call(template, source)
18 | "Redcarpet::Markdown.new(BootstrapTableRenderer, tables: true).render(begin;#{compiled_source};end.to_s).html_safe"
19 | end
20 | end
21 |
22 | ActionView::Template.register_template_handler :md, MarkdownHandler
23 |
--------------------------------------------------------------------------------
/app/views/devise/mailer/reset_password_instructions.html.haml:
--------------------------------------------------------------------------------
1 | - content_for :subject, "Reset your password"
2 |
3 | %tr
4 | %td.content-block
5 | #{@resource.name}, someone has requested a link to change your password.
6 | You can do this through the link below.
7 | %tr
8 | %td.content-block
9 | = link_to 'Change my password', edit_password_url(@resource, reset_password_token: @token), class: "btn-primary"
10 | %tr
11 | %td.content-block
12 | If you didn't request this, please ignore this email.
13 | %tr
14 | %td.content-block
15 | Your password won't change until you access the link above and create a new one.
16 | %tr
17 | %td.content-block
18 | — The
19 | %em= Rails.configuration.project_name
20 | team
21 |
--------------------------------------------------------------------------------
/app/views/application/_social_share.html.haml:
--------------------------------------------------------------------------------
1 | %aside.social-share
2 | %h2.social-share-heading.small
3 | Share
4 |
5 | -# TODO: The visual layout of this is pretty awfull right now. The icons and the text are not vertically center aligned as they should be
6 | %ul.list-inline.small
7 | %li
8 | = link_to "https://www.facebook.com/sharer/sharer.php?u=#{request.original_url}&t=", title: "Share on Facebook", class: 'share-link share-link-facebook' do
9 | %i.fa-brands.fa-facebook
10 | Facebook
11 |
12 | %li
13 | = link_to "https://bsky.app/intent/compose?text=#{request.original_url}", title: "Share on Bluesky", class: 'share-link share-link-bluesky' do
14 | %i.fa-brands.fa-bluesky
15 | Bluesky
16 |
17 |
--------------------------------------------------------------------------------
/db/migrate/20220421041242_drop_member_distances.rb:
--------------------------------------------------------------------------------
1 | class DropMemberDistances < ActiveRecord::Migration[6.0]
2 | def change
3 | drop_table :member_distances do |t|
4 | t.integer :member1_id, null: false
5 | t.integer :member2_id, null: false
6 | t.integer :nvotessame
7 | t.integer :nvotesdiffer
8 | t.integer :nvotesabsent
9 | t.float :distance_a, limit: 24
10 | t.float :distance_b, limit: 24
11 | t.datetime :created_at
12 | t.datetime :updated_at
13 | t.index [:member1_id, :member2_id], name: "mp_id1_2", unique: true, using: :btree
14 | t.index [:member1_id], name: "mp_id1", using: :btree
15 | t.index [:member2_id], name: "mp_id2", using: :btree
16 | end
17 | end
18 | end
19 |
--------------------------------------------------------------------------------
/app/policies/policy_policy.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PolicyPolicy < ApplicationPolicy
4 | def create?
5 | user&.staff?
6 | end
7 |
8 | def update?
9 | user&.staff?
10 | end
11 |
12 | # NOTE: Up to Pundit v2.3.1, the inheritance was declared as
13 | # `Scope < Scope` rather than `Scope < ApplicationPolicy::Scope`.
14 | # In most cases the behavior will be identical, but if updating existing
15 | # code, beware of possible changes to the ancestors:
16 | # https://gist.github.com/Burgestrand/4b4bc22f31c8a95c425fc0e30d7ef1f5
17 |
18 | class Scope < ApplicationPolicy::Scope
19 | # NOTE: Be explicit about which records you allow access to!
20 | # def resolve
21 | # scope.all
22 | # end
23 | end
24 | end
25 |
--------------------------------------------------------------------------------
/app/views/application/_logged_in_user_menu.html.haml:
--------------------------------------------------------------------------------
1 | %li.dropdown
2 | %a.dropdown-toggle(href="#" data-toggle="dropdown")
3 | = current_user.name
4 | %ul.dropdown-menu(role="menu")
5 | %li= link_to "Your page", current_user
6 | %li= link_to "Your subscriptions", user_subscriptions_path(current_user)
7 | %li= link_to "Edit profile", edit_user_registration_path
8 | - if current_user.admin?
9 | %li.divider
10 | %li= link_to "Admin panel", admin_root_path
11 | %li= link_to "Admin for feature flags", admin_flipper_path
12 | %li.divider
13 | %li= link_to "Logout", destroy_user_session_path, title: "Make your browser forget that you are logged into #{Rails.configuration.project_name} as #{current_user.name}", method: :delete
14 |
--------------------------------------------------------------------------------
/app/controllers/api/v1/application_controller.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module Api
4 | module V1
5 | class ApplicationController < ::ApplicationController
6 | before_action :require_key
7 | after_action :log_api_request
8 |
9 | private
10 |
11 | def require_key
12 | # Not every user has the api_key set. So explicitly handle the nil case
13 | user = User.find_by(api_key: params[:key]) if params[:key]
14 | render json: { error: "You need a valid api key. Sign up for an account on #{Rails.configuration.project_name} to get one." }, status: :unauthorized if user.nil?
15 | end
16 |
17 | def log_api_request
18 | ApiStatistic.log(request)
19 | end
20 | end
21 | end
22 | end
23 |
--------------------------------------------------------------------------------
/app/views/members/_policy_comparisons_block.html.haml:
--------------------------------------------------------------------------------
1 | - unless distances.empty?
2 | .policy-comparision-block.col-md-7{class: "position-#{label}"}
3 | .row
4 | %h3.policy-comparision-position.col-xs-9= title
5 | .row
6 | %ul.policy-comparision-list.object-list-compact.list-unstyled.col-xs-12
7 | - distances.sort_by{ |ppd| ppd.policy.name.downcase }.each do |ppd|
8 | %li.policy-comparision-policy.object-item
9 | = link_to capitalise_initial_character(ppd.policy.name), member_policy_path_simple(member, ppd.policy), class: 'policy-title'
10 | =link_to "Something not right?", help_faq_path(anchor: 'stance'), title: "Is this information inaccurate? Find out how you can improve it.", class: 'policy-correction-notice small'
11 |
--------------------------------------------------------------------------------
/db/migrate/20140828083134_add_vote_without_tell_to_votes.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class AddVoteWithoutTellToVotes < ActiveRecord::Migration
4 | def change
5 | add_column :votes, :vote_without_tell, :string, limit: 10
6 | add_index :votes, :vote_without_tell
7 | add_column :votes, :teller, :boolean, null: false, default: false
8 | add_index :votes, :teller
9 | Vote.reset_column_information
10 | Vote.all.find_each do |vote|
11 | case vote.vote
12 | when "tellaye"
13 | vote.update!(vote_without_tell: "aye", teller: true)
14 | when "tellno"
15 | vote.update!(vote_without_tell: "no", teller: true)
16 | else
17 | vote.update!(vote_without_tell: vote.vote)
18 | end
19 | end
20 | end
21 | end
22 |
--------------------------------------------------------------------------------
/app/views/policies/history.html.haml:
--------------------------------------------------------------------------------
1 | - content_for :title do
2 | Recent history:
3 | = capitalise_initial_character(@policy.name_with_for)
4 | - set_meta_tags description: "Recent changes made to the “#{@policy.name_with_for}” policy."
5 |
6 | .page-header.row
7 | %nav.header-actions.col-md-3
8 | - if policy(@policy).edit?
9 | =link_to_if(@policy, "Edit", edit_policy_path(@policy), title: "Change title and definition of policy", class: "btn btn-default btn-xs")
10 | - if policy(Policy).new?
11 | =link_to "New policy", new_policy_path, class: "link-policy-new btn btn-primary btn-xs"
12 | -# TODO This title is just a stop-gap. Make it not suck.
13 | %h1.col-md-9= yield :title
14 |
15 | = render partial: "layouts/history_list", locals: { policy: @policy, history: @history }
16 |
--------------------------------------------------------------------------------
/app/views/api/v1/people/show.json.jbuilder:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | json.partial! "person", person: @person
4 |
5 | # Extra information that's not on the index action
6 |
7 | json.rebellions @person.rebellions
8 | json.votes_attended @person.votes_attended
9 | json.votes_possible @person.votes_possible
10 |
11 | json.offices @person.current_offices, partial: "api/v1/offices/office", as: :office
12 |
13 | json.policy_comparisons do
14 | json.array! @person.policy_person_distances.includes(:policy).published.order(:distance_a) do |ppd|
15 | json.policy do
16 | json.partial! "api/v1/policies/policy", policy: ppd.policy
17 | end
18 | json.agreement number_with_precision(ppd.agreement_fraction * 100, precision: 2, significant: true)
19 | json.voted ppd.voted?
20 | end
21 | end
22 |
--------------------------------------------------------------------------------
/config/credentials/production.yml.enc:
--------------------------------------------------------------------------------
1 | IJZeuZl94FpCwg0Nn/oZF9Ss+NXt0BTFR742gvRT4gFuLrhQcbiO17zXqmwclEzB5YPkXsDbIQQbyzZWVTLZr9oVhOvI7F3xAt/mb1vupIjH0FS+raubBQqjgBsWECFNHCdZepn+kG1cE1UwMFSbcapnJdMymEo6tUFEsHqgpgoM7BKnIkvz2Wu7apwoBgFkyb6rr9ToJRaSnWHnJbAY6AVFVlu+/s0kbRCf12UlEpm5ZVsdFynkzxQfGGgGu24rpoT456cj9tUBXSA9r9PE4TFz/mgcBZtqWuTe6t70v7MphZfGEmQaTWyDbYNCPQ5iezhwSSYm7G3fJUMTZz2lYSNDt8cIxFQDW9E6a3QXGtUa7O3wGEhWfaIy6FueR/rs71hBOeo+In/pBTLKXCHTbn1qULUM4wZ0d7eZgb8GAnbYdrlh3ZjitKuvVvm4GgKVGhtCUYHudGqmszOvy+u+gQRJiPN4OWQpk1CaCMBIesl84T2D27PW9yLXkTAyTD1p4Qco2tFxSbRFcIdzIJtTDQXgYT/FrsOvgaE8HCwETlnC0tQWlEjsX2b7MgDFeJqib8zD6qmfTpsoyJxWEHFyDEFvWC9vEZCmGGMAy9HiT0wrg2HjfVqOByRi3O8Q1WKLYj6SglhLYOsQ0dc4BqHYSdCuFA/q9EPpqPjwSh618ZtnXgLTTN1xZbsINttujYK95m9h9Mlf5N3I9eizcmZAK4hNHGXhC/eqz1/WlF58iBCDwx/xlczInf2n6xXsgyJBymI=--FGDdt3DgeKYGu6wm--kTZnQ56Sd/SjK/fc8NMjFw==
--------------------------------------------------------------------------------
/vendor/assets/stylesheets/bootstrap-accessibility.css:
--------------------------------------------------------------------------------
1 | .btn:focus{outline:dotted 2px #000}div.active:focus{outline:dotted 1px #000}a:focus{outline:dotted 1px #000}.close:hover,.close:focus{outline:dotted 1px #000}.nav>li>a:hover,.nav>li>a:focus{outline:dotted 1px #000}.carousel-inner>.item{position:absolute;top:-999999em;display:block;-webkit-transition:0.6s ease-in-out left;-moz-transition:0.6s ease-in-out left;-o-transition:0.6s ease-in-out left;transition:0.6s ease-in-out left}.carousel-inner>.active{top:0}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{position:relative}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.alert-success{color:#2d4821}.alert-info{color:#214c62}.alert-warning{color:#6c4a00;background-color:#f9f1c6}.alert-danger{color:#d2322d}.alert-danger:hover{color:#a82824}
2 |
--------------------------------------------------------------------------------
/app/assets/stylesheets/divisions/_division-show.scss:
--------------------------------------------------------------------------------
1 | .motion {
2 | padding: 0;
3 | }
4 |
5 | .division-external-links {
6 | width: 100%;
7 | clear: left;
8 |
9 | @include make-md-column(7);
10 | padding: 0;
11 |
12 | .motion-edited + & {
13 | @media (max-width: $screen-sm-max) {
14 | padding: 0;
15 | }
16 |
17 | @media (min-width: $screen-md-min) {
18 | float: right !important;
19 | clear: right;
20 | }
21 |
22 | // @include make-lg-column-offset(8);
23 | @include make-md-column(4);
24 | @include make-lg-column(4);
25 | }
26 |
27 | h2:first-child {
28 | margin-top: 46px;
29 | margin-bottom: 0;
30 | }
31 |
32 | .object-item {
33 | padding-right: 0;
34 | padding-left: 0;
35 |
36 | a {
37 | display: block;
38 | }
39 | }
40 | }
41 |
42 |
--------------------------------------------------------------------------------
/design_docs/principles.md:
--------------------------------------------------------------------------------
1 | # Design Principles
2 |
3 | Ideas that guide decision making on this project.
4 |
5 | 1. *Focus on enabling actions that citizens want to take and access to the knowledge that they are looking for*. Reduce the cost of them taking action. The action is the important bit. Citizens don't need to understand the bureaucracy in order to use and access government.
6 |
7 | 2. Assume people are *smart & busy*—present the important information up front and put detail within reach.
8 |
9 | 3. Strive for *universal accessibility*.
10 |
11 | 4. Design and implement with *Progressive Enhancement*.
12 |
13 | 5. *Create change by doing*. Implement ideas quickly and assess—don't be frozen by documentation and proposal.
14 |
15 | 6. *Maintainability* is crucial, this project should last and evolve long into the future.
16 |
--------------------------------------------------------------------------------
/spec/models/policy_division_spec.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require "spec_helper"
4 |
5 | describe PolicyDivision do
6 | describe "#vote" do
7 | it { expect(described_class.new(policy: Policy.new, division: Division.new)).not_to be_valid }
8 | it { expect(described_class.new(policy: Policy.new, division: Division.new, vote: "aye3")).to be_valid }
9 | it { expect(described_class.new(policy: Policy.new, division: Division.new, vote: "aye")).to be_valid }
10 | it { expect(described_class.new(policy: Policy.new, division: Division.new, vote: "no")).to be_valid }
11 | it { expect(described_class.new(policy: Policy.new, division: Division.new, vote: "no3")).to be_valid }
12 | it { expect(described_class.new(policy: Policy.new, division: Division.new, vote: "bottom")).not_to be_valid }
13 | end
14 | end
15 |
--------------------------------------------------------------------------------
/app/policies/policy_division_policy.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PolicyDivisionPolicy < ApplicationPolicy
4 | def create?
5 | user&.staff?
6 | end
7 |
8 | def update?
9 | user&.staff?
10 | end
11 |
12 | def destroy?
13 | user&.staff?
14 | end
15 |
16 | # NOTE: Up to Pundit v2.3.1, the inheritance was declared as
17 | # `Scope < Scope` rather than `Scope < ApplicationPolicy::Scope`.
18 | # In most cases the behavior will be identical, but if updating existing
19 | # code, beware of possible changes to the ancestors:
20 | # https://gist.github.com/Burgestrand/4b4bc22f31c8a95c425fc0e30d7ef1f5
21 |
22 | class Scope < ApplicationPolicy::Scope
23 | # NOTE: Be explicit about which records you allow access to!
24 | # def resolve
25 | # scope.all
26 | # end
27 | end
28 | end
29 |
--------------------------------------------------------------------------------
/db/migrate/20220217004002_convert_users_text_fields_to_string.rb:
--------------------------------------------------------------------------------
1 | class ConvertUsersTextFieldsToString < ActiveRecord::Migration[6.0]
2 | def up
3 | # Temporary columns to hold truncated values
4 | add_column :users, :temp_name, :string, null: false
5 | add_column :users, :temp_email, :string
6 |
7 | # There's only spam accounts that have long names or emails. So we can just chop them off
8 | User.find_each do |user|
9 | user.update!(temp_name: user.name[0..254], temp_email: user.email&.[](0..254))
10 | end
11 |
12 | remove_column :users, :name
13 | rename_column :users, :temp_name, :name
14 |
15 | remove_column :users, :email
16 | rename_column :users, :temp_email, :email
17 | end
18 |
19 | def down
20 | change_column :users, :name, :text, null: false
21 | change_column :users, :email, :text
22 | end
23 | end
24 |
--------------------------------------------------------------------------------
/app/views/members/_policy_comparisons.html.haml:
--------------------------------------------------------------------------------
1 | %section.page-section#voting-stace
2 | %h2 How do they vote?
3 |
4 | - if member.person.policy_person_distances.empty?
5 | %ul
6 | %li
7 | No policies match this person's votes. You can
8 | = link_to "edit or make a policy", policies_path
9 | that will appear here.
10 | - else
11 | - distances = member.person.policy_person_distances.published.includes(:policy)
12 | - PolicyPersonDistance.all_categories.each do |c|
13 | = render "policy_comparisons_block", member: member, distances: distances.select{ |d| d.category == c }, title: category_words_sentence(c).capitalize, label: c.to_s
14 |
15 | %p.small.text-muted
16 | Please note that #{link_to "our voting records start in #{formatted_month(Division.date_earliest_division)}", help_faq_path(anchor: "timeperiod"), class: 'text-muted'}.
17 |
--------------------------------------------------------------------------------
/app/policies/application_policy.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class ApplicationPolicy
4 | attr_reader :user, :record
5 |
6 | def initialize(user, record)
7 | @user = user
8 | @record = record
9 | end
10 |
11 | def index?
12 | false
13 | end
14 |
15 | def show?
16 | false
17 | end
18 |
19 | def create?
20 | false
21 | end
22 |
23 | def new?
24 | create?
25 | end
26 |
27 | def update?
28 | false
29 | end
30 |
31 | def edit?
32 | update?
33 | end
34 |
35 | def destroy?
36 | false
37 | end
38 |
39 | class Scope
40 | def initialize(user, scope)
41 | @user = user
42 | @scope = scope
43 | end
44 |
45 | def resolve
46 | raise NoMethodError, "You must define #resolve in #{self.class}"
47 | end
48 |
49 | private
50 |
51 | attr_reader :user, :scope
52 | end
53 | end
54 |
--------------------------------------------------------------------------------
/app/views/policies/_policy.html.haml:
--------------------------------------------------------------------------------
1 | %li
2 | = link_to policy, class: 'object-item panel-link row' do
3 | %article
4 | %h2.policy-title.object-heading.panel-link-title.col-md-7
5 | = capitalise_initial_character(policy.name)
6 |
7 | %p.policy-data.object-secondary
8 | %span
9 | = pluralize(policy.divisions.count, "division")
10 | - if policy.unedited_motions_count != 0
11 | %em= "(#{policy.unedited_motions_count} unedited)"
12 | %small.policy-edit-notice.text-muted
13 | edited #{time_ago_in_words(policy.last_edited_at)} ago
14 | %small.policy-subscriber-count.text-muted.hidden-md.hidden-lg
15 | = pluralize(policy.watches.count, "subscriber")
16 |
17 | %p.policy-subscriber-count.visible-md.visible-lg.col-md-7.text-muted.small
18 | = pluralize(policy.watches.count, "subscriber")
19 |
--------------------------------------------------------------------------------
/app/views/devise/confirmations/new.html.haml:
--------------------------------------------------------------------------------
1 | - content_for :title, 'Resend email confirmation'
2 |
3 | .thin-page
4 | %h1.long-title= yield :title
5 |
6 | %p We’ll send you an email to confirm address
7 |
8 | = simple_form_for(resource, as: resource_name, url: confirmation_path(resource_name), html: { method: :post }) do |f|
9 | - if f.error :confirmation_token
10 | .alert.alert-danger= "Confirmation token is invalid. Enter your email and we'll send you another confirmation."
11 | - else
12 | = f.error_notification
13 |
14 | .form-group= f.input :email, as: :email, autofocus: true, hint: "Enter your email address", hint_html: {class: 'small hint-block-intime'}
15 |
16 | = f.button :submit, "Resend confirmation", class: "btn btn-primary btn-wide"
17 |
18 | %ul.form-secondary.nav.nav-pills
19 | %li= link_to 'Back to Log in', new_user_session_path, class: "btn-xs"
20 |
--------------------------------------------------------------------------------
/app/views/alert_mailer/policy_updated.html.haml:
--------------------------------------------------------------------------------
1 | %h1.unstyled-heading
2 | %strong
3 | = link_to capitalise_initial_character(@policy.name_with_for), policy_url(@policy), class: "heading-object-link"
4 |
5 | - if @version.kind_of?(WikiMotion)
6 | %p
7 | Changed text on related division
8 | = link_to @version.division.name, division_url_simple(@version.division)
9 | - else
10 | = version_sentence(@version)
11 |
12 | %p.small.object-primary
13 | = link_to version_author(@version).name, version_author(@version)
14 | %span.text-muted.small
15 | = @version.created_at.strftime("%l:%M%p - %d %b %Y")
16 |
17 | %br
18 |
19 | .text-muted
20 | %p.small
21 | Visit the
22 | = link_to "policy page", policy_url(@policy), class: "small"
23 | to unsubscribe from this policy.
24 | %p.small
25 | = link_to "View all your subscriptions.", user_subscriptions_url(@user), class: "small"
26 |
--------------------------------------------------------------------------------
/bin/pry:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | # frozen_string_literal: true
3 |
4 | #
5 | # This file was generated by Bundler.
6 | #
7 | # The application 'pry' is installed as part of a gem, and
8 | # this file is here to facilitate running it.
9 | #
10 |
11 | require "pathname"
12 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
13 | Pathname.new(__FILE__).realpath)
14 |
15 | bundle_binstub = File.expand_path("../bundle", __FILE__)
16 |
17 | if File.file?(bundle_binstub)
18 | if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
19 | load(bundle_binstub)
20 | else
21 | abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22 | Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23 | end
24 | end
25 |
26 | require "rubygems"
27 | require "bundler/setup"
28 |
29 | load Gem.bin_path("pry", "pry")
30 |
--------------------------------------------------------------------------------
/bin/ri:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | # frozen_string_literal: true
3 |
4 | #
5 | # This file was generated by Bundler.
6 | #
7 | # The application 'ri' is installed as part of a gem, and
8 | # this file is here to facilitate running it.
9 | #
10 |
11 | require "pathname"
12 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
13 | Pathname.new(__FILE__).realpath)
14 |
15 | bundle_binstub = File.expand_path("../bundle", __FILE__)
16 |
17 | if File.file?(bundle_binstub)
18 | if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
19 | load(bundle_binstub)
20 | else
21 | abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22 | Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23 | end
24 | end
25 |
26 | require "rubygems"
27 | require "bundler/setup"
28 |
29 | load Gem.bin_path("rdoc", "ri")
30 |
--------------------------------------------------------------------------------
/bin/haml:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | # frozen_string_literal: true
3 |
4 | #
5 | # This file was generated by Bundler.
6 | #
7 | # The application 'haml' is installed as part of a gem, and
8 | # this file is here to facilitate running it.
9 | #
10 |
11 | require "pathname"
12 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
13 | Pathname.new(__FILE__).realpath)
14 |
15 | bundle_binstub = File.expand_path("../bundle", __FILE__)
16 |
17 | if File.file?(bundle_binstub)
18 | if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
19 | load(bundle_binstub)
20 | else
21 | abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22 | Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23 | end
24 | end
25 |
26 | require "rubygems"
27 | require "bundler/setup"
28 |
29 | load Gem.bin_path("haml", "haml")
30 |
--------------------------------------------------------------------------------
/bin/mina:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | # frozen_string_literal: true
3 |
4 | #
5 | # This file was generated by Bundler.
6 | #
7 | # The application 'mina' is installed as part of a gem, and
8 | # this file is here to facilitate running it.
9 | #
10 |
11 | require "pathname"
12 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
13 | Pathname.new(__FILE__).realpath)
14 |
15 | bundle_binstub = File.expand_path("../bundle", __FILE__)
16 |
17 | if File.file?(bundle_binstub)
18 | if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
19 | load(bundle_binstub)
20 | else
21 | abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22 | Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23 | end
24 | end
25 |
26 | require "rubygems"
27 | require "bundler/setup"
28 |
29 | load Gem.bin_path("mina", "mina")
30 |
--------------------------------------------------------------------------------
/bin/racc:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | # frozen_string_literal: true
3 |
4 | #
5 | # This file was generated by Bundler.
6 | #
7 | # The application 'racc' is installed as part of a gem, and
8 | # this file is here to facilitate running it.
9 | #
10 |
11 | require "pathname"
12 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
13 | Pathname.new(__FILE__).realpath)
14 |
15 | bundle_binstub = File.expand_path("../bundle", __FILE__)
16 |
17 | if File.file?(bundle_binstub)
18 | if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
19 | load(bundle_binstub)
20 | else
21 | abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22 | Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23 | end
24 | end
25 |
26 | require "rubygems"
27 | require "bundler/setup"
28 |
29 | load Gem.bin_path("racc", "racc")
30 |
--------------------------------------------------------------------------------
/bin/rdoc:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | # frozen_string_literal: true
3 |
4 | #
5 | # This file was generated by Bundler.
6 | #
7 | # The application 'rdoc' is installed as part of a gem, and
8 | # this file is here to facilitate running it.
9 | #
10 |
11 | require "pathname"
12 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
13 | Pathname.new(__FILE__).realpath)
14 |
15 | bundle_binstub = File.expand_path("../bundle", __FILE__)
16 |
17 | if File.file?(bundle_binstub)
18 | if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
19 | load(bundle_binstub)
20 | else
21 | abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22 | Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23 | end
24 | end
25 |
26 | require "rubygems"
27 | require "bundler/setup"
28 |
29 | load Gem.bin_path("rdoc", "rdoc")
30 |
--------------------------------------------------------------------------------
/bin/sdoc:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | # frozen_string_literal: true
3 |
4 | #
5 | # This file was generated by Bundler.
6 | #
7 | # The application 'sdoc' is installed as part of a gem, and
8 | # this file is here to facilitate running it.
9 | #
10 |
11 | require "pathname"
12 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
13 | Pathname.new(__FILE__).realpath)
14 |
15 | bundle_binstub = File.expand_path("../bundle", __FILE__)
16 |
17 | if File.file?(bundle_binstub)
18 | if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
19 | load(bundle_binstub)
20 | else
21 | abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22 | Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23 | end
24 | end
25 |
26 | require "rubygems"
27 | require "bundler/setup"
28 |
29 | load Gem.bin_path("sdoc", "sdoc")
30 |
--------------------------------------------------------------------------------
/bin/thor:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | # frozen_string_literal: true
3 |
4 | #
5 | # This file was generated by Bundler.
6 | #
7 | # The application 'thor' is installed as part of a gem, and
8 | # this file is here to facilitate running it.
9 | #
10 |
11 | require "pathname"
12 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
13 | Pathname.new(__FILE__).realpath)
14 |
15 | bundle_binstub = File.expand_path("../bundle", __FILE__)
16 |
17 | if File.file?(bundle_binstub)
18 | if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
19 | load(bundle_binstub)
20 | else
21 | abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22 | Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23 | end
24 | end
25 |
26 | require "rubygems"
27 | require "bundler/setup"
28 |
29 | load Gem.bin_path("thor", "thor")
30 |
--------------------------------------------------------------------------------
/bin/tilt:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | # frozen_string_literal: true
3 |
4 | #
5 | # This file was generated by Bundler.
6 | #
7 | # The application 'tilt' is installed as part of a gem, and
8 | # this file is here to facilitate running it.
9 | #
10 |
11 | require "pathname"
12 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
13 | Pathname.new(__FILE__).realpath)
14 |
15 | bundle_binstub = File.expand_path("../bundle", __FILE__)
16 |
17 | if File.file?(bundle_binstub)
18 | if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
19 | load(bundle_binstub)
20 | else
21 | abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22 | Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23 | end
24 | end
25 |
26 | require "rubygems"
27 | require "bundler/setup"
28 |
29 | load Gem.bin_path("tilt", "tilt")
30 |
--------------------------------------------------------------------------------
/bin/cap:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | # frozen_string_literal: true
3 |
4 | #
5 | # This file was generated by Bundler.
6 | #
7 | # The application 'cap' is installed as part of a gem, and
8 | # this file is here to facilitate running it.
9 | #
10 |
11 | require "pathname"
12 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
13 | Pathname.new(__FILE__).realpath)
14 |
15 | bundle_binstub = File.expand_path("../bundle", __FILE__)
16 |
17 | if File.file?(bundle_binstub)
18 | if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
19 | load(bundle_binstub)
20 | else
21 | abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22 | Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23 | end
24 | end
25 |
26 | require "rubygems"
27 | require "bundler/setup"
28 |
29 | load Gem.bin_path("capistrano", "cap")
30 |
--------------------------------------------------------------------------------
/bin/guard:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | # frozen_string_literal: true
3 |
4 | #
5 | # This file was generated by Bundler.
6 | #
7 | # The application 'guard' is installed as part of a gem, and
8 | # this file is here to facilitate running it.
9 | #
10 |
11 | require "pathname"
12 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
13 | Pathname.new(__FILE__).realpath)
14 |
15 | bundle_binstub = File.expand_path("../bundle", __FILE__)
16 |
17 | if File.file?(bundle_binstub)
18 | if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
19 | load(bundle_binstub)
20 | else
21 | abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22 | Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23 | end
24 | end
25 |
26 | require "rubygems"
27 | require "bundler/setup"
28 |
29 | load Gem.bin_path("guard", "guard")
30 |
--------------------------------------------------------------------------------
/bin/ldiff:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | # frozen_string_literal: true
3 |
4 | #
5 | # This file was generated by Bundler.
6 | #
7 | # The application 'ldiff' is installed as part of a gem, and
8 | # this file is here to facilitate running it.
9 | #
10 |
11 | require "pathname"
12 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
13 | Pathname.new(__FILE__).realpath)
14 |
15 | bundle_binstub = File.expand_path("../bundle", __FILE__)
16 |
17 | if File.file?(bundle_binstub)
18 | if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
19 | load(bundle_binstub)
20 | else
21 | abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22 | Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23 | end
24 | end
25 |
26 | require "rubygems"
27 | require "bundler/setup"
28 |
29 | load Gem.bin_path("diff-lcs", "ldiff")
30 |
--------------------------------------------------------------------------------
/bin/rackup:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | # frozen_string_literal: true
3 |
4 | #
5 | # This file was generated by Bundler.
6 | #
7 | # The application 'rackup' is installed as part of a gem, and
8 | # this file is here to facilitate running it.
9 | #
10 |
11 | require "pathname"
12 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
13 | Pathname.new(__FILE__).realpath)
14 |
15 | bundle_binstub = File.expand_path("../bundle", __FILE__)
16 |
17 | if File.file?(bundle_binstub)
18 | if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
19 | load(bundle_binstub)
20 | else
21 | abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22 | Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23 | end
24 | end
25 |
26 | require "rubygems"
27 | require "bundler/setup"
28 |
29 | load Gem.bin_path("rack", "rackup")
30 |
--------------------------------------------------------------------------------
/app/assets/stylesheets/global/_variables.scss:
--------------------------------------------------------------------------------
1 | // Typography
2 | $font-family-base: "Fira Sans", sans-serif;
3 | $font-size-base: 18px;
4 | $line-height-base: 1.6;
5 |
6 | $font-size-supporting: 14px;
7 |
8 | $grid-float-breakpoint: 60em;
9 |
10 | // Colours
11 | // http://color.hailpixel.com/#FFEA8A,FFF2B8,C64E39,B15D4E,94716B,767676,467043,3E7939,308A28,
12 |
13 | $text-color: #444444;
14 |
15 | $color-lemon: #ffea8a;
16 | $color-lemon-light: #fff2b8;
17 |
18 | $color-orange: #ffbb43;
19 |
20 | $color-blue: #428bca;
21 | $color-blue-dark: #274486;
22 |
23 | $brand-primary: $color-blue;
24 |
25 | $color-for3: #308A28;
26 | $color-for2: #3E7939;
27 | $color-for1: #467043;
28 | $color-mixed-position: #767676;
29 | $color-against1: #94716B;
30 | $color-against2: #B15D4E;
31 | $color-against3: #C64E39;
32 |
33 | $color-vote-against: $color-against3;
34 | $color-vote-for: $color-for3;
35 | $color-rebel: $color-against3;
36 |
--------------------------------------------------------------------------------
/bin/capify:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | # frozen_string_literal: true
3 |
4 | #
5 | # This file was generated by Bundler.
6 | #
7 | # The application 'capify' is installed as part of a gem, and
8 | # this file is here to facilitate running it.
9 | #
10 |
11 | require "pathname"
12 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
13 | Pathname.new(__FILE__).realpath)
14 |
15 | bundle_binstub = File.expand_path("../bundle", __FILE__)
16 |
17 | if File.file?(bundle_binstub)
18 | if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
19 | load(bundle_binstub)
20 | else
21 | abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22 | Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23 | end
24 | end
25 |
26 | require "rubygems"
27 | require "bundler/setup"
28 |
29 | load Gem.bin_path("capistrano", "capify")
30 |
--------------------------------------------------------------------------------
/bin/coderay:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | # frozen_string_literal: true
3 |
4 | #
5 | # This file was generated by Bundler.
6 | #
7 | # The application 'coderay' is installed as part of a gem, and
8 | # this file is here to facilitate running it.
9 | #
10 |
11 | require "pathname"
12 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
13 | Pathname.new(__FILE__).realpath)
14 |
15 | bundle_binstub = File.expand_path("../bundle", __FILE__)
16 |
17 | if File.file?(bundle_binstub)
18 | if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
19 | load(bundle_binstub)
20 | else
21 | abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22 | Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23 | end
24 | end
25 |
26 | require "rubygems"
27 | require "bundler/setup"
28 |
29 | load Gem.bin_path("coderay", "coderay")
30 |
--------------------------------------------------------------------------------
/bin/foreman:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | # frozen_string_literal: true
3 |
4 | #
5 | # This file was generated by Bundler.
6 | #
7 | # The application 'foreman' is installed as part of a gem, and
8 | # this file is here to facilitate running it.
9 | #
10 |
11 | require "pathname"
12 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
13 | Pathname.new(__FILE__).realpath)
14 |
15 | bundle_binstub = File.expand_path("../bundle", __FILE__)
16 |
17 | if File.file?(bundle_binstub)
18 | if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
19 | load(bundle_binstub)
20 | else
21 | abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22 | Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23 | end
24 | end
25 |
26 | require "rubygems"
27 | require "bundler/setup"
28 |
29 | load Gem.bin_path("foreman", "foreman")
30 |
--------------------------------------------------------------------------------
/bin/launchy:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | # frozen_string_literal: true
3 |
4 | #
5 | # This file was generated by Bundler.
6 | #
7 | # The application 'launchy' is installed as part of a gem, and
8 | # this file is here to facilitate running it.
9 | #
10 |
11 | require "pathname"
12 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
13 | Pathname.new(__FILE__).realpath)
14 |
15 | bundle_binstub = File.expand_path("../bundle", __FILE__)
16 |
17 | if File.file?(bundle_binstub)
18 | if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
19 | load(bundle_binstub)
20 | else
21 | abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22 | Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23 | end
24 | end
25 |
26 | require "rubygems"
27 | require "bundler/setup"
28 |
29 | load Gem.bin_path("launchy", "launchy")
30 |
--------------------------------------------------------------------------------
/bin/listen:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | # frozen_string_literal: true
3 |
4 | #
5 | # This file was generated by Bundler.
6 | #
7 | # The application 'listen' is installed as part of a gem, and
8 | # this file is here to facilitate running it.
9 | #
10 |
11 | require "pathname"
12 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
13 | Pathname.new(__FILE__).realpath)
14 |
15 | bundle_binstub = File.expand_path("../bundle", __FILE__)
16 |
17 | if File.file?(bundle_binstub)
18 | if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
19 | load(bundle_binstub)
20 | else
21 | abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22 | Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23 | end
24 | end
25 |
26 | require "rubygems"
27 | require "bundler/setup"
28 |
29 | load Gem.bin_path("listen", "listen")
30 |
--------------------------------------------------------------------------------
/app/lib/card_screenshotter/policies.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module CardScreenshotter
4 | class Policies
5 | class << self
6 | include Rails.application.routes.url_helpers
7 | include PathHelper
8 |
9 | def run
10 | screenshotter = CardScreenshotter::Utils.new
11 | policies = Policy.all
12 | progress = ProgressBar.create(total: policies.count, format: "%t: |%B| %E %a")
13 | policies.each do |policy|
14 | screenshotter.screenshot_and_save(url(policy), save_path(policy))
15 | progress.increment
16 | end
17 | screenshotter.close_driver!
18 | end
19 |
20 | def url(policy)
21 | policy_url(policy, ActionMailer::Base.default_url_options.merge(card: true))
22 | end
23 |
24 | def save_path(policy)
25 | "public/cards#{policy_path(policy)}.png"
26 | end
27 | end
28 | end
29 | end
30 |
--------------------------------------------------------------------------------
/bin/bootsnap:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | # frozen_string_literal: true
3 |
4 | #
5 | # This file was generated by Bundler.
6 | #
7 | # The application 'bootsnap' is installed as part of a gem, and
8 | # this file is here to facilitate running it.
9 | #
10 |
11 | require "pathname"
12 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
13 | Pathname.new(__FILE__).realpath)
14 |
15 | bundle_binstub = File.expand_path("../bundle", __FILE__)
16 |
17 | if File.file?(bundle_binstub)
18 | if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
19 | load(bundle_binstub)
20 | else
21 | abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22 | Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23 | end
24 | end
25 |
26 | require "rubygems"
27 | require "bundler/setup"
28 |
29 | load Gem.bin_path("bootsnap", "bootsnap")
30 |
--------------------------------------------------------------------------------
/bin/htmldiff:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | # frozen_string_literal: true
3 |
4 | #
5 | # This file was generated by Bundler.
6 | #
7 | # The application 'htmldiff' is installed as part of a gem, and
8 | # this file is here to facilitate running it.
9 | #
10 |
11 | require "pathname"
12 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
13 | Pathname.new(__FILE__).realpath)
14 |
15 | bundle_binstub = File.expand_path("../bundle", __FILE__)
16 |
17 | if File.file?(bundle_binstub)
18 | if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
19 | load(bundle_binstub)
20 | else
21 | abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22 | Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23 | end
24 | end
25 |
26 | require "rubygems"
27 | require "bundler/setup"
28 |
29 | load Gem.bin_path("diff-lcs", "htmldiff")
30 |
--------------------------------------------------------------------------------
/bin/httparty:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | # frozen_string_literal: true
3 |
4 | #
5 | # This file was generated by Bundler.
6 | #
7 | # The application 'httparty' is installed as part of a gem, and
8 | # this file is here to facilitate running it.
9 | #
10 |
11 | require "pathname"
12 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
13 | Pathname.new(__FILE__).realpath)
14 |
15 | bundle_binstub = File.expand_path("../bundle", __FILE__)
16 |
17 | if File.file?(bundle_binstub)
18 | if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
19 | load(bundle_binstub)
20 | else
21 | abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22 | Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23 | end
24 | end
25 |
26 | require "rubygems"
27 | require "bundler/setup"
28 |
29 | load Gem.bin_path("httparty", "httparty")
30 |
--------------------------------------------------------------------------------
/bin/nokogiri:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | # frozen_string_literal: true
3 |
4 | #
5 | # This file was generated by Bundler.
6 | #
7 | # The application 'nokogiri' is installed as part of a gem, and
8 | # this file is here to facilitate running it.
9 | #
10 |
11 | require "pathname"
12 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
13 | Pathname.new(__FILE__).realpath)
14 |
15 | bundle_binstub = File.expand_path("../bundle", __FILE__)
16 |
17 | if File.file?(bundle_binstub)
18 | if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
19 | load(bundle_binstub)
20 | else
21 | abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22 | Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23 | end
24 | end
25 |
26 | require "rubygems"
27 | require "bundler/setup"
28 |
29 | load Gem.bin_path("nokogiri", "nokogiri")
30 |
--------------------------------------------------------------------------------
/bin/skylight:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | # frozen_string_literal: true
3 |
4 | #
5 | # This file was generated by Bundler.
6 | #
7 | # The application 'skylight' is installed as part of a gem, and
8 | # this file is here to facilitate running it.
9 | #
10 |
11 | require "pathname"
12 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
13 | Pathname.new(__FILE__).realpath)
14 |
15 | bundle_binstub = File.expand_path("../bundle", __FILE__)
16 |
17 | if File.file?(bundle_binstub)
18 | if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
19 | load(bundle_binstub)
20 | else
21 | abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22 | Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23 | end
24 | end
25 |
26 | require "rubygems"
27 | require "bundler/setup"
28 |
29 | load Gem.bin_path("skylight", "skylight")
30 |
--------------------------------------------------------------------------------
/db/migrate/20140623022321_add_confirmable_to_devise.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class AddConfirmableToDevise < ActiveRecord::Migration
4 | def self.up
5 | add_column :pw_dyn_user, :confirmation_token, :string
6 | add_column :pw_dyn_user, :confirmed_at, :datetime
7 | add_column :pw_dyn_user, :confirmation_sent_at, :datetime
8 | add_column :pw_dyn_user, :unconfirmed_email, :string
9 | add_index :pw_dyn_user, :confirmation_token, unique: true
10 |
11 | # Temporarily use old table name
12 | user_table_name = User.table_name
13 | User.table_name = "pw_dyn_user"
14 | # Update existing records
15 | User.update_all(confirmed_at: Time.now)
16 | # Reset table name
17 | User.table_name = user_table_name
18 | end
19 |
20 | def self.down
21 | remove_columns :pw_dyn_user, :confirmation_token, :confirmed_at, :confirmation_sent_at, :unconfirmed_email
22 | end
23 | end
24 |
--------------------------------------------------------------------------------
/app/controllers/admin/application_controller.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | # All Administrate controllers inherit from this
4 | # `Administrate::ApplicationController`, making it the ideal place to put
5 | # authentication logic or other before_actions.
6 | #
7 | # If you want to add pagination or other controller-level concerns,
8 | # you're free to overwrite the RESTful controller actions.
9 | module Admin
10 | class ApplicationController < Administrate::ApplicationController
11 | before_action :authenticate_admin
12 |
13 | def authenticate_admin
14 | authenticate_user!
15 | render plain: "Not authorised", status: :forbidden unless current_user.admin?
16 | end
17 |
18 | # Override this value to specify the number of elements to display at a time
19 | # on index pages. Defaults to 20.
20 | # def records_per_page
21 | # params[:per_page] || 20
22 | # end
23 | end
24 | end
25 |
--------------------------------------------------------------------------------
/app/controllers/confirmations_controller.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class ConfirmationsController < Devise::ConfirmationsController
4 | # Override Devise to automatically sign in the user
5 | # GET /resource/confirmation?confirmation_token=abcdef
6 | def show
7 | self.resource = resource_class.confirm_by_token(params[:confirmation_token])
8 | yield resource if block_given?
9 |
10 | if resource.errors.empty?
11 | set_flash_message(:notice, :confirmed) if is_flashing_format?
12 |
13 | # Was this likely an email change or a new sign up?
14 | if signed_in?(resource_name)
15 | redirect_to signed_in_root_path(resource)
16 | else
17 | sign_in(resource_name, resource)
18 | redirect_to user_welcome_path
19 | end
20 | else
21 | respond_with_navigational(resource.errors, status: :unprocessable_entity) { render :new }
22 | end
23 | end
24 | end
25 |
--------------------------------------------------------------------------------
/bin/_guard-core:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | # frozen_string_literal: true
3 |
4 | #
5 | # This file was generated by Bundler.
6 | #
7 | # The application '_guard-core' is installed as part of a gem, and
8 | # this file is here to facilitate running it.
9 | #
10 |
11 | require "pathname"
12 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
13 | Pathname.new(__FILE__).realpath)
14 |
15 | bundle_binstub = File.expand_path("../bundle", __FILE__)
16 |
17 | if File.file?(bundle_binstub)
18 | if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
19 | load(bundle_binstub)
20 | else
21 | abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22 | Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23 | end
24 | end
25 |
26 | require "rubygems"
27 | require "bundler/setup"
28 |
29 | load Gem.bin_path("guard", "_guard-core")
30 |
--------------------------------------------------------------------------------
/bin/redcarpet:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | # frozen_string_literal: true
3 |
4 | #
5 | # This file was generated by Bundler.
6 | #
7 | # The application 'redcarpet' is installed as part of a gem, and
8 | # this file is here to facilitate running it.
9 | #
10 |
11 | require "pathname"
12 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
13 | Pathname.new(__FILE__).realpath)
14 |
15 | bundle_binstub = File.expand_path("../bundle", __FILE__)
16 |
17 | if File.file?(bundle_binstub)
18 | if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
19 | load(bundle_binstub)
20 | else
21 | abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22 | Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23 | end
24 | end
25 |
26 | require "rubygems"
27 | require "bundler/setup"
28 |
29 | load Gem.bin_path("redcarpet", "redcarpet")
30 |
--------------------------------------------------------------------------------
/bin/ruby-parse:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | # frozen_string_literal: true
3 |
4 | #
5 | # This file was generated by Bundler.
6 | #
7 | # The application 'ruby-parse' is installed as part of a gem, and
8 | # this file is here to facilitate running it.
9 | #
10 |
11 | require "pathname"
12 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
13 | Pathname.new(__FILE__).realpath)
14 |
15 | bundle_binstub = File.expand_path("../bundle", __FILE__)
16 |
17 | if File.file?(bundle_binstub)
18 | if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
19 | load(bundle_binstub)
20 | else
21 | abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22 | Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23 | end
24 | end
25 |
26 | require "rubygems"
27 | require "bundler/setup"
28 |
29 | load Gem.bin_path("parser", "ruby-parse")
30 |
--------------------------------------------------------------------------------
/bin/sdoc-merge:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | # frozen_string_literal: true
3 |
4 | #
5 | # This file was generated by Bundler.
6 | #
7 | # The application 'sdoc-merge' is installed as part of a gem, and
8 | # this file is here to facilitate running it.
9 | #
10 |
11 | require "pathname"
12 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
13 | Pathname.new(__FILE__).realpath)
14 |
15 | bundle_binstub = File.expand_path("../bundle", __FILE__)
16 |
17 | if File.file?(bundle_binstub)
18 | if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
19 | load(bundle_binstub)
20 | else
21 | abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22 | Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23 | end
24 | end
25 |
26 | require "rubygems"
27 | require "bundler/setup"
28 |
29 | load Gem.bin_path("sdoc", "sdoc-merge")
30 |
--------------------------------------------------------------------------------
/bin/sprockets:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | # frozen_string_literal: true
3 |
4 | #
5 | # This file was generated by Bundler.
6 | #
7 | # The application 'sprockets' is installed as part of a gem, and
8 | # this file is here to facilitate running it.
9 | #
10 |
11 | require "pathname"
12 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
13 | Pathname.new(__FILE__).realpath)
14 |
15 | bundle_binstub = File.expand_path("../bundle", __FILE__)
16 |
17 | if File.file?(bundle_binstub)
18 | if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
19 | load(bundle_binstub)
20 | else
21 | abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22 | Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23 | end
24 | end
25 |
26 | require "rubygems"
27 | require "bundler/setup"
28 |
29 | load Gem.bin_path("sprockets", "sprockets")
30 |
--------------------------------------------------------------------------------
/bin/stackprof:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | # frozen_string_literal: true
3 |
4 | #
5 | # This file was generated by Bundler.
6 | #
7 | # The application 'stackprof' is installed as part of a gem, and
8 | # this file is here to facilitate running it.
9 | #
10 |
11 | require "pathname"
12 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
13 | Pathname.new(__FILE__).realpath)
14 |
15 | bundle_binstub = File.expand_path("../bundle", __FILE__)
16 |
17 | if File.file?(bundle_binstub)
18 | if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
19 | load(bundle_binstub)
20 | else
21 | abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22 | Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23 | end
24 | end
25 |
26 | require "rubygems"
27 | require "bundler/setup"
28 |
29 | load Gem.bin_path("stackprof", "stackprof")
30 |
--------------------------------------------------------------------------------
/bin/ruby-rewrite:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | # frozen_string_literal: true
3 |
4 | #
5 | # This file was generated by Bundler.
6 | #
7 | # The application 'ruby-rewrite' is installed as part of a gem, and
8 | # this file is here to facilitate running it.
9 | #
10 |
11 | require "pathname"
12 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
13 | Pathname.new(__FILE__).realpath)
14 |
15 | bundle_binstub = File.expand_path("../bundle", __FILE__)
16 |
17 | if File.file?(bundle_binstub)
18 | if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
19 | load(bundle_binstub)
20 | else
21 | abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22 | Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23 | end
24 | end
25 |
26 | require "rubygems"
27 | require "bundler/setup"
28 |
29 | load Gem.bin_path("parser", "ruby-rewrite")
30 |
--------------------------------------------------------------------------------
/bin/ruby_parse:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | # frozen_string_literal: true
3 |
4 | #
5 | # This file was generated by Bundler.
6 | #
7 | # The application 'ruby_parse' is installed as part of a gem, and
8 | # this file is here to facilitate running it.
9 | #
10 |
11 | require "pathname"
12 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
13 | Pathname.new(__FILE__).realpath)
14 |
15 | bundle_binstub = File.expand_path("../bundle", __FILE__)
16 |
17 | if File.file?(bundle_binstub)
18 | if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
19 | load(bundle_binstub)
20 | else
21 | abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22 | Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23 | end
24 | end
25 |
26 | require "rubygems"
27 | require "bundler/setup"
28 |
29 | load Gem.bin_path("ruby_parser", "ruby_parse")
30 |
--------------------------------------------------------------------------------
/bin/honeybadger:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | # frozen_string_literal: true
3 |
4 | #
5 | # This file was generated by Bundler.
6 | #
7 | # The application 'honeybadger' is installed as part of a gem, and
8 | # this file is here to facilitate running it.
9 | #
10 |
11 | require "pathname"
12 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
13 | Pathname.new(__FILE__).realpath)
14 |
15 | bundle_binstub = File.expand_path("../bundle", __FILE__)
16 |
17 | if File.file?(bundle_binstub)
18 | if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
19 | load(bundle_binstub)
20 | else
21 | abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22 | Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23 | end
24 | end
25 |
26 | require "rubygems"
27 | require "bundler/setup"
28 |
29 | load Gem.bin_path("honeybadger", "honeybadger")
30 |
--------------------------------------------------------------------------------
/bin/mongrel_rpm:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | # frozen_string_literal: true
3 |
4 | #
5 | # This file was generated by Bundler.
6 | #
7 | # The application 'mongrel_rpm' is installed as part of a gem, and
8 | # this file is here to facilitate running it.
9 | #
10 |
11 | require "pathname"
12 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
13 | Pathname.new(__FILE__).realpath)
14 |
15 | bundle_binstub = File.expand_path("../bundle", __FILE__)
16 |
17 | if File.file?(bundle_binstub)
18 | if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
19 | load(bundle_binstub)
20 | else
21 | abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22 | Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23 | end
24 | end
25 |
26 | require "rubygems"
27 | require "bundler/setup"
28 |
29 | load Gem.bin_path("newrelic_rpm", "mongrel_rpm")
30 |
--------------------------------------------------------------------------------
/app/views/devise/sessions/new.html.haml:
--------------------------------------------------------------------------------
1 | - content_for :title, "Log in"
2 |
3 | .thin-page
4 | %h1.long-title= yield :title
5 |
6 | = simple_form_for(resource, as: resource_name, url: session_path(resource_name), html: {class: "login-form"}) do |f|
7 | = f.error_notification
8 |
9 | .form-group= f.input :email, as: :email, autofocus: true
10 | .form-group= f.input :password
11 |
12 | - if devise_mapping.rememberable?
13 | .checkbox
14 | %label
15 | = f.check_box :remember_me
16 | Remember me
17 |
18 | = f.submit "Log in", class: "btn btn-primary btn-wide"
19 |
20 | %ul.form-secondary.nav.nav-pills
21 | %li= link_to 'Sign up for a new account', new_registration_path(resource_name), class: "btn-xs"
22 | %li= link_to 'Forgotten your password?', new_password_path(resource_name), class: "btn-xs"
23 | %li= link_to 'Resend confirmation', new_user_confirmation_path, class: 'btn-xs'
24 |
--------------------------------------------------------------------------------
/app/views/divisions/_summary_table.html.haml:
--------------------------------------------------------------------------------
1 | %table.table
2 | %colgroup.column-name{span: 1}
3 | %colgroup.column-vote{span: 1}
4 | %colgroup.column-toggler{span: 1}
5 | %thead
6 | %tr
7 | %th Party
8 | %th.cell-vote Votes
9 | %th.cell-toggler
10 | %tbody
11 | - whips.each do |whip|
12 | = render 'summary_whip', whip: whip, votes: votes, members_vote_null: members_vote_null
13 |
14 | %tr
15 | %th.whip
16 | Totals
17 | %small.post-title.text-muted= '(' + fraction_to_percentage_display(division.attendance_fraction) + ' turnout)'
18 | %td.cell-vote
19 | %span{class: aye_vote_total_class(division)}
20 | = division.aye_votes_including_tells
21 | = vote_display "aye"
22 | –
23 | %span{class: no_vote_total_class(division)}
24 | = division.no_votes_including_tells
25 | = vote_display "no"
26 | %td.cell-toggler
27 |
--------------------------------------------------------------------------------
/app/views/people_distances/_summary_vote_numbers.html.haml:
--------------------------------------------------------------------------------
1 | %p
2 | - if person_distance.nvotesdiffer > person_distance.nvotessame
3 | = succeed "." do
4 | In divisions they have voted differently
5 | = number_of_times(person_distance.nvotesdiffer)
6 | = succeed "." do
7 | - if person_distance.nvotessame.zero?
8 | They have
9 | %strong never voted the same
10 | - else
11 | They have only voted
12 | %strong= "the same #{number_of_times(person_distance.nvotessame)}"
13 | - else
14 | = succeed "." do
15 | In divisions they have voted the same
16 | = number_of_times(person_distance.nvotessame)
17 | = succeed "." do
18 | - if person_distance.nvotesdiffer.zero?
19 | They have
20 | %strong never voted differently
21 | - else
22 | They have only voted
23 | %strong= "differently #{number_of_times(person_distance.nvotesdiffer)}"
24 |
--------------------------------------------------------------------------------
/.github/stale.yml:
--------------------------------------------------------------------------------
1 | # Number of days of inactivity before an issue becomes stale
2 | daysUntilStale: 180
3 | # Number of days of inactivity before a stale issue is closed
4 | daysUntilClose: 7
5 | # Issues with these labels will never be considered stale
6 | exemptLabels:
7 | - pinned
8 | - security
9 | # Label to use when marking an issue as stale
10 | staleLabel: wontfix
11 | # Comment to post when marking an issue as stale. Set to `false` to disable
12 | markComment: >
13 | This issue has been automatically marked as stale because there has been no
14 | activity on it for about six months. If you want to keep it open please make a comment
15 | and explain why this issue is still relevant. Otherwise it will be
16 | automatically closed in a week. Thank you!
17 | # Comment to post when closing a stale issue. Set to `false` to disable
18 | closeComment: false
19 | # Limit the number of actions per hour, from 1-30. Default is 30
20 | limitPerRun: 1
21 |
--------------------------------------------------------------------------------
/app/views/policies/_vote_summary_table.html.haml:
--------------------------------------------------------------------------------
1 | %table.table.divisions-table
2 | %thead
3 | %tr
4 | %th Division
5 | - people.each do |person|
6 | %th= person.name
7 | %th.policyvotehead Supporters vote
8 | %tbody
9 | - if policy_divisions.empty?
10 | %tr
11 | %td{colspan: 7} no votes listed
12 | - else
13 | - policy_divisions.each do |pd|
14 | %tr
15 | %td
16 | %h3.division-title.h4
17 | %small.pre-title= division_date_and_time(pd.division) + " – " + pd.division.house_name
18 | = link_to(pd.division.name, division_path_simple(pd.division))
19 | - people.each do |person|
20 | %td.division-member-vote{data: {member: "#{person.name}"}}
21 | = vote_display(pd.division.vote_for_person(person))
22 | %td.division-policy-vote
23 | = vote_display(PolicyDivision.vote_without_strong(pd.vote))
24 |
--------------------------------------------------------------------------------
/app/views/policies/how_the_number_is_calculated/_not_enough.html.haml:
--------------------------------------------------------------------------------
1 | - if policy_person_distance.number_of_votes.zero?
2 | %p
3 | Normally a person's votes count towards a score which is used to work out a simple
4 | phrase to summarise their position on a policy. However in this case
5 | = policy_person_distance.person.name
6 | was absent during all divisions for this policy. So, it's impossible to say anything concrete.
7 | - else
8 | %p
9 | = policy_person_distance.person.name
10 | has only voted once on this policy and it wasn't on a "strong" vote. So it's not possible to draw a clear conclusion about their position.
11 | %p
12 | This could be because there were simply not many relevant divisions (formal votes) during the time they've been in parliament (most votes
13 | happen on "the voices", so we simply have no decent record) or they were absent for votes that could have contributed to
14 | their voting record.
15 |
--------------------------------------------------------------------------------
/bin/update:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | require 'fileutils'
3 | include FileUtils
4 |
5 | # path to your application root.
6 | APP_ROOT = File.expand_path('..', __dir__)
7 |
8 | def system!(*args)
9 | system(*args) || abort("\n== Command #{args} failed ==")
10 | end
11 |
12 | chdir APP_ROOT do
13 | # This script is a way to update your development environment automatically.
14 | # Add necessary update steps to this file.
15 |
16 | puts '== Installing dependencies =='
17 | system! 'gem install bundler --conservative'
18 | system('bundle check') || system!('bundle install')
19 |
20 | # Install JavaScript dependencies if using Yarn
21 | # system('bin/yarn')
22 |
23 | puts "\n== Updating database =="
24 | system! 'bin/rails db:migrate'
25 |
26 | puts "\n== Removing old logs and tempfiles =="
27 | system! 'bin/rails log:clear tmp:clear'
28 |
29 | puts "\n== Restarting application server =="
30 | system! 'bin/rails restart'
31 | end
32 |
--------------------------------------------------------------------------------
/app/assets/javascripts/application.js:
--------------------------------------------------------------------------------
1 | // This is a manifest file that'll be compiled into application.js, which will include all the files
2 | // listed below.
3 | //
4 | // Any JavaScript file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
5 | // or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
6 | //
7 | // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8 | // compiled file.
9 | //
10 | // Read Sprockets README (https://github.com/sstephenson/sprockets#sprockets-directives) for details
11 | // about supported directives.
12 | //
13 | //= require jquery
14 | //= require bootstrap-sprockets
15 | //= require jquery_ujs
16 | //= require marked
17 | //= require jquery.widowFix-1.3.2
18 | //= require jquery.lazyload
19 | //= require bootstrap-accessibility
20 | //= require modernizr_custom
21 | //= require bootstrap-select
22 | //= require_tree .
23 |
--------------------------------------------------------------------------------
/app/views/api/v1/policies/show.json.jbuilder:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | json.partial! "policy", policy: @policy
4 |
5 | # More detailed information
6 | json.policy_divisions do
7 | json.array! @policy.policy_divisions.includes(division: %i[wiki_motions whips division_info]) do |pd|
8 | json.division do
9 | json.partial! "api/v1/divisions/division", division: pd.division
10 | end
11 | json.vote PolicyDivision.vote_without_strong(pd.vote)
12 | json.strong pd.strong_vote?
13 | end
14 | end
15 |
16 | json.people_comparisons do
17 | json.array! @policy.policy_person_distances.includes(person: :members).order(:distance_a) do |ppd|
18 | json.person do
19 | json.partial! "api/v1/people/person", person: ppd.person
20 | end
21 | json.agreement number_with_precision(ppd.agreement_fraction * 100, precision: 2, significant: true)
22 | json.voted ppd.voted?
23 | json.category ppd.category
24 | end
25 | end
26 |
--------------------------------------------------------------------------------
/app/views/help/faq/_rebel.md:
--------------------------------------------------------------------------------
1 | An MP or Senator rebels by voting against the
2 | [party whip](https://peo.gov.au/understand-our-parliament/parliament-and-its-people/people-in-parliament/party-whip/). This is known as
3 | [crossing the floor](https://peo.gov.au/understand-our-parliament/how-parliament-works/parliament-at-work/crossing-the-floor/).
4 |
5 | Currently in the Australian Federal Parliament MPs and Senators nearly always vote along party lines.
6 |
7 | Labor party members are not allowed to rebel. In the Liberal party
8 | backbenchers are officially allowed to rebel but this is becoming increasingly uncommon in practise.
9 |
10 | For more on the rules of the different political parties around rebellions see this 2002 Issues Brief from the Parliamentary library "[Free Votes in Australian and some Overseas Parliaments](http://www.aph.gov.au/About_Parliament/Parliamentary_Departments/Parliamentary_Library/Publications_Archive/CIB/cib0203/03CIB01#votes)"
11 |
--------------------------------------------------------------------------------
/bin/reverse_markdown:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | # frozen_string_literal: true
3 |
4 | #
5 | # This file was generated by Bundler.
6 | #
7 | # The application 'reverse_markdown' is installed as part of a gem, and
8 | # this file is here to facilitate running it.
9 | #
10 |
11 | require "pathname"
12 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
13 | Pathname.new(__FILE__).realpath)
14 |
15 | bundle_binstub = File.expand_path("../bundle", __FILE__)
16 |
17 | if File.file?(bundle_binstub)
18 | if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
19 | load(bundle_binstub)
20 | else
21 | abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22 | Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23 | end
24 | end
25 |
26 | require "rubygems"
27 | require "bundler/setup"
28 |
29 | load Gem.bin_path("reverse_markdown", "reverse_markdown")
30 |
--------------------------------------------------------------------------------
/bin/elastic_ruby_console:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | # frozen_string_literal: true
3 |
4 | #
5 | # This file was generated by Bundler.
6 | #
7 | # The application 'elastic_ruby_console' is installed as part of a gem, and
8 | # this file is here to facilitate running it.
9 | #
10 |
11 | require "pathname"
12 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
13 | Pathname.new(__FILE__).realpath)
14 |
15 | bundle_binstub = File.expand_path("../bundle", __FILE__)
16 |
17 | if File.file?(bundle_binstub)
18 | if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
19 | load(bundle_binstub)
20 | else
21 | abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22 | Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23 | end
24 | end
25 |
26 | require "rubygems"
27 | require "bundler/setup"
28 |
29 | load Gem.bin_path("elasticsearch", "elastic_ruby_console")
30 |
--------------------------------------------------------------------------------
/spec/features/user_profile_spec.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require "spec_helper"
4 |
5 | describe "User profile", type: :feature do
6 | before do
7 | create(:member)
8 | end
9 |
10 | let(:user) { create(:user, confirmed_at: Time.zone.now) }
11 |
12 | it "changing name without changing password" do
13 | visit "/"
14 | click_on "Log in"
15 | within "#new_user" do
16 | fill_in "Email", with: user.email
17 | fill_in "Password", with: user.password
18 | click_on "Log in"
19 | end
20 | expect(page).to have_content "Welcome!"
21 | click_on "Edit profile"
22 | within "#edit_user" do
23 | fill_in "Username", with: "Henare Degan, Esquire"
24 | fill_in "Current password", with: user.password
25 | end
26 | click_on "Update"
27 | expect(page).to have_content "You updated your account successfully."
28 | expect(user.reload.name).to eql "Henare Degan, Esquire"
29 | end
30 | end
31 |
--------------------------------------------------------------------------------
/app/views/people_distances/_divisions_same.html.haml:
--------------------------------------------------------------------------------
1 | - if person_distance.nvotessame.positive?
2 | %section.page-section
3 | %h2 Divisions in which they voted the same
4 | = render "summary_vote_numbers", person_distance: @person_distance
5 | %ol.divisions-list.list-unstyled{class: active_house_for_list_class(nil)}
6 | - person_distance.divisions_same.order(date: :desc, clock_time: :desc, name: :asc).each do |division|
7 | -# Doing this terrible hack because some divisions (e.g. representatives/2018-12-04/1) have votes for Julia Bank attached to the wrong member. The votes are attached to the member before she changed party and became independent.
8 | - member1 = person_distance.person1.members.find {|m| !m.division_vote(division).nil? }
9 | - member2 = person_distance.person2.members.find {|m| !m.division_vote(division).nil? }
10 | = render 'divisions/division', members: [member1, member2], house: nil, division: division
11 |
--------------------------------------------------------------------------------
/bin/stackprof-flamegraph.pl:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | # frozen_string_literal: true
3 |
4 | #
5 | # This file was generated by Bundler.
6 | #
7 | # The application 'stackprof-flamegraph.pl' is installed as part of a gem, and
8 | # this file is here to facilitate running it.
9 | #
10 |
11 | require "pathname"
12 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
13 | Pathname.new(__FILE__).realpath)
14 |
15 | bundle_binstub = File.expand_path("../bundle", __FILE__)
16 |
17 | if File.file?(bundle_binstub)
18 | if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
19 | load(bundle_binstub)
20 | else
21 | abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22 | Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23 | end
24 | end
25 |
26 | require "rubygems"
27 | require "bundler/setup"
28 |
29 | load Gem.bin_path("stackprof", "stackprof-flamegraph.pl")
30 |
--------------------------------------------------------------------------------
/bin/stackprof-gprof2dot.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | # frozen_string_literal: true
3 |
4 | #
5 | # This file was generated by Bundler.
6 | #
7 | # The application 'stackprof-gprof2dot.py' is installed as part of a gem, and
8 | # this file is here to facilitate running it.
9 | #
10 |
11 | require "pathname"
12 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
13 | Pathname.new(__FILE__).realpath)
14 |
15 | bundle_binstub = File.expand_path("../bundle", __FILE__)
16 |
17 | if File.file?(bundle_binstub)
18 | if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
19 | load(bundle_binstub)
20 | else
21 | abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22 | Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23 | end
24 | end
25 |
26 | require "rubygems"
27 | require "bundler/setup"
28 |
29 | load Gem.bin_path("stackprof", "stackprof-gprof2dot.py")
30 |
--------------------------------------------------------------------------------
/bin/ruby_parse_extract_error:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | # frozen_string_literal: true
3 |
4 | #
5 | # This file was generated by Bundler.
6 | #
7 | # The application 'ruby_parse_extract_error' is installed as part of a gem, and
8 | # this file is here to facilitate running it.
9 | #
10 |
11 | require "pathname"
12 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
13 | Pathname.new(__FILE__).realpath)
14 |
15 | bundle_binstub = File.expand_path("../bundle", __FILE__)
16 |
17 | if File.file?(bundle_binstub)
18 | if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
19 | load(bundle_binstub)
20 | else
21 | abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22 | Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23 | end
24 | end
25 |
26 | require "rubygems"
27 | require "bundler/setup"
28 |
29 | load Gem.bin_path("ruby_parser", "ruby_parse_extract_error")
30 |
--------------------------------------------------------------------------------