Election results in the London Borough of Sutton.
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.
 
 
 
 

210 lignes
5.5 KiB

  1. #!/usr/bin/env ruby
  2. require 'petrify'
  3. require_relative '../models'
  4. require_relative '../lib/helpers'
  5. def gen_info_pages
  6. Petrify.page('about', 'about')
  7. Petrify.page('guides', 'guides')
  8. Petrify.page(%w(guides how-the-parliament-election-works), 'parliament')
  9. Petrify.page(%w(guides how-the-council-election-works), 'election')
  10. end
  11. def gen_bodies_pages
  12. # Body detail pages
  13. Body.each do |b|
  14. locals = {
  15. body: b,
  16. districts: District.all(:body => b, :order => [:name])
  17. }
  18. locals['elections'] = repository(:default).adapter.select("
  19. SELECT
  20. e.id,
  21. e.kind,
  22. e.d,
  23. SUM(p.ballot_papers_issued)::float / SUM(p.electorate) * 100 AS turnout_percent
  24. FROM elections e
  25. LEFT JOIN polls p
  26. ON e.id = p.election_id
  27. WHERE e.body_id = ?
  28. GROUP BY p.election_id, e.id
  29. ORDER BY e.d DESC
  30. ", b.id)
  31. Petrify.page(['bodies', b.slug], 'body', locals)
  32. # Districts for this body
  33. b.districts.each do |d|
  34. locals = {
  35. district: d,
  36. body: b
  37. }
  38. Petrify.page(['bodies', b.slug, b.districts_name, d.slug], 'district', locals)
  39. end
  40. end
  41. end
  42. def gen_candidates_pages
  43. # Candidate index
  44. locals = { candidates: Candidate.all(:order => [ :surname, :forenames ]) }
  45. Petrify.page('candidates', 'candidates', locals)
  46. # Candidate pages
  47. # FIXME: What do we do about deleted candidates/redirects?
  48. Candidate.each do |c|
  49. locals = {
  50. candidate: c
  51. }
  52. locals['candidacies'] = repository(:default).adapter.select("
  53. SELECT
  54. e.d,
  55. c.*,
  56. p.name AS party_name,
  57. p.colour AS party_colour,
  58. b.name AS body_name,
  59. b.slug AS body_slug,
  60. b.districts_name AS districts_name,
  61. d.name AS district_name,
  62. d.slug AS district_slug
  63. FROM candidacies c
  64. INNER JOIN elections e
  65. ON c.election_id = e.id
  66. INNER JOIN parties p
  67. ON c.party_id = p.id
  68. INNER JOIN bodies b
  69. ON e.body_id = b.id
  70. INNER JOIN districts d
  71. ON c.district_id = d.id
  72. WHERE c.candidate_id = ?
  73. ORDER BY d
  74. ", c.id)
  75. Petrify.page(['candidates', c.id.to_s], 'candidate', locals)
  76. end
  77. end
  78. def gen_elections_pages
  79. # Election pages
  80. Election.each do |e|
  81. locals = {
  82. body: Body.first(:slug => e.body.slug),
  83. election: Election.first(:body => e.body, :d => e.d),
  84. elections_for_this_body: Election.all(:body => e.body, :order => [:d]),
  85. total_seats: Candidacy.sum(:seats, :election => e),
  86. total_votes: Candidacy.sum(:votes, :election => e)
  87. }
  88. # There's got to be a better way to do this, either with SQL or Datamapper
  89. locals['total_districts'] = repository(:default).adapter.select("
  90. SELECT district_id
  91. FROM candidacies
  92. WHERE election_id = ?
  93. GROUP BY district_id
  94. ORDER BY district_id
  95. ", e.id).count
  96. locals['results_by_party'] = repository(:default).adapter.select("
  97. SELECT
  98. p.colour,
  99. p.name,
  100. SUM(c.votes) AS votez,
  101. SUM(c.seats) AS seatz,
  102. COUNT(*) AS cands
  103. FROM candidacies c
  104. LEFT JOIN parties p ON p.id = c.party_id
  105. WHERE c.election_id = ?
  106. GROUP BY c.party_id, p.colour, p.name
  107. ORDER BY seatz DESC, votez DESC
  108. ", e.id)
  109. Petrify.page(['bodies', e.body.slug, 'elections', e.d.to_s], 'electionsummary', locals)
  110. # District results for this election (resultsdistrict)
  111. # Loop through all districts in this election
  112. e.candidacies.districts.each do |d|
  113. total_seats = Candidacy.sum(:seats, :district => d, :election => e)
  114. total_votes = Candidacy.sum(:votes, :district => d, :election => e)
  115. poll = Poll.get(d.id, e.id)
  116. locals = {
  117. district: d,
  118. body: d.body,
  119. election: e,
  120. candidacies: Candidacy.all(:district => d, :election => e, :order => [:position]),
  121. total_votes: total_votes,
  122. total_candidates: Candidacy.count(:district => d, :election => e),
  123. total_seats: total_seats,
  124. districts_in_this_election: e.candidacies.districts,
  125. poll: poll
  126. }
  127. locals['share_message'] = nil
  128. if total_seats == 1
  129. locals['share_denominator'] = total_votes
  130. elsif poll && poll.valid_ballot_papers
  131. locals['share_denominator'] = poll.valid_ballot_papers
  132. else
  133. locals['share_denominator'] = total_votes / total_seats
  134. 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."
  135. end
  136. # Postgres: All the columns selected when using GROUP BY must either be aggregate functions or appear in the GROUP BY clause
  137. locals['results_by_party'] = repository(:default).adapter.select("
  138. SELECT
  139. p.name AS party_name,
  140. p.colour AS party_colour,
  141. COUNT(c.id) AS num_candidates,
  142. SUM(c.seats) AS num_seats,
  143. SUM(c.votes) AS total_votes
  144. FROM candidacies c
  145. LEFT JOIN parties p
  146. ON c.party_id = p.id
  147. WHERE c.district_id = ?
  148. AND c.election_id = ?
  149. GROUP BY p.name, p.colour
  150. ORDER BY total_votes DESC
  151. ", d.id, e.id)
  152. Petrify.page(['bodies', e.body.slug, 'elections', e.d.to_s, e.body.districts_name, d.slug], 'resultsdistrict', locals)
  153. end
  154. end
  155. end
  156. def gen_homepage
  157. locals = {
  158. future_elections: Election.future,
  159. past_elections: Election.past
  160. }
  161. Petrify.page('.', 'index', locals)
  162. end
  163. Petrify.setup
  164. gen_homepage
  165. gen_elections_pages
  166. gen_bodies_pages
  167. gen_info_pages
  168. gen_candidates_pages