hdo-storting-importer 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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