Election results in the London Borough of Sutton.
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

13 лет назад
14 лет назад
13 лет назад
11 лет назад
13 лет назад
13 лет назад
13 лет назад
14 лет назад
13 лет назад
14 лет назад
13 лет назад
13 лет назад
13 лет назад
13 лет назад
13 лет назад
14 лет назад
13 лет назад
13 лет назад
11 лет назад
13 лет назад
11 лет назад
13 лет назад
11 лет назад
13 лет назад
13 лет назад
11 лет назад
13 лет назад
13 лет назад
11 лет назад
13 лет назад
13 лет назад
11 лет назад
13 лет назад
13 лет назад
14 лет назад
13 лет назад
13 лет назад
13 лет назад
11 лет назад
11 лет назад
13 лет назад
13 лет назад
13 лет назад
13 лет назад
13 лет назад
12 лет назад
12 лет назад
12 лет назад
11 лет назад
12 лет назад
12 лет назад
11 лет назад
12 лет назад
13 лет назад
14 лет назад
13 лет назад
14 лет назад
14 лет назад
13 лет назад
14 лет назад
14 лет назад
13 лет назад
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