@@ -11,7 +11,7 @@ GEM | |||||
specs: | specs: | ||||
addressable (2.5.2) | addressable (2.5.2) | ||||
public_suffix (>= 2.0.2, < 4.0) | public_suffix (>= 2.0.2, < 4.0) | ||||
bcrypt (3.1.11) | |||||
bcrypt (3.1.12) | |||||
bcrypt-ruby (3.1.5) | bcrypt-ruby (3.1.5) | ||||
bcrypt (>= 3.1.3) | bcrypt (>= 3.1.3) | ||||
data_mapper (1.2.0) | data_mapper (1.2.0) | ||||
@@ -37,15 +37,15 @@ GEM | |||||
dm-core (~> 1.2.0) | dm-core (~> 1.2.0) | ||||
dm-migrations (1.2.0) | dm-migrations (1.2.0) | ||||
dm-core (~> 1.2.0) | dm-core (~> 1.2.0) | ||||
dm-postgres-adapter (1.2.0) | |||||
dm-do-adapter (~> 1.2.0) | |||||
do_postgres (~> 0.10.6) | |||||
dm-serializer (1.2.2) | dm-serializer (1.2.2) | ||||
dm-core (~> 1.2.0) | dm-core (~> 1.2.0) | ||||
fastercsv (~> 1.5) | fastercsv (~> 1.5) | ||||
json (~> 1.6) | json (~> 1.6) | ||||
json_pure (~> 1.6) | json_pure (~> 1.6) | ||||
multi_json (~> 1.0) | multi_json (~> 1.0) | ||||
dm-sqlite-adapter (1.2.0) | |||||
dm-do-adapter (~> 1.2.0) | |||||
do_sqlite3 (~> 0.10.6) | |||||
dm-timestamps (1.2.0) | dm-timestamps (1.2.0) | ||||
dm-core (~> 1.2.0) | dm-core (~> 1.2.0) | ||||
dm-transactions (1.2.0) | dm-transactions (1.2.0) | ||||
@@ -60,7 +60,7 @@ GEM | |||||
uuidtools (~> 2.1) | uuidtools (~> 2.1) | ||||
dm-validations (1.2.0) | dm-validations (1.2.0) | ||||
dm-core (~> 1.2.0) | dm-core (~> 1.2.0) | ||||
do_postgres (0.10.17) | |||||
do_sqlite3 (0.10.17) | |||||
data_objects (= 0.10.17) | data_objects (= 0.10.17) | ||||
fastercsv (1.5.5) | fastercsv (1.5.5) | ||||
haml (5.0.4) | haml (5.0.4) | ||||
@@ -69,8 +69,7 @@ GEM | |||||
json (1.8.6) | json (1.8.6) | ||||
json_pure (1.8.6) | json_pure (1.8.6) | ||||
multi_json (1.13.1) | multi_json (1.13.1) | ||||
pg (1.0.0) | |||||
public_suffix (3.0.2) | |||||
public_suffix (3.0.3) | |||||
stringex (1.5.1) | stringex (1.5.1) | ||||
temple (0.8.0) | temple (0.8.0) | ||||
tilt (2.0.8) | tilt (2.0.8) | ||||
@@ -81,13 +80,11 @@ PLATFORMS | |||||
DEPENDENCIES | DEPENDENCIES | ||||
data_mapper | data_mapper | ||||
dm-postgres-adapter | |||||
haml | |||||
dm-sqlite-adapter | |||||
petrify! | petrify! | ||||
pg | |||||
RUBY VERSION | RUBY VERSION | ||||
ruby 2.3.1p112 | ruby 2.3.1p112 | ||||
BUNDLED WITH | BUNDLED WITH | ||||
1.16.1 | |||||
1.16.6 |
@@ -2,6 +2,7 @@ | |||||
require 'petrify' | require 'petrify' | ||||
require_relative '../models' | require_relative '../models' | ||||
require_relative '../lib/helpers' | require_relative '../lib/helpers' | ||||
require 'pp' | |||||
def gen_info_pages | def gen_info_pages | ||||
Petrify.page('about', 'about') | Petrify.page('about', 'about') | ||||
@@ -23,7 +24,7 @@ def gen_bodies_pages | |||||
e.id, | e.id, | ||||
e.kind, | e.kind, | ||||
e.d, | e.d, | ||||
SUM(p.ballot_papers_issued)::float / SUM(p.electorate) * 100 AS turnout_percent | |||||
(SUM(p.ballot_papers_issued) * 1.0) / SUM(p.electorate) * 100 AS turnout_percent | |||||
FROM elections e | FROM elections e | ||||
@@ -0,0 +1,32 @@ | |||||
# require_relative '../models' | |||||
require 'scraperwiki' | |||||
require 'sequel' | |||||
load '_config.rb' | |||||
require 'pp' | |||||
class Object | |||||
def to_hash | |||||
h = {} | |||||
instance_variables.each do |var| | |||||
h[var.to_s.delete('@')] = instance_variable_get(var) | |||||
end | |||||
# Remove DataMapper-specific keys, which start with an underscore | |||||
h.keys.each do |k| | |||||
h.delete(k) if k.match(/^_/) | |||||
end | |||||
h | |||||
end | |||||
end | |||||
DB = Sequel.connect(ENV['DATABASE_URL']) | |||||
DB[:polls].each { |o| ScraperWiki.save_sqlite([:district_id, :election_id], o.to_hash, 'polls') } | |||||
DB[:candidates].each { |o| ScraperWiki.save_sqlite([:id], o.to_hash, 'candidates') } | |||||
DB[:candidacies].each { |o| ScraperWiki.save_sqlite([:id], o.to_hash, 'candidacies') } | |||||
DB[:deleted_candidates].each { |o| ScraperWiki.save_sqlite([:old_candidate_id], o.to_hash, 'deleted_candidates') } | |||||
DB[:elections].each { |o| ScraperWiki.save_sqlite([:id], o.to_hash, 'elections') } | |||||
DB[:districts].each { |o| ScraperWiki.save_sqlite([:id], o.to_hash, 'districts') } | |||||
DB[:bodies].each { |o| ScraperWiki.save_sqlite([:id], o.to_hash, 'bodies') } | |||||
DB[:parties].each { |o| ScraperWiki.save_sqlite([:id], o.to_hash, 'parties') } |
@@ -37,14 +37,19 @@ def format_percent(num) | |||||
end | end | ||||
def short_date(d) | def short_date(d) | ||||
# FIXME wtf - because sometimes we're doing raw sql queries and sometimes it's coming through the DataMapper::Resource class | |||||
d = Date.parse(d) unless d.class == Date | |||||
d.strftime("%e %b %Y") | d.strftime("%e %b %Y") | ||||
end | end | ||||
def long_date(d) | def long_date(d) | ||||
# FIXME wtf - because sometimes we're doing raw sql queries and sometimes it's coming through the DataMapper::Resource class | |||||
d = Date.parse(d) unless d.class == Date | |||||
d.strftime("%e %B %Y") | d.strftime("%e %B %Y") | ||||
end | end | ||||
# Exception for Labour/Co-operative candidacies | # Exception for Labour/Co-operative candidacies | ||||
def party_name(labcoop, party_name) | def party_name(labcoop, party_name) | ||||
labcoop ? "Labour and Co-operative Party" : party_name | |||||
# puts labcoop.class # FIXME wtf - because sometimes we're doing raw sql queries and sometimes it's coming through the DataMapper::Resource class | |||||
labcoop == 1 || labcoop == '1' ? "Labour and Co-operative Party" : party_name | |||||
end | end |
@@ -62,73 +62,6 @@ class Poll | |||||
belongs_to :district | belongs_to :district | ||||
end | end | ||||
class PollingStation | |||||
include DataMapper::Resource | |||||
property :id, String, :key => true, :length => 2 # e.g. "KA" | |||||
property :name, String, :length => 255#, :required => true | |||||
property :address, String, :length => 255#, :required => true | |||||
property :postcode, String#, :required => true | |||||
property :easting, Float, :required => true | |||||
property :northing, Float, :required => true | |||||
property :lat, Float, :required => true | |||||
property :lng, Float, :required => true | |||||
has n, :postcodes | |||||
end | |||||
class Postcode | |||||
include DataMapper::Resource | |||||
# Postcode natural key, uppercase with space, eg. "SM1 1EA" | |||||
# Column names derived from Ordnance Survey CodePoint Open | |||||
property :postcode, String, :key => true | |||||
property :positional_quality_indicator, Integer | |||||
property :eastings, Integer, :required => true | |||||
property :northings, Integer, :required => true | |||||
property :country_code, String, :required => true | |||||
property :nhs_regional_ha_code, String, :required => true | |||||
property :nhs_ha_code, String, :required => true | |||||
property :admin_county_code, String # NULL within Greater London | |||||
property :admin_district_code, String, :required => true # e.g. London Borough of Sutton | |||||
property :admin_ward_code, String, :required => true # e.g. Sutton Central | |||||
property :lat, Float, :required => true | |||||
property :lng, Float, :required => true | |||||
property :ward_id, Integer, :required => true # Sutton Council | |||||
property :constituency_id, Integer, :required => false # UK Parliament | |||||
property :polling_station_id, String, :length => 2 | |||||
belongs_to :district, :child_key => [:ward_id] | |||||
belongs_to :polling_station | |||||
def self.finder(postcode) | |||||
postcode = postcode.strip.upcase | |||||
if o = self.get(postcode) | |||||
return o | |||||
end | |||||
result = Pat.get(postcode) | |||||
unless result.code == 404 | |||||
# cache API result | |||||
self.create( | |||||
:postcode => postcode, | |||||
:lat => result['geo']['lat'], | |||||
:lng => result['geo']['lng'], | |||||
:district_name => result['administrative']['district']['title'], | |||||
:district_code => result['administrative']['district']['uri'].match(/.+\/(.+)$/)[1], | |||||
:ward_name => result['administrative']['ward']['title'], | |||||
:ward_code => result['administrative']['ward']['uri'].match(/.+\/(.+)$/)[1] | |||||
) | |||||
else | |||||
# invalid postcode | |||||
nil | |||||
end | |||||
end | |||||
end | |||||
class Candidate | class Candidate | ||||
include DataMapper::Resource | include DataMapper::Resource | ||||
@@ -136,7 +69,7 @@ class Candidate | |||||
property :forenames, String, :required => true | property :forenames, String, :required => true | ||||
property :surname, String, :required => true, :index => true | property :surname, String, :required => true, :index => true | ||||
has n, :candidacies | |||||
has n, :candidacies#, 'Candidacy' | |||||
def short_name | def short_name | ||||
@forenames.split(' ')[0] + ' ' + @surname | @forenames.split(' ')[0] + ' ' + @surname | ||||
@@ -171,7 +104,7 @@ class Candidacy | |||||
property :postcode, String | property :postcode, String | ||||
property :position, Integer # Position of this candidate in this district. (1..n) | property :position, Integer # Position of this candidate in this district. (1..n) | ||||
property :seats, Integer # Number of seats won by this candidacy (0 or 1) | property :seats, Integer # Number of seats won by this candidacy (0 or 1) | ||||
property :labcoop, Boolean, :default => false # Candidacy is for joint Labour/Co-op party | |||||
property :labcoop, String, :default => '0' # Candidacy is for joint Labour/Co-op party | |||||
belongs_to :election | belongs_to :election | ||||
belongs_to :candidate | belongs_to :candidate | ||||
@@ -179,19 +112,6 @@ class Candidacy | |||||
belongs_to :district | belongs_to :district | ||||
end | end | ||||
class Campaign | |||||
include DataMapper::Resource | |||||
property :party_id, Integer, :key => true | |||||
property :election_id, Integer, :key => true | |||||
property :party_url, String, :length => 255 | |||||
property :manifesto_html_url, String, :length => 255 | |||||
property :manifesto_pdf_url, String, :length => 255 | |||||
belongs_to :party | |||||
belongs_to :election | |||||
end | |||||
class Election | class Election | ||||
include DataMapper::Resource | include DataMapper::Resource | ||||
@@ -204,7 +124,6 @@ class Election | |||||
has n, :candidacies | has n, :candidacies | ||||
has n, :polls | has n, :polls | ||||
belongs_to :body | belongs_to :body | ||||
has n, :campaigns | |||||
def self.past | def self.past | ||||
self.all(:d.lt => Time.now.to_s, :order => [ :d.desc ]) | self.all(:d.lt => Time.now.to_s, :order => [ :d.desc ]) | ||||
@@ -238,7 +157,6 @@ class District | |||||
property :ons_district_code, String | property :ons_district_code, String | ||||
belongs_to :body | belongs_to :body | ||||
has n, :postcodes, :child_key => [:ward_id] | |||||
has n, :polls | has n, :polls | ||||
def self.slugify(name) | def self.slugify(name) | ||||
@@ -267,8 +185,9 @@ class Party | |||||
property :colour, String | property :colour, String | ||||
has n, :candidacies | has n, :candidacies | ||||
has n, :campaigns | |||||
# has n, :campaigns | |||||
end | end | ||||
DataMapper.setup(:default, ENV['DATABASE_URL']) | DataMapper.setup(:default, ENV['DATABASE_URL']) | ||||
DataMapper.repository(:default).adapter.resource_naming_convention = DataMapper::NamingConventions::Resource::UnderscoredAndPluralized | |||||
DataMapper.auto_upgrade! | DataMapper.auto_upgrade! |
@@ -23,7 +23,7 @@ | |||||
%td | %td | ||||
%a{ :href => "/bodies/#{ccy['body_slug']}/elections/#{ccy['d']}" } | %a{ :href => "/bodies/#{ccy['body_slug']}/elections/#{ccy['d']}" } | ||||
-# Postgres returns ccy['d'] as a Date and sqlite returns it as a String | -# Postgres returns ccy['d'] as a Date and sqlite returns it as a String | ||||
= long_date(ccy['d'].to_time) | |||||
= long_date(ccy['d']) | |||||
%td= party_name(ccy['labcoop'], ccy['party_name']) | %td= party_name(ccy['labcoop'], ccy['party_name']) | ||||
%td | %td | ||||
%a{ :href => "/bodies/#{ccy['body_slug']}" } | %a{ :href => "/bodies/#{ccy['body_slug']}" } | ||||
@@ -11,7 +11,7 @@ | |||||
- unless election_index == 0 | - unless election_index == 0 | ||||
- previous_election = elections_for_this_body[election_index - 1] | - previous_election = elections_for_this_body[election_index - 1] | ||||
%a{ :href => "/bodies/#{election.body.slug}/elections/#{previous_election.d}", :title => "#{previous_election.kind} #{short_date(previous_election.d)}" } | |||||
%a{ :href => "/bodies/#{election.body.slug}/elections/#{previous_election.d.to_s}", :title => "#{previous_election.kind} #{short_date(previous_election.d.to_s)}" } | |||||
« | « | ||||
Previous | Previous | ||||
= election.body.name | = election.body.name | ||||
@@ -20,7 +20,7 @@ | |||||
- unless election_index == elections_for_this_body.size - 1 | - unless election_index == elections_for_this_body.size - 1 | ||||
- next_election = elections_for_this_body[election_index + 1] | - next_election = elections_for_this_body[election_index + 1] | ||||
%a{ :href => "/bodies/#{election.body.slug}/elections/#{next_election.d}", :title => "#{next_election.kind} #{short_date(next_election.d)}" } | |||||
%a{ :href => "/bodies/#{election.body.slug}/elections/#{next_election.d.to_s}", :title => "#{next_election.kind} #{short_date(next_election.d)}" } | |||||
Next | Next | ||||
= election.body.name | = election.body.name | ||||
election | election | ||||
@@ -131,7 +131,7 @@ | |||||
- election.polls.each do |p| | - election.polls.each do |p| | ||||
%tr | %tr | ||||
%td | %td | ||||
%a{ :href => "/bodies/#{election.body.slug}/elections/#{election.d}/#{election.body.districts_name}/#{p.district.slug}"} | |||||
%a{ :href => "/bodies/#{election.body.slug}/elections/#{election.d.to_s}/#{election.body.districts_name}/#{p.district.slug}"} | |||||
= p.district.name | = p.district.name | ||||
- p.successful_candidacies.each do |sc| | - p.successful_candidacies.each do |sc| | ||||
%td{ :style => "background-color: #{sc.party.colour};" } | %td{ :style => "background-color: #{sc.party.colour};" } | ||||