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.
 
 
 
 

227 lines
6.5 KiB

  1. require 'data_mapper'
  2. require 'pat'
  3. class Poll
  4. include DataMapper::Resource
  5. property :district_id, Integer, :key => true
  6. property :election_id, Integer, :key => true
  7. property :electorate, Integer # The number of people eligible to vote in this district in this election
  8. property :ballot_papers_issued, Integer # The number of ballot papers issued (includes spoiled ballots)
  9. property :seats, Integer, :required => true # The number of seats to be elected in this district in this election
  10. def turnout_percent
  11. @ballot_papers_issued.to_f / @electorate.to_f * 100.0
  12. end
  13. end
  14. class Postcode
  15. include DataMapper::Resource
  16. # Postcode natural key, uppercase with space, eg. "SM1 1EA"
  17. property :postcode, String, :key => true
  18. property :created_at, DateTime
  19. property :updated_at, DateTime
  20. property :lat, Float, :required => true
  21. property :lng, Float, :required => true
  22. property :district_name, String, :required => true
  23. property :district_code, String, :required => true
  24. property :ward_name, String, :required => true
  25. property :ward_code, String, :required => true
  26. def self.finder(postcode)
  27. postcode = postcode.strip.upcase
  28. if o = self.get(postcode)
  29. return o
  30. end
  31. result = Pat.get(postcode)
  32. unless result.code == 404
  33. # cache API result
  34. self.create(
  35. :postcode => postcode,
  36. :lat => result['geo']['lat'],
  37. :lng => result['geo']['lng'],
  38. :district_name => result['administrative']['district']['title'],
  39. :district_code => result['administrative']['district']['uri'].match(/.+\/(.+)$/)[1],
  40. :ward_name => result['administrative']['ward']['title'],
  41. :ward_code => result['administrative']['ward']['uri'].match(/.+\/(.+)$/)[1]
  42. )
  43. else
  44. # invalid postcode
  45. nil
  46. end
  47. end
  48. end
  49. class Candidate
  50. include DataMapper::Resource
  51. property :id, Serial
  52. property :forenames, String, :required => true
  53. property :surname, String, :required => true
  54. property :sex, String
  55. has n, :candidacies
  56. def short_name
  57. @forenames.split(' ')[0] + ' ' + @surname
  58. end
  59. def name
  60. @forenames + ' ' + @surname
  61. end
  62. end
  63. class Candidacy
  64. include DataMapper::Resource
  65. property :id, Serial
  66. property :election_id, Integer, :required => true
  67. property :candidate_id, Integer, :required => true
  68. property :party_id, Integer
  69. property :district_id, Integer, :required => true
  70. property :votes, Integer
  71. property :address, String, :length => 200
  72. property :postcode, String
  73. property :position, Integer
  74. property :seats, Integer
  75. belongs_to :election
  76. belongs_to :candidate
  77. belongs_to :party
  78. belongs_to :district
  79. end
  80. class Election
  81. include DataMapper::Resource
  82. property :id, Serial
  83. property :body_id, Integer, :required => true
  84. property :d, Date, :required => true
  85. property :reason, String, :length => 255
  86. property :kind, String, :length => 255
  87. has n, :candidacies
  88. belongs_to :body
  89. def self.past
  90. self.all(:d.lt => Time.now.to_s, :order => [ :d.desc ])
  91. end
  92. def self.future
  93. self.all(:d.gte => Time.now.to_s, :order => [ :d.desc ])
  94. end
  95. end
  96. class District
  97. include DataMapper::Resource
  98. property :id, Serial
  99. property :body_id, Integer, :required => true
  100. property :name, String, :length => 255, :required => true
  101. property :slug, String
  102. property :seats, Integer
  103. belongs_to :body
  104. def self.slugify(name)
  105. name.gsub(/[^\w\s-]/, '').gsub(/\s+/, '-').downcase
  106. end
  107. end
  108. class Body
  109. include DataMapper::Resource
  110. property :id, Serial
  111. property :name, String, :length => 255, :required => true
  112. property :district_name, String, :length => 255, :required => true # singular
  113. property :districts_name, String, :length => 255, :required => true # plural
  114. property :slug, String, :length => 255
  115. has n, :elections
  116. has n, :districts
  117. end
  118. class Party
  119. include DataMapper::Resource
  120. property :id, Serial
  121. property :name, String, :required => true
  122. property :colour, String
  123. has n, :candidacies
  124. end
  125. # These models are now redundant
  126. class Ward
  127. include DataMapper::Resource
  128. property :id, Serial
  129. property :slug, String, :required => true
  130. property :ons_id, String, :required => true
  131. property :name, String, :required => true
  132. property :constituency_id, Integer, :required => true
  133. has n, :councilcandidates, :order => ['surname']
  134. belongs_to :constituency
  135. def self.slugify(name)
  136. name.gsub(/[^\w\s-]/, '').gsub(/\s+/, '-').downcase
  137. end
  138. end
  139. class Councilcandidate
  140. include DataMapper::Resource
  141. property :id, Serial
  142. property :ward_id, Integer, :required => true
  143. property :party_id, Integer, :required => true
  144. property :forenames, String, :required => true
  145. property :surname, String, :required => true
  146. property :address, String, :length => 200
  147. property :postcode, String, :required => true
  148. property :votes_2010, Integer
  149. belongs_to :party
  150. belongs_to :ward
  151. end
  152. class Parliamentcandidate
  153. include DataMapper::Resource
  154. property :id, Serial
  155. property :constituency_id, Integer, :required => true
  156. property :party_id, Integer, :required => true
  157. property :forenames, String, :required => true
  158. property :surname, String, :required => true
  159. property :address, String, :length => 200
  160. property :postcode, String
  161. property :votes_2010, Integer
  162. property :votes_2005, Integer
  163. property :percent_2005, Float
  164. belongs_to :party
  165. belongs_to :constituency
  166. end
  167. class Constituency
  168. include DataMapper::Resource
  169. property :id, Serial
  170. property :name, String, :required => true
  171. has n, :wards, :order => ['name']
  172. has n, :parliamentcandidates, :order => ['surname']
  173. end
  174. DataMapper.setup(:default, ENV['DATABASE_URL'] || "sqlite3://#{Dir.pwd}/db/suttonelections.db")
  175. DataMapper.auto_upgrade!