everypolitician-popolo 0.6.1 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 262682eaaa9963c7749cd96f5a5134fab88e815f
4
- data.tar.gz: 3d90b328a132fba3ea0a3d2100f5a00e585dd1b1
3
+ metadata.gz: c51032c9ca912048c8d0c49fce9d6226da6247eb
4
+ data.tar.gz: f89f6deb7b30f34d2d148801da1c7ac6470f4737
5
5
  SHA512:
6
- metadata.gz: 29f9a20d955a4281608a4482fc8374c5dee19d75c0b040f6f7a46aeaa70715c1104000b6c074655394c48717226bffd755396d873a6a56bd946f146649fd5786
7
- data.tar.gz: 593e9de9b997aa687a2e3967918938ed49a30b2964953e772b3fd7dd0369d0caf4462f8c0765a769c6e21f8d6e4ec0bed0e75328276f1dcb2dc2e6bc9d574dc9
6
+ metadata.gz: dd0c15c730568c77cdf45ccc8d5edf8d751cea35bd489b1999d87b0aa0f2d65665460961a2d2799e8b34e6c3640d9dbffa8f41bf970935bac9eb38b219c9d513
7
+ data.tar.gz: d53eb7d691c1c4f263442358669ba66708fd160d95305396017063c652aab7abc503dc309a9ecb5bd912ca4b58e40caad8f566088f8c2113cac5d3996d578a98
data/.gitignore CHANGED
@@ -7,3 +7,4 @@
7
7
  /pkg/
8
8
  /spec/reports/
9
9
  /tmp/
10
+ .rubocop-https---raw-githubusercontent-com-everypolitician-everypolitician-data-master--rubocop-base-yml
@@ -3,6 +3,44 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  This project adheres to [Semantic Versioning](http://semver.org/).
5
5
 
6
+ ## [0.8.0] - 2016-10-28
7
+
8
+ ### Added
9
+
10
+ - `Popolo#latest_term` replaces `Popolo#current_term` and has the same
11
+ functionality. It will return the most recent term for the legislature
12
+ but it is not guaranteed that the term will be a current one. You
13
+ should check the `start_date` and `end_date` of the term to determine that.
14
+ - Added `Election` and `LegislativePeriod` classes for `Event`s.
15
+ - `Collection#where` now returns a `Collection` rather than an `Array`
16
+ - Added the following shortcut methods:
17
+ - `Membership#area`
18
+ - `Membership#legislative_period` or `Membership#term`
19
+ - `Membership#person`
20
+ - `Membership#on_behalf_of` or `Membership#party`
21
+ - `Membership#organization`
22
+ - `Membership#post`
23
+ - `Post#organization`
24
+ - `Person#memberships`
25
+
26
+ ### Changed
27
+
28
+ - Accessors are no longer generated dynamically for Popolo properties,
29
+ which means that all normal accessor methods will now exist even where
30
+ a record doesn’t have that property.
31
+
32
+ ### Deprecated
33
+
34
+ - `Popolo#current_term` - use `latest_term` instead.
35
+
36
+ ## [0.7.0] - 2016-09-26
37
+
38
+ ### Added
39
+
40
+ - Property lookups are now cached the first time they are used so
41
+ multiple searches on the same property should be much quicker,
42
+ especially on large data sets.
43
+
6
44
  ## [0.6.1] - 2016-09-12
7
45
 
8
46
  ### Fixes
@@ -75,3 +113,5 @@ exist, rather than blowing up.
75
113
  [0.4.0]: https://github.com/everypolitician/everypolitician-popolo/compare/v0.3.0...v0.4.0
76
114
  [0.5.0]: https://github.com/everypolitician/everypolitician-popolo/compare/v0.4.0...v0.5.0
77
115
  [0.6.0]: https://github.com/everypolitician/everypolitician-popolo/compare/v0.5.0...v0.6.0
116
+ [0.7.0]: https://github.com/everypolitician/everypolitician-popolo/compare/v0.6.0...v0.7.0
117
+ [0.8.0]: https://github.com/everypolitician/everypolitician-popolo/compare/v0.7.0...v0.8.0
@@ -18,6 +18,8 @@ Gem::Specification.new do |spec|
18
18
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
19
19
  spec.require_paths = ['lib']
20
20
 
21
+ spec.add_dependency 'require_all'
22
+
21
23
  spec.add_development_dependency 'bundler', '~> 1.11'
22
24
  spec.add_development_dependency 'rake', '~> 10.0'
23
25
  spec.add_development_dependency 'minitest', '~> 5.0'
@@ -1,13 +1,7 @@
1
- require 'everypolitician/popolo/version'
2
- require 'everypolitician/popolo/collection'
3
- require 'everypolitician/popolo/entity'
4
- require 'everypolitician/popolo/person'
5
- require 'everypolitician/popolo/organization'
6
- require 'everypolitician/popolo/area'
7
- require 'everypolitician/popolo/event'
8
- require 'everypolitician/popolo/post'
9
- require 'everypolitician/popolo/membership'
10
1
  require 'json'
2
+ require 'require_all'
3
+
4
+ require_rel 'popolo'
11
5
 
12
6
  module Everypolitician
13
7
  module Popolo
@@ -30,38 +24,46 @@ module Everypolitician
30
24
  end
31
25
 
32
26
  def persons
33
- People.new(popolo[:persons], self)
27
+ @persons ||= People.new(popolo[:persons], self)
34
28
  end
35
29
 
36
30
  def organizations
37
- Organizations.new(popolo[:organizations], self)
31
+ @organizations ||= Organizations.new(popolo[:organizations], self)
38
32
  end
39
33
 
40
34
  def areas
41
- Areas.new(popolo[:areas], self)
35
+ @areas ||= Areas.new(popolo[:areas], self)
42
36
  end
43
37
 
44
38
  def events
45
- Events.new(popolo[:events], self)
39
+ # do the sorting at the popolo level so we still get an Events object back
40
+ @events ||= Events.new(popolo[:events].to_a.sort_by { |e| e[:start_date] }, self)
46
41
  end
47
42
 
48
43
  def posts
49
- Posts.new(popolo[:posts], self)
44
+ @posts ||= Posts.new(popolo[:posts], self)
50
45
  end
51
46
 
52
47
  def memberships
53
- Memberships.new(popolo[:memberships], self)
48
+ @memberships ||= Memberships.new(popolo[:memberships], self)
49
+ end
50
+
51
+ def elections
52
+ @elections ||= events.elections
54
53
  end
55
54
 
56
55
  def legislative_periods
57
- events.where(classification: 'legislative period').sort_by(&:start_date)
56
+ @legislative_periods ||= events.legislative_periods
58
57
  end
59
58
  alias terms legislative_periods
60
59
 
61
- def current_legislative_period
62
- legislative_periods.last
60
+ def latest_legislative_period
61
+ legislative_periods.max_by(&:start_date)
63
62
  end
64
- alias current_term current_legislative_period
63
+ alias latest_term latest_legislative_period
64
+
65
+ alias current_legislative_period latest_legislative_period
66
+ alias current_term latest_legislative_period
65
67
  end
66
68
  end
67
69
  end
@@ -1,6 +1,29 @@
1
1
  module Everypolitician
2
2
  module Popolo
3
- class Areas < Collection; end
4
- class Area < Entity; end
3
+ class Area < Entity
4
+ def identifiers
5
+ document.fetch(:identifiers, [])
6
+ end
7
+
8
+ def name
9
+ document.fetch(:name, nil)
10
+ end
11
+
12
+ def other_names
13
+ document.fetch(:other_names, [])
14
+ end
15
+
16
+ def type
17
+ document.fetch(:type, nil)
18
+ end
19
+
20
+ def wikidata
21
+ identifier('wikidata')
22
+ end
23
+ end
24
+
25
+ class Areas < Collection
26
+ entity_class Area
27
+ end
5
28
  end
6
29
  end
@@ -6,9 +6,18 @@ module Everypolitician
6
6
  attr_reader :documents
7
7
  attr_reader :popolo
8
8
 
9
+ # set the class that represents individual items in the
10
+ # collection
11
+ def self.entity_class(entity = nil)
12
+ @entity_class ||= entity
13
+ end
14
+
9
15
  def initialize(documents, popolo = nil)
10
- @documents = documents ? documents.map { |p| klass.new(p, popolo) } : []
16
+ @entity_class = {}
17
+ @documents = documents ? documents.map { |p| class_for_entity(p).new(p, popolo) } : []
11
18
  @popolo = popolo
19
+ @indexes = {}
20
+ @of_collection = {}
12
21
  end
13
22
 
14
23
  def each(&block)
@@ -25,32 +34,29 @@ module Everypolitician
25
34
  end
26
35
 
27
36
  def where(attributes = {})
28
- select do |object|
29
- attributes.all? { |k, v| object.send(k) == v }
30
- end
37
+ new_collection(attributes.map { |k, v| index_for(k.to_sym)[v].to_a }.reduce(:&))
38
+ end
39
+
40
+ def empty?
41
+ count.zero?
42
+ end
43
+
44
+ def of_collection(collection)
45
+ @of_collection[collection] ||= new_collection(select { |e| e.class == collection.entity_class }, collection)
31
46
  end
32
47
 
33
48
  private
34
49
 
35
- # TODO: This feels pretty nasty, is there a better way of working out the
36
- # class name?
37
- def klass
38
- case self.class.to_s.split('::').last
39
- when 'People'
40
- Person
41
- when 'Organizations'
42
- Organization
43
- when 'Memberships'
44
- Membership
45
- when 'Events'
46
- Event
47
- when 'Posts'
48
- Post
49
- when 'Areas'
50
- Area
51
- else
52
- raise "Unknown class: #{self.class}"
53
- end
50
+ def index_for(attr)
51
+ @indexes[attr] ||= group_by(&attr)
52
+ end
53
+
54
+ def new_collection(entities, klass = self.class)
55
+ klass.new(entities.to_a.map(&:document), popolo)
56
+ end
57
+
58
+ def class_for_entity(_document)
59
+ self.class.entity_class
54
60
  end
55
61
  end
56
62
  end
@@ -0,0 +1,10 @@
1
+ module Everypolitician
2
+ module Popolo
3
+ class Election < Event
4
+ classification 'general election'
5
+ end
6
+ class Elections < Collection
7
+ entity_class Election
8
+ end
9
+ end
10
+ end
@@ -1,10 +1,22 @@
1
1
  module Everypolitician
2
2
  module Popolo
3
3
  class Entity
4
- attr_accessor :id
5
4
  attr_reader :document
6
5
  attr_reader :popolo
7
6
 
7
+ def self.classification(classification = nil)
8
+ @classification ||= classification
9
+ end
10
+
11
+ def self.inherited(subclass)
12
+ @subclasses ||= []
13
+ @subclasses.push(subclass)
14
+ end
15
+
16
+ def self.subclasses
17
+ @subclasses || []
18
+ end
19
+
8
20
  def initialize(document, popolo = nil)
9
21
  @document = document
10
22
  @popolo = popolo
@@ -18,6 +30,10 @@ module Everypolitician
18
30
  end
19
31
  end
20
32
 
33
+ def id
34
+ document.fetch(:id, nil)
35
+ end
36
+
21
37
  def [](key)
22
38
  document[key]
23
39
  end
@@ -38,6 +54,10 @@ module Everypolitician
38
54
  def identifier(scheme)
39
55
  identifiers.find(-> { {} }) { |i| i[:scheme] == scheme }[:identifier]
40
56
  end
57
+
58
+ def wikidata
59
+ identifier('wikidata')
60
+ end
41
61
  end
42
62
  end
43
63
  end
@@ -1,8 +1,43 @@
1
1
  module Everypolitician
2
2
  module Popolo
3
- class Events < Collection; end
4
3
  class Event < Entity
5
- attr_accessor :start_date, :end_date
4
+ def start_date
5
+ document.fetch(:start_date, nil)
6
+ end
7
+
8
+ def end_date
9
+ document.fetch(:end_date, nil)
10
+ end
11
+
12
+ def name
13
+ document.fetch(:name, nil)
14
+ end
15
+
16
+ def classification
17
+ document.fetch(:classification, nil)
18
+ end
19
+
20
+ def organization_id
21
+ document.fetch(:organization_id, nil)
22
+ end
23
+ end
24
+
25
+ class Events < Collection
26
+ entity_class Event
27
+
28
+ def elections
29
+ of_collection(Elections)
30
+ end
31
+
32
+ def legislative_periods
33
+ of_collection(LegislativePeriods)
34
+ end
35
+
36
+ def class_for_entity(document)
37
+ @entity_class[document[:classification]] ||= self.class.entity_class.subclasses.find do |e|
38
+ e.classification == document[:classification]
39
+ end || self.class.entity_class
40
+ end
6
41
  end
7
42
  end
8
43
  end
@@ -0,0 +1,14 @@
1
+ module Everypolitician
2
+ module Popolo
3
+ class LegislativePeriod < Event
4
+ classification 'legislative period'
5
+
6
+ def memberships
7
+ @memberships ||= popolo.memberships.where(legislative_period_id: id, organization_id: organization_id)
8
+ end
9
+ end
10
+ class LegislativePeriods < Collection
11
+ entity_class LegislativePeriod
12
+ end
13
+ end
14
+ end
@@ -1,13 +1,78 @@
1
1
  module Everypolitician
2
2
  module Popolo
3
- class Memberships < Collection; end
4
-
5
3
  class Membership < Entity
6
- attr_accessor :person_id, :on_behalf_of_id, :organization_id, :area_id, :role, :start_date, :end_date
4
+ def person_id
5
+ document.fetch(:person_id, nil)
6
+ end
7
+
8
+ def on_behalf_of_id
9
+ document.fetch(:on_behalf_of_id, nil)
10
+ end
11
+
12
+ def organization_id
13
+ document.fetch(:organization_id, nil)
14
+ end
15
+
16
+ def area_id
17
+ document.fetch(:area_id, nil)
18
+ end
19
+
20
+ def legislative_period_id
21
+ document.fetch(:legislative_period_id, nil)
22
+ end
23
+
24
+ def post_id
25
+ document.fetch(:post_id, nil)
26
+ end
27
+
28
+ def role
29
+ document.fetch(:role, nil)
30
+ end
31
+
32
+ def start_date
33
+ document.fetch(:start_date, nil)
34
+ end
35
+
36
+ def end_date
37
+ document.fetch(:end_date, nil)
38
+ end
7
39
 
8
40
  def person
9
41
  popolo.persons.find_by(id: person_id)
10
42
  end
43
+
44
+ def organization
45
+ popolo.organizations.find_by(id: organization_id)
46
+ end
47
+
48
+ def legislative_period
49
+ popolo.events.find_by(id: legislative_period_id)
50
+ end
51
+
52
+ alias term legislative_period
53
+
54
+ def on_behalf_of
55
+ popolo.organizations.find_by(id: on_behalf_of_id)
56
+ end
57
+
58
+ alias party on_behalf_of
59
+
60
+ def area
61
+ popolo.areas.find_by(id: area_id)
62
+ end
63
+
64
+ def post
65
+ popolo.posts.find_by(id: post_id)
66
+ end
67
+
68
+ def ==(other)
69
+ self.class == other.class && instance_variables.all? { |v| instance_variable_get(v) == other.instance_variable_get(v) }
70
+ end
71
+ alias eql? ==
72
+ end
73
+
74
+ class Memberships < Collection
75
+ entity_class Membership
11
76
  end
12
77
  end
13
78
  end
@@ -1,11 +1,45 @@
1
1
  module Everypolitician
2
2
  module Popolo
3
- class Organizations < Collection; end
4
-
5
3
  class Organization < Entity
6
- def wikidata
7
- identifier('wikidata')
4
+ def classification
5
+ document.fetch(:classification, nil)
6
+ end
7
+
8
+ def identifiers
9
+ document.fetch(:identifiers, [])
10
+ end
11
+
12
+ def image
13
+ document.fetch(:image, nil)
14
+ end
15
+
16
+ def links
17
+ document.fetch(:links, [])
18
+ end
19
+
20
+ def name
21
+ document.fetch(:name, nil)
8
22
  end
23
+
24
+ def other_names
25
+ document.fetch(:other_names, [])
26
+ end
27
+
28
+ # TODO: this should be pushed into a Legislature class when we split
29
+ # this into Party and Legislature classes
30
+ def seats
31
+ document.fetch(:seats, nil)
32
+ end
33
+
34
+ def srgb
35
+ document.fetch(:srgb, nil)
36
+ end
37
+ alias associated_colour srgb
38
+ alias associated_color srgb
39
+ end
40
+
41
+ class Organizations < Collection
42
+ entity_class Organization
9
43
  end
10
44
  end
11
45
  end
@@ -1,11 +1,47 @@
1
1
  module Everypolitician
2
2
  module Popolo
3
- class People < Collection; end
4
-
5
3
  class Person < Entity
6
4
  class Error < StandardError; end
7
5
 
8
- attr_accessor :name, :email, :image, :gender, :birth_date, :death_date, :honorific_prefix, :honorific_suffix
6
+ def name
7
+ document.fetch(:name, nil)
8
+ end
9
+
10
+ def email
11
+ document.fetch(:email, nil)
12
+ end
13
+
14
+ def image
15
+ document.fetch(:image, nil)
16
+ end
17
+
18
+ def gender
19
+ document.fetch(:gender, nil)
20
+ end
21
+
22
+ def national_identity
23
+ document.fetch(:national_identity, nil)
24
+ end
25
+
26
+ def summary
27
+ document.fetch(:summary, nil)
28
+ end
29
+
30
+ def birth_date
31
+ document.fetch(:birth_date, nil)
32
+ end
33
+
34
+ def death_date
35
+ document.fetch(:death_date, nil)
36
+ end
37
+
38
+ def honorific_prefix
39
+ document.fetch(:honorific_prefix, nil)
40
+ end
41
+
42
+ def honorific_suffix
43
+ document.fetch(:honorific_suffix, nil)
44
+ end
9
45
 
10
46
  def links
11
47
  document.fetch(:links, [])
@@ -39,14 +75,38 @@ module Everypolitician
39
75
  link('facebook')
40
76
  end
41
77
 
42
- def wikidata
43
- identifier('wikidata')
44
- end
45
-
46
78
  def sort_name
47
79
  name
48
80
  end
49
81
 
82
+ def family_name
83
+ document.fetch(:family_name, nil)
84
+ end
85
+
86
+ def given_name
87
+ document.fetch(:given_name, nil)
88
+ end
89
+
90
+ def patronymic_name
91
+ document.fetch(:patronymic_name, nil)
92
+ end
93
+
94
+ def identifiers
95
+ document.fetch(:identifiers, [])
96
+ end
97
+
98
+ def images
99
+ document.fetch(:images, [])
100
+ end
101
+
102
+ def other_names
103
+ document.fetch(:other_names, [])
104
+ end
105
+
106
+ def sources
107
+ document.fetch(:sources, [])
108
+ end
109
+
50
110
  def name_at(date)
51
111
  return name unless key?(:other_names)
52
112
  historic = other_names.select { |n| n.key?(:end_date) }
@@ -63,5 +123,9 @@ module Everypolitician
63
123
  popolo.memberships.where(person_id: id)
64
124
  end
65
125
  end
126
+
127
+ class People < Collection
128
+ entity_class Person
129
+ end
66
130
  end
67
131
  end
@@ -1,8 +1,20 @@
1
1
  module Everypolitician
2
2
  module Popolo
3
- class Posts < Collection; end
4
3
  class Post < Entity
5
- attr_reader :label
4
+ def label
5
+ document.fetch(:label, nil)
6
+ end
7
+
8
+ def organization_id
9
+ document.fetch(:organization_id, nil)
10
+ end
11
+
12
+ def organization
13
+ popolo.organizations.find_by(id: organization_id)
14
+ end
15
+ end
16
+ class Posts < Collection
17
+ entity_class Post
6
18
  end
7
19
  end
8
20
  end
@@ -1,5 +1,5 @@
1
1
  module Everypolitician
2
2
  module Popolo
3
- VERSION = '0.6.1'.freeze
3
+ VERSION = '0.8.0'.freeze
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: everypolitician-popolo
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.1
4
+ version: 0.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Mytton
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-09-12 00:00:00.000000000 Z
11
+ date: 2016-10-28 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: require_all
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: bundler
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -103,8 +117,10 @@ files:
103
117
  - lib/everypolitician/popolo.rb
104
118
  - lib/everypolitician/popolo/area.rb
105
119
  - lib/everypolitician/popolo/collection.rb
120
+ - lib/everypolitician/popolo/election.rb
106
121
  - lib/everypolitician/popolo/entity.rb
107
122
  - lib/everypolitician/popolo/event.rb
123
+ - lib/everypolitician/popolo/legislative_period.rb
108
124
  - lib/everypolitician/popolo/membership.rb
109
125
  - lib/everypolitician/popolo/organization.rb
110
126
  - lib/everypolitician/popolo/person.rb