remote_table 0.2.32 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +5 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +65 -0
- data/LICENSE +1 -1
- data/README.rdoc +21 -7
- data/Rakefile +12 -61
- data/lib/remote_table/cleaner.rb +19 -0
- data/lib/remote_table/executor.rb +29 -0
- data/lib/remote_table/format/delimited.rb +62 -0
- data/lib/remote_table/format/excel.rb +10 -0
- data/lib/remote_table/format/excelx.rb +10 -0
- data/lib/remote_table/format/fixed_width.rb +47 -0
- data/lib/remote_table/format/html.rb +43 -0
- data/lib/remote_table/format/mixins/rooable.rb +47 -0
- data/lib/remote_table/format/mixins/textual.rb +34 -0
- data/lib/remote_table/format/open_office.rb +10 -0
- data/lib/remote_table/format.rb +35 -0
- data/lib/remote_table/hasher.rb +25 -0
- data/lib/remote_table/local_file.rb +92 -0
- data/lib/remote_table/properties.rb +209 -0
- data/lib/remote_table/transformer.rb +17 -0
- data/lib/remote_table/version.rb +3 -0
- data/lib/remote_table.rb +91 -99
- data/remote_table.gemspec +32 -77
- data/test/{test_helper.rb → helper.rb} +9 -2
- data/test/test_big.rb +61 -0
- data/test/test_errata.rb +46 -0
- data/test/test_old_syntax.rb +229 -0
- data/test/test_old_transform.rb +49 -0
- data/test/test_remote_table.rb +13 -0
- metadata +176 -53
- data/VERSION +0 -1
- data/lib/remote_table/file/csv.rb +0 -49
- data/lib/remote_table/file/fixed_width.rb +0 -19
- data/lib/remote_table/file/html.rb +0 -37
- data/lib/remote_table/file/ods.rb +0 -11
- data/lib/remote_table/file/roo_spreadsheet.rb +0 -44
- data/lib/remote_table/file/xls.rb +0 -11
- data/lib/remote_table/file/xlsx.rb +0 -11
- data/lib/remote_table/file.rb +0 -100
- data/lib/remote_table/package.rb +0 -89
- data/lib/remote_table/request.rb +0 -44
- data/lib/remote_table/transform.rb +0 -58
- data/test/remote_table_test.rb +0 -386
@@ -0,0 +1,92 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'escape'
|
3
|
+
require 'tmpdir'
|
4
|
+
class RemoteTable
|
5
|
+
class LocalFile
|
6
|
+
|
7
|
+
attr_reader :t
|
8
|
+
|
9
|
+
def initialize(t)
|
10
|
+
@t = t
|
11
|
+
end
|
12
|
+
|
13
|
+
def path
|
14
|
+
save_locally
|
15
|
+
@path
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def save_locally
|
21
|
+
return if @path.is_a?(::String)
|
22
|
+
@path = ::File.join(staging_dir_path, ::File.basename(t.properties.uri.path))
|
23
|
+
download
|
24
|
+
decompress
|
25
|
+
unpack
|
26
|
+
pick
|
27
|
+
@path
|
28
|
+
end
|
29
|
+
|
30
|
+
def download
|
31
|
+
if t.properties.uri.scheme == 'file'
|
32
|
+
::FileUtils.cp t.properties.uri.path, @path
|
33
|
+
else
|
34
|
+
# sabshere 1/20/11 FIXME: ::RemoteTable.config.curl_bin_path or smth
|
35
|
+
::RemoteTable.executor.backtick_with_reporting %{
|
36
|
+
curl
|
37
|
+
--header "Expect: "
|
38
|
+
--location
|
39
|
+
#{"--data #{::Escape.shell_single_word t.properties.form_data}" if t.properties.form_data.present?}
|
40
|
+
--output #{::Escape.shell_single_word @path}
|
41
|
+
#{::Escape.shell_single_word t.properties.uri.to_s}
|
42
|
+
2>&1
|
43
|
+
}
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def decompress
|
48
|
+
return unless t.properties.compression
|
49
|
+
new_path = @path.chomp ".#{t.properties.compression}"
|
50
|
+
cmd = case t.properties.compression
|
51
|
+
when 'zip', 'exe'
|
52
|
+
"unzip #{::Escape.shell_single_word @path} -d #{::File.dirname(@path)}"
|
53
|
+
# can't set path yet because there may be multiple files
|
54
|
+
when 'bz2'
|
55
|
+
"bunzip2 --stdout #{::Escape.shell_single_word @path} > #{::Escape.shell_single_word new_path}"
|
56
|
+
@path = new_path
|
57
|
+
when 'gz'
|
58
|
+
"gunzip --stdout #{::Escape.shell_single_word @path} > #{::Escape.shell_single_word new_path}"
|
59
|
+
@path = new_path
|
60
|
+
end
|
61
|
+
::RemoteTable.executor.backtick_with_reporting cmd
|
62
|
+
end
|
63
|
+
|
64
|
+
def unpack
|
65
|
+
return unless t.properties.packing
|
66
|
+
cmd = case t.properties.packing
|
67
|
+
when 'tar'
|
68
|
+
"tar -xf #{::Escape.shell_single_word @path} -C #{::File.dirname(@path)}"
|
69
|
+
end
|
70
|
+
::RemoteTable.executor.backtick_with_reporting cmd
|
71
|
+
end
|
72
|
+
|
73
|
+
# ex. A: 2007-01.csv.gz (compression not capable of storing multiple files)
|
74
|
+
# ex. B: 2007-01.tar.gz (packing)
|
75
|
+
# ex. C: 2007-01.zip (compression capable of storing multiple files)
|
76
|
+
def pick
|
77
|
+
if t.properties.filename.present?
|
78
|
+
@path = ::File.join ::File.dirname(@path), t.properties.filename
|
79
|
+
elsif t.properties.glob.present?
|
80
|
+
@path = ::Dir[::File.dirname(@path)+t.properties.glob].first
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def staging_dir_path
|
85
|
+
return @staging_dir_path if @staging_dir_path.is_a?(::String)
|
86
|
+
@staging_dir_path = ::File.join ::Dir.tmpdir, 'remote_table_gem', rand.to_s
|
87
|
+
::FileUtils.mkdir_p @staging_dir_path
|
88
|
+
::RemoteTable.cleaner.remove_at_exit @staging_dir_path
|
89
|
+
@staging_dir_path
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,209 @@
|
|
1
|
+
require 'uri'
|
2
|
+
class RemoteTable
|
3
|
+
# Represents the properties of a RemoteTable, whether they are explicitly set by the user or inferred automatically.
|
4
|
+
class Properties
|
5
|
+
attr_reader :t
|
6
|
+
def initialize(t)
|
7
|
+
@t = t
|
8
|
+
end
|
9
|
+
|
10
|
+
# The parsed URI of the file to get.
|
11
|
+
def uri
|
12
|
+
return @uri if @uri.is_a?(::URI)
|
13
|
+
@uri = ::URI.parse t.url
|
14
|
+
if @uri.host == 'spreadsheets.google.com'
|
15
|
+
@uri.query = 'output=csv&' + @uri.query.sub(/\&?output=.*?(\&|\z)/, '\1')
|
16
|
+
end
|
17
|
+
@uri
|
18
|
+
end
|
19
|
+
|
20
|
+
# The headers specified by the user
|
21
|
+
def headers
|
22
|
+
t.options['headers']
|
23
|
+
end
|
24
|
+
|
25
|
+
# The sheet specified by the user as a number or a string
|
26
|
+
#
|
27
|
+
# Default: 0
|
28
|
+
def sheet
|
29
|
+
t.options['sheet'] || 0
|
30
|
+
end
|
31
|
+
|
32
|
+
# Whether to keep blank rows
|
33
|
+
#
|
34
|
+
# Default: false
|
35
|
+
def keep_blank_rows
|
36
|
+
t.options['keep_blank_rows'] || false
|
37
|
+
end
|
38
|
+
|
39
|
+
# Form data to send in with the download request
|
40
|
+
def form_data
|
41
|
+
t.options['form_data']
|
42
|
+
end
|
43
|
+
|
44
|
+
# How many rows to skip
|
45
|
+
#
|
46
|
+
# Default: 0
|
47
|
+
def skip
|
48
|
+
t.options['skip'].to_i
|
49
|
+
end
|
50
|
+
|
51
|
+
# The encoding
|
52
|
+
#
|
53
|
+
# Default: "UTF-8"
|
54
|
+
def encoding
|
55
|
+
t.options['encoding'] || 'UTF-8'
|
56
|
+
end
|
57
|
+
|
58
|
+
# The delimiter
|
59
|
+
#
|
60
|
+
# Default: ","
|
61
|
+
def delimiter
|
62
|
+
t.options['delimiter'] || ','
|
63
|
+
end
|
64
|
+
|
65
|
+
# The XPath used to find rows
|
66
|
+
def row_xpath
|
67
|
+
t.options['row_xpath']
|
68
|
+
end
|
69
|
+
|
70
|
+
# The XPath used to find columns
|
71
|
+
def column_xpath
|
72
|
+
t.options['column_xpath']
|
73
|
+
end
|
74
|
+
|
75
|
+
# The compression type.
|
76
|
+
#
|
77
|
+
# Default: guessed from URI.
|
78
|
+
#
|
79
|
+
# Can be specified as: "gz", "zip", "bz2", "exe" (treated as "zip")
|
80
|
+
def compression
|
81
|
+
clue = if t.options['compression']
|
82
|
+
t.options['compression'].to_s
|
83
|
+
else
|
84
|
+
::File.extname uri.path
|
85
|
+
end
|
86
|
+
case clue.downcase
|
87
|
+
when /gz/, /gunzip/
|
88
|
+
'gz'
|
89
|
+
when /zip/
|
90
|
+
'zip'
|
91
|
+
when /bz2/, /bunzip2/
|
92
|
+
'bz2'
|
93
|
+
when /exe/
|
94
|
+
'exe'
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
# The packing type.
|
99
|
+
#
|
100
|
+
# Default: guessed from URI.
|
101
|
+
#
|
102
|
+
# Can be specified as: "tar"
|
103
|
+
def packing
|
104
|
+
clue = if t.options['packing']
|
105
|
+
t.options['packing'].to_s
|
106
|
+
else
|
107
|
+
::File.extname(uri.path.sub(/\.#{compression}\z/, ''))
|
108
|
+
end
|
109
|
+
case clue.downcase
|
110
|
+
when /tar/
|
111
|
+
'tar'
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
# The glob used to pick a file out of an archive.
|
116
|
+
#
|
117
|
+
# Example:
|
118
|
+
# RemoteTable.new 'http://www.fueleconomy.gov/FEG/epadata/08data.zip', 'glob' => '/*.csv'
|
119
|
+
def glob
|
120
|
+
t.options['glob']
|
121
|
+
end
|
122
|
+
|
123
|
+
# The filename, which can be used to pick a file out of an archive.
|
124
|
+
#
|
125
|
+
# Example:
|
126
|
+
# RemoteTable.new 'http://www.fueleconomy.gov/FEG/epadata/08data.zip', 'filename' => '2008_FE_guide_ALL_rel_dates_-no sales-for DOE-5-1-08.csv'
|
127
|
+
def filename
|
128
|
+
t.options['filename']
|
129
|
+
end
|
130
|
+
|
131
|
+
# Cut columns up to this character
|
132
|
+
def cut
|
133
|
+
t.options['cut']
|
134
|
+
end
|
135
|
+
|
136
|
+
# Crop rows after this line
|
137
|
+
def crop
|
138
|
+
t.options['crop']
|
139
|
+
end
|
140
|
+
|
141
|
+
# The fixed-width schema, given as an array
|
142
|
+
#
|
143
|
+
# Example:
|
144
|
+
# RemoteTable.new('http://cloud.github.com/downloads/seamusabshere/remote_table/test2.fixed_width.txt',
|
145
|
+
# 'format' => 'fixed_width',
|
146
|
+
# 'skip' => 1,
|
147
|
+
# 'schema' => [[ 'header4', 10, { :type => :string } ],
|
148
|
+
# [ 'spacer', 1 ],
|
149
|
+
# [ 'header5', 10, { :type => :string } ],
|
150
|
+
# [ 'spacer', 12 ],
|
151
|
+
# [ 'header6', 10, { :type => :string } ]])
|
152
|
+
def schema
|
153
|
+
t.options['schema']
|
154
|
+
end
|
155
|
+
|
156
|
+
# The name of the fixed-width schema according to Slither
|
157
|
+
def schema_name
|
158
|
+
t.options['schema_name']
|
159
|
+
end
|
160
|
+
|
161
|
+
# A proc to call to decide whether to return a row.
|
162
|
+
def select
|
163
|
+
t.options['select']
|
164
|
+
end
|
165
|
+
|
166
|
+
# A proc to call to decide whether to return a row.
|
167
|
+
def reject
|
168
|
+
t.options['reject']
|
169
|
+
end
|
170
|
+
|
171
|
+
# An Errata object (see the Errata gem at http://github.com/seamusabshere/errata) to be used on every row.
|
172
|
+
def errata
|
173
|
+
t.options['errata']
|
174
|
+
end
|
175
|
+
|
176
|
+
# Get the format in the form of RemoteTable::Format::Excel, etc.
|
177
|
+
#
|
178
|
+
# Note: treats all spreadsheets.google.com URLs as Format::Delimited (i.e., CSV)
|
179
|
+
#
|
180
|
+
# Default: guessed from file extension (which is usually the same as the URI, but sometimes not if you pick out a specific file from an archive)
|
181
|
+
#
|
182
|
+
# Can be specified as: "xlsx", "xls", "csv", "ods", "fixed_width", "html"
|
183
|
+
def format
|
184
|
+
return Format::Delimited if uri.host == 'spreadsheets.google.com'
|
185
|
+
clue = if t.options['format']
|
186
|
+
t.options['format'].to_s
|
187
|
+
else
|
188
|
+
::File.extname t.local_file.path
|
189
|
+
end
|
190
|
+
return Format::Delimited if clue.blank?
|
191
|
+
case clue.downcase
|
192
|
+
when /xlsx/, /excelx/
|
193
|
+
Format::Excelx
|
194
|
+
when /xls/, /excel/
|
195
|
+
Format::Excel
|
196
|
+
when /csv/, /tsv/, /delimited/
|
197
|
+
Format::Delimited
|
198
|
+
when /ods/, /open_?office/
|
199
|
+
Format::OpenOffice
|
200
|
+
when /fixed_?width/
|
201
|
+
Format::FixedWidth
|
202
|
+
when /htm/
|
203
|
+
Format::HTML
|
204
|
+
else
|
205
|
+
raise Format::Unknown, clue
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
209
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class RemoteTable
|
2
|
+
class Transformer
|
3
|
+
attr_reader :t
|
4
|
+
attr_accessor :legacy_transformer
|
5
|
+
def initialize(t)
|
6
|
+
@t = t
|
7
|
+
end
|
8
|
+
# eventually this will support a different way of specifying a transformer
|
9
|
+
def transform(row)
|
10
|
+
if legacy_transformer
|
11
|
+
legacy_transformer.apply row
|
12
|
+
else
|
13
|
+
[ row ]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/lib/remote_table.rb
CHANGED
@@ -1,130 +1,122 @@
|
|
1
|
-
require 'digest/md5'
|
2
|
-
require 'uri'
|
3
|
-
require 'tmpdir'
|
4
|
-
require 'kconv'
|
5
1
|
require 'active_support'
|
6
2
|
require 'active_support/version'
|
7
3
|
%w{
|
8
|
-
active_support/core_ext/
|
9
|
-
active_support/core_ext/
|
10
|
-
active_support/core_ext/
|
11
|
-
active_support/core_ext/array/wrap
|
12
|
-
active_support/core_ext/hash/except
|
13
|
-
active_support/core_ext/class/attribute_accessors
|
4
|
+
active_support/core_ext/hash
|
5
|
+
active_support/core_ext/string
|
6
|
+
active_support/core_ext/module
|
14
7
|
}.each do |active_support_3_requirement|
|
15
8
|
require active_support_3_requirement
|
16
9
|
end if ActiveSupport::VERSION::MAJOR == 3
|
17
10
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
require 'fastercsv'
|
24
|
-
rescue LoadError
|
25
|
-
$stderr.puts "[remote_table gem] You probably need to manually install the fastercsv gem."
|
26
|
-
raise $!
|
27
|
-
end
|
28
|
-
end
|
11
|
+
class RemoteTable
|
12
|
+
autoload :Format, 'remote_table/format'
|
13
|
+
autoload :Properties, 'remote_table/properties'
|
14
|
+
autoload :LocalFile, 'remote_table/local_file'
|
15
|
+
autoload :Transformer, 'remote_table/transformer'
|
29
16
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
require 'remote_table/file/roo_spreadsheet'
|
42
|
-
require 'remote_table/file/ods'
|
43
|
-
require 'remote_table/file/xls'
|
44
|
-
require 'remote_table/file/xlsx'
|
45
|
-
require 'remote_table/file/html'
|
17
|
+
# singletons
|
18
|
+
autoload :Cleaner, 'remote_table/cleaner'
|
19
|
+
autoload :Executor, 'remote_table/executor'
|
20
|
+
autoload :Hasher, 'remote_table/hasher'
|
21
|
+
|
22
|
+
# Legacy
|
23
|
+
class Transform
|
24
|
+
def self.row_hash(row)
|
25
|
+
::RemoteTable.hasher.hash row
|
26
|
+
end
|
27
|
+
end
|
46
28
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
29
|
+
include ::Enumerable
|
30
|
+
|
31
|
+
attr_reader :url
|
32
|
+
attr_reader :options
|
33
|
+
|
34
|
+
# Create a new RemoteTable.
|
35
|
+
#
|
36
|
+
# RemoteTable.new(url, options = {})
|
37
|
+
#
|
38
|
+
# New syntax:
|
39
|
+
# RemoteTable.new('www.customerreferenceprogram.org/uploads/CRP_RFP_template.xlsx', 'foo' => 'bar')
|
40
|
+
# Old syntax:
|
41
|
+
# RemoteTable.new(:url => 'www.customerreferenceprogram.org/uploads/CRP_RFP_template.xlsx', :foo => 'bar')
|
42
|
+
#
|
43
|
+
# See the <tt>Properties</tt> object for the sorts of options you can pass.
|
44
|
+
def initialize(*args)
|
45
|
+
@options = args.last.is_a?(::Hash) ? args.last.dup : {}
|
46
|
+
if args.first.is_a? ::String
|
47
|
+
@url = args.first.dup
|
48
|
+
else
|
49
|
+
@url = @options['url'] || @options[:url]
|
55
50
|
end
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
51
|
+
# deprecated
|
52
|
+
if options[:transform]
|
53
|
+
transformer.legacy_transformer = options[:transform][:class].new options[:transform].except(:class)
|
54
|
+
transformer.legacy_transformer.add_hints! @options
|
60
55
|
end
|
56
|
+
@options.stringify_keys!
|
57
|
+
@url.freeze
|
58
|
+
@options.freeze
|
59
|
+
at_exit { ::RemoteTable.cleaner.cleanup }
|
61
60
|
end
|
62
|
-
|
63
|
-
attr_accessor :request, :package, :file, :transform
|
64
|
-
attr_accessor :table
|
65
61
|
|
66
|
-
|
62
|
+
def each(&blk)
|
63
|
+
format.each do |row|
|
64
|
+
row['row_hash'] = ::RemoteTable.hasher.hash row
|
65
|
+
# allow the transformer to return multiple "virtual rows" for every real row
|
66
|
+
transformer.transform(row).each do |virtual_row|
|
67
|
+
if properties.errata
|
68
|
+
next if properties.errata.rejects? virtual_row
|
69
|
+
properties.errata.correct! virtual_row
|
70
|
+
end
|
71
|
+
next if properties.select and !properties.select.call(virtual_row)
|
72
|
+
next if properties.reject and properties.reject.call(virtual_row)
|
73
|
+
yield virtual_row
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
67
77
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
@request = Request.new(bus)
|
72
|
-
@file = File.new(bus)
|
73
|
-
at_exit { RemoteTable.cleanup }
|
78
|
+
# Get a row by row number
|
79
|
+
def [](row_number)
|
80
|
+
to_a[row_number]
|
74
81
|
end
|
75
82
|
|
76
|
-
|
77
|
-
|
78
|
-
|
83
|
+
# Get the whole row array back
|
84
|
+
def rows
|
85
|
+
to_a
|
79
86
|
end
|
80
|
-
alias :each_row :each
|
81
87
|
|
82
|
-
|
83
|
-
|
84
|
-
|
88
|
+
# Used internally as a sort of garbage collector.
|
89
|
+
def self.cleaner
|
90
|
+
Cleaner.instance
|
85
91
|
end
|
86
|
-
alias :rows :to_a
|
87
92
|
|
88
|
-
|
89
|
-
|
93
|
+
# Used internally to execute stuff in shells.
|
94
|
+
def self.executor
|
95
|
+
Executor.instance
|
90
96
|
end
|
91
|
-
|
92
|
-
protected
|
93
97
|
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
FileUtils.mv tmp_path, path
|
98
|
+
# Used internally to create unique hashes of rows.
|
99
|
+
def self.hasher
|
100
|
+
Hasher.instance
|
98
101
|
end
|
99
102
|
|
100
|
-
#
|
101
|
-
def
|
102
|
-
|
103
|
-
output = `#{cmd}`
|
104
|
-
if not $?.success?
|
105
|
-
raise %{
|
106
|
-
From the remote_table gem...
|
107
|
-
|
108
|
-
Command failed:
|
109
|
-
#{cmd}
|
110
|
-
|
111
|
-
Output:
|
112
|
-
#{output}
|
113
|
-
}
|
114
|
-
end
|
103
|
+
# Used internally to access to a downloaded copy of the file
|
104
|
+
def local_file
|
105
|
+
@local_file ||= LocalFile.new self
|
115
106
|
end
|
116
107
|
|
117
|
-
|
108
|
+
# Used internally to access to the properties of the table, either set by the user or implied
|
109
|
+
def properties
|
110
|
+
@properties ||= Properties.new self
|
111
|
+
end
|
118
112
|
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
raw_table = file.tabulate(file_path)
|
123
|
-
self.table = transform.apply(raw_table) # must return something that responds to each_row
|
113
|
+
# Used internally to access to the driver that reads the format
|
114
|
+
def format
|
115
|
+
@format ||= properties.format.new self
|
124
116
|
end
|
125
117
|
|
126
|
-
|
127
|
-
|
128
|
-
|
118
|
+
# Used internally to acess the transformer (aka parser).
|
119
|
+
def transformer
|
120
|
+
@transformer ||= Transformer.new self
|
129
121
|
end
|
130
122
|
end
|
data/remote_table.gemspec
CHANGED
@@ -1,83 +1,38 @@
|
|
1
|
-
# Generated by jeweler
|
2
|
-
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
-
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
1
|
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "remote_table/version"
|
5
4
|
|
6
5
|
Gem::Specification.new do |s|
|
7
|
-
s.name
|
8
|
-
s.version
|
6
|
+
s.name = "remote_table"
|
7
|
+
s.version = RemoteTable::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Seamus Abshere", "Andy Rossmeissl"]
|
10
|
+
s.email = ["seamus@abshere.net"]
|
11
|
+
s.homepage = "https://github.com/seamusabshere/remote_table"
|
12
|
+
s.summary = "Open local or remote XLSX, XLS, ODS, CSV and fixed-width files."
|
13
|
+
s.description = %q{Gives you a standard way to parse various formats and treat them as an array of hashes.}
|
9
14
|
|
10
|
-
s.
|
11
|
-
s.authors = ["Seamus Abshere", "Andy Rossmeissl"]
|
12
|
-
s.date = %q{2010-10-07}
|
13
|
-
s.description = %q{Remotely open and parse Excel XLS, ODS, CSV and fixed-width tables.}
|
14
|
-
s.email = %q{seamus@abshere.net}
|
15
|
-
s.extra_rdoc_files = [
|
16
|
-
"LICENSE",
|
17
|
-
"README.rdoc"
|
18
|
-
]
|
19
|
-
s.files = [
|
20
|
-
".document",
|
21
|
-
".gitignore",
|
22
|
-
"CHANGELOG",
|
23
|
-
"LICENSE",
|
24
|
-
"README.rdoc",
|
25
|
-
"Rakefile",
|
26
|
-
"VERSION",
|
27
|
-
"lib/remote_table.rb",
|
28
|
-
"lib/remote_table/file.rb",
|
29
|
-
"lib/remote_table/file/csv.rb",
|
30
|
-
"lib/remote_table/file/fixed_width.rb",
|
31
|
-
"lib/remote_table/file/html.rb",
|
32
|
-
"lib/remote_table/file/ods.rb",
|
33
|
-
"lib/remote_table/file/roo_spreadsheet.rb",
|
34
|
-
"lib/remote_table/file/xls.rb",
|
35
|
-
"lib/remote_table/file/xlsx.rb",
|
36
|
-
"lib/remote_table/package.rb",
|
37
|
-
"lib/remote_table/request.rb",
|
38
|
-
"lib/remote_table/transform.rb",
|
39
|
-
"remote_table.gemspec",
|
40
|
-
"test/remote_table_test.rb",
|
41
|
-
"test/test_helper.rb"
|
42
|
-
]
|
43
|
-
s.homepage = %q{http://github.com/seamusabshere/remote_table}
|
44
|
-
s.rdoc_options = ["--charset=UTF-8", "--line-numbers", "--inline-source"]
|
45
|
-
s.require_paths = ["lib"]
|
46
|
-
s.requirements = ["curl"]
|
47
|
-
s.rubyforge_project = %q{remotetable}
|
48
|
-
s.rubygems_version = %q{1.3.7}
|
49
|
-
s.summary = %q{Remotely open and parse XLS, ODS, CSV and fixed-width tables.}
|
50
|
-
s.test_files = [
|
51
|
-
"test/remote_table_test.rb",
|
52
|
-
"test/test_helper.rb"
|
53
|
-
]
|
54
|
-
|
55
|
-
if s.respond_to? :specification_version then
|
56
|
-
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
57
|
-
s.specification_version = 3
|
15
|
+
s.rubyforge_project = "remotetable"
|
58
16
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
s.add_dependency(%q<errata>, [">= 0.2.0"])
|
81
|
-
end
|
17
|
+
s.files = `git ls-files`.split("\n")
|
18
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
|
+
s.require_paths = ["lib"]
|
21
|
+
|
22
|
+
s.add_dependency 'activesupport', '>=2.3.4'
|
23
|
+
# sabshere 9/30/10 depending on fastercsv when using ruby 1.9.2 results in exiting with error
|
24
|
+
# s.add_dependency 'fastercsv', '>=1.5.0'
|
25
|
+
s.add_dependency 'roo', '~>1.9'
|
26
|
+
s.add_dependency 'slither', '>=0.99.4'
|
27
|
+
s.add_dependency 'i18n' # activesupport?
|
28
|
+
s.add_dependency 'builder' # roo?
|
29
|
+
s.add_dependency 'zip' # roo
|
30
|
+
s.add_dependency 'nokogiri', '>=1.4.1' # roo
|
31
|
+
s.add_dependency 'spreadsheet' #roo
|
32
|
+
s.add_dependency 'google-spreadsheet-ruby' #roo
|
33
|
+
s.add_dependency 'escape', '>=0.0.4'
|
34
|
+
s.add_development_dependency 'errata', '>=0.2.0'
|
35
|
+
s.add_development_dependency 'test-unit'
|
36
|
+
s.add_development_dependency 'shoulda'
|
37
|
+
s.add_development_dependency 'ruby-debug'
|
82
38
|
end
|
83
|
-
|
@@ -1,9 +1,16 @@
|
|
1
1
|
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
unless RUBY_VERSION >= '1.9'
|
4
|
+
gem 'fastercsv'
|
5
|
+
require 'fastercsv'
|
6
|
+
end
|
7
|
+
Bundler.setup
|
2
8
|
require 'test/unit'
|
3
9
|
require 'shoulda'
|
10
|
+
require 'ruby-debug'
|
4
11
|
# require 'ruby-debug'
|
5
|
-
require 'errata'
|
6
|
-
require 'active_support/all'
|
12
|
+
# require 'errata'
|
13
|
+
# require 'active_support/all'
|
7
14
|
|
8
15
|
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
9
16
|
$LOAD_PATH.unshift(File.dirname(__FILE__))
|