hdo-storting-importer 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -5,12 +5,32 @@ module Hdo
5
5
 
6
6
  attr_reader :external_id, :name
7
7
 
8
+ def self.type_name
9
+ 'party'
10
+ end
11
+
12
+ def self.description
13
+ 'a political party'
14
+ end
15
+
16
+ def self.xml_example(builder = Util.builder)
17
+ new("DEM", "Democratic Party").to_hdo_xml(builder)
18
+ end
19
+
20
+ def self.fields
21
+ [EXTERNAL_ID_FIELD, Field.new(:name, true, :string, 'The name of the party.')]
22
+ end
23
+
8
24
  def self.from_storting_doc(doc)
9
25
  doc.css("partier_liste parti").map do |node|
10
26
  new node.css("id").first.text, node.css("navn").first.text
11
27
  end
12
28
  end
13
29
 
30
+ def self.from_hdo_doc(doc)
31
+ doc.css("parties > party").map { |e| from_hdo_node(e) }
32
+ end
33
+
14
34
  def self.from_hdo_node(node)
15
35
  new node.css("externalId").first.text, node.css("name").first.text
16
36
  end
@@ -1,3 +1,5 @@
1
+ # encoding: UTF-8
2
+
1
3
  require 'csv'
2
4
 
3
5
  module Hdo
@@ -6,6 +8,47 @@ module Hdo
6
8
  attr_reader :party, :body, :general, :categories, :source, :page
7
9
  alias_method :general?, :general
8
10
 
11
+ def self.type_name
12
+ 'promise'
13
+ end
14
+
15
+ def self.description
16
+ 'a party promise'
17
+ end
18
+
19
+ def self.fields
20
+ [
21
+ Field.new(:party, true, :string, 'The external id of the party.'),
22
+ Field.new(:general, true, :boolean, "Whether this is considered a general promise (i.e. can be ambigious whether it has been fulfilled)."),
23
+ Field.new(:categories, true, :list, "List of category names (matching names imported in <a href='#input-format-category'>&lt;category&gt;</a>)"),
24
+ Field.new(:source, true, :string, "The source of the promise. (TODO: this should always be a URL)"),
25
+ Field.new(:body, true, :string, "The body text of the promise."),
26
+ ]
27
+ end
28
+
29
+ def self.example
30
+ new("H", "Stille strengere krav til orden og oppførsel for å hindre at uro ødelegger undervisningen.", true, ["GRUNNSKOLE"], "PP", 8)
31
+ end
32
+
33
+ def self.xml_example(builder = Util.builder)
34
+ example.to_hdo_xml(builder)
35
+ end
36
+
37
+ def self.from_hdo_doc(doc)
38
+ doc.css("promises > promise").map { |e| from_hdo_node(e) }
39
+ end
40
+
41
+ def self.from_hdo_node(node)
42
+ source, page = node.css("source").first.text.split(":")
43
+
44
+ new node.css("party").first.text,
45
+ node.css("body").first.text,
46
+ node.css("general").first.text == "true",
47
+ node.css("categories > category").map { |e| e.text },
48
+ source,
49
+ page
50
+ end
51
+
9
52
  def self.from_csv(str)
10
53
  # cleanup
11
54
  str.gsub!(/\bFrp\b/, "FrP")
@@ -28,7 +71,7 @@ module Hdo
28
71
  pr[:party].to_s.strip,
29
72
  pr[:body].to_s.strip,
30
73
  pr[:general].to_s.downcase == 'ja',
31
- pr[:categories].split(",").map(&:upcase).map(&:strip),
74
+ pr[:categories].to_s.split(",").map(&:upcase).map(&:strip),
32
75
  pr[:source].to_s.strip,
33
76
  pr[:page].to_s.strip
34
77
  )
@@ -44,6 +87,18 @@ module Hdo
44
87
  @page = page
45
88
  end
46
89
 
90
+ def to_hdo_xml(builder = Util.builder)
91
+ builder.promise do |promise|
92
+ promise.party party
93
+ promise.general general?
94
+ promise.categories do |cats|
95
+ categories.each { |e| cats.category e }
96
+ end
97
+ promise.source [source, page].join(":")
98
+ promise.body body
99
+ end
100
+ end
101
+
47
102
  end
48
103
  end
49
104
  end
@@ -18,31 +18,12 @@ module Hdo
18
18
  builder.promises do |promises|
19
19
  @promises.each do |data|
20
20
  next if data.body == "Løftetekst" || data.body.nil? || data.body.empty?
21
- add_promise(promises, data)
21
+ data.to_hdo_xml(promises)
22
22
  end
23
23
  end
24
24
 
25
25
  builder.target!
26
26
  end
27
-
28
- def add_promise(promises, data)
29
- promises.promise do |promise|
30
- promise.party data.party.strip
31
- promise.general data.general
32
- promise.categories do |categories|
33
- data.categories.each do |name|
34
- categories.category name
35
- end
36
- end
37
-
38
- promise.source [data.source, data.page].join(":")
39
- promise.body data.body.strip
40
- end
41
- rescue
42
- STDERR.puts data.inspect
43
- raise
44
- end
45
27
  end
46
-
47
28
  end
48
29
  end
@@ -1,3 +1,5 @@
1
+ # encoding: UTF-8
2
+
1
3
  module Hdo
2
4
  module StortingImporter
3
5
  class Representative
@@ -8,6 +10,47 @@ module Hdo
8
10
 
9
11
  attr_accessor :vote_result
10
12
 
13
+ def self.type_name
14
+ 'representative'
15
+ end
16
+
17
+ def self.description
18
+ 'a member of parliament'
19
+ end
20
+
21
+ def self.example
22
+ new(
23
+ 'ADA',
24
+ 'André Oktay',
25
+ 'Dahl',
26
+ 'M',
27
+ '1975-07-07T00:00:00',
28
+ '0001-01-01T00:00:00',
29
+ 'Akershus',
30
+ 'Høyre',
31
+ ['Justiskomiteen'],
32
+ '2011-2012'
33
+ )
34
+ end
35
+
36
+ def self.xml_example(builder = Util.builder)
37
+ example.to_hdo_xml(builder)
38
+ end
39
+
40
+ def self.fields
41
+ [
42
+ EXTERNAL_ID_FIELD,
43
+ Field.new(:firstName, true, :string, 'The first name of the representative.'),
44
+ Field.new(:lastName, true, :string, 'The last name of the representative.'),
45
+ Field.new(:period, true, :string, "An identifier for the period the representative is elected for."),
46
+ Field.new(:district, true, :string, "The electoral district the representative belongs to. Must match the 'name' field of the district type."),
47
+ Field.new(:party, true, :string, "The name of the representative's party."),
48
+ Field.new(:committee, true, :list, "A (possibly empty) list of committees the representative is a member of. This should match the 'name' field of the committee type."),
49
+ Field.new(:dateOfBirth, true, :string, "The representative's birth date."),
50
+ Field.new(:dateOfDeath, false, :string, "The representative's death date."),
51
+ ]
52
+ end
53
+
11
54
  def self.from_storting_doc(doc)
12
55
  nodes = doc.css("dagensrepresentant")
13
56
  nodes += doc.css("representant")
@@ -39,6 +82,10 @@ module Hdo
39
82
  )
40
83
  end
41
84
 
85
+ def self.from_hdo_doc(doc)
86
+ doc.css("representatives > representative").map { |e| from_hdo_node e }
87
+ end
88
+
42
89
  def self.from_hdo_node(node)
43
90
  district_node = node.css("district").first
44
91
  district = district_node ? district_node.text : ''
@@ -1,5 +1,5 @@
1
1
  module Hdo
2
2
  module StortingImporter
3
- VERSION = "0.0.1"
3
+ VERSION = "0.0.2"
4
4
  end
5
5
  end
@@ -1,3 +1,5 @@
1
+ # encoding: UTF-8
2
+
1
3
  module Hdo
2
4
  module StortingImporter
3
5
  class Vote
@@ -10,6 +12,47 @@ module Hdo
10
12
  alias_method :personal?, :personal
11
13
  alias_method :enacted?, :enacted
12
14
 
15
+ def self.type_name
16
+ 'vote'
17
+ end
18
+
19
+ def self.description
20
+ 'a parliamentary vote'
21
+ end
22
+
23
+ def self.fields
24
+ [
25
+ EXTERNAL_ID_FIELD,
26
+ Field.new(:externalIssueId, true, :string, "The id (matching the issue's externalId) of the issue being voted on."),
27
+ Field.new(:counts, true, :element, "An element with <for>, <against> and <absent> counts (see example)."),
28
+ Field.new(:enacted, true, :boolean, "Whether the proposal was enacted."),
29
+ Field.new(:subject, true, :string, "The subject of the vote."),
30
+ Field.new(:method, true, :string, "??"),
31
+ Field.new(:resultType, true, :string, "??"),
32
+ Field.new(:time, true, :string, "The timestamp for the vote."),
33
+ Field.new(:representatives, true, :element, "An element with each representative's vote. The element should contain a set of <a href='#input-format-representative'>&lt;representative&gt;</a> elements with an extra subnode 'voteResult', where valid values are 'for', 'against', 'absent'. See example."),
34
+ Field.new(:propositions, false, :element, "An element with each proposition being voted over. The element should contain a set of <a href='#input-format-proposition'>&lt;proposition&gt;</a> elements. See example."),
35
+ ]
36
+ end
37
+
38
+ def self.example
39
+ vote = new('2175', '51448', true, false, 'Forslag 24 - 26 på vegne av Per Olaf Lundteigen', 'ikke_spesifisert', 'ikke_spesifisert', '2012-04-12T16:37:27.053', 2, 96, 71)
40
+
41
+ rep = Representative.example
42
+ rep.vote_result = 'for'
43
+ vote.representatives << rep
44
+
45
+ prop = Vote::Proposition.example
46
+
47
+ vote.propositions << prop
48
+
49
+ vote
50
+ end
51
+
52
+ def self.xml_example(builder = Util.builder)
53
+ example.to_hdo_xml(builder)
54
+ end
55
+
13
56
  def self.from_storting_doc(doc)
14
57
  issue_id = doc.css("sak_id").first.text
15
58
 
@@ -35,6 +78,10 @@ module Hdo
35
78
  end
36
79
  end
37
80
 
81
+ def self.from_hdo_doc(doc)
82
+ doc.css("votes > vote").map { |e| from_hdo_node(e) }
83
+ end
84
+
38
85
  def self.from_hdo_node(node)
39
86
  external_id = node.css("externalId").first.text
40
87
  external_issue_id = node.css("externalIssueId").first.text
@@ -140,6 +187,32 @@ module Hdo
140
187
  end
141
188
 
142
189
  class Proposition < Struct.new(:external_id, :description, :on_behalf_of, :body, :delivered_by)
190
+ def self.type_name
191
+ 'proposition'
192
+ end
193
+
194
+ def self.example
195
+ new('1234', 'description', 'on behalf of', 'body', Representative.example)
196
+ end
197
+
198
+ def self.description
199
+ 'a proposition being voted over'
200
+ end
201
+
202
+ def self.fields
203
+ [
204
+ EXTERNAL_ID_FIELD,
205
+ Field.new(:description, true, :string, 'A short description of the proposition.'),
206
+ Field.new(:deliveredBy, true, :string, "The representative that delivered the proposition. The element should contain a <a href='#input-format-representative'>&lt;representative&gt;</a> element."),
207
+ Field.new(:onBehalfOf, true, :string, "Description of who is behind the proposition."),
208
+ Field.new(:body, true, :string, "The full text of the proposition."),
209
+ ]
210
+ end
211
+
212
+ def self.xml_example(builder = Util.builder)
213
+ example.to_hdo_xml(builder)
214
+ end
215
+
143
216
  def self.from_hdo_node(node)
144
217
  external_id = node.css("externalId").first.text
145
218
  description = node.css("description").first.text
@@ -3,6 +3,9 @@ module Hdo
3
3
  def self.root
4
4
  @root ||= File.expand_path("../../..", __FILE__)
5
5
  end
6
+
7
+ Field = Struct.new(:name, :required, :type, :description)
8
+ EXTERNAL_ID_FIELD = Field.new(:externalId, false, :string, 'An optional external id, matching potential id fields in the input data. This is useful if you want to reimport previous data without creating duplicates.')
6
9
  end
7
10
  end
8
11
 
@@ -22,7 +25,6 @@ require 'hdo/storting_importer/data_source'
22
25
  require 'hdo/storting_importer/disk_data_source'
23
26
  require 'hdo/storting_importer/api_data_source'
24
27
  require 'hdo/storting_importer/parsing_data_source'
25
- require 'hdo/storting_importer/script_importer'
26
28
 
27
29
  require 'hdo/storting_importer/category'
28
30
  require 'hdo/storting_importer/committee'
@@ -64,13 +64,37 @@ module Hdo
64
64
  XML
65
65
  end
66
66
 
67
- it 'can deserialize HDO XML' do
67
+ it 'can deserialize a HDO XML node' do
68
68
  orig = Category.new("5", "ARBEIDSLIV")
69
69
  orig.children << Category.new("3", "LØNN")
70
70
 
71
71
  Category.from_hdo_node(parse(orig.to_hdo_xml)).should == orig
72
72
  end
73
73
 
74
+ it 'can deserialize a HDO XML doc' do
75
+ orig = Category.new("5", "ARBEIDSLIV")
76
+ orig.children << Category.new("3", "LØNN")
77
+
78
+ Category.from_hdo_doc(parse("<categories>#{orig.to_hdo_xml}</categories>")).should == [orig]
79
+ end
80
+
81
+ it 'has a type name' do
82
+ Category.type_name.should == 'category'
83
+ end
84
+
85
+ it 'has a description' do
86
+ Category.description.should be_kind_of(String)
87
+ end
88
+
89
+ it 'has an XML example' do
90
+ Category.xml_example.should be_kind_of(String)
91
+ end
92
+
93
+ it 'has a list of fields' do
94
+ Category.fields.should_not be_empty
95
+ end
96
+
97
+
74
98
  end
75
99
  end
76
100
  end
@@ -35,11 +35,32 @@ module Hdo
35
35
  XML
36
36
  end
37
37
 
38
- it 'can deserialize HDO XML' do
38
+ it 'can deserialize a HDO XML node' do
39
39
  com = Committee.new("ARBSOS", 'Arbeids- og sosialkomiteen')
40
40
  Committee.from_hdo_node(parse(com.to_hdo_xml)).should == com
41
41
  end
42
42
 
43
+ it 'can deserialize a HDO XML doc' do
44
+ com = Committee.new("ARBSOS", 'Arbeids- og sosialkomiteen')
45
+ Committee.from_hdo_doc(parse("<committees>#{com.to_hdo_xml}</committees>")).should == [com]
46
+ end
47
+
48
+ it 'has a type name' do
49
+ Committee.type_name.should == 'committee'
50
+ end
51
+
52
+ it 'has a description' do
53
+ Committee.description.should be_kind_of(String)
54
+ end
55
+
56
+ it 'has an XML example' do
57
+ Committee.xml_example.should be_kind_of(String)
58
+ end
59
+
60
+ it 'has a list of fields' do
61
+ Committee.fields.should_not be_empty
62
+ end
63
+
43
64
 
44
65
  end
45
66
  end
@@ -43,11 +43,32 @@ module Hdo
43
43
  XML
44
44
  end
45
45
 
46
- it 'can deserialize HDO XML' do
46
+ it 'can deserialize a HDO XML node' do
47
47
  orig = District.new("Ak", "Akershus")
48
48
  District.from_hdo_node(parse(orig.to_hdo_xml)).should == orig
49
49
  end
50
50
 
51
+ it 'can deserialize a HDO XML doc' do
52
+ orig = District.new("Ak", "Akershus")
53
+ District.from_hdo_doc(parse("<districts>#{orig.to_hdo_xml}</districts>")).should == [orig]
54
+ end
55
+
56
+ it 'has a type name' do
57
+ District.type_name.should == 'district'
58
+ end
59
+
60
+ it 'has a description' do
61
+ District.description.should be_kind_of(String)
62
+ end
63
+
64
+ it 'has an XML example' do
65
+ District.xml_example.should be_kind_of(String)
66
+ end
67
+
68
+ it 'has a list of fields' do
69
+ District.fields.should_not be_empty
70
+ end
71
+
51
72
 
52
73
  end
53
74
  end
@@ -5,21 +5,6 @@ module Hdo
5
5
  module StortingImporter
6
6
  describe Issue do
7
7
 
8
- def create_issue
9
- Issue.new(
10
- "53520",
11
- "Inngåelse av avtale om opprettelse av sekretariatet for Den nordlige dimensjons partnerskap for helse og livskvalitet (NDPHS)",
12
- "Samtykke til inngåelse av avtale av 25. november 2011 om opprettelse av sekretariatet for Den nordlige dimensjons partnerskap for helse og livskvalitet (NDPHS)",
13
- "alminneligsak",
14
- "mottatt",
15
- "2012-04-20T00:00:00",
16
- "Prop. 90 S (2011-2012)",
17
- "proposisjon",
18
- "Transport- og kommunikasjonskomiteen",
19
- ['UTENRIKSSAKER', 'TRAKTATER', 'NORDISK SAMARBEID']
20
- )
21
- end
22
-
23
8
  it 'builds issues from Storting XML list' do
24
9
  xml = <<-XML
25
10
  <?xml version="1.0" encoding="utf-8"?>
@@ -85,7 +70,7 @@ module Hdo
85
70
  end
86
71
 
87
72
  it 'can serialize as HDO XML' do
88
- create_issue.to_hdo_xml.should == <<-XML
73
+ Issue.example.to_hdo_xml.should == <<-XML
89
74
  <issue>
90
75
  <externalId>53520</externalId>
91
76
  <summary>Inngåelse av avtale om opprettelse av sekretariatet for Den nordlige dimensjons partnerskap for helse og livskvalitet (NDPHS)</summary>
@@ -105,11 +90,32 @@ module Hdo
105
90
  XML
106
91
  end
107
92
 
108
- it 'can deserialize HDO XML' do
109
- orig = create_issue
93
+ it 'can deserialize an HDO XML node' do
94
+ orig = Issue.example
110
95
  Issue.from_hdo_node(parse(orig.to_hdo_xml)).should == orig
111
96
  end
112
97
 
98
+ it 'can deserialize an HDO XML doc' do
99
+ orig = Issue.example
100
+ Issue.from_hdo_doc(parse("<issues>#{orig.to_hdo_xml}</issues>")).should == [orig]
101
+ end
102
+
103
+ it 'has a type name' do
104
+ Issue.type_name.should == 'issue'
105
+ end
106
+
107
+ it 'has a description' do
108
+ Issue.description.should be_kind_of(String)
109
+ end
110
+
111
+ it 'has an XML example' do
112
+ Issue.xml_example.should be_kind_of(String)
113
+ end
114
+
115
+ it 'has a list of fields' do
116
+ Issue.fields.should_not be_empty
117
+ end
118
+
113
119
  end
114
120
  end
115
121
  end
@@ -41,11 +41,31 @@ module Hdo
41
41
  XML
42
42
  end
43
43
 
44
- it 'can deserialize HDO XML' do
44
+ it 'can deserialize a HDO XML node' do
45
45
  orig = Party.new('Sp', 'Senterpartiet')
46
46
  Party.from_hdo_node(parse(orig.to_hdo_xml)).should == orig
47
47
  end
48
48
 
49
+ it 'can deserialize a HDO XML doc' do
50
+ orig = Party.new('Sp', 'Senterpartiet')
51
+ Party.from_hdo_doc(parse("<parties>#{orig.to_hdo_xml}</parties>")).should == [orig]
52
+ end
53
+
54
+ it 'has a type name' do
55
+ Party.type_name.should == 'party'
56
+ end
57
+
58
+ it 'has a description' do
59
+ Party.description.should be_kind_of(String)
60
+ end
61
+
62
+ it 'has an XML example' do
63
+ Party.xml_example.should be_kind_of(String)
64
+ end
65
+
66
+ it 'has a list of fields' do
67
+ Party.fields.should_not be_empty
68
+ end
49
69
 
50
70
  end
51
71
  end
@@ -33,6 +33,62 @@ module Hdo
33
33
  prom.page.should == '10'
34
34
  end
35
35
 
36
+ it 'serializes to HDO XML' do
37
+ Promise.example.to_hdo_xml.should == <<-XML
38
+ <promise>
39
+ <party>H</party>
40
+ <general>true</general>
41
+ <categories>
42
+ <category>GRUNNSKOLE</category>
43
+ </categories>
44
+ <source>PP:8</source>
45
+ <body>Stille strengere krav til orden og oppførsel for å hindre at uro ødelegger undervisningen.</body>
46
+ </promise>
47
+ XML
48
+ end
49
+
50
+ it 'deserializes from HDO XML' do
51
+ promises = Promise.from_hdo_doc(parse(<<-XML))
52
+ <promises>
53
+ <promise>
54
+ <party>H</party>
55
+ <general>true</general>
56
+ <categories>
57
+ <category>GRUNNSKOLE</category>
58
+ </categories>
59
+ <source>PP:8</source>
60
+ <body>Stille strengere krav til orden og oppførsel for å hindre at uro ødelegger undervisningen.</body>
61
+ </promise>
62
+ </promises>
63
+ XML
64
+
65
+ promises.size.should == 1
66
+ promise = promises.first
67
+
68
+ promise.party.should == "H"
69
+ promise.should be_general
70
+ promise.categories.should == ["GRUNNSKOLE"]
71
+ promise.source.should == "PP"
72
+ promise.page.should == "8"
73
+ promise.body.should == "Stille strengere krav til orden og oppførsel for å hindre at uro ødelegger undervisningen."
74
+ end
75
+
76
+ it 'has a description' do
77
+ Promise.description.should be_kind_of(String)
78
+ end
79
+
80
+ it 'has fields' do
81
+ Promise.fields.should_not be_empty
82
+ end
83
+
84
+ it 'has a type name' do
85
+ Promise.type_name.should == 'promise'
86
+ end
87
+
88
+ it 'has a an XML example' do
89
+ Promise.xml_example.should be_kind_of(String)
90
+ end
91
+
36
92
  end
37
93
  end
38
94
  end
@@ -4,10 +4,6 @@ module Hdo
4
4
  module StortingImporter
5
5
  describe Representative do
6
6
 
7
- def create_representative
8
- Representative.new('ADA', 'André Oktay', 'Dahl', 'M', '1975-07-07T00:00:00', '0001-01-01T00:00:00', 'Akershus', 'Høyre', ['Justiskomiteen'], '2011-2012')
9
- end
10
-
11
7
  it "builds representatives from the Storting XML list" do
12
8
  xml = <<-XML
13
9
  <?xml version="1.0" encoding="utf-8"?>
@@ -52,7 +48,7 @@ module Hdo
52
48
  end
53
49
 
54
50
  it 'converts itself into HDO XML' do
55
- rep = create_representative
51
+ rep = Representative.example
56
52
  rep.to_hdo_xml.should == <<-XML
57
53
  <representative>
58
54
  <externalId>ADA</externalId>
@@ -71,11 +67,32 @@ module Hdo
71
67
  XML
72
68
  end
73
69
 
74
- it 'can deserialize HDO XML' do
75
- rep = create_representative
70
+ it 'can deserialize a HDO XML node' do
71
+ rep = Representative.example
76
72
  Representative.from_hdo_node(parse(rep.to_hdo_xml)).should == rep
77
73
  end
78
74
 
75
+ it 'can deserialize a HDO XML doc' do
76
+ rep = Representative.example
77
+ Representative.from_hdo_doc(parse("<representatives>#{rep.to_hdo_xml}</representatives>")).should == [rep]
78
+ end
79
+
80
+ it 'has a type name' do
81
+ Representative.type_name.should == 'representative'
82
+ end
83
+
84
+ it 'has a description' do
85
+ Representative.description.should be_kind_of(String)
86
+ end
87
+
88
+ it 'has an XML example' do
89
+ Representative.xml_example.should be_kind_of(String)
90
+ end
91
+
92
+ it 'has a list of fields' do
93
+ Representative.fields.should_not be_empty
94
+ end
95
+
79
96
  end
80
97
  end
81
98
  end