my_representatives 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.
- checksums.yaml +7 -0
- data/.gitignore +4 -0
- data/Gemfile +3 -0
- data/LICENSE.md +8 -0
- data/README.md +60 -0
- data/lib/my_representatives/abbreviatable.rb +29 -0
- data/lib/my_representatives/act/csv_lower.rb +118 -0
- data/lib/my_representatives/act/merge_lower.rb +38 -0
- data/lib/my_representatives/act/web_index.rb +37 -0
- data/lib/my_representatives/act/web_index_row.rb +86 -0
- data/lib/my_representatives/act/web_lower.rb +65 -0
- data/lib/my_representatives/act/web_show.rb +46 -0
- data/lib/my_representatives/commonwealth/commonwealth.rb +5 -0
- data/lib/my_representatives/commonwealth/csv_email.rb +93 -0
- data/lib/my_representatives/commonwealth/csv_lower.rb +130 -0
- data/lib/my_representatives/commonwealth/csv_upper.rb +129 -0
- data/lib/my_representatives/commonwealth/merge_lower.rb +54 -0
- data/lib/my_representatives/commonwealth/merge_upper.rb +54 -0
- data/lib/my_representatives/commonwealth/web_index.rb +57 -0
- data/lib/my_representatives/commonwealth/web_lower.rb +55 -0
- data/lib/my_representatives/commonwealth/web_show.rb +99 -0
- data/lib/my_representatives/commonwealth/web_upper.rb +54 -0
- data/lib/my_representatives/electorate.rb +146 -0
- data/lib/my_representatives/errors.rb +7 -0
- data/lib/my_representatives/fileable.rb +11 -0
- data/lib/my_representatives/guessable.rb +120 -0
- data/lib/my_representatives/hashable.rb +11 -0
- data/lib/my_representatives/nsw/csv_lower.rb +115 -0
- data/lib/my_representatives/nsw/csv_upper.rb +115 -0
- data/lib/my_representatives/nsw/merge_lower.rb +41 -0
- data/lib/my_representatives/nsw/merge_upper.rb +41 -0
- data/lib/my_representatives/nsw/web_index.rb +56 -0
- data/lib/my_representatives/nsw/web_lower.rb +54 -0
- data/lib/my_representatives/nsw/web_show.rb +140 -0
- data/lib/my_representatives/nsw/web_upper.rb +54 -0
- data/lib/my_representatives/nt/web_index.rb +46 -0
- data/lib/my_representatives/nt/web_lower.rb +54 -0
- data/lib/my_representatives/nt/web_show.rb +134 -0
- data/lib/my_representatives/person.rb +197 -0
- data/lib/my_representatives/qld/csv_lower.rb +117 -0
- data/lib/my_representatives/qld/merge_lower.rb +37 -0
- data/lib/my_representatives/qld/web_index.rb +47 -0
- data/lib/my_representatives/qld/web_lower.rb +54 -0
- data/lib/my_representatives/qld/web_show.rb +146 -0
- data/lib/my_representatives/sa/csv_lower.rb +120 -0
- data/lib/my_representatives/sa/csv_upper.rb +115 -0
- data/lib/my_representatives/sa/merge_lower.rb +39 -0
- data/lib/my_representatives/sa/merge_upper.rb +39 -0
- data/lib/my_representatives/sa/web_index_lower.rb +42 -0
- data/lib/my_representatives/sa/web_index_upper.rb +43 -0
- data/lib/my_representatives/sa/web_lower.rb +54 -0
- data/lib/my_representatives/sa/web_show.rb +158 -0
- data/lib/my_representatives/sa/web_upper.rb +54 -0
- data/lib/my_representatives/static.rb +5 -0
- data/lib/my_representatives/tas/csv_lower.rb +125 -0
- data/lib/my_representatives/tas/csv_upper.rb +125 -0
- data/lib/my_representatives/version.rb +5 -0
- data/lib/my_representatives/vic/csv_lower.rb +99 -0
- data/lib/my_representatives/vic/csv_upper.rb +97 -0
- data/lib/my_representatives/vic/merge_lower.rb +37 -0
- data/lib/my_representatives/vic/merge_upper.rb +37 -0
- data/lib/my_representatives/vic/web_index.rb +58 -0
- data/lib/my_representatives/vic/web_lower.rb +54 -0
- data/lib/my_representatives/vic/web_show.rb +118 -0
- data/lib/my_representatives/vic/web_upper.rb +54 -0
- data/lib/my_representatives/wa/csv_lower.rb +144 -0
- data/lib/my_representatives/wa/csv_upper.rb +131 -0
- data/lib/my_representatives/wa/merge_lower.rb +41 -0
- data/lib/my_representatives/wa/merge_upper.rb +37 -0
- data/lib/my_representatives/wa/web_index.rb +45 -0
- data/lib/my_representatives/wa/web_lower.rb +54 -0
- data/lib/my_representatives/wa/web_show.rb +195 -0
- data/lib/my_representatives/wa/web_upper.rb +54 -0
- data/lib/my_representatives.rb +150 -0
- data/my_representatives.gemspec +25 -0
- metadata +204 -0
@@ -0,0 +1,99 @@
|
|
1
|
+
module MyRepresentatives
|
2
|
+
module VIC
|
3
|
+
class CSVLower
|
4
|
+
include MyRepresentatives::Fileable
|
5
|
+
include MyRepresentatives::Guessable
|
6
|
+
|
7
|
+
attr_accessor :csv_url, :csv_filename, :people
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
@csv_url = "http://www.parliament.vic.gov.au/members/house/mla?format=csv"
|
11
|
+
@csv_filename = "tmp/csv_vic_lower.csv"
|
12
|
+
@people = []
|
13
|
+
|
14
|
+
csv_from_url
|
15
|
+
people_from_csv
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def csv_from_url
|
21
|
+
create_tmp
|
22
|
+
begin
|
23
|
+
open(@csv_filename, "wb") do |file|
|
24
|
+
open(@csv_url) do |uri|
|
25
|
+
file.write(uri.read)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
rescue SocketError => err
|
29
|
+
@logger.debug("Unable to connect to #{@csv_url}")
|
30
|
+
raise err
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def people_from_csv
|
35
|
+
CSV.foreach(@csv_filename, headers: true) do |row|
|
36
|
+
|
37
|
+
# Setup the electorate
|
38
|
+
electorate_name = find_electorate(row)
|
39
|
+
electorate = Electorate.new(electorate_name)
|
40
|
+
electorate.state_vic_lower!
|
41
|
+
|
42
|
+
# Setup the Representative (Person)
|
43
|
+
person = Person.new(electorate)
|
44
|
+
|
45
|
+
person.formal_name = find_formal_name(row)
|
46
|
+
person.gender = find_gender(row)
|
47
|
+
person.email = find_email(row)
|
48
|
+
person.phone = find_phone(row)
|
49
|
+
person.party_name = find_party(row)
|
50
|
+
person.first_name = guess_first(person.formal_name)
|
51
|
+
person.last_name = guess_last(person.formal_name)
|
52
|
+
person.title = guess_title(person.formal_name)
|
53
|
+
person.physical_address = format_physical_address(row)
|
54
|
+
person.postal_address = format_postal_address(row)
|
55
|
+
person.honorifics = "MP"
|
56
|
+
person.preferred_name = nil
|
57
|
+
person.salutation = nil
|
58
|
+
person.image_url = nil
|
59
|
+
person.homepage_url = nil
|
60
|
+
|
61
|
+
@people << person
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def find_formal_name(arr)
|
66
|
+
arr["Name"]
|
67
|
+
end
|
68
|
+
|
69
|
+
def find_electorate(arr)
|
70
|
+
arr["Electorate"]
|
71
|
+
end
|
72
|
+
|
73
|
+
def find_email(arr)
|
74
|
+
arr["Email"]
|
75
|
+
end
|
76
|
+
|
77
|
+
def find_gender(arr)
|
78
|
+
arr["Sex"]
|
79
|
+
end
|
80
|
+
|
81
|
+
def find_party(arr)
|
82
|
+
arr["Party"]
|
83
|
+
end
|
84
|
+
|
85
|
+
def find_phone(arr)
|
86
|
+
arr["Phone"]
|
87
|
+
end
|
88
|
+
|
89
|
+
def format_physical_address(arr)
|
90
|
+
"#{arr["Electorate Office Address line 1"]}\n#{arr["Electorate Office Address line 2"]}\n#{arr["Electorate Office Address line 3"]}\n#{arr["Electorate Office Address line 4"]} #{arr["Electorate Office Address line 5"]} #{arr["Electoral Office Postcode"]}"
|
91
|
+
end
|
92
|
+
|
93
|
+
def format_postal_address(arr)
|
94
|
+
"#{arr["PO Address line 1"]}\n#{arr["PO Address line 2"]}\n#{arr["PO Address line 3"]}\n#{arr["PO Address line 4"]} #{arr["PO Address line 5"]}"
|
95
|
+
end
|
96
|
+
|
97
|
+
end # CSVLower
|
98
|
+
end # VIC
|
99
|
+
end # MyRepresentatives
|
@@ -0,0 +1,97 @@
|
|
1
|
+
module MyRepresentatives
|
2
|
+
module VIC
|
3
|
+
class CSVUpper
|
4
|
+
include MyRepresentatives::Fileable
|
5
|
+
include MyRepresentatives::Guessable
|
6
|
+
|
7
|
+
attr_accessor :csv_url, :csv_filename, :people
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
@csv_url = "http://www.parliament.vic.gov.au/members/house/mlc?format=csv"
|
11
|
+
@csv_filename = "tmp/csv_vic_upper.csv"
|
12
|
+
@people = []
|
13
|
+
|
14
|
+
csv_from_url
|
15
|
+
people_from_csv
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def csv_from_url
|
21
|
+
create_tmp
|
22
|
+
begin
|
23
|
+
open(@csv_filename, "wb") do |file|
|
24
|
+
open(@csv_url) do |uri|
|
25
|
+
file.write(uri.read)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
rescue SocketError => err
|
29
|
+
@logger.debug("Unable to connect to #{@csv_url}")
|
30
|
+
raise err
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def people_from_csv
|
35
|
+
CSV.foreach(@csv_filename, headers: true) do |row|
|
36
|
+
# Setup the electorate
|
37
|
+
electorate_name = find_electorate(row)
|
38
|
+
electorate = Electorate.new(electorate_name)
|
39
|
+
electorate.state_vic_upper!
|
40
|
+
|
41
|
+
# Setup the Representative (Person)
|
42
|
+
person = Person.new(electorate)
|
43
|
+
|
44
|
+
person.formal_name = find_formal_name(row)
|
45
|
+
person.gender = find_gender(row)
|
46
|
+
person.email = find_email(row)
|
47
|
+
person.phone = find_phone(row)
|
48
|
+
person.party_name = find_party(row)
|
49
|
+
person.first_name = guess_first(person.formal_name)
|
50
|
+
person.last_name = guess_last(person.formal_name)
|
51
|
+
person.title = guess_title(person.formal_name)
|
52
|
+
person.physical_address = format_physical_address(row)
|
53
|
+
person.postal_address = format_postal_address(row)
|
54
|
+
person.honorifics = "MLC"
|
55
|
+
person.preferred_name = nil
|
56
|
+
person.salutation = nil
|
57
|
+
person.image_url = nil
|
58
|
+
person.homepage_url = nil
|
59
|
+
|
60
|
+
@people << person unless person.formal_name.downcase.include?("vacant")
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def find_formal_name(arr)
|
65
|
+
arr["Name"]
|
66
|
+
end
|
67
|
+
|
68
|
+
def find_electorate(arr)
|
69
|
+
arr["Electorate"]
|
70
|
+
end
|
71
|
+
|
72
|
+
def find_email(arr)
|
73
|
+
arr["Email"]
|
74
|
+
end
|
75
|
+
|
76
|
+
def find_gender(arr)
|
77
|
+
arr["Sex"]
|
78
|
+
end
|
79
|
+
|
80
|
+
def find_party(arr)
|
81
|
+
arr["Party"]
|
82
|
+
end
|
83
|
+
|
84
|
+
def find_phone(arr)
|
85
|
+
arr["Phone"]
|
86
|
+
end
|
87
|
+
|
88
|
+
def format_physical_address(arr)
|
89
|
+
"#{arr["Electorate Office Address line 1"]}\n#{arr["Electorate Office Address line 2"]}\n#{arr["Electorate Office Address line 3"]}\n#{arr["Electorate Office Address line 4"]} #{arr["Electorate Office Address line 5"]} #{arr["Electoral Office Postcode"]}"
|
90
|
+
end
|
91
|
+
|
92
|
+
def format_postal_address(arr)
|
93
|
+
"#{arr["PO Address line 1"]}\n#{arr["PO Address line 2"]}\n#{arr["PO Address line 3"]}\n#{arr["PO Address line 4"]} #{arr["PO Address line 5"]}"
|
94
|
+
end
|
95
|
+
end # CSVUpper
|
96
|
+
end # VIC
|
97
|
+
end # MyRepresentatives
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module MyRepresentatives
|
2
|
+
module VIC
|
3
|
+
class MergeLower
|
4
|
+
attr_accessor :csv_people, :web_people, :people
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
@csv_people = MyRepresentatives::VIC::CSVLower.new.people
|
8
|
+
@web_people = MyRepresentatives::VIC::WebLower.new.people
|
9
|
+
@people = []
|
10
|
+
check_and_update_person
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def check_and_update_person
|
16
|
+
@csv_people.each do |person|
|
17
|
+
if @web_people.any? { |wp| wp.phone == person.phone} || @web_people.any? { |wp| wp.email == person.email}
|
18
|
+
index = @web_people.find_index {|wp| wp.phone == person.phone}
|
19
|
+
|
20
|
+
if !index
|
21
|
+
index = @web_people.find_index { |wp| wp.email == person.email }
|
22
|
+
end
|
23
|
+
|
24
|
+
if index
|
25
|
+
person.homepage_url = @web_people[index].homepage_url
|
26
|
+
person.image_url = @web_people[index].image_url
|
27
|
+
person.successful_merge = true
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
@people << person
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
end # MergeLower
|
36
|
+
end # VIC
|
37
|
+
end # MyRepresentatives
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module MyRepresentatives
|
2
|
+
module VIC
|
3
|
+
class MergeUpper
|
4
|
+
attr_accessor :csv_people, :web_people, :people
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
@csv_people = MyRepresentatives::VIC::CSVUpper.new.people
|
8
|
+
@web_people = MyRepresentatives::VIC::WebUpper.new.people
|
9
|
+
@people = []
|
10
|
+
check_and_update_person
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def check_and_update_person
|
16
|
+
@csv_people.each do |person|
|
17
|
+
if @web_people.any? { |wp| wp.phone == person.phone} || @web_people.any? { |wp| wp.email == person.email}
|
18
|
+
index = @web_people.find_index {|wp| wp.phone == person.phone}
|
19
|
+
|
20
|
+
if !index
|
21
|
+
index = @web_people.find_index { |wp| wp.email == person.email }
|
22
|
+
end
|
23
|
+
|
24
|
+
if index
|
25
|
+
person.homepage_url = @web_people[index].homepage_url
|
26
|
+
person.image_url = @web_people[index].image_url
|
27
|
+
person.successful_merge = true
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
@people << person
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
end # MergeUpper
|
36
|
+
end # VIC
|
37
|
+
end # MyRepresentatives
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module MyRepresentatives
|
2
|
+
module VIC
|
3
|
+
class WebIndex
|
4
|
+
attr_accessor :index_url, :document, :upper_urls, :lower_urls
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
@logger = Logger.new(STDOUT)
|
8
|
+
@index_url = nil
|
9
|
+
@document = nil
|
10
|
+
@lower_urls = []
|
11
|
+
@upper_urls = []
|
12
|
+
|
13
|
+
(1..3).each do |page|
|
14
|
+
@index_url = "http://www.parliament.vic.gov.au/members/results?house=Legislative+Assembly&page=#{page}"
|
15
|
+
@document = find_representatives
|
16
|
+
representative_urls_from_document( { lower_house: true } )
|
17
|
+
end
|
18
|
+
|
19
|
+
(1..2).each do |page|
|
20
|
+
@index_url = "http://www.parliament.vic.gov.au/members/results?house=Legislative+Council&page=#{page}"
|
21
|
+
@document = find_representatives
|
22
|
+
representative_urls_from_document( { lower_house: false } )
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def find_representatives
|
30
|
+
begin
|
31
|
+
request = open(@index_url)
|
32
|
+
Nokogiri::HTML(request)
|
33
|
+
rescue SocketError => err
|
34
|
+
@logger.debug("Unable to connect to #{@index_url}")
|
35
|
+
raise err
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def representative_urls_from_document(options = { lower_house: true } )
|
40
|
+
begin
|
41
|
+
results = @document.css("div.results-list")
|
42
|
+
representatives = results.css("div.result-item") if results
|
43
|
+
rescue
|
44
|
+
end
|
45
|
+
|
46
|
+
representatives.each do |row|
|
47
|
+
begin
|
48
|
+
uri = "http://www.parliament.vic.gov.au" + row.css("h2").css("a").first.attr("href")
|
49
|
+
@lower_urls << uri if options[:lower_house] unless uri.include?("vacant")
|
50
|
+
@upper_urls << uri if !options[:lower_house] unless uri.include?("vacant")
|
51
|
+
rescue
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
end # WebIndex
|
57
|
+
end # VIC
|
58
|
+
end # MyRepresentatives
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module MyRepresentatives
|
2
|
+
module VIC
|
3
|
+
class WebLower
|
4
|
+
include MyRepresentatives::Abbreviatable
|
5
|
+
include MyRepresentatives::Guessable
|
6
|
+
|
7
|
+
attr_accessor :urls, :people
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
@logger = Logger.new(STDOUT)
|
11
|
+
@urls = WebIndex.new.lower_urls
|
12
|
+
@people = []
|
13
|
+
|
14
|
+
@urls.each do |url|
|
15
|
+
document = WebShow.new(url)
|
16
|
+
create_person_from_document(document)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def create_person_from_document(document)
|
23
|
+
@logger.info("Attempting to create #{document.formal_name}")
|
24
|
+
|
25
|
+
# Setup the electorate
|
26
|
+
electorate_name = document.electorate_name
|
27
|
+
electorate = MyRepresentatives::Electorate.new(electorate_name)
|
28
|
+
electorate.state_vic_lower!
|
29
|
+
|
30
|
+
# Setup the Representative (Person)
|
31
|
+
person = MyRepresentatives::Person.new(electorate)
|
32
|
+
person.formal_name = document.formal_name
|
33
|
+
person.first_name = guess_first(document.formal_name)
|
34
|
+
person.last_name = guess_last(document.formal_name)
|
35
|
+
person.title = guess_title(document.formal_name)
|
36
|
+
person.email = document.email
|
37
|
+
person.phone = document.phone
|
38
|
+
person.party_name = document.party_name
|
39
|
+
person.image_url = document.image_url
|
40
|
+
person.homepage_url = document.homepage_url
|
41
|
+
person.preferred_name = document.preferred_name
|
42
|
+
person.gender = guess_gender(document.formal_name)
|
43
|
+
person.physical_address = nil
|
44
|
+
person.postal_address = nil
|
45
|
+
person.honorifics = nil
|
46
|
+
person.salutation = nil
|
47
|
+
|
48
|
+
@people << person
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
end # WebLower
|
53
|
+
end # VIC
|
54
|
+
end # MyRepresentatives
|
@@ -0,0 +1,118 @@
|
|
1
|
+
module MyRepresentatives
|
2
|
+
module VIC
|
3
|
+
class WebShow
|
4
|
+
include MyRepresentatives::Guessable
|
5
|
+
|
6
|
+
attr_accessor :url, :document, :logger
|
7
|
+
|
8
|
+
def initialize(url)
|
9
|
+
@logger = Logger.new(STDOUT)
|
10
|
+
raise MyRepresentatives::InvalidURLError unless url && url.is_a?(String)
|
11
|
+
@url = url
|
12
|
+
fetch_document
|
13
|
+
raise MyRepresentatives::NokogiriDocumentPropertiesError unless test_document_for_validity
|
14
|
+
end
|
15
|
+
|
16
|
+
def homepage_url
|
17
|
+
@url
|
18
|
+
end
|
19
|
+
|
20
|
+
def formal_name
|
21
|
+
begin
|
22
|
+
@document.css("div#page-title").css("h2").text
|
23
|
+
rescue NoMethodError
|
24
|
+
nil
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def title
|
29
|
+
begin
|
30
|
+
guess_title(formal_name)
|
31
|
+
rescue NoMethodError
|
32
|
+
nil
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def first_name
|
37
|
+
begin
|
38
|
+
guess_first(formal_name)
|
39
|
+
rescue NoMethodError
|
40
|
+
nil
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def last_name
|
45
|
+
begin
|
46
|
+
guess_last(formal_name)
|
47
|
+
rescue NoMethodError
|
48
|
+
nil
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def preferred_name
|
53
|
+
begin
|
54
|
+
guess_preferred(formal_name)
|
55
|
+
rescue NoMethodError
|
56
|
+
nil
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def electorate_name
|
61
|
+
begin
|
62
|
+
@document.css("dl.member-overview").at('dt:contains("Electorate")').next_element.text
|
63
|
+
rescue NoMethodError
|
64
|
+
nil
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def party_name
|
69
|
+
begin
|
70
|
+
@document.css("dl.member-overview").at('dt:contains("Party")').next_element.text
|
71
|
+
rescue NoMethodError
|
72
|
+
nil
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def email
|
77
|
+
begin
|
78
|
+
@document.css("dl.member-overview").at('dt:contains("Email")').next_element.text.strip
|
79
|
+
rescue
|
80
|
+
nil
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def image_url
|
85
|
+
begin
|
86
|
+
@document.css("img.details-portrait").attr("src").value
|
87
|
+
rescue
|
88
|
+
nil
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def phone
|
93
|
+
begin
|
94
|
+
@document.css("dl.member-overview").at('dt:contains("Phone")').next_element.text.strip
|
95
|
+
rescue
|
96
|
+
nil
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
private
|
101
|
+
|
102
|
+
def fetch_document
|
103
|
+
begin
|
104
|
+
request = open(@url)
|
105
|
+
@document = Nokogiri::HTML(request)
|
106
|
+
rescue => err
|
107
|
+
@logger.debug("Failed to connect to the url: #{@url}")
|
108
|
+
raise err
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def test_document_for_validity
|
113
|
+
true
|
114
|
+
end
|
115
|
+
|
116
|
+
end # WebShow
|
117
|
+
end # VIC
|
118
|
+
end # MyRepresentatives
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module MyRepresentatives
|
2
|
+
module VIC
|
3
|
+
class WebUpper
|
4
|
+
include MyRepresentatives::Abbreviatable
|
5
|
+
include MyRepresentatives::Guessable
|
6
|
+
|
7
|
+
attr_accessor :urls, :people
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
@logger = Logger.new(STDOUT)
|
11
|
+
@urls = WebIndex.new.upper_urls
|
12
|
+
@people = []
|
13
|
+
|
14
|
+
@urls.each do |url|
|
15
|
+
document = WebShow.new(url)
|
16
|
+
create_person_from_document(document)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def create_person_from_document(document)
|
23
|
+
@logger.info("Attempting to create #{document.formal_name}")
|
24
|
+
|
25
|
+
# Setup the electorate
|
26
|
+
electorate_name = document.electorate_name
|
27
|
+
electorate = MyRepresentatives::Electorate.new(electorate_name)
|
28
|
+
electorate.state_vic_upper!
|
29
|
+
|
30
|
+
# Setup the Representative (Person)
|
31
|
+
person = MyRepresentatives::Person.new(electorate)
|
32
|
+
person.formal_name = document.formal_name
|
33
|
+
person.first_name = guess_first(document.formal_name)
|
34
|
+
person.last_name = guess_last(document.formal_name)
|
35
|
+
person.title = guess_title(document.formal_name)
|
36
|
+
person.email = document.email
|
37
|
+
person.phone = document.phone
|
38
|
+
person.party_name = document.party_name
|
39
|
+
person.image_url = document.image_url
|
40
|
+
person.homepage_url = document.homepage_url
|
41
|
+
person.preferred_name = document.preferred_name
|
42
|
+
person.gender = guess_gender(document.formal_name)
|
43
|
+
person.physical_address = nil
|
44
|
+
person.postal_address = nil
|
45
|
+
person.honorifics = nil
|
46
|
+
person.salutation = nil
|
47
|
+
|
48
|
+
@people << person
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
end # WebUpper
|
53
|
+
end # VIC
|
54
|
+
end # MyRepresentatives
|
@@ -0,0 +1,144 @@
|
|
1
|
+
module MyRepresentatives
|
2
|
+
module WA
|
3
|
+
class CSVLower
|
4
|
+
include MyRepresentatives::Fileable
|
5
|
+
include MyRepresentatives::Guessable
|
6
|
+
|
7
|
+
attr_accessor :xls_url, :xls_filename, :csv_filename, :people
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
@xls_url = "http://www.parliament.wa.gov.au/WebCMS/WebCMS.nsf/resources/file-mla-merge-data/$file/MLA%20Merge%20Data%2026042017.xls"
|
11
|
+
@xls_filename = "tmp/csv_wa_lower.xls"
|
12
|
+
@csv_filename = "tmp/csv_wa_lower.csv"
|
13
|
+
@people = []
|
14
|
+
|
15
|
+
csv_from_url
|
16
|
+
people_from_csv
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def csv_from_url
|
22
|
+
create_tmp
|
23
|
+
|
24
|
+
open(@xls_filename, "wb") do |file|
|
25
|
+
open(@xls_url) do |uri|
|
26
|
+
file.write(uri.read)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
excel = Excel2CSV.read(@xls_filename)
|
31
|
+
CSV.open(@csv_filename, "wb") do |csv|
|
32
|
+
excel.each_with_index do |row, index|
|
33
|
+
|
34
|
+
if index == 0 # This exists to fix duplicate values in the header row
|
35
|
+
renamed_postal_address = false
|
36
|
+
renamed_electorate_address = false
|
37
|
+
renamed_parliament_address = false
|
38
|
+
new_row = []
|
39
|
+
|
40
|
+
row.each do |col|
|
41
|
+
if col.downcase == "postal address" && renamed_postal_address == false
|
42
|
+
col = "postal_address_1"
|
43
|
+
renamed_postal_address = true
|
44
|
+
elsif col.downcase == "electorate address" && renamed_electorate_address == false
|
45
|
+
col = "electorate_address_1"
|
46
|
+
renamed_electorate_address = true
|
47
|
+
elsif col.downcase == "parliament" && renamed_parliament_address == false
|
48
|
+
col = "parliament_1"
|
49
|
+
renamed_parliament_address = true
|
50
|
+
end
|
51
|
+
new_row << col
|
52
|
+
end
|
53
|
+
csv << new_row
|
54
|
+
else
|
55
|
+
csv << row
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
FileUtils.rm_r(@xls_filename)
|
60
|
+
end
|
61
|
+
|
62
|
+
def people_from_csv
|
63
|
+
CSV.foreach(@csv_filename, headers: true) do |row|
|
64
|
+
|
65
|
+
if row["First Name"] && row["Surname"] && row["Electorate"] # Fix for blank rows
|
66
|
+
|
67
|
+
# Setup the electorate
|
68
|
+
electorate_name = find_electorate(row)
|
69
|
+
electorate = Electorate.new(electorate_name)
|
70
|
+
electorate.state_wa_lower!
|
71
|
+
|
72
|
+
# Setup the Representative (Person)
|
73
|
+
person = Person.new(electorate)
|
74
|
+
|
75
|
+
person.title = find_title(row)
|
76
|
+
person.first_name = find_first_name(row)
|
77
|
+
person.last_name = find_last_name(row)
|
78
|
+
person.email = find_email(row)
|
79
|
+
person.phone = find_phone(row)
|
80
|
+
person.party_name = find_party(row)
|
81
|
+
person.gender = guess_gender(row["Title"])
|
82
|
+
person.formal_name = format_formal_name(row,person)
|
83
|
+
person.physical_address = format_physical_address(row)
|
84
|
+
person.postal_address = format_postal_address(row)
|
85
|
+
person.honorifics = "MLA"
|
86
|
+
person.preferred_name = nil
|
87
|
+
person.salutation = nil
|
88
|
+
person.image_url = nil
|
89
|
+
person.homepage_url = nil
|
90
|
+
|
91
|
+
@people << person
|
92
|
+
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def find_first_name(arr)
|
98
|
+
arr["First Name"]
|
99
|
+
end
|
100
|
+
|
101
|
+
def find_last_name(arr)
|
102
|
+
arr["Surname"]
|
103
|
+
end
|
104
|
+
|
105
|
+
def find_title(arr)
|
106
|
+
arr["Hon."].nil? ? arr["Title"] : "Hon"
|
107
|
+
end
|
108
|
+
|
109
|
+
def find_electorate(arr)
|
110
|
+
|
111
|
+
if arr && arr["Electorate"]
|
112
|
+
arr["Electorate"].gsub("Member for ","")
|
113
|
+
else
|
114
|
+
nil
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def find_email(arr)
|
119
|
+
arr["Member Email"]
|
120
|
+
end
|
121
|
+
|
122
|
+
def find_party(arr)
|
123
|
+
nil
|
124
|
+
end
|
125
|
+
|
126
|
+
def find_phone(arr)
|
127
|
+
nil
|
128
|
+
end
|
129
|
+
|
130
|
+
def format_formal_name(arr, person)
|
131
|
+
arr["Hon."].nil? ? "#{person.title} #{person.first_name} #{person.last_name}" : "Hon #{person.first_name} #{person.last_name}"
|
132
|
+
end
|
133
|
+
|
134
|
+
def format_physical_address(arr)
|
135
|
+
"#{arr["electorate_address_1"]}\n#{arr["Electorate Address"]}"
|
136
|
+
end
|
137
|
+
|
138
|
+
def format_postal_address(arr)
|
139
|
+
"#{arr["postal_address_1"]}\n#{arr["Postal Address"]}"
|
140
|
+
end
|
141
|
+
|
142
|
+
end # CSVLower
|
143
|
+
end # WA
|
144
|
+
end # MyRepresentatives
|