Election results in the London Borough of Sutton.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

225 lines
6.1 KiB

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