Election results in the London Borough of Sutton.
25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

app.rb 6.3 KiB

13 년 전
14 년 전
14 년 전
14 년 전
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  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. # Exception for Labour/Co-operative candidacies
  48. def party_name(labcoop, party_name)
  49. labcoop ? "Labour and Co-operative Party" : party_name
  50. end
  51. end
  52. get '/' do
  53. # if params[:postcode]
  54. # @postcode = params[:postcode].strip.upcase
  55. #
  56. # unless result = Postcode.finder(@postcode)
  57. # # Invalid postcode
  58. # redirect '/error'
  59. # end
  60. #
  61. # # Postcode valid but not in LB Sutton
  62. # if result.district_code != "00BF"
  63. # redirect '/aliens'
  64. # end
  65. #
  66. # # Postcode in LB Sutton
  67. # @ward = Ward.first( :ons_id => result.ward_code )
  68. # redirect "/wards/#{@ward.slug}/postcode/#{@postcode}"
  69. # end
  70. @future_elections = Election.future
  71. @past_elections = Election.past
  72. haml :index
  73. end
  74. get '/bodies/:body/elections/:date' do
  75. @body = Body.first(:slug => params[:body])
  76. @election = Election.first(:body => @body, :d => params[:date])
  77. @elections_for_this_body = Election.all(:body => @body, :order => [:d])
  78. @total_seats = Candidacy.sum(:seats, :election => @election)
  79. @total_votes = Candidacy.sum(:votes, :election => @election)
  80. # There's got to be a better way to do this, either with SQL or Datamapper
  81. @total_districts = repository(:default).adapter.select("
  82. SELECT district_id
  83. FROM candidacies
  84. WHERE election_id = ?
  85. GROUP BY district_id
  86. ORDER BY district_id
  87. ", @election.id).count
  88. @results_by_party = repository(:default).adapter.select("
  89. SELECT
  90. p.colour,
  91. p.name,
  92. SUM(c.votes) AS votez,
  93. SUM(c.seats) AS seatz,
  94. COUNT(*) AS cands
  95. FROM candidacies c
  96. LEFT JOIN parties p ON p.id = c.party_id
  97. WHERE c.election_id = ?
  98. GROUP BY c.party_id, p.colour, p.name
  99. ORDER BY seatz DESC, votez DESC
  100. ", @election.id)
  101. @results_by_district = repository(:default).adapter.select("
  102. SELECT
  103. d.name,
  104. d.slug AS district_slug,
  105. SUM(c.seats) AS seats,
  106. SUM(c.votes) AS votez,
  107. COUNT(c.id) AS num_candidates
  108. FROM districts d, candidacies c
  109. WHERE
  110. c.district_id = d.id
  111. AND c.election_id = ?
  112. GROUP BY c.district_id, d.name, d.slug
  113. ORDER BY d.name
  114. ", @election.id)
  115. haml :electionsummary
  116. end
  117. # get '/bodies/:body/elections/:date/parties/:party' do
  118. # Not written yet. Show how this party did at this election.
  119. # end
  120. get '/bodies/?' do
  121. @bodies = Body.all
  122. haml :bodies
  123. end
  124. get '/bodies/:body/?' do
  125. @body = Body.first(:slug => params[:body])
  126. @elections = Election.all(:body => @body, :order => [:d.desc])
  127. @districts = District.all(:body => @body, :order => [:name])
  128. haml :body
  129. end
  130. # get '/wards/:slug/postcode/:postcode/?' do
  131. # @ward = Ward.first(:slug => params[:slug])
  132. # @postcode = params[:postcode]
  133. # haml :wards
  134. # end
  135. get '/candidates/:id/?' do
  136. if @candidate = Candidate.get(params[:id])
  137. @candidacies = repository(:default).adapter.select("
  138. SELECT
  139. e.d,
  140. c.*,
  141. p.name AS party_name,
  142. p.colour AS party_colour,
  143. b.name AS body_name,
  144. b.slug AS body_slug,
  145. b.districts_name AS districts_name,
  146. d.name AS district_name,
  147. d.slug AS district_slug
  148. FROM candidacies c
  149. INNER JOIN elections e
  150. ON c.election_id = e.id
  151. INNER JOIN parties p
  152. ON c.party_id = p.id
  153. INNER JOIN bodies b
  154. ON e.body_id = b.id
  155. INNER JOIN districts d
  156. ON c.district_id = d.id
  157. WHERE c.candidate_id = ?
  158. ORDER BY d
  159. ", @candidate.id)
  160. haml :candidate
  161. else
  162. 404
  163. end
  164. end
  165. get '/candidates/?' do
  166. @candidates = Candidate.all(:order => [ :surname, :forenames ])
  167. haml :candidates
  168. end
  169. get '/bodies/:body/elections/:date/:districts_name/:district' do
  170. @district = District.first(:slug => params[:district])
  171. @body = Body.first(:slug => params[:body])
  172. @election = Election.first(:body => @body, :d => params[:date])
  173. @candidacies = Candidacy.all(:district => @district, :election => @election, :order => [:votes.desc])
  174. @total_votes = Candidacy.sum(:votes, :district => @district, :election => @election)
  175. @total_candidates = Candidacy.count(:district => @district, :election => @election)
  176. @total_seats = Candidacy.sum(:seats, :district => @district, :election => @election)
  177. @districts_in_this_election = @election.candidacies.districts
  178. # Postgres: All the columns selected when using GROUP BY must either be aggregate functions or appear in the GROUP BY clause
  179. @results_by_party = repository(:default).adapter.select("
  180. SELECT
  181. p.name AS party_name,
  182. p.colour AS party_colour,
  183. COUNT(c.id) AS num_candidates,
  184. SUM(c.seats) AS num_seats,
  185. SUM(c.votes) AS total_votes
  186. FROM candidacies c
  187. LEFT JOIN parties p
  188. ON c.party_id = p.id
  189. WHERE c.district_id = ?
  190. AND c.election_id = ?
  191. GROUP BY p.name, p.colour
  192. ORDER BY total_votes DESC
  193. ", @district.id, @election.id)
  194. haml :resultsdistrict
  195. end
  196. get '/bodies/:body/:districts_name/:district' do
  197. @district = District.first(:slug => params[:district])
  198. @body = Body.first(:slug => params[:body])
  199. haml :district
  200. end
  201. get '/how-the-council-election-works' do
  202. haml :election
  203. end
  204. get '/how-the-parliament-election-works' do
  205. haml :parliament
  206. end
  207. # get '/voting' do
  208. # haml :voting
  209. # end
  210. get '/error' do
  211. haml :error
  212. end
  213. get '/about' do
  214. haml :about
  215. end
  216. # get '/aliens' do
  217. # haml :aliens
  218. # end
  219. not_found do
  220. haml :not_found
  221. end