diff --git a/.gitignore b/.gitignore index 34376c2..568590b 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ .bundle/config /.ruby-gemset /tmp/ +_* diff --git a/bin/build b/bin/build new file mode 100755 index 0000000..d72bbed --- /dev/null +++ b/bin/build @@ -0,0 +1,292 @@ +#!/usr/bin/env ruby +# Generate a static site +require 'logger' +require 'haml' +require_relative '../models' + +OUTPUT_DIR = '_site' +VIEWS_DIR = File.join('..', 'views') +LAYOUT_FN = File.join(VIEWS_DIR, 'layout.haml') + +@log = Logger.new($stdout) +@log.level = Logger::INFO +@log.info "Build starts." +@log.info "Output directory is: #{OUTPUT_DIR}" + +class String + def pluralize(num) + if num == 1 + return self + end + + case self[-1] + when 'y' + self[0..-2] + 'ies' + when 's' + self + "es" + else + self + "s" + end + end +end + +def commify(num) + num.to_s.reverse.gsub(/(\d\d\d)(?=\d)(?!\d*\.)/,'\1,').reverse +end + +# From http://snippets.dzone.com/posts/show/593 +def to_ordinal(num) + num = num.to_i + if (10...20) === num + "#{num}th" + else + g = %w{ th st nd rd th th th th th th } + a = num.to_s + c = a[-1..-1].to_i + a + g[c] + end +end + +def format_percent(num) + sprintf("%.0f%%", num) +end + +def short_date(d) + d.strftime("%e %b %Y") +end + +def long_date(d) + d.strftime("%e %B %Y") +end + +# Exception for Labour/Co-operative candidacies +def party_name(labcoop, party_name) + labcoop ? "Labour and Co-operative Party" : party_name +end + +def write_page(path_items, template, locals = {}) + dir = File.join(path_items) + FileUtils.mkdir_p(dir) + @log.debug dir + fn = File.join(dir, 'index.html') + + # https://stackoverflow.com/questions/6125265/using-layouts-in-haml-files-independently-of-rails + html = Haml::Engine.new(File.read(LAYOUT_FN)).render do + Haml::Engine.new(File.read(File.join(VIEWS_DIR, "#{template}.haml"))).render(Object.new, locals) + end + + File.write(fn, html) + @log.info fn + # TODO - add page to sitemap.xml or sitemap.txt + # https://support.google.com/webmasters/answer/183668?hl=en&ref_topic=4581190 +end + +test_dir = File.join(Dir.pwd, OUTPUT_DIR) +# FIXME - clear output directory at the start of every run +# FileUtils.rm_rf(test_dir) + +Dir.mkdir(test_dir) unless File.directory?(test_dir) +Dir.chdir(test_dir) + +# Copy `public` dir to output dir +FileUtils.copy_entry(File.join('..', 'public'), '.') + +# Home page +locals = { + future_elections: Election.future, + past_elections: Election.past +} +write_page('.', 'index', locals) + +# Election pages +Election.each do |e| + locals = { + body: Body.first(:slug => e.body.slug), + election: Election.first(:body => e.body, :d => e.d), + elections_for_this_body: Election.all(:body => e.body, :order => [:d]), + total_seats: Candidacy.sum(:seats, :election => e), + total_votes: Candidacy.sum(:votes, :election => e) + } + + # There's got to be a better way to do this, either with SQL or Datamapper + locals['total_districts'] = repository(:default).adapter.select(" + SELECT district_id + FROM candidacies + WHERE election_id = ? + GROUP BY district_id + ORDER BY district_id + ", e.id).count + + locals['results_by_party'] = repository(:default).adapter.select(" + SELECT + p.colour, + p.name, + SUM(c.votes) AS votez, + SUM(c.seats) AS seatz, + COUNT(*) AS cands + + FROM candidacies c + + LEFT JOIN parties p ON p.id = c.party_id + + WHERE c.election_id = ? + + GROUP BY c.party_id, p.colour, p.name + + ORDER BY seatz DESC, votez DESC + ", e.id) + + write_page(['bodies', e.body.slug, 'elections', e.d.to_s], 'electionsummary', locals) + + + # District results for this election (resultsdistrict) + # Loop through all districts in this election + e.candidacies.districts.each do |d| + total_seats = Candidacy.sum(:seats, :district => d, :election => e) + total_votes = Candidacy.sum(:votes, :district => d, :election => e) + poll = Poll.get(d.id, e.id) + + locals = { + district: d, + body: d.body, + election: e, + candidacies: Candidacy.all(:district => d, :election => e, :order => [:position]), + total_votes: total_votes, + total_candidates: Candidacy.count(:district => d, :election => e), + total_seats: total_seats, + districts_in_this_election: e.candidacies.districts, + poll: poll + } + + locals['share_message'] = nil + if total_seats == 1 + locals['share_denominator'] = total_votes + elsif poll && poll.valid_ballot_papers + locals['share_denominator'] = poll.valid_ballot_papers + else + locals['share_denominator'] = total_votes / total_seats + locals['share_message'] = "The vote share percentages have been estimated as we don't have data for the number of valid ballot papers in this poll." + end + + # Postgres: All the columns selected when using GROUP BY must either be aggregate functions or appear in the GROUP BY clause + locals['results_by_party'] = repository(:default).adapter.select(" + SELECT + p.name AS party_name, + p.colour AS party_colour, + COUNT(c.id) AS num_candidates, + SUM(c.seats) AS num_seats, + SUM(c.votes) AS total_votes + + FROM candidacies c + + LEFT JOIN parties p + ON c.party_id = p.id + + WHERE c.district_id = ? + AND c.election_id = ? + + GROUP BY p.name, p.colour + + ORDER BY total_votes DESC + ", d.id, e.id) + + write_page(['bodies', e.body.slug, 'elections', e.d.to_s, e.body.districts_name, d.slug], 'resultsdistrict', locals) + end +end + +# Candidate index +locals = { candidates: Candidate.all(:order => [ :surname, :forenames ]) } +write_page('candidates', 'candidates', locals) + +# Candidate pages +# FIXME: What do we do about deleted candidates/redirects? +Candidate.each do |c| + locals = { + candidate: c + } + + locals['candidacies'] = repository(:default).adapter.select(" + SELECT + e.d, + c.*, + p.name AS party_name, + p.colour AS party_colour, + b.name AS body_name, + b.slug AS body_slug, + b.districts_name AS districts_name, + d.name AS district_name, + d.slug AS district_slug + + FROM candidacies c + + INNER JOIN elections e + ON c.election_id = e.id + + INNER JOIN parties p + ON c.party_id = p.id + + INNER JOIN bodies b + ON e.body_id = b.id + + INNER JOIN districts d + ON c.district_id = d.id + + WHERE c.candidate_id = ? + + ORDER BY d + ", c.id) + + write_page(['candidates', c.id.to_s], 'candidate', locals) +end + +# Bodies index +dir = 'bodies' +FileUtils.mkdir_p(dir) +@log.debug dir +fn = File.join(dir, 'index.html') +FileUtils.touch(fn) # empty file +@log.info fn + +# Body detail pages +Body.each do |b| + locals = { + body: b, + districts: District.all(:body => b, :order => [:name]) + } + + locals['elections'] = repository(:default).adapter.select(" + SELECT + e.id, + e.kind, + e.d, + SUM(p.ballot_papers_issued)::float / SUM(p.electorate) * 100 AS turnout_percent + + FROM elections e + + LEFT JOIN polls p + ON e.id = p.election_id + + WHERE e.body_id = ? + + GROUP BY p.election_id, e.id + ORDER BY e.d DESC + ", b.id) + + write_page(['bodies', b.slug], 'body', locals) + + # Districts for this body + b.districts.each do |d| + locals = { + district: d, + body: b + } + write_page(['bodies', b.slug, b.districts_name, d.slug], 'district', locals) + end +end + +write_page('about', 'about') +write_page('guides', 'guides') +write_page(%w(guides how-the-parliament-election-works), 'parliament') +write_page(%w(guides how-the-council-election-works), 'election') + +@log.info "Build complete." diff --git a/views/body.haml b/views/body.haml index 086d5b2..5f95173 100644 --- a/views/body.haml +++ b/views/body.haml @@ -1,4 +1,4 @@ -%h1= @page_title = @body.name +%h1= page_title = body.name %h2 Elections @@ -8,10 +8,10 @@ %th %th %th turnout - - @elections.each do |election| + - elections.each do |election| %tr %td - %a{ :href => "/bodies/#{@body.slug}/elections/#{election.d}" }< + %a{ :href => "/bodies/#{body.slug}/elections/#{election.d}" }< = short_date(election.d) %td = election.kind @@ -20,9 +20,9 @@ = format_percent(election.turnout_percent) %h2 - = @body.districts_name.capitalize + = body.districts_name.capitalize -- @districts.each do |district| +- districts.each do |district| %p - %a{ :href => "/bodies/#{@body.slug}/#{@body.districts_name}/#{district.slug}" } + %a{ :href => "/bodies/#{body.slug}/#{body.districts_name}/#{district.slug}" } = district.name diff --git a/views/candidate.haml b/views/candidate.haml index c36e0bc..215cc0c 100644 --- a/views/candidate.haml +++ b/views/candidate.haml @@ -2,7 +2,7 @@ %a{ :href => "/candidates" } « All candidates -%h1= @page_title = @candidate.name +%h1= page_title = candidate.name %h2 Elections contested @@ -17,7 +17,7 @@ %th position %th   - - @candidacies.each do |ccy| + - candidacies.each do |ccy| %tr %td{ :style => "background-color: #{ccy['party_colour']}" }   %td @@ -46,6 +46,6 @@ %p Some candidates have more than one profile page due to them using slightly different names in different elections. See the full - %a{ :href => "/candidates/##{@candidate.surname[0]}" }< + %a{ :href => "/candidates/##{candidate.surname[0]}" }< candidates list for details. diff --git a/views/candidates.haml b/views/candidates.haml index 419e198..2c9343f 100644 --- a/views/candidates.haml +++ b/views/candidates.haml @@ -1,21 +1,21 @@ -%h1= @page_title = "Candidates" +%h1= page_title = "Candidates" %nav.letter_index - ("A".."Z").each do |letter| %a{ :href => "##{letter}" }< = letter -- @first_letter = '' +- first_letter = '' %table - - @candidates.each do |c| - - if c.surname[0] != @first_letter - - @first_letter = c.surname[0] + - candidates.each do |c| + - if c.surname[0] != first_letter + - first_letter = c.surname[0] %tr.noborder %td   %td - %tr.noborder{ :name => @first_letter, :id => @first_letter } - %td.strong{ :style => "font-size: 300%;" }= @first_letter.upcase + %tr.noborder{ :name => first_letter, :id => first_letter } + %td.strong{ :style => "font-size: 300%;" }= first_letter.upcase %td %tr %td diff --git a/views/district.haml b/views/district.haml index 937e9b6..a4bf1be 100644 --- a/views/district.haml +++ b/views/district.haml @@ -1,26 +1,26 @@ -- @page_title = "#{@district.name} #{@district.body.district_name}, #{@district.body.name}" +- page_title = "#{district.name} #{district.body.district_name}, #{district.body.name}" %nav - %a{ :href => "/bodies/#{@district.body.slug}" } + %a{ :href => "/bodies/#{district.body.slug}" } «  - = @district.body.name + = district.body.name -%h1= "#{@district.name} #{@district.body.district_name}" +%h1= "#{district.name} #{district.body.district_name}" -# - - @election = Election.get(9) # FIXME magic number + - election = Election.get(9) # FIXME magic number %h2 - = @district.name + = district.name ward candidates for the - %a{ :href => "/bodies/#{@election.body.slug}/elections/#{@election.d}"} - = @election.body.name + %a{ :href => "/bodies/#{election.body.slug}/elections/#{election.d}"} + = election.body.name election on - = long_date(@election.d) + = long_date(election.d) %table - - Candidacy.all(:election => @election, :district => @district, :order => [:party_id]).each do |c| - - campaign = Campaign.first(:party => c.party, :election => @election) + - Candidacy.all(:election => election, :district => district, :order => [:party_id]).each do |c| + - campaign = Campaign.first(:party => c.party, :election => election) %tr.vcard %td{ :style => "background-color: #{c.party.colour}" }   %td.candidate_name.fn @@ -42,12 +42,12 @@ %h2 Candidates elected -- Election.all(:body => @district.body, :order => [:d.desc]).each do |election| - - ccys = Candidacy.all(:election_id => election.id, :district_id => @district.id, :seats => 1, :order => [:votes.desc]) +- Election.all(:body => district.body, :order => [:d.desc]).each do |election| + - ccys = Candidacy.all(:election_id => election.id, :district_id => district.id, :seats => 1, :order => [:votes.desc]) - unless ccys == [] %h3 - %a{ :href => "/bodies/#{@district.body.slug}/elections/#{election.d}/#{election.body.districts_name}/#{@district.slug}"} + %a{ :href => "/bodies/#{district.body.slug}/elections/#{election.d}/#{election.body.districts_name}/#{district.slug}"} = long_date election.d = election.kind diff --git a/views/election.haml b/views/election.haml index 36147e0..7fbd89f 100644 --- a/views/election.haml +++ b/views/election.haml @@ -19,5 +19,3 @@ %p If a political party gets 28 or more councillors they get to run Sutton Council and decide its policies and services. %p If no party gets 28 councillors the parties have to agree among themselves who will run the council. This is called “no overall control”. - -= haml :register, :layout => false diff --git a/views/electionsummary.haml b/views/electionsummary.haml index caf3c94..1affbc4 100644 --- a/views/electionsummary.haml +++ b/views/electionsummary.haml @@ -1,66 +1,66 @@ -- @page_title = "#{@election.body.name} #{@election.kind} #{long_date(@election.d)}" +- page_title = "#{election.body.name} #{election.kind} #{long_date(election.d)}" %nav - %a{ :href => "/bodies/#{@election.body.slug}" } + %a{ :href => "/bodies/#{election.body.slug}" } « - = @election.body.name + = election.body.name - - if @elections_for_this_body.size > 1 + - if elections_for_this_body.size > 1 %p - - @election_index = @elections_for_this_body.index(@election) + - election_index = elections_for_this_body.index(election) - - unless @election_index == 0 - - @previous_election = @elections_for_this_body[@election_index - 1] - %a{ :href => "/bodies/#{@election.body.slug}/elections/#{@previous_election.d}", :title => "#{@previous_election.kind} #{short_date(@previous_election.d)}" } + - unless election_index == 0 + - previous_election = elections_for_this_body[election_index - 1] + %a{ :href => "/bodies/#{election.body.slug}/elections/#{previous_election.d}", :title => "#{previous_election.kind} #{short_date(previous_election.d)}" } « Previous - = @election.body.name + = election.body.name election     - - unless @election_index == @elections_for_this_body.size - 1 - - @next_election = @elections_for_this_body[@election_index + 1] - %a{ :href => "/bodies/#{@election.body.slug}/elections/#{@next_election.d}", :title => "#{@next_election.kind} #{short_date(@next_election.d)}" } + - unless election_index == elections_for_this_body.size - 1 + - next_election = elections_for_this_body[election_index + 1] + %a{ :href => "/bodies/#{election.body.slug}/elections/#{next_election.d}", :title => "#{next_election.kind} #{short_date(next_election.d)}" } Next - = @election.body.name + = election.body.name election » %h1 - = @election.body.name - = @election.kind + = election.body.name + = election.kind %br - = long_date(@election.d) + = long_date(election.d) -# Does this election have any recorded votes, i.e. has it been held? -- @election_held = Candidacy.sum(:votes, :election => @election) +- election_held = Candidacy.sum(:votes, :election => election) -- unless @election_held +- unless election_held .warning We don't have the results for this election yet. -%p= @polling_station +-# %p= polling_station -%p= @election.reason +%p= election.reason %p - = @election.candidacies.count - = "candidate".pluralize(@election.candidacies.count) - - if @election_held + = election.candidacies.count + = "candidate".pluralize(election.candidacies.count) + - if election_held contested - else will be contesting -# We can't calculate the number of seats being contested if the election hasn't been held - - if @election_held - = @total_seats - = "seat".pluralize(@total_seats) + - if election_held + = total_seats + = "seat".pluralize(total_seats) in - = @total_districts - = @election.body.district_name.pluralize(@total_districts) + = total_districts + = election.body.district_name.pluralize(total_districts) in Sutton. -- if @election_held +- if election_held %table %tr.header @@ -69,69 +69,69 @@ %th.highlight seats won %th votes %th % votes - - if @total_seats > 1 + - if total_seats > 1 %th % seats %th votes per seat %th candidates %th votes per candidate -# %th relative popularity - - @max_votes_per_candidate = @results_by_party.first.votez.to_f / @results_by_party.first.cands.to_f # We really need to scan the array for the max value - - @results_by_party.each do |row| + - max_votes_per_candidate = results_by_party.first.votez.to_f / results_by_party.first.cands.to_f # We really need to scan the array for the max value + - results_by_party.each do |row| %tr %td{ :style => "background-color: #{row.colour}" }   %td.data_party= row.name %td.data_seats.right.highlight= row.seatz %td.data_votes.right= commify(row.votez) - - if @election_held - %td.right= format_percent(row.votez.to_f / @total_votes * 100) - - if @total_seats > 1 - %td.right= format_percent(row.seatz.to_f / @total_seats * 100) + - if election_held + %td.right= format_percent(row.votez.to_f / total_votes * 100) + - if total_seats > 1 + %td.right= format_percent(row.seatz.to_f / total_seats * 100) %td.data_votes_per_seat.right - if row.seatz > 0 = commify(row.votez / row.seatz) - else — %td.data_candidates.right= row.cands - - if @election_held && @total_seats > 1 + - if election_held && total_seats > 1 %td.right= commify(row.votez / row.cands) -# - %td.right= format_percent( ( row.votez.to_f / row.cands.to_f ) / @max_votes_per_candidate * 100) + %td.right= format_percent( ( row.votez.to_f / row.cands.to_f ) / max_votes_per_candidate * 100) %tr.footer %td   %td   - %td.right.highlight= @total_seats - %td.right= commify(@total_votes) + %td.right.highlight= total_seats + %td.right= commify(total_votes) %td   - - if @total_seats > 1 + - if total_seats > 1 %td   %td   - %td.right= commify(@election.candidacies.count) + %td.right= commify(election.candidacies.count) %td   - - if @election.ballot_papers_issued + - if election.ballot_papers_issued %table %tr %td Electorate - %td.right= commify(@election.electorate) + %td.right= commify(election.electorate) %tr %td Ballot papers issued - %td.right= commify(@election.ballot_papers_issued) + %td.right= commify(election.ballot_papers_issued) %tr %td Turnout - %td.right= sprintf("%.0f%%", @election.ballot_papers_issued / @election.electorate.to_f * 100) + %td.right= sprintf("%.0f%%", election.ballot_papers_issued / election.electorate.to_f * 100) %h2 - = "Candidate".pluralize(@total_seats) + = "Candidate".pluralize(total_seats) elected %table - - @election.polls.each do |p| + - election.polls.each do |p| %tr %td - %a{ :href => "/bodies/#{@election.body.slug}/elections/#{@election.d}/#{@election.body.districts_name}/#{p.district.slug}"} + %a{ :href => "/bodies/#{election.body.slug}/elections/#{election.d}/#{election.body.districts_name}/#{p.district.slug}"} = p.district.name - p.successful_candidacies.each do |sc| %td{ :style => "background-color: #{sc.party.colour};" } diff --git a/views/index.haml b/views/index.haml index c854c4a..5a5157f 100644 --- a/views/index.haml +++ b/views/index.haml @@ -1,16 +1,17 @@ -#lookup - %h2= @election_title - %form{ :method => 'get', :action => '/' } - %label{ :for => "postcode" } My postcode is - %input{ :type => 'text', :name => 'postcode', :value => @default_pc, :size => 8, :maxlength => 8 } - %input{ :type => 'submit', :value => "Find my results" } +-# + #lookup + %h2= @election_title + %form{ :method => 'get', :action => '/' } + %label{ :for => "postcode" } My postcode is + %input{ :type => 'text', :name => 'postcode', :value => @default_pc, :size => 8, :maxlength => 8 } + %input{ :type => 'submit', :value => "Find my results" } -- if @future_elections.size > 0 +- if future_elections.size > 0 %h2 Upcoming elections %table - - @future_elections.each do |election| + - future_elections.each do |election| %tr %td %a{ :href => "/bodies/#{election.body.slug}/elections/#{election.d}" } @@ -20,12 +21,12 @@ %td = election.kind -- if @past_elections.size > 0 +- if past_elections.size > 0 %h2 Past elections %table - - @past_elections.each do |election| + - past_elections.each do |election| %tr %td %a{ :href => "/bodies/#{election.body.slug}/elections/#{election.d}" } diff --git a/views/layout.haml b/views/layout.haml index b34bd33..ee2f200 100644 --- a/views/layout.haml +++ b/views/layout.haml @@ -2,7 +2,7 @@ %html %head %title= @page_title ? @page_title + " - Sutton Elections" : "Sutton Elections - Your guide to voting and election results in the London Borough of Sutton" - %link{ :rel => 'stylesheet', :type => 'text/css', :href => 'http://yui.yahooapis.com/pure/0.6.0/pure-min.css' } + %link{ :rel => 'stylesheet', :type => 'text/css', :href => '/style.css' } %link{ :rel => 'stylesheet', :type => 'text/css', :href => '/print.css', :media => 'print' } %meta{ :name => 'referrer', :content => 'no-referrer' } @@ -28,10 +28,11 @@ %a{ :href => '/about' } About #main - - if flash[:notice] - #notice - %p= flash[:notice] - - if flash[:error] - #error - %p= flash[:error] + + -# - if flash[:notice] + -# #notice + -# %p= flash[:notice] + -# - if flash[:error] + -# #error + -# %p= flash[:error] = yield diff --git a/views/parliament.haml b/views/parliament.haml index 684a57a..365e5e7 100644 --- a/views/parliament.haml +++ b/views/parliament.haml @@ -23,5 +23,3 @@ %p If no party gets 326 MPs the parties have to agree among themselves who will run the country. This is called a “hung parliament”. %p Elections for parliament must be held at least once every five years. The prime minister can choose to have an election earlier if they wish. - -= haml :register, :layout => false diff --git a/views/resultsdistrict.haml b/views/resultsdistrict.haml index 084a06b..3708e01 100644 --- a/views/resultsdistrict.haml +++ b/views/resultsdistrict.haml @@ -1,35 +1,35 @@ -- @page_title = "#{@district.name} #{@district.body.district_name} results, #{@body.name} election #{short_date(@election.d)}" +- page_title = "#{district.name} #{district.body.district_name} results, #{body.name} election #{short_date(election.d)}" %nav - - if @districts_in_this_election.size > 1 - - @district_index = @districts_in_this_election.index(@district) + - if districts_in_this_election.size > 1 + - district_index = districts_in_this_election.index(district) - - unless @district_index == 0 # Don't show the previous link if this is the first district for this election - - @previous_district = @districts_in_this_election[@district_index - 1] - %a{ :href => "/bodies/#{@election.body.slug}/elections/#{@election.d}/#{@election.body.districts_name}/#{@previous_district.slug}" } + - unless district_index == 0 # Don't show the previous link if this is the first district for this election + - previous_district = districts_in_this_election[district_index - 1] + %a{ :href => "/bodies/#{election.body.slug}/elections/#{election.d}/#{election.body.districts_name}/#{previous_district.slug}" } «  - = @previous_district.name + = previous_district.name     - - unless @district_index == @districts_in_this_election.size - 1 # Don't show the next link if this is the last district for this election - - @next_district = @districts_in_this_election[@district_index + 1] - %a{ :href => "/bodies/#{@election.body.slug}/elections/#{@election.d}/#{@election.body.districts_name}/#{@next_district.slug}" } - = @next_district.name + - unless district_index == districts_in_this_election.size - 1 # Don't show the next link if this is the last district for this election + - next_district = districts_in_this_election[district_index + 1] + %a{ :href => "/bodies/#{election.body.slug}/elections/#{election.d}/#{election.body.districts_name}/#{next_district.slug}" } + = next_district.name » %p - %a{ :href => "/bodies/#{@district.body.slug}/elections/#{@election.d}" } - = @body.name - = @election.kind - = long_date(@election.d) + %a{ :href => "/bodies/#{district.body.slug}/elections/#{election.d}" } + = body.name + = election.kind + = long_date(election.d) %h1 - %a{ :href => "/bodies/#{@district.body.slug}/#{@district.body.district_name.pluralize(2)}/#{@district.slug}" } - = @district.name + " " + @district.body.district_name + %a{ :href => "/bodies/#{district.body.slug}/#{district.body.district_name.pluralize(2)}/#{district.slug}" } + = district.name + " " + district.body.district_name -- @election_held = Candidacy.sum(:votes, :election => @election, :district => @district) +- election_held = Candidacy.sum(:votes, :election => election, :district => district) -- unless @election_held +- unless election_held .warning We don't have the results for this election yet. @@ -44,7 +44,7 @@ %th   - count = 0 - - @candidacies.each do |candidacy| + - candidacies.each do |candidacy| - count += 1 %tr.vcard %td= count @@ -54,9 +54,9 @@ = candidacy.candidate.short_name %td.org = party_name(candidacy.labcoop, candidacy.party.name) - - if @election_held + - if election_held %td.right= commify(candidacy.votes) - %td.right= format_percent(candidacy.votes.to_f / @share_denominator * 100) + %td.right= format_percent(candidacy.votes.to_f / share_denominator * 100) - if candidacy.seats == 1 %td.elected.elected_text="Elected" @@ -72,15 +72,15 @@ %td   %td   %td   - %td.right= commify(@total_votes) + %td.right= commify(total_votes) %td   %td   -- if @share_message +- if share_message .warning - = @share_message + = share_message -- if @total_seats > 1 +- if total_seats > 1 %h2 Votes by party %table @@ -96,20 +96,20 @@ - count = 0 - - @results_by_party.each do |row| + - results_by_party.each do |row| - count += 1 %tr %td.right= count %td{ :style => "background-color: #{row['party_colour'] }" }   %td= row['party_name'] - - if @election_held + - if election_held %td.right.highlight= row['num_seats'] - else %td.right.highlight — %td.right= row['num_candidates'] - - if @election_held + - if election_held %td.right= commify(row['total_votes']) - %td.right= format_percent(row['total_votes'].to_f / @total_votes * 100) + %td.right= format_percent(row['total_votes'].to_f / total_votes * 100) %td.right= commify(row['total_votes'] / row['num_candidates']) - else %td.right — @@ -120,48 +120,48 @@ %td   %td   %td   - - if @election_held - %td.right.highlight= @total_seats + - if election_held + %td.right.highlight= total_seats - else %td.right.highlight   - %td.right= @total_candidates - %td.right= commify(@total_votes) + %td.right= total_candidates + %td.right= commify(total_votes) %td   %td   -- if @poll +- if poll %p %table - - if @poll.ballot_papers_issued + - if poll.ballot_papers_issued %tr %td Ballot papers issued - %td.right= commify(@poll.ballot_papers_issued) - - if @poll.electorate + %td.right= commify(poll.ballot_papers_issued) + - if poll.electorate %tr %td Electorate - %td.right= commify(@poll.electorate) - - if @poll.turnout_percent > 0 + %td.right= commify(poll.electorate) + - if poll.turnout_percent > 0 %tr %td Turnout - %td.right= sprintf("%.0f%%", @poll.turnout_percent) + %td.right= sprintf("%.0f%%", poll.turnout_percent) -# Show this table conditionally as sometimes we have electorate data but no -# breakdown of rejected ballot papers - - if @poll.rejected_no_official_mark + - if poll.rejected_no_official_mark %h2 Rejected ballot papers %table %tr %td No official mark on the ballot paper - %td.right= commify(@poll.rejected_no_official_mark) + %td.right= commify(poll.rejected_no_official_mark) %tr %td Voting for too many candidates - %td.right= commify(@poll.rejected_too_many_candidates) + %td.right= commify(poll.rejected_too_many_candidates) %tr %td Voter could be identified by writing or a mark on the ballot paper - %td.right= commify(@poll.rejected_identifiable_voter) + %td.right= commify(poll.rejected_identifiable_voter) %tr %td Ballot paper unmarked or voter's intention uncertain - %td.right= commify(@poll.rejected_blank_or_uncertain) + %td.right= commify(poll.rejected_blank_or_uncertain) %tr.footer %td   - %td.right= commify(@poll.total_rejected_ballots) + %td.right= commify(poll.total_rejected_ballots)