hdo-storting-importer 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. data/.gitignore +16 -0
  2. data/.gitmodules +3 -0
  3. data/.travis.yml +7 -0
  4. data/Gemfile +8 -0
  5. data/LICENSE +20 -0
  6. data/README.md +14 -0
  7. data/Rakefile +11 -0
  8. data/bin/hdo-converter +7 -0
  9. data/features/import.feature +85 -0
  10. data/features/step_definitions/import_steps.rb +0 -0
  11. data/features/support/env.rb +7 -0
  12. data/hdo-storting-importer.gemspec +17 -0
  13. data/lib/hdo/storting_importer/api_data_source.rb +62 -0
  14. data/lib/hdo/storting_importer/category.rb +55 -0
  15. data/lib/hdo/storting_importer/cli.rb +141 -0
  16. data/lib/hdo/storting_importer/committee.rb +35 -0
  17. data/lib/hdo/storting_importer/converter.rb +45 -0
  18. data/lib/hdo/storting_importer/core_ext/enumerable.rb +12 -0
  19. data/lib/hdo/storting_importer/data_source.rb +22 -0
  20. data/lib/hdo/storting_importer/disk_data_source.rb +61 -0
  21. data/lib/hdo/storting_importer/district.rb +36 -0
  22. data/lib/hdo/storting_importer/issue.rb +90 -0
  23. data/lib/hdo/storting_importer/ivar_equality.rb +22 -0
  24. data/lib/hdo/storting_importer/parsing_data_source.rb +59 -0
  25. data/lib/hdo/storting_importer/party.rb +31 -0
  26. data/lib/hdo/storting_importer/promise.rb +49 -0
  27. data/lib/hdo/storting_importer/promise_converter.rb +48 -0
  28. data/lib/hdo/storting_importer/representative.rb +106 -0
  29. data/lib/hdo/storting_importer/script_importer.rb +20 -0
  30. data/lib/hdo/storting_importer/util.rb +26 -0
  31. data/lib/hdo/storting_importer/version.rb +5 -0
  32. data/lib/hdo/storting_importer/vote.rb +171 -0
  33. data/lib/hdo/storting_importer.rb +41 -0
  34. data/spec/fixtures/input/categories.xml +1351 -0
  35. data/spec/fixtures/input/committees.xml +92 -0
  36. data/spec/fixtures/input/districts.xml +101 -0
  37. data/spec/fixtures/input/issues.xml +2852 -0
  38. data/spec/fixtures/input/parties.xml +42 -0
  39. data/spec/fixtures/input/promises-a.csv +341 -0
  40. data/spec/fixtures/input/propositions_2175.xml +64 -0
  41. data/spec/fixtures/input/propositions_2176.xml +64 -0
  42. data/spec/fixtures/input/representatives.xml +3218 -0
  43. data/spec/fixtures/input/representatives_today.xml +4872 -0
  44. data/spec/fixtures/input/vote_results_2175.xml +4400 -0
  45. data/spec/fixtures/input/vote_results_2176.xml +4400 -0
  46. data/spec/fixtures/input/votes.xml +85 -0
  47. data/spec/fixtures/output/categories.xml +803 -0
  48. data/spec/fixtures/output/committees.xml +71 -0
  49. data/spec/fixtures/output/districts.xml +79 -0
  50. data/spec/fixtures/output/issues.xml +836 -0
  51. data/spec/fixtures/output/parties.xml +31 -0
  52. data/spec/fixtures/output/promises-a.xml +3224 -0
  53. data/spec/fixtures/output/representatives.xml +2567 -0
  54. data/spec/fixtures/output/votes.xml +4899 -0
  55. data/spec/hdo/storting_importer/category_spec.rb +76 -0
  56. data/spec/hdo/storting_importer/committee_spec.rb +46 -0
  57. data/spec/hdo/storting_importer/converter_spec.rb +72 -0
  58. data/spec/hdo/storting_importer/district_spec.rb +54 -0
  59. data/spec/hdo/storting_importer/issue_spec.rb +115 -0
  60. data/spec/hdo/storting_importer/party_spec.rb +52 -0
  61. data/spec/hdo/storting_importer/promise_spec.rb +38 -0
  62. data/spec/hdo/storting_importer/representative_spec.rb +81 -0
  63. data/spec/hdo/storting_importer/vote_spec.rb +155 -0
  64. data/spec/spec_helper.rb +39 -0
  65. metadata +145 -0
data/.gitignore ADDED
@@ -0,0 +1,16 @@
1
+ Gemfile.lock
2
+ *.gem
3
+ *.rbc
4
+ .bundle
5
+ .config
6
+ .yardoc
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ pkg
12
+ rdoc
13
+ spec/reports
14
+ test/tmp
15
+ test/version_tmp
16
+ tmp
data/.gitmodules ADDED
@@ -0,0 +1,3 @@
1
+ [submodule "folketingparser"]
2
+ path = folketingparser
3
+ url = git://gitorious.org/nuug/folketingparser.git
data/.travis.yml ADDED
@@ -0,0 +1,7 @@
1
+ rvm:
2
+ - 1.9.3
3
+ notifications:
4
+ recipients:
5
+ - jari.bakken@gmail.com
6
+ irc: "irc.freenode.net#holderdeord"
7
+ script: "bundle exec rake"
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ source :rubygems
2
+
3
+ gem "builder"
4
+ gem "nokogiri"
5
+ gem "socksify"
6
+ gem "aruba"
7
+ gem "rake"
8
+ gem "rest-client"
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2012 Holder De Ord
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,14 @@
1
+ What
2
+ ====
3
+
4
+ Convert and import XML from data.stortinget.no
5
+
6
+ Usage
7
+ =====
8
+
9
+ $ bin/hdo-converter --app-root /src/hdo-site all
10
+
11
+ Caveats
12
+ =======
13
+
14
+ Right now we're executing script/import from hdo-site to perform the import. That means running this with bundler may fail if the gems don't match. Don't do that.
data/Rakefile ADDED
@@ -0,0 +1,11 @@
1
+ require 'rake'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new
5
+
6
+ require 'cucumber/rake/task'
7
+ Cucumber::Rake::Task.new
8
+
9
+ task :default => [:spec, :cucumber]
10
+
11
+ require "bundler/gem_tasks"
data/bin/hdo-converter ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $LOAD_PATH.unshift File.expand_path("../../lib", __FILE__)
4
+ require 'hdo/storting_importer'
5
+ require 'optparse'
6
+
7
+ Hdo::StortingImporter::CLI.new(ARGV).execute
@@ -0,0 +1,85 @@
1
+ Feature: Import data
2
+ Scenario: Import districts
3
+ When I run `hdo-converter --only-print districts`
4
+ Then the stdout should contain:
5
+ """
6
+ <?xml version="1.0" encoding="UTF-8"?>
7
+ <districts>
8
+ <district>
9
+ <externalId>Ak</externalId>
10
+ <name>Akershus</name>
11
+ </district>
12
+ <district>
13
+ <externalId>AA</externalId>
14
+ <name>Aust-Agder</name>
15
+ </district>
16
+ <district>
17
+ <externalId>Bu</externalId>
18
+ <name>Buskerud</name>
19
+ </district>
20
+ <district>
21
+ <externalId>Fi</externalId>
22
+ <name>Finnmark</name>
23
+ </district>
24
+ <district>
25
+ <externalId>He</externalId>
26
+ <name>Hedmark</name>
27
+ </district>
28
+ <district>
29
+ <externalId>Ho</externalId>
30
+ <name>Hordaland</name>
31
+ </district>
32
+ <district>
33
+ <externalId>MR</externalId>
34
+ <name>Møre og Romsdal</name>
35
+ </district>
36
+ <district>
37
+ <externalId>NT</externalId>
38
+ <name>Nord-Trøndelag</name>
39
+ </district>
40
+ <district>
41
+ <externalId>No</externalId>
42
+ <name>Nordland</name>
43
+ </district>
44
+ <district>
45
+ <externalId>Op</externalId>
46
+ <name>Oppland</name>
47
+ </district>
48
+ <district>
49
+ <externalId>Os</externalId>
50
+ <name>Oslo</name>
51
+ </district>
52
+ <district>
53
+ <externalId>Ro</externalId>
54
+ <name>Rogaland</name>
55
+ </district>
56
+ <district>
57
+ <externalId>SF</externalId>
58
+ <name>Sogn og Fjordane</name>
59
+ </district>
60
+ <district>
61
+ <externalId>ST</externalId>
62
+ <name>Sør-Trøndelag</name>
63
+ </district>
64
+ <district>
65
+ <externalId>Te</externalId>
66
+ <name>Telemark</name>
67
+ </district>
68
+ <district>
69
+ <externalId>Tr</externalId>
70
+ <name>Troms</name>
71
+ </district>
72
+ <district>
73
+ <externalId>VA</externalId>
74
+ <name>Vest-Agder</name>
75
+ </district>
76
+ <district>
77
+ <externalId>Ve</externalId>
78
+ <name>Vestfold</name>
79
+ </district>
80
+ <district>
81
+ <externalId>Øs</externalId>
82
+ <name>Østfold</name>
83
+ </district>
84
+ </districts>
85
+ """
File without changes
@@ -0,0 +1,7 @@
1
+ require 'aruba'
2
+ require 'aruba/cucumber'
3
+
4
+ Before do
5
+ @aruba_timeout_seconds = 10
6
+ ENV['VOTE_COUNT'] = '5'
7
+ end
@@ -0,0 +1,17 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/hdo/storting_importer/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Jari Bakken"]
6
+ gem.email = ["jari.bakken@gmail.com"]
7
+ gem.description = %q{Gem to process data from data.stortinget.no}
8
+ gem.summary = %q{Gem to process data from data.stortinget.no}
9
+ gem.homepage = "http://github.com/holderdeord/hdo-storting-importer"
10
+
11
+ gem.files = `git ls-files`.split($\).reject { |e| e =~ /^(data|folketingparser)/ }
12
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.name = "hdo-storting-importer"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = Hdo::StortingImporter::VERSION
17
+ end
@@ -0,0 +1,62 @@
1
+ module Hdo
2
+ module StortingImporter
3
+ class ApiDataSource < DataSource
4
+
5
+ def initialize(url)
6
+ @log = Logger.new(STDERR)
7
+ @resource = RestClient::Resource.new(URI.parse(url))
8
+ end
9
+
10
+ def representatives(period = DEFAULT_PERIOD)
11
+ fetch "eksport/representanter/?StortingsPeriodeId=#{period}"
12
+ end
13
+
14
+ def representatives_today
15
+ fetch 'eksport/dagensrepresentanter/'
16
+ end
17
+
18
+ def parties(session_id = DEFAULT_SESSION)
19
+ fetch "eksport/partier/?sesjonid=#{session_id}"
20
+ end
21
+
22
+ def committees(session_id = DEFAULT_SESSION)
23
+ fetch "eksport/komiteer/?SesjonId=#{session_id}"
24
+ end
25
+
26
+ def districts
27
+ fetch "eksport/fylker"
28
+ end
29
+
30
+ def categories
31
+ fetch "eksport/emner"
32
+ end
33
+
34
+ def issues(session_id = DEFAULT_SESSION)
35
+ fetch "eksport/saker?sesjonid=#{session_id}"
36
+ end
37
+
38
+ def votes_for(issue_id)
39
+ fetch "eksport/voteringer?sakid=#{issue_id}"
40
+ end
41
+
42
+ def propositions_for(vote_id)
43
+ fetch "eksport/voteringsforslag/?voteringid=#{vote_id}"
44
+ end
45
+
46
+ def vote_results_for(vote_id)
47
+ fetch "eksport/voteringsresultat/?voteringid=#{vote_id}"
48
+ end
49
+
50
+ private
51
+
52
+ def fetch(path)
53
+ sub_resource = @resource[path]
54
+ @log.info "parsing #{sub_resource}"
55
+
56
+ parse sub_resource.get
57
+ end
58
+
59
+ end
60
+ end
61
+ end
62
+
@@ -0,0 +1,55 @@
1
+ module Hdo
2
+ module StortingImporter
3
+ class Category
4
+ include IvarEquality
5
+
6
+ attr_reader :external_id, :name
7
+ attr_accessor :children
8
+
9
+ def self.from_storting_doc(doc)
10
+ doc.css("emne_liste > emne").map { |xt| from_storting_node(xt) }
11
+ end
12
+
13
+ def self.from_storting_node(node)
14
+ cat = Category.new node.css("id").first.text, node.css("navn").first.text
15
+
16
+ subnodes = node.css("underemne_liste > emne")
17
+ subnodes.map do |subnode|
18
+ cat.children << Category.new(subnode.css("id").first.text, subnode.css("navn").first.text)
19
+ end
20
+
21
+ cat
22
+ end
23
+
24
+ def self.from_hdo_node(node)
25
+ external_id = node.css("externalId").first.text
26
+ name = node.css("name").first.text
27
+
28
+ cat = new external_id, name
29
+ cat.children = node.css("subcategories category").map { |e| from_hdo_node(e) }
30
+
31
+ cat
32
+ end
33
+
34
+ def initialize(external_id, name)
35
+ @external_id = external_id
36
+ @name = name
37
+ @children = []
38
+ end
39
+
40
+ def to_hdo_xml(builder = Util.builder)
41
+ builder.category do |cat|
42
+ cat.externalId external_id
43
+ cat.name name
44
+
45
+ if children.any?
46
+ cat.subcategories do |sub|
47
+ children.each { |child| child.to_hdo_xml(sub) }
48
+ end
49
+ end
50
+ end
51
+ end
52
+
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,141 @@
1
+ module Hdo
2
+ module StortingImporter
3
+ class CLI
4
+ def initialize(args)
5
+ @log = Logger.new(STDERR)
6
+ @cmd, @options = parse(args)
7
+ end
8
+
9
+ def execute
10
+ import @cmd.to_sym
11
+ end
12
+
13
+ private
14
+
15
+ def parse(args)
16
+ options = {:source => (has_submodule? ? 'disk' : 'api')}
17
+
18
+ parser = OptionParser.new do |opt|
19
+ opt.banner = "Usage: #{$0} <import-type> [options]"
20
+
21
+ opt.on("--help", "You're looking at it.") { puts opt; exit; }
22
+ opt.on("--only-print", "Don't run import, only print generated XML.") { options[:only_print] = true }
23
+ opt.on("--except WHAT", 'Ignore this comma separated list of entities from import.') { |s| options[:ignore] = s.split(",").map(&:strip).map(&:to_sym) }
24
+ opt.on("--app-root APP_ROOT", 'Path to clone of git://github.com/holderdeord/hdo-site.git') { |path| options[:app_root] = path }
25
+ opt.on("--app-url APP_URL", 'URL to hdo-site') { |url| options[:app_url] = url }
26
+ opt.on("--source SOURCE ", 'Where to take data from [disk|api]') { |source| options[:source] = source }
27
+ opt.on("--socks PROXY", 'host:port for SOCKS proxy') do |proxy|
28
+ require 'socksify'
29
+ host, port = proxy.split ":"
30
+ TCPSocket.socks_server = host
31
+ TCPSocket.socks_port = Integer(port)
32
+ end
33
+ end
34
+
35
+ parser.parse!(args)
36
+
37
+ cmd = args.shift
38
+
39
+ unless cmd
40
+ puts(parser)
41
+ exit 1
42
+ end
43
+
44
+ [cmd, options]
45
+ end
46
+
47
+ def data_source
48
+ @data_source ||= (
49
+ ds = if @options[:source] == "disk"
50
+ DiskDataSource.new(File.join(StortingImporter.root, 'folketingparser/rawdata/data.stortinget.no'))
51
+ elsif @options[:source] == "api"
52
+ ApiDataSource.new("http://data.stortinget.no/")
53
+ else
54
+ raise ArgumentError, "invalid source: #{@options[:source].inspect}"
55
+ end
56
+
57
+ ParsingDataSource.new(ds)
58
+ )
59
+ end
60
+
61
+ def importer
62
+ @importer ||= (
63
+ if @options[:app_root]
64
+ ScriptImporter.new(@options[:app_root])
65
+ else
66
+ raise ArgumentError, "app-root not given, can't import"
67
+ end
68
+ )
69
+ end
70
+
71
+ def import(what)
72
+ case what
73
+ when :dld
74
+ import_dld
75
+ when :promises
76
+ import_promises
77
+ when :all
78
+ import_all
79
+ else
80
+ import_docs converter.xml_for(what.to_sym)
81
+ end
82
+ end
83
+
84
+ def import_all
85
+ ignore = Array(@options[:ignore])
86
+
87
+ import_docs converter.xml_for(:parties) unless ignore.include?(:parties)
88
+ import_docs converter.xml_for(:committees) unless ignore.include?(:committees)
89
+ import_docs converter.xml_for(:districts) unless ignore.include?(:districts)
90
+ import_docs converter.xml_for(:representatives) unless ignore.include?(:representatives)
91
+ import_docs converter.xml_for(:categories) unless ignore.include?(:categories)
92
+ import_docs converter.xml_for(:issues) unless ignore.include?(:issues)
93
+ import_docs converter.xml_for(:votes) unless ignore.include?(:votes)
94
+
95
+ import_dld unless ignore.include?(:dld)
96
+ import_promises unless ignore.include?(:promises)
97
+ end
98
+
99
+ def converter
100
+ @converter ||= Converter.new(data_source)
101
+ end
102
+
103
+ def import_dld
104
+ if has_submodule?
105
+ print_or_import File.read(File.join(StortingImporter.root, 'data/dld-issues.xml'))
106
+ print_or_import File.read(File.join(StortingImporter.root, 'folketingparser/data/votering-2011-04-04-dld-hdo.xml'))
107
+ else
108
+ $stderr.puts "folketingparser not found, skipping DLD votes and issues (run `git submodule update --init` if you need this)"
109
+ end
110
+ end
111
+
112
+ def import_promises
113
+ csvs = Dir[File.join(StortingImporter.root, 'data/promises-*.csv')].sort_by { |e| File.basename(e) }
114
+ csvs.each do |path|
115
+ print_or_import PromiseConverter.new(path).xml
116
+ end
117
+ end
118
+
119
+ def import_docs(docs)
120
+ docs = [docs] unless docs.kind_of?(Array)
121
+
122
+ docs.each do |doc|
123
+ print_or_import doc.to_s
124
+ end
125
+ end
126
+
127
+ def print_or_import(xml)
128
+ if @options[:only_print]
129
+ puts xml
130
+ else
131
+ importer.import xml
132
+ end
133
+ end
134
+
135
+ def has_submodule?
136
+ File.exist?(File.join(StortingImporter.root, 'folketingparser/data'))
137
+ end
138
+
139
+ end
140
+ end
141
+ end
@@ -0,0 +1,35 @@
1
+ module Hdo
2
+ module StortingImporter
3
+ class Committee
4
+ include IvarEquality
5
+
6
+ attr_reader :external_id, :name
7
+
8
+ def self.from_storting_doc(doc)
9
+ doc.css("komiteer_liste komite").map do |node|
10
+ from_storting_node(node)
11
+ end
12
+ end
13
+
14
+ def self.from_storting_node(node)
15
+ new node.css("id").first.text, node.css("navn").first.text
16
+ end
17
+
18
+ def self.from_hdo_node(node)
19
+ new node.css("externalId").first.text, node.css("name").first.text
20
+ end
21
+
22
+ def initialize(external_id, name)
23
+ @external_id = external_id
24
+ @name = name
25
+ end
26
+
27
+ def to_hdo_xml(builder = Util.builder)
28
+ builder.committee do |com|
29
+ com.externalId external_id
30
+ com.name name
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,45 @@
1
+ module Hdo
2
+ module StortingImporter
3
+ class Converter
4
+
5
+ def initialize(data_source)
6
+ @data_source = data_source
7
+ @cache = {}
8
+ end
9
+
10
+ def xml_for(name)
11
+ Util.builder do |xml|
12
+ xml.instruct!
13
+ xml.__send__(name) do |builder|
14
+ data_for(name).each do |obj|
15
+ obj.to_hdo_xml(builder)
16
+ end
17
+ end
18
+ end
19
+ end
20
+
21
+ private
22
+
23
+ def data_for(name)
24
+ case name
25
+ when :votes
26
+ # not ideal
27
+ issue_ids = fetch(:issues).map { |e| e.external_id }
28
+ issue_ids.map { |id| @data_source.votes_for(id) }.flatten.uniq_by { |e| e.external_id }
29
+ when :districts
30
+ fetch(name).sort_by { |e| e.name }
31
+ when :representatives
32
+ data = fetch(:representatives_today) + fetch(:representatives)
33
+ data.uniq_by { |e| e.external_id }.sort_by { |e| e.external_id }
34
+ else
35
+ fetch(name)
36
+ end
37
+ end
38
+
39
+ def fetch(name)
40
+ @cache[name] ||= @data_source.__send__(name)
41
+ end
42
+
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,12 @@
1
+ module Enumerable
2
+ def uniq_by(&blk)
3
+ res = {}
4
+
5
+ each do |e|
6
+ res[yield(e)] ||= e
7
+ end
8
+
9
+ res.values
10
+ end
11
+ end
12
+
@@ -0,0 +1,22 @@
1
+ module Hdo
2
+ module StortingImporter
3
+ class DataSource
4
+
5
+ class NotFoundError < StandardError
6
+ end
7
+
8
+ DEFAULT_SESSION = '2011-2012'
9
+ DEFAULT_PERIOD = '2009-2013'
10
+
11
+ private
12
+
13
+ def parse(str)
14
+ doc = Nokogiri.XML(str)
15
+ doc.remove_namespaces!
16
+
17
+ doc.first_element_child
18
+ end
19
+
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,61 @@
1
+ module Hdo
2
+ module StortingImporter
3
+ class DiskDataSource < DataSource
4
+
5
+ def initialize(root)
6
+ @root = Pathname.new(root)
7
+ @log = Logger.new(STDERR)
8
+ end
9
+
10
+ def parties(session_id = DEFAULT_SESSION)
11
+ fetch "eksport/partier/index.html?sesjonid=#{session_id}"
12
+ end
13
+
14
+ def committees(session_id = DEFAULT_SESSION)
15
+ fetch "eksport/komiteer/index.html?SesjonId=#{session_id}"
16
+ end
17
+
18
+ def districts
19
+ fetch "eksport/fylker/index.html"
20
+ end
21
+
22
+ def categories
23
+ fetch "eksport/emner/index.html"
24
+ end
25
+
26
+ def issues(session_id = DEFAULT_SESSION)
27
+ fetch "eksport/saker/index.html?sesjonid=#{session_id}"
28
+ end
29
+
30
+ def representatives(period = DEFAULT_PERIOD)
31
+ fetch "eksport/representanter/index.html?StortingsPeriodeId=#{period}"
32
+ end
33
+
34
+ def representatives_today
35
+ fetch 'eksport/dagensrepresentanter/index.html'
36
+ end
37
+
38
+ def votes_for(issue_id)
39
+ fetch "eksport/voteringer/index.html?sakid=#{issue_id}"
40
+ end
41
+
42
+ def propositions_for(vote_id)
43
+ fetch "eksport/voteringsforslag/index.html?voteringid=#{vote_id}"
44
+ end
45
+
46
+ def vote_results_for(vote_id)
47
+ fetch "eksport/voteringsresultat/index.html?voteringid=#{vote_id}"
48
+ end
49
+
50
+ private
51
+
52
+ def fetch(path)
53
+ subpath = @root.join(path)
54
+ @log.info "parsing #{subpath}"
55
+
56
+ parse subpath.read
57
+ end
58
+
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,36 @@
1
+ module Hdo
2
+ module StortingImporter
3
+ class District
4
+ include IvarEquality
5
+
6
+ attr_reader :external_id, :name
7
+
8
+ def self.from_storting_doc(doc)
9
+ doc.css("fylker_liste fylke").map do |node|
10
+ from_storting_node(node)
11
+ end
12
+ end
13
+
14
+ def self.from_storting_node(node)
15
+ new node.css("id").first.text, node.css("navn").first.text
16
+ end
17
+
18
+ def self.from_hdo_node(node)
19
+ new node.css("externalId").first.text, node.css("name").first.text
20
+ end
21
+
22
+ def initialize(external_id, name)
23
+ @external_id = external_id
24
+ @name = name
25
+ end
26
+
27
+ def to_hdo_xml(builder = Util.builder)
28
+ builder.district do |d|
29
+ d.externalId external_id
30
+ d.name name
31
+ end
32
+ end
33
+
34
+ end
35
+ end
36
+ end