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,117 @@
|
|
1
|
+
require 'excel2csv'
|
2
|
+
|
3
|
+
module MyRepresentatives
|
4
|
+
module QLD
|
5
|
+
class CSVLower
|
6
|
+
include MyRepresentatives::Fileable
|
7
|
+
include MyRepresentatives::Guessable
|
8
|
+
|
9
|
+
attr_accessor :xls_url, :csv_filename, :xls_filename, :people
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
self.xls_url = "https://www.parliament.qld.gov.au/documents/Members/mailingLists/MEMMERGEEXCEL.xls"
|
13
|
+
self.xls_filename = "tmp/csv_qld_lower.xls"
|
14
|
+
self.csv_filename = "tmp/csv_qld_lower.csv"
|
15
|
+
self.people = []
|
16
|
+
|
17
|
+
csv_from_url
|
18
|
+
people_from_csv
|
19
|
+
end
|
20
|
+
|
21
|
+
def csv_from_url
|
22
|
+
create_tmp
|
23
|
+
open(@xls_filename, "wb") do |file|
|
24
|
+
open(@xls_url) do |uri|
|
25
|
+
file.write(uri.read)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
excel = Excel2CSV.read(@xls_filename)
|
30
|
+
CSV.open(@csv_filename, "wb") do |csv|
|
31
|
+
excel.each do |row|
|
32
|
+
csv << row
|
33
|
+
end
|
34
|
+
end
|
35
|
+
FileUtils.rm_r(@xls_filename)
|
36
|
+
end
|
37
|
+
|
38
|
+
def people_from_csv
|
39
|
+
CSV.foreach(@csv_filename, headers: true) do |row|
|
40
|
+
|
41
|
+
# Setup the electorate
|
42
|
+
electorate_name = find_electorate(row)
|
43
|
+
electorate = Electorate.new(electorate_name)
|
44
|
+
electorate.state_qld_lower!
|
45
|
+
|
46
|
+
# Setup the Representative (Person)
|
47
|
+
person = Person.new(electorate)
|
48
|
+
|
49
|
+
person.title = find_title(row)
|
50
|
+
person.first_name = find_first_name(row)
|
51
|
+
person.last_name = find_last_name(row)
|
52
|
+
person.email = find_email(row)
|
53
|
+
person.phone = find_phone(row)
|
54
|
+
person.party_name = find_party(row)
|
55
|
+
person.formal_name = format_formal_name(person)
|
56
|
+
person.physical_address = format_physical_address(row)
|
57
|
+
person.postal_address = format_postal_address(row)
|
58
|
+
person.gender = guess_gender(person.title)
|
59
|
+
person.honorifics = "MP"
|
60
|
+
person.preferred_name = nil
|
61
|
+
person.salutation = nil
|
62
|
+
person.image_url = nil
|
63
|
+
person.homepage_url = nil
|
64
|
+
|
65
|
+
@people << person
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
private
|
70
|
+
|
71
|
+
def find_first_name(arr)
|
72
|
+
arr["first"]
|
73
|
+
end
|
74
|
+
|
75
|
+
def find_last_name(arr)
|
76
|
+
arr["last"]
|
77
|
+
end
|
78
|
+
|
79
|
+
def find_electorate(arr)
|
80
|
+
if arr && arr["electorate"]
|
81
|
+
arr["electorate"].gsub("Member for ","")
|
82
|
+
else
|
83
|
+
nil
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def find_party(arr)
|
88
|
+
arr["party"]
|
89
|
+
end
|
90
|
+
|
91
|
+
def find_email(arr)
|
92
|
+
nil
|
93
|
+
end
|
94
|
+
|
95
|
+
def find_phone(arr)
|
96
|
+
nil
|
97
|
+
end
|
98
|
+
|
99
|
+
def find_title(arr)
|
100
|
+
arr["title"]
|
101
|
+
end
|
102
|
+
|
103
|
+
def format_formal_name(person)
|
104
|
+
"#{person.title} #{person.first_name} #{person.last_name}"
|
105
|
+
end
|
106
|
+
|
107
|
+
def format_physical_address(arr)
|
108
|
+
"#{arr["address 1"]}\n#{arr["address 2"]}"
|
109
|
+
end
|
110
|
+
|
111
|
+
def format_postal_address(arr)
|
112
|
+
"#{arr["address 1"]}\n#{arr["address 2"]}"
|
113
|
+
end
|
114
|
+
|
115
|
+
end # CSVLower
|
116
|
+
end # QLD
|
117
|
+
end # MyRepresentatives
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module MyRepresentatives
|
2
|
+
module QLD
|
3
|
+
class MergeLower
|
4
|
+
attr_accessor :csv_people, :web_people, :people
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
@csv_people = MyRepresentatives::QLD::CSVLower.new.people
|
8
|
+
@web_people = MyRepresentatives::QLD::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.electorate.name == person.electorate.name }
|
18
|
+
index = @web_people.find_index { |wp| wp.electorate.name == person.electorate.name}
|
19
|
+
|
20
|
+
if index
|
21
|
+
person.formal_name = @web_people[index].formal_name
|
22
|
+
person.first_name = @web_people[index].first_name
|
23
|
+
person.preferred_name = @web_people[index].preferred_name
|
24
|
+
person.email = @web_people[index].email unless person.email
|
25
|
+
person.phone = @web_people[index].phone unless person.phone
|
26
|
+
person.homepage_url = @web_people[index].homepage_url
|
27
|
+
person.image_url = @web_people[index].image_url
|
28
|
+
person.successful_merge = true
|
29
|
+
end
|
30
|
+
end
|
31
|
+
@people << person
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
end # MergeLower
|
36
|
+
end # QLD
|
37
|
+
end # MyRepresentatives
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module MyRepresentatives
|
2
|
+
module QLD
|
3
|
+
class WebIndex
|
4
|
+
attr_accessor :index_url, :document, :lower_urls
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
@logger = Logger.new(STDOUT)
|
8
|
+
@lower_urls = []
|
9
|
+
|
10
|
+
# Lower House
|
11
|
+
@index_url = "https://www.parliament.qld.gov.au/members/current/list"
|
12
|
+
@document = find_representatives
|
13
|
+
representative_urls_from_document
|
14
|
+
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def find_representatives
|
21
|
+
begin
|
22
|
+
request = open(@index_url)
|
23
|
+
Nokogiri::HTML(request)
|
24
|
+
rescue SocketError => err
|
25
|
+
@logger.debug("Unable to connect to #{@index_url}")
|
26
|
+
raise err
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
def representative_urls_from_document
|
32
|
+
begin
|
33
|
+
representatives = @document.css("select")[1].children
|
34
|
+
rescue
|
35
|
+
end
|
36
|
+
|
37
|
+
representatives.each do |row|
|
38
|
+
begin
|
39
|
+
@lower_urls << "https://www.parliament.qld.gov.au"+row.attr('value') if row.attr('value').include? "MemberDetails?ID="
|
40
|
+
rescue
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
end # WebIndex
|
46
|
+
end # QLD
|
47
|
+
end # MyRepresentatives
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module MyRepresentatives
|
2
|
+
module QLD
|
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 = Electorate.new(electorate_name)
|
28
|
+
electorate.state_nt_lower!
|
29
|
+
|
30
|
+
# Setup the Representative (Person)
|
31
|
+
person = MyRepresentatives::Person.new(electorate)
|
32
|
+
person.email = document.email
|
33
|
+
person.phone = document.phone
|
34
|
+
person.party_name = document.party_name
|
35
|
+
person.image_url = document.image_url
|
36
|
+
person.homepage_url = document.homepage_url
|
37
|
+
person.formal_name = document.formal_name
|
38
|
+
person.first_name = document.first_name
|
39
|
+
person.last_name = document.last_name
|
40
|
+
person.preferred_name = document.preferred_name
|
41
|
+
person.title = document.title
|
42
|
+
person.gender = guess_gender(document.title)
|
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 # QLD
|
54
|
+
end # MyRepresentatives
|
@@ -0,0 +1,146 @@
|
|
1
|
+
module MyRepresentatives
|
2
|
+
module QLD
|
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(".member-heading").css("h1").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 preferred_name
|
45
|
+
begin
|
46
|
+
guess_preferred(formal_name)
|
47
|
+
rescue NoMethodError
|
48
|
+
nil
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def last_name
|
53
|
+
begin
|
54
|
+
guess_last(formal_name)
|
55
|
+
rescue NoMethodError
|
56
|
+
nil
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def phone
|
61
|
+
begin
|
62
|
+
regex = /Phone: (.+?)[Fax|Email]/
|
63
|
+
text = @document.at('strong:contains("Phone:")').parent.text.strip
|
64
|
+
match = text.match(regex)
|
65
|
+
if match
|
66
|
+
match[1]
|
67
|
+
else
|
68
|
+
nil
|
69
|
+
end
|
70
|
+
rescue NoMethodError
|
71
|
+
nil
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def email
|
76
|
+
begin
|
77
|
+
regex = /Email: (.+?@parliament.qld.gov.au)/
|
78
|
+
text = @document.at('strong:contains("Email:")').parent.text.strip
|
79
|
+
match = text.match(regex)
|
80
|
+
if match
|
81
|
+
match[1]
|
82
|
+
else
|
83
|
+
nil
|
84
|
+
end
|
85
|
+
rescue NoMethodError
|
86
|
+
nil
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def electorate_name
|
91
|
+
begin
|
92
|
+
regex = /^\s+([A-Z].+?) -/
|
93
|
+
text = @document.at('strong:contains("Electorate")').parent.text.strip
|
94
|
+
match = text.match(regex)
|
95
|
+
if match
|
96
|
+
match[1]
|
97
|
+
else
|
98
|
+
nil
|
99
|
+
end
|
100
|
+
rescue NoMethodError
|
101
|
+
nil
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def party_name
|
106
|
+
begin
|
107
|
+
regex = /^\s+([A-Z].+?)$/
|
108
|
+
text = @document.at('strong:contains("Party")').parent.text.strip
|
109
|
+
match = text.match(regex)
|
110
|
+
if match
|
111
|
+
match[1].gsub(/ (\(.+?\))/,"")
|
112
|
+
else
|
113
|
+
nil
|
114
|
+
end
|
115
|
+
rescue NoMethodError
|
116
|
+
nil
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def image_url
|
121
|
+
begin
|
122
|
+
"https://www.parliament.qld.gov.au"+@document.css("div.member-bio").css("img").attr('src').value.gsub("../../..","")
|
123
|
+
rescue NoMethodError
|
124
|
+
nil
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
private
|
129
|
+
|
130
|
+
def fetch_document
|
131
|
+
begin
|
132
|
+
request = open(@url)
|
133
|
+
@document = Nokogiri::HTML(request)
|
134
|
+
rescue => err
|
135
|
+
@logger.debug("Failed to connect to the url: #{@url}")
|
136
|
+
raise err
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
def test_document_for_validity
|
141
|
+
true
|
142
|
+
end
|
143
|
+
|
144
|
+
end # WebShow
|
145
|
+
end # QLD
|
146
|
+
end # MyRepresentatives
|
@@ -0,0 +1,120 @@
|
|
1
|
+
module MyRepresentatives
|
2
|
+
module SA
|
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://www2.parliament.sa.gov.au/Internet/DesktopModules/CreateMM.aspx?type=ha"
|
11
|
+
@csv_filename = "tmp/csv_sa_lower.csv"
|
12
|
+
@people = []
|
13
|
+
|
14
|
+
csv_from_url
|
15
|
+
people_from_csv
|
16
|
+
end
|
17
|
+
|
18
|
+
def csv_from_url
|
19
|
+
create_tmp
|
20
|
+
|
21
|
+
f = open(@csv_url)
|
22
|
+
doc = Nokogiri::HTML(f)
|
23
|
+
|
24
|
+
CSV.open(@csv_filename, "wb") do |csv|
|
25
|
+
csv << ["title", "first", "last", "electorate", "address", "email"]
|
26
|
+
loops = 0
|
27
|
+
|
28
|
+
doc.css("table").css("tr").each do |row|
|
29
|
+
if loops > 0
|
30
|
+
arr = []
|
31
|
+
row.css("td").each do |cell|
|
32
|
+
arr << cell.text
|
33
|
+
end
|
34
|
+
csv << arr
|
35
|
+
end
|
36
|
+
loops += 1
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def people_from_csv
|
42
|
+
CSV.foreach(@csv_filename, headers: true) do |row|
|
43
|
+
|
44
|
+
# Setup the electorate
|
45
|
+
electorate_name = find_electorate(row)
|
46
|
+
electorate = Electorate.new(electorate_name)
|
47
|
+
electorate.state_sa_lower!
|
48
|
+
|
49
|
+
# Setup the Representative (Person)
|
50
|
+
person = Person.new(electorate)
|
51
|
+
|
52
|
+
person.title = find_title(row)
|
53
|
+
person.first_name = find_first_name(row)
|
54
|
+
person.last_name = find_last_name(row)
|
55
|
+
person.email = find_email(row)
|
56
|
+
person.phone = find_phone(row)
|
57
|
+
person.party_name = find_party(row)
|
58
|
+
person.gender = guess_gender(person.title)
|
59
|
+
person.formal_name = format_formal_name(person)
|
60
|
+
person.physical_address = format_physical_address(row)
|
61
|
+
person.postal_address = format_postal_address(row)
|
62
|
+
person.honorifics = "MP"
|
63
|
+
person.preferred_name = nil
|
64
|
+
person.salutation = nil
|
65
|
+
person.image_url = nil
|
66
|
+
person.homepage_url = nil
|
67
|
+
|
68
|
+
@people << person
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
def find_first_name(arr)
|
75
|
+
arr["first"]
|
76
|
+
end
|
77
|
+
|
78
|
+
def find_last_name(arr)
|
79
|
+
arr["last"]
|
80
|
+
end
|
81
|
+
|
82
|
+
def find_title(arr)
|
83
|
+
arr["title"]
|
84
|
+
end
|
85
|
+
|
86
|
+
def find_electorate(arr)
|
87
|
+
if arr && arr["electorate"]
|
88
|
+
arr["electorate"].gsub("Member for ","")
|
89
|
+
else
|
90
|
+
nil
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def find_email(arr)
|
95
|
+
arr["email"]
|
96
|
+
end
|
97
|
+
|
98
|
+
def find_party(arr)
|
99
|
+
nil
|
100
|
+
end
|
101
|
+
|
102
|
+
def find_phone(arr)
|
103
|
+
nil
|
104
|
+
end
|
105
|
+
|
106
|
+
def format_formal_name(person)
|
107
|
+
"#{person.title} #{person.first_name} #{person.last_name}"
|
108
|
+
end
|
109
|
+
|
110
|
+
def format_physical_address(arr)
|
111
|
+
"#{arr["address"]}"
|
112
|
+
end
|
113
|
+
|
114
|
+
def format_postal_address(arr)
|
115
|
+
"#{arr["address"]}"
|
116
|
+
end
|
117
|
+
|
118
|
+
end # CSVLower
|
119
|
+
end # SA
|
120
|
+
end # MyRepresentatives
|
@@ -0,0 +1,115 @@
|
|
1
|
+
module MyRepresentatives
|
2
|
+
module SA
|
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://www2.parliament.sa.gov.au/Internet/DesktopModules/CreateMM.aspx?type=lc"
|
11
|
+
@csv_filename = "tmp/csv_sa_upper.csv"
|
12
|
+
@people = []
|
13
|
+
|
14
|
+
csv_from_url
|
15
|
+
people_from_csv
|
16
|
+
end
|
17
|
+
|
18
|
+
def csv_from_url
|
19
|
+
create_tmp
|
20
|
+
f = open(@csv_url)
|
21
|
+
doc = Nokogiri::HTML(f)
|
22
|
+
|
23
|
+
CSV.open(@csv_filename, "wb") do |csv|
|
24
|
+
csv << ["title", "first", "last", "address", "city", "state", "postcode"]
|
25
|
+
loops = 0
|
26
|
+
|
27
|
+
doc.css("table").css("tr").each do |row|
|
28
|
+
if loops > 0
|
29
|
+
arr = []
|
30
|
+
row.css("td").each do |cell|
|
31
|
+
arr << cell.text
|
32
|
+
end
|
33
|
+
csv << arr
|
34
|
+
end
|
35
|
+
loops += 1
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def people_from_csv
|
41
|
+
CSV.foreach(@csv_filename, headers: true) do |row|
|
42
|
+
|
43
|
+
# Setup the electorate
|
44
|
+
electorate_name = find_electorate
|
45
|
+
electorate = Electorate.new(electorate_name)
|
46
|
+
electorate.state_sa_upper!
|
47
|
+
|
48
|
+
# Setup the Representative (Person)
|
49
|
+
person = Person.new(electorate)
|
50
|
+
|
51
|
+
person.title = find_title(row)
|
52
|
+
person.first_name = find_first_name(row)
|
53
|
+
person.last_name = find_last_name(row)
|
54
|
+
person.email = find_email(row)
|
55
|
+
person.phone = find_phone(row)
|
56
|
+
person.party_name = find_party(row)
|
57
|
+
person.gender = guess_gender(person.title)
|
58
|
+
person.formal_name = format_formal_name(person)
|
59
|
+
person.physical_address = format_physical_address(row)
|
60
|
+
person.postal_address = format_postal_address(row)
|
61
|
+
person.honorifics = "MLC"
|
62
|
+
person.preferred_name = nil
|
63
|
+
person.salutation = nil
|
64
|
+
person.image_url = nil
|
65
|
+
person.homepage_url = nil
|
66
|
+
|
67
|
+
@people << person
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
private
|
72
|
+
|
73
|
+
def find_first_name(arr)
|
74
|
+
arr["first"]
|
75
|
+
end
|
76
|
+
|
77
|
+
def find_last_name(arr)
|
78
|
+
arr["last"]
|
79
|
+
end
|
80
|
+
|
81
|
+
def find_title(arr)
|
82
|
+
arr["title"]
|
83
|
+
end
|
84
|
+
|
85
|
+
def find_electorate
|
86
|
+
"All SA"
|
87
|
+
end
|
88
|
+
|
89
|
+
def find_email(arr)
|
90
|
+
arr["email"]
|
91
|
+
end
|
92
|
+
|
93
|
+
def find_party(arr)
|
94
|
+
nil
|
95
|
+
end
|
96
|
+
|
97
|
+
def find_phone(arr)
|
98
|
+
nil
|
99
|
+
end
|
100
|
+
|
101
|
+
def format_formal_name(person)
|
102
|
+
"#{person.title} #{person.first_name} #{person.last_name}"
|
103
|
+
end
|
104
|
+
|
105
|
+
def format_physical_address(arr)
|
106
|
+
"#{arr["address"]}\n#{arr["city"]} #{arr["state"]} #{arr["postcode"]}"
|
107
|
+
end
|
108
|
+
|
109
|
+
def format_postal_address(arr)
|
110
|
+
"#{arr["address"]}\n#{arr["city"]} #{arr["state"]} #{arr["postcode"]}"
|
111
|
+
end
|
112
|
+
|
113
|
+
end # CSVUpper
|
114
|
+
end # SA
|
115
|
+
end # MyRepresentatives
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module MyRepresentatives
|
2
|
+
module SA
|
3
|
+
class MergeLower
|
4
|
+
attr_accessor :csv_people, :web_people, :people
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
@csv_people = MyRepresentatives::SA::CSVLower.new.people
|
8
|
+
@web_people = MyRepresentatives::SA::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.electorate.name == person.electorate.name }
|
18
|
+
index = @web_people.find_index { |wp| wp.electorate.name == person.electorate.name}
|
19
|
+
|
20
|
+
if index
|
21
|
+
person.formal_name = @web_people[index].formal_name
|
22
|
+
person.first_name = @web_people[index].first_name
|
23
|
+
person.preferred_name = @web_people[index].preferred_name
|
24
|
+
person.party_name = @web_people[index].party_name
|
25
|
+
person.email = @web_people[index].email unless person.email
|
26
|
+
person.phone = @web_people[index].phone unless person.phone
|
27
|
+
person.homepage_url = @web_people[index].homepage_url
|
28
|
+
person.image_url = @web_people[index].image_url
|
29
|
+
person.successful_merge = true
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
@people << person
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
end # MergeLower
|
38
|
+
end # SA
|
39
|
+
end # MyRepresentatives
|