Election results in the London Borough of Sutton.
Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

app.rb 6.1 KiB

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