parliamentarian 0.8.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/lib/Array/blankQ.rb +13 -0
- data/lib/Array/extract_optionsX.rb +14 -0
- data/lib/Array/peek_options.rb +14 -0
- data/lib/Array/to_csv.rb +41 -0
- data/lib/FalseClass/blankQ.rb +15 -0
- data/lib/Hash/blankQ.rb +13 -0
- data/lib/Hash/to_csv.rb +34 -0
- data/lib/NilClass/blankQ.rb +15 -0
- data/lib/NilClass/default_to.rb +25 -0
- data/lib/Numeric/blankQ.rb +15 -0
- data/lib/Object/blankQ.rb +18 -0
- data/lib/Object/default_to.rb +25 -0
- data/lib/Parliamentarian.rb +31 -0
- data/lib/Parliamentarian/Australia.rb +4 -0
- data/lib/Parliamentarian/Australia/Federal.rb +95 -0
- data/lib/Parliamentarian/Australia/Victoria.rb +74 -0
- data/lib/Parliamentarian/VERSION.rb +5 -0
- data/lib/SimpleCSV.rb +389 -0
- data/lib/SimpleCSV/File.rb +50 -0
- data/lib/SimpleCSV/String.rb +30 -0
- data/lib/String/blankQ.rb +18 -0
- data/lib/String/split_csv.rb +66 -0
- data/lib/String/underscore.rb +32 -0
- data/lib/TrueClass/blankQ.rb +15 -0
- data/lib/_meta/blankQ.rb +13 -0
- data/lib/_meta/default_to.rb +7 -0
- metadata +112 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 9cd38f5cb99774b5aacfa8074a76cace5f9e68e1fca7939242fdccdea7dac42e
|
4
|
+
data.tar.gz: 1c8ebbec3a095b89f0250ba39620ef1fc2c7f0878aecb235dd867853983bf35d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: f5e3702bec1c772317f3fd86a1893b964ba3ea5dbf00ff24ff61d240719b2c8ced76f4dbc1b8e35f5821f4a3612f42dc990c4613366fff915a2f73ad57bea971
|
7
|
+
data.tar.gz: b1bb5f7dc7ccca8ab0a898057df147573e4d4540acec4ec6821713f5565997733673cc783a0fe225b8d166e983784fbeee10d43cfb770d8ff333d001ecb3b716
|
data/lib/Array/blankQ.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
# Array#peek_options
|
2
|
+
|
3
|
+
# 20100308
|
4
|
+
# 0.1.0
|
5
|
+
|
6
|
+
# History: Originally called #extract_options (no exclamation mark), but written again a few days ago for Switches as #peek_options. #extract_options has been moved to #extract_options! as an alias for it.
|
7
|
+
|
8
|
+
class Array
|
9
|
+
|
10
|
+
def peek_options
|
11
|
+
last.is_a?(::Hash) ? last : {}
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
data/lib/Array/to_csv.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
# Array#to_csv
|
2
|
+
|
3
|
+
# 20111211
|
4
|
+
# 0.9.9
|
5
|
+
|
6
|
+
# Todo:
|
7
|
+
# 1. Split all these up and move each method into Array... Done as of 0.9.0.
|
8
|
+
# 2. ~ Array#to_csv, massive refactor, including getting rid of a lot of aliases for now at least. Done as of 0.9.0.
|
9
|
+
|
10
|
+
# Changes since 0.8:
|
11
|
+
# 1. Has it's own file now.
|
12
|
+
# 0/1
|
13
|
+
# 2. Removed all the require lines for the array methods since these are simple operations. So, I am now doing the quoting directly, since quote_each() which calls wrap_each() which in turn calls wrap() is lots of extra method calls.
|
14
|
+
# 2/3
|
15
|
+
# 3. + require '_meta/default_to' && making use of it in the case test, since if I explicitly supply nil, then the quote is not set to double in the argument definition.
|
16
|
+
# 3/9
|
17
|
+
# 4. Version number bump to 0.9.9.
|
18
|
+
# 5. /+ e +/+ e.to_s +/.
|
19
|
+
|
20
|
+
require '_meta/default_to'
|
21
|
+
|
22
|
+
class Array
|
23
|
+
|
24
|
+
def to_csv(quote = :double)
|
25
|
+
case quote.default_to(:double).to_sym
|
26
|
+
when :double
|
27
|
+
self.collect{|e| '"' + e.to_s + '"'}.join(',')
|
28
|
+
when :spacey_double
|
29
|
+
self.collect{|e| '"' + e.to_s + '"'}.join(', ')
|
30
|
+
when :single
|
31
|
+
self.collect{|e| "'" + e.to_s + "'"}.join(',')
|
32
|
+
when :spacey_single
|
33
|
+
self.collect{|e| "'" + e.to_s + "'"}.join(', ')
|
34
|
+
when :none, :unquoted
|
35
|
+
self.join(',')
|
36
|
+
when :spacey_none, :spacey_unquoted
|
37
|
+
self.join(', ')
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
data/lib/Hash/blankQ.rb
ADDED
data/lib/Hash/to_csv.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
# Hash#to_csv
|
2
|
+
|
3
|
+
# 2010.05.21
|
4
|
+
# 0.9.1
|
5
|
+
|
6
|
+
# Changes:
|
7
|
+
# 1. - Hash#write.
|
8
|
+
# 2. ~ Hash#to_csv, a significant reduction in complexity.
|
9
|
+
# 0/1
|
10
|
+
# 3. /desired_columns/selected_columns/.
|
11
|
+
|
12
|
+
# Todo:
|
13
|
+
# 1. Split all these up and move each method into Array... Done as of 0.9.0.
|
14
|
+
# 2. Tidy the splat stuff with that technique from recently!?... Done/made redundant as of 0.9.0.
|
15
|
+
|
16
|
+
require 'Array/extract_optionsX'
|
17
|
+
require 'Array/to_csv'
|
18
|
+
|
19
|
+
class Hash
|
20
|
+
|
21
|
+
def to_csv(*args)
|
22
|
+
options = args.extract_options!
|
23
|
+
quote = options[:quote]
|
24
|
+
selected_columns = options[:selected_columns]
|
25
|
+
collector = []
|
26
|
+
if selected_columns
|
27
|
+
selected_columns.each{|column| collector << self[column]}
|
28
|
+
else
|
29
|
+
self.each{|k,v| collector << self[v]}
|
30
|
+
end
|
31
|
+
collector.to_csv(quote)
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# NilClass/default_to.rb
|
2
|
+
# NilClass#default_to
|
3
|
+
|
4
|
+
# 20140524
|
5
|
+
# 0.2.0
|
6
|
+
|
7
|
+
# Description: Used in concert with Object#default_to, NilClass#default_to will assign a default value to a variable if that variable is nil, or if it isn't nil Object#default_to will return the value of the variable already set.
|
8
|
+
|
9
|
+
# History: Taken from Switches 0.9.9.
|
10
|
+
|
11
|
+
# Changes:
|
12
|
+
# 1. - alias_method :default, since the complement, Object#default_to, was clashing with the ruby mail gem.
|
13
|
+
# 2. + require 'Object/default_to', since these two are supposed to work together.
|
14
|
+
|
15
|
+
require 'Object/default_to'
|
16
|
+
|
17
|
+
class NilClass
|
18
|
+
|
19
|
+
def default_to(o)
|
20
|
+
o
|
21
|
+
end
|
22
|
+
alias_method :defaults_to, :default_to
|
23
|
+
alias_method :default_is, :default_to
|
24
|
+
|
25
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# Object#blankQ
|
2
|
+
# Object#blank?
|
3
|
+
|
4
|
+
# 2010.04.04
|
5
|
+
# 0.0.1
|
6
|
+
|
7
|
+
# History: Stolen wholesale from a recent version of ActiveSupport.
|
8
|
+
|
9
|
+
# Changes:
|
10
|
+
# 1. Now using a more recent version from ActiveSupport. This more recent version from ActiveSupport is likely more efficient and slightly more succinct.
|
11
|
+
|
12
|
+
class Object
|
13
|
+
|
14
|
+
def blank?
|
15
|
+
respond_to?(:empty?) ? empty? : !self
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# Object/default_to.rb
|
2
|
+
# Object#default_to
|
3
|
+
|
4
|
+
# 20140524
|
5
|
+
# 0.2.0
|
6
|
+
|
7
|
+
# Description: Enables a slightly more powerful assignment mechanism than does ||=, such that it will assign a default value to a variable if the parameterized source is nil, whereas ||= will only assign to the paramterized source if the variable is not already set.
|
8
|
+
|
9
|
+
# History: Taken from Switches 0.9.9.
|
10
|
+
|
11
|
+
# Changes:
|
12
|
+
# 1. - alias_method :default, since it was clashing with the ruby mail gem.
|
13
|
+
# 2. + require 'NilClass/default_to', since these two are supposed to work together.
|
14
|
+
|
15
|
+
require 'NilClass/default_to'
|
16
|
+
|
17
|
+
class Object
|
18
|
+
|
19
|
+
def default_to(o)
|
20
|
+
self
|
21
|
+
end
|
22
|
+
alias_method :defaults_to, :default_to
|
23
|
+
alias_method :default_is, :default_to
|
24
|
+
|
25
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# Parliamentarian.rb
|
2
|
+
# Parliamentarian
|
3
|
+
|
4
|
+
# 20210408
|
5
|
+
# 0.8.5
|
6
|
+
|
7
|
+
# Changes since 0.7:
|
8
|
+
# 0: Paramterised the location of the CSV files so that it can be a local file or the original URL by default with a view to making use of those files as fixtures for tests.
|
9
|
+
# 1. ~ Australia::Federal.fetch, .senators, .members, so that one is able to supply a csv file location.
|
10
|
+
# 2. ~ Australia::Victoria.fetch, .legislative_councillors, .legislative_assemblymen, so that one is able to supply a csv file location.
|
11
|
+
# 3. Removed the self-run sections from Australia::Federal and Australia::Victoria with proper tests in their stead.
|
12
|
+
# 4. + ./test
|
13
|
+
# 0/1
|
14
|
+
# 5. /require 'SimpleCSV.rbd'/SimpleCSV/require 'SimpleCSV'/
|
15
|
+
# 1/2
|
16
|
+
# 6. Swapped Victorian councillors and assemblymen URLs as they were the reverse of what they should be.
|
17
|
+
# 7. /legislative_assemblymen/legislative_assemblymembers/, so as to be consistent with the CSV filename being downloaded.
|
18
|
+
# 2/3
|
19
|
+
# 8. Underscored all the dynamically created methods for each of the column names in the CSV files.
|
20
|
+
# 3/4
|
21
|
+
# 9. Missed some aliases when underscoring in the previous version.
|
22
|
+
# 4/5
|
23
|
+
# 10. + VERSION file
|
24
|
+
# 11. + parliamentarian.gemspec
|
25
|
+
# 12. ~ Gemfile to include webmock.
|
26
|
+
# 13. + required lib files (to be broken out later.)
|
27
|
+
|
28
|
+
lib_dir = File.dirname(File.expand_path(__FILE__))
|
29
|
+
$LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir)
|
30
|
+
|
31
|
+
require_relative 'Parliamentarian/Australia'
|
@@ -0,0 +1,95 @@
|
|
1
|
+
# Parliamentarian/Australia/Federal.rb
|
2
|
+
# Parliamentarian::Australia::Federal
|
3
|
+
|
4
|
+
require 'open-uri'
|
5
|
+
require 'SimpleCSV'
|
6
|
+
require 'String/underscore'
|
7
|
+
|
8
|
+
module Parliamentarian
|
9
|
+
module Australia
|
10
|
+
class Federal
|
11
|
+
|
12
|
+
SENATE_URL = 'https://www.aph.gov.au/~/media/03%20Senators%20and%20Members/Address%20Labels%20and%20CSV%20files/Senators/allsenel.csv?la=en'
|
13
|
+
HOUSE_OF_REPRESENTATIVES_URL = 'https://www.aph.gov.au/~/media/03%20Senators%20and%20Members/Address%20Labels%20and%20CSV%20files/SurnameRepsCSV.csv?la=en'
|
14
|
+
|
15
|
+
class << self
|
16
|
+
|
17
|
+
def fetch(csv_file_location)
|
18
|
+
raw_csv = if ['http', 'https'].include?(URI.parse(csv_file_location).scheme)
|
19
|
+
URI.open(csv_file_location)
|
20
|
+
else
|
21
|
+
File.read(csv_file_location)
|
22
|
+
end
|
23
|
+
SimpleCSV.read(raw_csv, headers: true)
|
24
|
+
end
|
25
|
+
|
26
|
+
def all(senators_csv_file_location = nil, members_csv_file_location = nil)
|
27
|
+
@all ||= (senators(senators_csv_file_location) + house_of_representatives(members_csv_file_location)).flatten
|
28
|
+
end
|
29
|
+
|
30
|
+
def senators(csv_file_location = nil)
|
31
|
+
@senators ||= (
|
32
|
+
csv_file_location = csv_file_location || SENATE_URL
|
33
|
+
fetch(csv_file_location).collect{|row| self.new(row)}
|
34
|
+
)
|
35
|
+
end
|
36
|
+
alias_method :senate, :senators
|
37
|
+
|
38
|
+
def members(csv_file_location = nil)
|
39
|
+
@members ||= (
|
40
|
+
csv_file_location = csv_file_location || HOUSE_OF_REPRESENTATIVES_URL
|
41
|
+
fetch(csv_file_location).collect{|row| self.new(row)}
|
42
|
+
)
|
43
|
+
end
|
44
|
+
alias_method :house_of_representatives, :members
|
45
|
+
|
46
|
+
end # class << self
|
47
|
+
|
48
|
+
def initialize(row)
|
49
|
+
row.keys.each do |header|
|
50
|
+
attr_name = self.attr_name(header)
|
51
|
+
self.class.send(:attr_accessor, attr_name)
|
52
|
+
self.send("#{attr_name}=", row[header])
|
53
|
+
end
|
54
|
+
synthesize_email_address
|
55
|
+
end
|
56
|
+
|
57
|
+
# For consistency with Australia::Victoria and vice-versa...
|
58
|
+
def firstname; first_name; end
|
59
|
+
def lastname; surname; end
|
60
|
+
def last_name; surname; end
|
61
|
+
|
62
|
+
def postcode
|
63
|
+
@electorate_postcode
|
64
|
+
end
|
65
|
+
|
66
|
+
# predicate methods
|
67
|
+
|
68
|
+
def senator?
|
69
|
+
salutation == 'Senator'
|
70
|
+
end
|
71
|
+
|
72
|
+
def member?
|
73
|
+
!senator?
|
74
|
+
end
|
75
|
+
|
76
|
+
private
|
77
|
+
|
78
|
+
def attr_name(header)
|
79
|
+
header.underscore
|
80
|
+
end
|
81
|
+
|
82
|
+
def synthesize_email_address
|
83
|
+
self.class.send(:attr_accessor, 'email')
|
84
|
+
self.email = (
|
85
|
+
if senator?
|
86
|
+
"senator.#{surname.downcase}@aph.gov.au"
|
87
|
+
else
|
88
|
+
"#{first_name}.#{surname}.MP@aph.gov.au"
|
89
|
+
end
|
90
|
+
)
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
# Parliamentarian/Australia/Victoria.rb
|
2
|
+
# Parliamentarian::Australia::Victoria
|
3
|
+
|
4
|
+
require 'open-uri'
|
5
|
+
require 'SimpleCSV'
|
6
|
+
require 'String/underscore'
|
7
|
+
|
8
|
+
module Parliamentarian
|
9
|
+
module Australia
|
10
|
+
class Victoria
|
11
|
+
|
12
|
+
LEGISLATIVE_COUNCIL_URL = 'https://www.parliament.vic.gov.au/images/members/councilmembers.csv'
|
13
|
+
LEGISLATIVE_ASSEMBLY_URL = 'https://www.parliament.vic.gov.au/images/members/assemblymembers.csv'
|
14
|
+
|
15
|
+
class << self
|
16
|
+
|
17
|
+
def fetch(csv_file_location)
|
18
|
+
raw_csv = if ['http', 'https'].include?(URI.parse(csv_file_location).scheme)
|
19
|
+
URI.open(csv_file_location)
|
20
|
+
else
|
21
|
+
File.read(csv_file_location)
|
22
|
+
end
|
23
|
+
SimpleCSV.read(raw_csv, headers: true)
|
24
|
+
end
|
25
|
+
|
26
|
+
def all(legislative_councillors_csv_file_location = nil, legislative_assemblymembers_csv_file_location = nil)
|
27
|
+
@all ||= (legislative_councillors(legislative_councillors_csv_file_location) + legislative_assemblymembers(legislative_assemblymembers_csv_file_location)).flatten
|
28
|
+
end
|
29
|
+
|
30
|
+
def legislative_councillors(csv_file_location = nil)
|
31
|
+
@legislative_council ||= (
|
32
|
+
csv_file_location = csv_file_location || LEGISLATIVE_COUNCIL_URL
|
33
|
+
fetch(csv_file_location).collect{|row| self.new(row)}
|
34
|
+
)
|
35
|
+
end
|
36
|
+
|
37
|
+
def legislative_assemblymembers(csv_file_location = nil)
|
38
|
+
@legislative_assembly ||= (
|
39
|
+
csv_file_location = csv_file_location || LEGISLATIVE_ASSEMBLY_URL
|
40
|
+
fetch(csv_file_location).collect{|row| self.new(row)}
|
41
|
+
)
|
42
|
+
end
|
43
|
+
|
44
|
+
end # class << self
|
45
|
+
|
46
|
+
def initialize(row)
|
47
|
+
row.keys.each do |header|
|
48
|
+
attr_name = self.attr_name(header)
|
49
|
+
self.class.send(:attr_accessor, attr_name)
|
50
|
+
self.send("#{attr_name}=", row[header])
|
51
|
+
end
|
52
|
+
extract_postcode_from_electorate_office_address
|
53
|
+
end
|
54
|
+
|
55
|
+
# For consistency with Australia::Federal and vice-versa...
|
56
|
+
def firstname; preferred_name; end
|
57
|
+
def first_name; preferred_name; end
|
58
|
+
def surname; last_name; end
|
59
|
+
def lastname; last_name; end
|
60
|
+
|
61
|
+
private
|
62
|
+
|
63
|
+
def attr_name(header)
|
64
|
+
header.underscore
|
65
|
+
end
|
66
|
+
|
67
|
+
def extract_postcode_from_electorate_office_address
|
68
|
+
self.class.send(:attr_accessor, 'postcode')
|
69
|
+
self.postcode = eo_address.split.last
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
data/lib/SimpleCSV.rb
ADDED
@@ -0,0 +1,389 @@
|
|
1
|
+
# SimpleCSV.rb
|
2
|
+
# SimpleCSV
|
3
|
+
|
4
|
+
# 20200606
|
5
|
+
# 0.10.3
|
6
|
+
|
7
|
+
# Description: A CSV object for reading and writing CSV (and similar) text files with tabulated data to and from files and strings.
|
8
|
+
|
9
|
+
# Todo:
|
10
|
+
# 1. Have it be able to read mixed CSV files. Done as of 0.9.0.
|
11
|
+
# 2. Have it be able to read escaped and quoted delimeters.
|
12
|
+
# 3. Separate out the different classes into separate files. Done as of 0.8 I think, but taken further with 0.9.
|
13
|
+
# 4. Create a gem and/or Rubylibify and/or
|
14
|
+
# 5. Optionally do line counts.
|
15
|
+
# 6. Optionally do column count checks.
|
16
|
+
# 7. Optionally do data consistency checks for column length, type, and anything else that makes sense.
|
17
|
+
# 8. Put the option to specify quoting into to_csv and possibly remove it from #init. Done as of at least 0.8.
|
18
|
+
# 9. Remove underscores when outputting the header line, but only if they were added---and only if they're wanting to be removed?... As of 0.9.0, I just use strings anyway.
|
19
|
+
# 10. Reorder the conditionals in #write_line and #write_header. Done as of 0.9.0.
|
20
|
+
# 11. Simplify some more! Done as of 0.9.1.
|
21
|
+
|
22
|
+
# Ideas:
|
23
|
+
# 1. Standardize on either symbols or strings for column names, since presently one has to be consistent. It would be nicer to be able to mix and match---if possible.
|
24
|
+
# 2. Automatically detect as to whether there is a header line by taking the first line and comparing the types (alpha, numeric, alpha-numeric, etcetera) with each of the column values with those of the subsequent 2 or 3 or so lines and if there is a correspondence, then assume that there is a header line. This would mean that the assumption that there is would change and that if the guess was wrong that it would need to be made explict.
|
25
|
+
# 3. Have it #read a file automatically if any of 'r' or 'r+' or 'w+' is given as the mode.
|
26
|
+
# 4. Finally try to make use of Index instead of Hash, since that library file is still hanging around. Using this class may be simpler but not faster than using Hash and Array.
|
27
|
+
|
28
|
+
# Bugs:
|
29
|
+
# 1. This did cope with commas within a quoted CSV file, however while I think I broke this again with 0.9.0, I'm not sure that I ever had it working properly. It works properly as of 0.9.3 at least.
|
30
|
+
# 2. Does SimpleCSV#write_row handle it if there are no attributes/columns defined? It needs to work with CSV files with no column names.
|
31
|
+
|
32
|
+
# Changes since 0.9:
|
33
|
+
# 1. - SimpleCSV.rbd directory, moving everything up a directory, and SimpleCSV.rb inside the lib directory, so it now adheres to a more conventional Ruby library structure. May re-introduce .rbd, self-contained Ruby libraries one day, but will need to have the require overload work correctly and be able to load .rbd files correctly when presented. This may have changed sometime in the past quite a few years...
|
34
|
+
# 2. + ./Kernel/silently.rb which was used in the speed testing file, but had never been incorporated into the lib directory as it should.
|
35
|
+
# 0/1
|
36
|
+
# 3. - ./test until such time as they are half-decent, which they have never been!
|
37
|
+
# 1/2
|
38
|
+
# 4. Separated CSVFile and CSVString into their own files.
|
39
|
+
# 5. require 'stringio' --> CSVString.rb
|
40
|
+
# 2/3
|
41
|
+
# 6. /CSVFile/SimpleCSV::File/
|
42
|
+
# 7. /CSVString/SimpleCSV::String/
|
43
|
+
# 8. Ensured that there are a number of leading class colon separators (::) in strategic places!
|
44
|
+
|
45
|
+
$LOAD_PATH.unshift(File.expand_path('..', __FILE__))
|
46
|
+
|
47
|
+
require '_meta/blankQ'
|
48
|
+
require 'Array/extract_optionsX'
|
49
|
+
require 'Array/peek_options'
|
50
|
+
require 'Array/to_csv'
|
51
|
+
require 'Hash/to_csv'
|
52
|
+
require 'String/split_csv'
|
53
|
+
|
54
|
+
require 'SimpleCSV/File'
|
55
|
+
require 'SimpleCSV/String'
|
56
|
+
|
57
|
+
class SimpleCSV
|
58
|
+
|
59
|
+
class << self
|
60
|
+
|
61
|
+
def source_type(source)
|
62
|
+
if ::File.exist?(source)
|
63
|
+
SimpleCSV::File
|
64
|
+
else
|
65
|
+
SimpleCSV::String
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def open(source, *args, &block)
|
70
|
+
@csv_file = new(source, *args)
|
71
|
+
if block
|
72
|
+
begin
|
73
|
+
yield @csv_file
|
74
|
+
@csv_file
|
75
|
+
ensure
|
76
|
+
@csv_file.close
|
77
|
+
end
|
78
|
+
else
|
79
|
+
@csv_file
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def each(source, *args, &block)
|
84
|
+
new(source, *args).each(&block)
|
85
|
+
end
|
86
|
+
alias_method :foreach, :each
|
87
|
+
|
88
|
+
def collect(source, *args, &block)
|
89
|
+
new_collection = []
|
90
|
+
each(source, *args){|row| new_collection << block.call(row)}
|
91
|
+
new_collection
|
92
|
+
end
|
93
|
+
alias_method :map, :collect
|
94
|
+
|
95
|
+
def select(source, *args, &block)
|
96
|
+
new_collection = []
|
97
|
+
each(source, *args){|row| new_collection << row if block.call(row)}
|
98
|
+
new_collection
|
99
|
+
end
|
100
|
+
alias_method :find_all, :select
|
101
|
+
|
102
|
+
def reject(source, *args, &block)
|
103
|
+
new_collection = []
|
104
|
+
each(source, *args){|row| new_collection << row unless block.call(row)}
|
105
|
+
new_collection
|
106
|
+
end
|
107
|
+
|
108
|
+
def detect(source, *args, &block)
|
109
|
+
each(source, *args){|row| return row if block.call(row)}
|
110
|
+
end
|
111
|
+
alias_method :find, :detect
|
112
|
+
|
113
|
+
def read(source, *args, &block)
|
114
|
+
if block
|
115
|
+
parse(source, *args, &block)
|
116
|
+
else
|
117
|
+
new(source, *args).read_csv
|
118
|
+
end
|
119
|
+
end
|
120
|
+
alias_method :read_csv, :read
|
121
|
+
|
122
|
+
def parse(source, *args, &block)
|
123
|
+
if block
|
124
|
+
each(source, *args, &block)
|
125
|
+
else
|
126
|
+
read(source, *args)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
alias_method :parse_csv, :parse
|
130
|
+
|
131
|
+
def write(source, *args)
|
132
|
+
new(source, *args).write_csv
|
133
|
+
end
|
134
|
+
alias_method :write_csv, :write
|
135
|
+
|
136
|
+
def header_row(source, *args)
|
137
|
+
new(source, *args).header_row
|
138
|
+
end
|
139
|
+
|
140
|
+
def first_row(source, *args)
|
141
|
+
new(source, *args).first_row
|
142
|
+
end
|
143
|
+
|
144
|
+
def attributes(source, *args)
|
145
|
+
new(source, *args).attributes
|
146
|
+
end
|
147
|
+
|
148
|
+
def columns(source, *args)
|
149
|
+
new(source, *args).columns
|
150
|
+
end
|
151
|
+
|
152
|
+
def parse_line(raw_row, *args) # For FasterCSV compatibility.
|
153
|
+
options = args.extract_options!
|
154
|
+
row_separator = options[:row_separator] || options[:row_sep] || "\n"
|
155
|
+
column_separator = options[:column_separator] || options[:col_sep] || ','
|
156
|
+
sc = SimpleCSV.new(raw_row, :quote => nil, :as_array => true, :row_separator => row_separator, :column_separator => column_separator)
|
157
|
+
sc.parse_row(raw_row)
|
158
|
+
end
|
159
|
+
|
160
|
+
end # class << self
|
161
|
+
|
162
|
+
include Enumerable
|
163
|
+
|
164
|
+
attr_accessor :header_row, :mode, :quote, :row_separator, :selected_columns, :as_array, :rows
|
165
|
+
|
166
|
+
def initialize(source, *args)
|
167
|
+
@source = (
|
168
|
+
if source.is_a?(::String)
|
169
|
+
SimpleCSV.source_type(source).new(source, *args).source
|
170
|
+
else
|
171
|
+
source
|
172
|
+
end
|
173
|
+
)
|
174
|
+
options = args.extract_options!
|
175
|
+
@header_row = options[:header_row] || options[:headers] || options[:header] || false
|
176
|
+
@mode = options[:mode] || 'r'
|
177
|
+
@quote = options[:quote] || nil
|
178
|
+
@row_separator = options[:row_separator] || options[:row_sep] || "\n"
|
179
|
+
@column_separator = options[:column_separator] || options[:col_sep] || ','
|
180
|
+
@selected_columns = options[:selected_columns]
|
181
|
+
@as_array = options[:as_array] || false
|
182
|
+
if options[:columns]
|
183
|
+
self.columns = options[:columns]
|
184
|
+
else
|
185
|
+
self.columns
|
186
|
+
end
|
187
|
+
@rows = []
|
188
|
+
end
|
189
|
+
|
190
|
+
def close
|
191
|
+
@source.close
|
192
|
+
end
|
193
|
+
|
194
|
+
def read(*selected_columns, &block)
|
195
|
+
if block
|
196
|
+
parse(*selected_columns, &block)
|
197
|
+
else
|
198
|
+
read_header
|
199
|
+
@source.each(@row_separator){|raw_row| @rows << parse_row(raw_row, *selected_columns)}
|
200
|
+
(@source.rewind; @source.truncate(0)) if @mode == 'r+'
|
201
|
+
@rows
|
202
|
+
end
|
203
|
+
end
|
204
|
+
alias_method :read_csv, :read
|
205
|
+
|
206
|
+
def read_header
|
207
|
+
columns
|
208
|
+
if header_row?
|
209
|
+
(@source.rewind; @source.gets(@row_separator))
|
210
|
+
else
|
211
|
+
@source.rewind
|
212
|
+
end
|
213
|
+
end
|
214
|
+
alias_method :read_csv_header, :read_header
|
215
|
+
|
216
|
+
def parse(*selected_columns, &block)
|
217
|
+
if block
|
218
|
+
each(*selected_columns, &block)
|
219
|
+
else
|
220
|
+
read(*selected_columns)
|
221
|
+
end
|
222
|
+
end
|
223
|
+
alias_method :parse_csv, :parse
|
224
|
+
|
225
|
+
def columns
|
226
|
+
@columns ||= (
|
227
|
+
if header_row? && ['r', 'r+', 'a+'].include?(@mode) && (first_row = first_row?)
|
228
|
+
columns, i = {}, -1
|
229
|
+
first_row.split_csv(@quote, @column_separator, @row_separator).each do |column_name|
|
230
|
+
if column_name.empty?
|
231
|
+
columns[column_name].blank? ? columns[column_name] = [i += 1] : columns[column_name] << (i += 1)
|
232
|
+
else
|
233
|
+
columns[column_name] = (i += 1)
|
234
|
+
end
|
235
|
+
end
|
236
|
+
columns
|
237
|
+
else
|
238
|
+
nil
|
239
|
+
end
|
240
|
+
)
|
241
|
+
end
|
242
|
+
|
243
|
+
def columns=(*column_order)
|
244
|
+
@columns = {}
|
245
|
+
column_order.flatten!
|
246
|
+
if column_order[0].is_a?(Hash)
|
247
|
+
column_order[0].each{|column_name, column_position| @columns[column_name.to_s] = column_position}
|
248
|
+
else
|
249
|
+
i = -1
|
250
|
+
column_order.each{|column| @columns[column.to_s] = (i += 1)}
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
254
|
+
def parse_row(raw_row, *selected_columns)
|
255
|
+
parsed_row = {}
|
256
|
+
i = -1
|
257
|
+
if selected_columns.empty?
|
258
|
+
if @columns.blank?
|
259
|
+
raw_row.split_csv(@quote, @column_separator, @row_separator).each{|column_value| parsed_row[i += 1] = column_value}
|
260
|
+
else
|
261
|
+
raw_row.split_csv(@quote, @column_separator, @row_separator).each{|column_value| parsed_row[attributes[i += 1]] = column_value}
|
262
|
+
end
|
263
|
+
else
|
264
|
+
selected_columns.flatten!
|
265
|
+
case selected_columns[0]
|
266
|
+
when Integer
|
267
|
+
raw_row.split_csv(@quote, @column_separator, @row_separator).each{|column_value| parsed_row[i] = column_value unless !selected_columns.include?(i += 1)}
|
268
|
+
else
|
269
|
+
raw_row.split_csv(@quote, @column_separator, @row_separator).each{|column_value| parsed_row[attributes[i]] = column_value unless !selected_columns.include?(attributes[i += 1])}
|
270
|
+
end
|
271
|
+
end
|
272
|
+
if @as_array
|
273
|
+
if @columns.blank?
|
274
|
+
(0..(parsed_row.size - 1)).inject([]){|a,i| a << parsed_row[i]}
|
275
|
+
else
|
276
|
+
attributes.collect{|attribute| parsed_row[attribute]}
|
277
|
+
end
|
278
|
+
else
|
279
|
+
parsed_row
|
280
|
+
end
|
281
|
+
end
|
282
|
+
|
283
|
+
def write(*selected_columns)
|
284
|
+
write_header(*selected_columns) if header_row?
|
285
|
+
each{|row| write_row(row, *selected_columns)}
|
286
|
+
end
|
287
|
+
alias_method :write_csv, :write
|
288
|
+
|
289
|
+
def write_header(*selected_columns)
|
290
|
+
selected_columns.flatten!
|
291
|
+
if selected_columns.empty?
|
292
|
+
write_row(attributes.to_csv)
|
293
|
+
else
|
294
|
+
write_row(columns.to_csv)
|
295
|
+
end
|
296
|
+
end
|
297
|
+
alias_method :write_csv_header, :write_header
|
298
|
+
|
299
|
+
def write_row(row, *selected_columns)
|
300
|
+
collector = []
|
301
|
+
selected_columns.flatten!
|
302
|
+
unless attributes.blank?
|
303
|
+
if selected_columns.blank?
|
304
|
+
attributes.each{|attribute| collector << row[attribute] unless row[attribute].nil?}
|
305
|
+
else
|
306
|
+
selected_columns.each{|column| collector << row[column] unless row[column].nil?}
|
307
|
+
end
|
308
|
+
@source.puts(collector.to_csv(@quote))
|
309
|
+
end
|
310
|
+
end
|
311
|
+
alias_method :write_csv_row, :write_row
|
312
|
+
|
313
|
+
def each(*selected_columns)
|
314
|
+
selected_columns.flatten!
|
315
|
+
if @rows[0]
|
316
|
+
if selected_columns.empty?
|
317
|
+
@rows.each{|row| yield row}
|
318
|
+
else
|
319
|
+
@rows.each do |row|
|
320
|
+
yield selected_columns.inject({}){|hash, column_name| hash[column_name] = row[column_name]; hash}
|
321
|
+
end
|
322
|
+
end
|
323
|
+
else
|
324
|
+
if selected_columns.empty?
|
325
|
+
read_csv.each{|row| yield row}
|
326
|
+
else
|
327
|
+
read_csv(selected_columns).each do |row|
|
328
|
+
yield selected_columns.inject({}){|hash, column_name| hash[column_name] = row[column_name]; hash}
|
329
|
+
end
|
330
|
+
end
|
331
|
+
end
|
332
|
+
end
|
333
|
+
alias_method :each_row, :each
|
334
|
+
|
335
|
+
def attributes
|
336
|
+
@attributes ||= (
|
337
|
+
if columns.blank?
|
338
|
+
nil
|
339
|
+
else
|
340
|
+
a = []
|
341
|
+
columns.each do |k,v|
|
342
|
+
case v
|
343
|
+
when Array
|
344
|
+
v.each{|e| a << ['', e]}
|
345
|
+
else
|
346
|
+
a << [k, v]
|
347
|
+
end
|
348
|
+
end
|
349
|
+
a.sort{|a,b| a[1] <=> b[1]}.collect{|a| a[0]}
|
350
|
+
end
|
351
|
+
)
|
352
|
+
end
|
353
|
+
|
354
|
+
def attributes=(attributes)
|
355
|
+
@attributes = attributes
|
356
|
+
end
|
357
|
+
|
358
|
+
def header_row?
|
359
|
+
@header_row
|
360
|
+
end
|
361
|
+
|
362
|
+
def first_row
|
363
|
+
@source.rewind
|
364
|
+
return_value = @source.gets(@row_separator)
|
365
|
+
@source.rewind
|
366
|
+
return_value
|
367
|
+
end
|
368
|
+
alias_method :first_row?, :first_row
|
369
|
+
|
370
|
+
def to_a
|
371
|
+
read_csv unless @rows[0]
|
372
|
+
if @as_array
|
373
|
+
@rows
|
374
|
+
elsif @columns.blank?
|
375
|
+
result = []
|
376
|
+
@rows.each do |row|
|
377
|
+
a = []
|
378
|
+
(0..(row.size - 1)).inject([]){|a,i| a << row[i]}
|
379
|
+
result << a
|
380
|
+
end
|
381
|
+
result
|
382
|
+
else
|
383
|
+
@rows.collect do |row|
|
384
|
+
attributes.collect{|attribute| row[attribute]}
|
385
|
+
end
|
386
|
+
end
|
387
|
+
end
|
388
|
+
|
389
|
+
end # class SimpleCSV
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# SimpleCSV/File.rb
|
2
|
+
# SimpleCSV::File
|
3
|
+
|
4
|
+
require_relative File.join('..', 'SimpleCSV')
|
5
|
+
|
6
|
+
class SimpleCSV
|
7
|
+
class File < SimpleCSV
|
8
|
+
|
9
|
+
class << self
|
10
|
+
|
11
|
+
def open(source, *args, &block)
|
12
|
+
@csv_file = new(source, *args)
|
13
|
+
super(source, *args, &block)
|
14
|
+
end
|
15
|
+
|
16
|
+
end # class << self
|
17
|
+
|
18
|
+
def initialize(filename, *args)
|
19
|
+
@filename = filename
|
20
|
+
@args = args
|
21
|
+
super(source, *args)
|
22
|
+
end
|
23
|
+
|
24
|
+
def source
|
25
|
+
@source ||= ::File.new(filename, mode, permissions)
|
26
|
+
end
|
27
|
+
|
28
|
+
def mode
|
29
|
+
@mode ||= (
|
30
|
+
case @args.peek_options[:mode].to_s
|
31
|
+
when 'r', 'r+', 'w', 'w+', 'a', 'a+'; @args.peek_options[:mode].to_s
|
32
|
+
when 'read_only', 'read-only', 'readonly'; 'r'
|
33
|
+
when 'rw', 'read_write', 'read-write', 'readwrite'; 'r+'
|
34
|
+
when 'write_only', 'write-only', 'writeonly'; 'w'
|
35
|
+
when 'append'; 'a'
|
36
|
+
else 'r'
|
37
|
+
end
|
38
|
+
)
|
39
|
+
end
|
40
|
+
|
41
|
+
def permissions
|
42
|
+
@permissions ||= @args.peek_options[:permissions]
|
43
|
+
end
|
44
|
+
|
45
|
+
def filename
|
46
|
+
@filename ||= File.expand_path(@filename)
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# SimpleCSV/String.rb
|
2
|
+
# SimpleCSV::String
|
3
|
+
|
4
|
+
require 'stringio'
|
5
|
+
|
6
|
+
require_relative File.join('..', 'SimpleCSV')
|
7
|
+
|
8
|
+
class SimpleCSV
|
9
|
+
class String < SimpleCSV
|
10
|
+
|
11
|
+
class << self
|
12
|
+
|
13
|
+
def open(source, *args, &block)
|
14
|
+
@csv_file = new(source, *args)
|
15
|
+
super(source, *args, &block)
|
16
|
+
end
|
17
|
+
|
18
|
+
end # class << self
|
19
|
+
|
20
|
+
def initialize(string, *args)
|
21
|
+
@string = string
|
22
|
+
super(source, *args)
|
23
|
+
end
|
24
|
+
|
25
|
+
def source
|
26
|
+
@source ||= StringIO.new(@string)
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# String#blank?
|
2
|
+
# String#blankQ
|
3
|
+
|
4
|
+
# 2010.04.04
|
5
|
+
# 0.0.1
|
6
|
+
|
7
|
+
# History: Stolen wholesale from a recent version of ActiveSupport.
|
8
|
+
|
9
|
+
# Changes:
|
10
|
+
# 1. Now using a more recent version from ActiveSupport. This more recent version from ActiveSupport is likely more efficient and slightly more succinct.
|
11
|
+
|
12
|
+
class String
|
13
|
+
|
14
|
+
def blank?
|
15
|
+
self !~ /\S/
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# String/split_csv
|
2
|
+
# String#split_csv
|
3
|
+
|
4
|
+
# 20111110
|
5
|
+
# 0.7.0
|
6
|
+
|
7
|
+
# History: Written for SimpleCSV.
|
8
|
+
|
9
|
+
# Todo:
|
10
|
+
# 1. Consider having a mode which splits up strings as if they were unquoted, but retains quotes (which contain commas) as per 0.4.0. I think that is what I had in mind when I thought that the other two libraries weren't handling it correctly. It should really be optional as to how quotes are handled.
|
11
|
+
|
12
|
+
# Notes:
|
13
|
+
# 1. I reckon both CSV and FasterCSV handle doubly-quoted quotes incorrectly. If I am wanting everything between the commas, then that means *everything*, including any quote marks regardless of where they are. If additionally, I am wanting to selectively choose only that which is between, then I can do this too by specifying that the data contained therein is mixed and so I dispense with the outer-most quote marks. CSV and FasterCSV presume to know what I want and dispense with the outer quote marks even though the rest of a line is being parsed as if there are none. This is inconsistent.
|
14
|
+
|
15
|
+
# Changes since 0.6:
|
16
|
+
# 1. + row_separator.
|
17
|
+
|
18
|
+
class String
|
19
|
+
|
20
|
+
def split_csv(quote = nil, column_separator = ',', row_separator = nil)
|
21
|
+
case quote
|
22
|
+
when :none, :unquoted
|
23
|
+
if row_separator
|
24
|
+
self.chomp(row_separator).split(column_separator)
|
25
|
+
else
|
26
|
+
self.chomp.split(column_separator)
|
27
|
+
end
|
28
|
+
when :double, :double_quoted, :double_quotes
|
29
|
+
if row_separator
|
30
|
+
self.chomp(row_separator).split(column_separator).collect{|e| e.sub(/^"/, '').sub(/"$/, '')}
|
31
|
+
else
|
32
|
+
self.chomp.split(column_separator).collect{|e| e.sub(/^"/, '').sub(/"$/, '')}
|
33
|
+
end
|
34
|
+
else
|
35
|
+
split_row = []
|
36
|
+
assembling_column = false
|
37
|
+
buffer = ''
|
38
|
+
if row_separator
|
39
|
+
self.chomp!(row_separator)
|
40
|
+
else
|
41
|
+
self.chomp!
|
42
|
+
end
|
43
|
+
self.split(column_separator).each do |e|
|
44
|
+
if assembling_column && !(e =~ /"$/) # e.not_closing_quotes?
|
45
|
+
buffer << e
|
46
|
+
elsif assembling_column && e =~ /"$/ # e.closing_quotes?
|
47
|
+
buffer << e.sub(/"$/, '') # remove the trailing quote
|
48
|
+
split_row << buffer
|
49
|
+
assembling_column = false
|
50
|
+
elsif (e =~ /^"/) && !(e =~ /"$/) # e.opening_quotes_but_not_closing_quotes?
|
51
|
+
buffer = ''
|
52
|
+
buffer << e.sub(/^"/, '') + column_separator # remove leading quote and replace the column_separator
|
53
|
+
assembling_column = true
|
54
|
+
else
|
55
|
+
if (e =~ /^"/) && (e =~ /"$/) # e.both_opening_and_closing_quotes?
|
56
|
+
split_row << e.sub(/^"/, '').sub(/"$/, '')
|
57
|
+
else
|
58
|
+
split_row << e
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
split_row
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# String#underscore
|
2
|
+
|
3
|
+
# 2010.10.15
|
4
|
+
# 0.1.0
|
5
|
+
|
6
|
+
# Description: The compliment of camelize. This takes a camel-case word and converts any capitals into lowercase and excepting for a leading capital letter, prepends each with an underscore. It also converts namespaces to paths, ie. '::' to '/'.
|
7
|
+
|
8
|
+
# History: Almost stolen wholesale from ActiveSupport::Inflector::Inflections#underscore 3.0.0.beta3.
|
9
|
+
|
10
|
+
# Examples:
|
11
|
+
# "ActiveRecord".underscore
|
12
|
+
# => "active_record"
|
13
|
+
# "ActiveRecord::Errors".underscore
|
14
|
+
# => active_record/errors
|
15
|
+
|
16
|
+
# Changes since 0.0
|
17
|
+
# 1. Updated with changes from active_support 3.0.0.
|
18
|
+
# 2. Will now successfully handle strings with spaces.
|
19
|
+
# 3. Removed the dup'ed word since once the transformational methods were chained this became unnecessary.
|
20
|
+
|
21
|
+
class String
|
22
|
+
|
23
|
+
def underscore
|
24
|
+
gsub(' ', '_').
|
25
|
+
gsub(/::/, '/').
|
26
|
+
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
27
|
+
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
28
|
+
tr("-", "_").
|
29
|
+
downcase
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
data/lib/_meta/blankQ.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
# _meta/blankQ
|
2
|
+
|
3
|
+
# 2010.04.04
|
4
|
+
# 0.0.0
|
5
|
+
|
6
|
+
require 'Array/blankQ'
|
7
|
+
require 'FalseClass/blankQ'
|
8
|
+
require 'Hash/blankQ'
|
9
|
+
require 'NilClass/blankQ'
|
10
|
+
require 'Numeric/blankQ'
|
11
|
+
require 'Object/blankQ'
|
12
|
+
require 'String/blankQ'
|
13
|
+
require 'TrueClass/blankQ'
|
metadata
ADDED
@@ -0,0 +1,112 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: parliamentarian
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.8.5
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- thoran
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2021-04-08 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: minitest
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: minitest-spec-context
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: webmock
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
description: This will download and parse the lastest list of members and their contact
|
56
|
+
details for the alleged parliament of the State of Victoria and the alleged federal
|
57
|
+
parliament for Australia so far.
|
58
|
+
email: code@thoran.com
|
59
|
+
executables: []
|
60
|
+
extensions: []
|
61
|
+
extra_rdoc_files: []
|
62
|
+
files:
|
63
|
+
- lib/Array/blankQ.rb
|
64
|
+
- lib/Array/extract_optionsX.rb
|
65
|
+
- lib/Array/peek_options.rb
|
66
|
+
- lib/Array/to_csv.rb
|
67
|
+
- lib/FalseClass/blankQ.rb
|
68
|
+
- lib/Hash/blankQ.rb
|
69
|
+
- lib/Hash/to_csv.rb
|
70
|
+
- lib/NilClass/blankQ.rb
|
71
|
+
- lib/NilClass/default_to.rb
|
72
|
+
- lib/Numeric/blankQ.rb
|
73
|
+
- lib/Object/blankQ.rb
|
74
|
+
- lib/Object/default_to.rb
|
75
|
+
- lib/Parliamentarian.rb
|
76
|
+
- lib/Parliamentarian/Australia.rb
|
77
|
+
- lib/Parliamentarian/Australia/Federal.rb
|
78
|
+
- lib/Parliamentarian/Australia/Victoria.rb
|
79
|
+
- lib/Parliamentarian/VERSION.rb
|
80
|
+
- lib/SimpleCSV.rb
|
81
|
+
- lib/SimpleCSV/File.rb
|
82
|
+
- lib/SimpleCSV/String.rb
|
83
|
+
- lib/String/blankQ.rb
|
84
|
+
- lib/String/split_csv.rb
|
85
|
+
- lib/String/underscore.rb
|
86
|
+
- lib/TrueClass/blankQ.rb
|
87
|
+
- lib/_meta/blankQ.rb
|
88
|
+
- lib/_meta/default_to.rb
|
89
|
+
homepage: http://github.com/thoran/Parliamentarian
|
90
|
+
licenses:
|
91
|
+
- Ruby
|
92
|
+
metadata: {}
|
93
|
+
post_install_message:
|
94
|
+
rdoc_options: []
|
95
|
+
require_paths:
|
96
|
+
- lib
|
97
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
98
|
+
requirements:
|
99
|
+
- - ">="
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '2.5'
|
102
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
103
|
+
requirements:
|
104
|
+
- - ">="
|
105
|
+
- !ruby/object:Gem::Version
|
106
|
+
version: '0'
|
107
|
+
requirements: []
|
108
|
+
rubygems_version: 3.2.3
|
109
|
+
signing_key:
|
110
|
+
specification_version: 4
|
111
|
+
summary: Download and parse details for members of parliament.
|
112
|
+
test_files: []
|