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.
 
 
 
 

272 lines
6.1 KiB

  1. require 'rubygems'
  2. require 'sinatra'
  3. require 'haml'
  4. require './models'
  5. class String
  6. def pluralize(num)
  7. if num == 1
  8. return self
  9. end
  10. case self[-1]
  11. when 'y'
  12. self[0..-2] + 'ies'
  13. when 's'
  14. self + "es"
  15. else
  16. self + "s"
  17. end
  18. end
  19. end
  20. helpers do
  21. # Format a number with commas for every ^3
  22. def commify(num)
  23. num.to_s.reverse.gsub(/(\d\d\d)(?=\d)(?!\d*\.)/,'\1,').reverse
  24. end
  25. # From http://snippets.dzone.com/posts/show/593
  26. def to_ordinal(num)
  27. num = num.to_i
  28. if (10...20) === num
  29. "#{num}th"
  30. else
  31. g = %w{ th st nd rd th th th th th th }
  32. a = num.to_s
  33. c = a[-1..-1].to_i
  34. a + g[c]
  35. end
  36. end
  37. def format_percent(num)
  38. sprintf("%.0f%%", num)
  39. end
  40. def short_date(d)
  41. d.strftime("%e %b %Y")
  42. end
  43. def long_date(d)
  44. d.strftime("%e %B %Y")
  45. end
  46. end
  47. get '/' do
  48. # if params[:postcode]
  49. # @postcode = params[:postcode].strip.upcase
  50. #
  51. # unless result = Postcode.finder(@postcode)
  52. # # Invalid postcode
  53. # redirect '/error'
  54. # end
  55. #
  56. # # Postcode valid but not in LB Sutton
  57. # if result.district_code != "00BF"
  58. # redirect '/aliens'
  59. # end
  60. #
  61. # # Postcode in LB Sutton
  62. # @ward = Ward.first( :ons_id => result.ward_code )
  63. # redirect "/wards/#{@ward.slug}/postcode/#{@postcode}"
  64. # end
  65. @future_elections = Election.future
  66. @past_elections = Election.past
  67. haml :index
  68. end
  69. get '/bodies/:body/elections/:date' do
  70. @body = Body.first(:slug => params[:body])
  71. @election = Election.first(:body => @body, :d => params[:date])
  72. @elections_for_this_body = Election.all(:body => @body, :order => [:d])
  73. @total_seats = Candidacy.sum(:seats, :election => @election)
  74. @total_votes = Candidacy.sum(:votes, :election => @election)
  75. # There's got to be a better way to do this, either with SQL or Datamapper
  76. @total_districts = repository(:default).adapter.select("
  77. SELECT district_id
  78. FROM candidacies
  79. WHERE election_id = #{@election.id}
  80. GROUP BY district_id
  81. ORDER BY district_id
  82. ").count
  83. @results_by_party = repository(:default).adapter.select("
  84. SELECT
  85. p.colour,
  86. p.name,
  87. SUM(c.votes) AS votez,
  88. SUM(c.seats) AS seatz,
  89. COUNT(*) AS cands
  90. FROM candidacies c
  91. LEFT JOIN parties p ON p.id = c.party_id
  92. WHERE c.election_id = #{@election.id}
  93. GROUP BY c.party_id, p.colour, p.name
  94. ORDER BY seatz DESC, votez DESC
  95. ")
  96. @results_by_district = repository(:default).adapter.select("
  97. SELECT
  98. d.name,
  99. d.slug AS district_slug,
  100. SUM(c.seats) AS seats,
  101. SUM(c.votes) AS votez,
  102. COUNT(c.id) AS num_candidates
  103. FROM districts d, candidacies c
  104. WHERE
  105. c.district_id = d.id
  106. AND c.election_id = #{@election.id}
  107. GROUP BY c.district_id, d.name, d.slug
  108. ORDER BY d.name
  109. ")
  110. haml :electionsummary
  111. end
  112. # get '/bodies/:body/elections/:date/parties/:party' do
  113. # Not written yet. Show how this party did at this election.
  114. # end
  115. get '/bodies/?' do
  116. @bodies = Body.all
  117. haml :bodies
  118. end
  119. get '/bodies/:body/?' do
  120. @body = Body.first(:slug => params[:body])
  121. @elections = Election.all(:body => @body, :order => [:d.desc])
  122. @districts = District.all(:body => @body, :order => [:name])
  123. haml :body
  124. end
  125. # get '/wards/:slug/postcode/:postcode/?' do
  126. # @ward = Ward.first(:slug => params[:slug])
  127. # @postcode = params[:postcode]
  128. # haml :wards
  129. # end
  130. get '/candidates/:id/?' do
  131. if @candidate = Candidate.get(params[:id])
  132. @candidacies = repository(:default).adapter.select("
  133. SELECT
  134. e.d,
  135. c.*,
  136. p.name AS party_name,
  137. p.colour AS party_colour,
  138. b.name AS body_name,
  139. b.slug AS body_slug,
  140. b.districts_name AS districts_name,
  141. d.name AS district_name,
  142. d.slug AS district_slug
  143. FROM candidacies c
  144. INNER JOIN elections e
  145. ON c.election_id = e.id
  146. INNER JOIN parties p
  147. ON c.party_id = p.id
  148. INNER JOIN bodies b
  149. ON e.body_id = b.id
  150. INNER JOIN districts d
  151. ON c.district_id = d.id
  152. WHERE c.candidate_id = #{@candidate.id}
  153. ORDER BY d
  154. ")
  155. haml :candidate
  156. else
  157. 404
  158. end
  159. end
  160. get '/candidates/?' do
  161. @candidates = Candidate.all(:order => [ :surname, :forenames ])
  162. haml :candidates
  163. end
  164. get '/bodies/:body/elections/:date/:districts_name/:district' do
  165. @district = District.first(:slug => params[:district])
  166. @body = Body.first(:slug => params[:body])
  167. @election = Election.first(:body => @body, :d => params[:date])
  168. @candidacies = Candidacy.all(:district => @district, :election => @election, :order => [:votes.desc])
  169. @total_votes = Candidacy.sum(:votes, :district => @district, :election => @election)
  170. @total_candidates = Candidacy.count(:district => @district, :election => @election)
  171. @total_seats = Candidacy.sum(:seats, :district => @district, :election => @election)
  172. @districts_in_this_election = @election.candidacies.districts
  173. # Postgres: All the columns selected when using GROUP BY must either be aggregate functions or appear in the GROUP BY clause
  174. @results_by_party = repository(:default).adapter.select("
  175. SELECT
  176. p.name AS party_name,
  177. p.colour AS party_colour,
  178. COUNT(c.id) AS num_candidates,
  179. SUM(c.seats) AS num_seats,
  180. SUM(c.votes) AS total_votes
  181. FROM candidacies c
  182. LEFT JOIN parties p
  183. ON c.party_id = p.id
  184. WHERE c.district_id = #{@district.id}
  185. AND c.election_id = #{@election.id}
  186. GROUP BY p.name, p.colour
  187. ORDER BY total_votes DESC
  188. ")
  189. haml :resultsdistrict
  190. end
  191. get '/bodies/:body/:districts_name/:district' do
  192. @district = District.first(:slug => params[:district])
  193. @body = Body.first(:slug => params[:body])
  194. haml :district
  195. end
  196. get '/how-the-council-election-works' do
  197. haml :election
  198. end
  199. get '/how-the-parliament-election-works' do
  200. haml :parliament
  201. end
  202. # get '/voting' do
  203. # haml :voting
  204. # end
  205. get '/error' do
  206. haml :error
  207. end
  208. get '/about' do
  209. haml :about
  210. end
  211. # get '/aliens' do
  212. # haml :aliens
  213. # end
  214. not_found do
  215. haml :not_found
  216. end