cartodb-importer 0.2.11 → 0.2.12

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.
data/.gitignore CHANGED
@@ -5,3 +5,4 @@ pkg/*
5
5
  misc/*.pyc
6
6
  bin/*
7
7
  build/*
8
+ *.DS_Store
@@ -3,7 +3,7 @@
3
3
  module CartoDB
4
4
  class Importer
5
5
  RESERVED_COLUMN_NAMES = %W{ oid tableoid xmin cmin xmax cmax ctid }
6
- SUPPORTED_FORMATS = %W{ .csv .shp .ods .xls .xlsx .tif .tiff }
6
+ SUPPORTED_FORMATS = %W{ .csv .shp .ods .xls .xlsx .tif .tiff .kml .kmz .js .json}
7
7
 
8
8
  class << self
9
9
  attr_accessor :debug
@@ -11,7 +11,7 @@ module CartoDB
11
11
  @@debug = true
12
12
 
13
13
  attr_accessor :import_from_file,:import_from_url, :suggested_name,
14
- :ext, :db_configuration, :db_connection
14
+ :ext, :db_configuration, :db_connection, :append_to_table
15
15
 
16
16
  attr_reader :table_created, :force_name
17
17
 
@@ -22,9 +22,9 @@ module CartoDB
22
22
  if !options[:import_from_url].blank?
23
23
  #download from internet first
24
24
  potential_name = File.basename(options[:import_from_url])
25
- curl_cmd = "curl -0 \"#{options[:import_from_url]}\" > /tmp/#{potential_name}"
26
- #log curl_cmd
27
- `#{curl_cmd}`
25
+ wget_cmd = "wget \"#{options[:import_from_url]}\" -O /tmp/#{potential_name}"
26
+ #log wget_cmd
27
+ `#{wget_cmd}`
28
28
  @import_from_file = "/tmp/#{potential_name}"
29
29
  else
30
30
  @import_from_file = options[:import_from_file]
@@ -36,7 +36,12 @@ module CartoDB
36
36
  @db_configuration[:port] ||= 5432
37
37
  @db_configuration[:host] ||= '127.0.0.1'
38
38
  @db_connection = Sequel.connect("postgres://#{@db_configuration[:username]}:#{@db_configuration[:password]}@#{@db_configuration[:host]}:#{@db_configuration[:port]}/#{@db_configuration[:database]}")
39
-
39
+ unless options[:append_to_table].nil?
40
+ @append_to_table = options[:append_to_table]
41
+ else
42
+ @append_to_table = nil
43
+ end
44
+
40
45
  unless options[:suggested_name].nil? || options[:suggested_name].blank?
41
46
  @force_name = true
42
47
  @suggested_name = get_valid_name(options[:suggested_name])
@@ -82,7 +87,8 @@ module CartoDB
82
87
  psql_bin_path = `which psql`.strip
83
88
 
84
89
  entries = []
85
- if @ext == '.zip'
90
+ #if @ext == '.zip'
91
+ if %W{ .zip .kmz }.include?(@ext)
86
92
  log "Importing zip file: #{path}"
87
93
  Zip::ZipFile.foreach(path) do |entry|
88
94
  name = entry.name.split('/').last
@@ -126,6 +132,59 @@ module CartoDB
126
132
  path = @import_from_file.path
127
133
  end
128
134
 
135
+ if %W{ .kmz .kml .json .js }.include?(@ext)
136
+ ogr2ogr_bin_path = `which ogr2ogr`.strip
137
+ ogr2ogr_command = %Q{#{ogr2ogr_bin_path} -f "ESRI Shapefile" #{path}.shp #{path}}
138
+ out = `#{ogr2ogr_command}`
139
+
140
+ if 0 < out.strip.length
141
+ runlog.stdout << out
142
+ end
143
+
144
+ if File.file?("#{path}.shp")
145
+ path = "#{path}.shp"
146
+ @ext = '.shp'
147
+ else
148
+ runlog.err << "failed to create shp file from kml"
149
+ end
150
+ end
151
+
152
+ if %W{ .exxxxppp }.include?(@ext)
153
+
154
+ ogr2ogr_bin_path = `which ogr2ogr`.strip
155
+ ogr2ogr_command = %Q{#{ogr2ogr_bin_path} -f "PostgreSQL" PG:"host=#{@db_configuration[:host]} port=#{@db_configuration[:port]} user=#{@db_configuration[:username]} dbname=#{@db_configuration[:database]}" #{path} -nln #{@suggested_name}}
156
+
157
+ out = `#{ogr2ogr_command}`
158
+ if 0 < out.strip.length
159
+ runlog.stdout << out
160
+ end
161
+
162
+ # Check if the file had data, if not rise an error because probably something went wrong
163
+ if @db_connection["SELECT * from #{@suggested_name} LIMIT 1"].first.nil?
164
+ runlog.err << "Empty table"
165
+ raise "Empty table"
166
+ end
167
+
168
+ # Sanitize column names where needed
169
+ column_names = @db_connection.schema(@suggested_name).map{ |s| s[0].to_s }
170
+ need_sanitizing = column_names.each do |column_name|
171
+ if column_name != column_name.sanitize_column_name
172
+ @db_connection.run("ALTER TABLE #{@suggested_name} RENAME COLUMN \"#{column_name}\" TO #{column_name.sanitize_column_name}")
173
+ end
174
+ end
175
+
176
+ @table_created = true
177
+
178
+ FileUtils.rm_rf(path)
179
+ rows_imported = @db_connection["SELECT count(*) as count from #{@suggested_name}"].first[:count]
180
+
181
+ return OpenStruct.new({
182
+ :name => @suggested_name,
183
+ :rows_imported => rows_imported,
184
+ :import_type => import_type,
185
+ :log => runlog
186
+ })
187
+ end
129
188
  if @ext == '.csv'
130
189
 
131
190
  ogr2ogr_bin_path = `which ogr2ogr`.strip
@@ -163,12 +222,12 @@ module CartoDB
163
222
  })
164
223
  end
165
224
  if @ext == '.shp'
166
-
225
+ log "processing shp"
167
226
  shp2pgsql_bin_path = `which shp2pgsql`.strip
168
227
 
169
228
  host = @db_configuration[:host] ? "-h #{@db_configuration[:host]}" : ""
170
229
  port = @db_configuration[:port] ? "-p #{@db_configuration[:port]}" : ""
171
- #@suggested_name = get_valid_name(File.basename(path).tr('.','_').downcase.sanitize) unless @force_name
230
+
172
231
  random_table_name = "importing_#{Time.now.to_i}_#{@suggested_name}"
173
232
 
174
233
  normalizer_command = "#{python_bin_path} -Wignore #{File.expand_path("../../../misc/shp_normalizer.py", __FILE__)} #{path} #{random_table_name}"
@@ -191,8 +250,10 @@ module CartoDB
191
250
 
192
251
  if shp_args_command[1] != '4326'
193
252
  begin
194
- @db_connection.run("SELECT UpdateGeometrySRID('#{random_table_name}', 'the_geom', 4326)")
195
- @db_connection.run("UPDATE \"#{random_table_name}\" SET the_geom = ST_Transform(the_geom, 4326)")
253
+ @db_connection.run("ALTER TABLE #{random_table_name} RENAME COLUMN the_geom TO the_geom_orig;")
254
+ geom_type = @db_connection["SELECT GeometryType(the_geom_orig) as type from #{random_table_name} LIMIT 1"].first[:type]
255
+ @db_connection.run("SELECT AddGeometryColumn('#{random_table_name}','the_geom',4326, '#{geom_type}', 2);")
256
+ @db_connection.run("UPDATE \"#{random_table_name}\" SET the_geom = ST_Transform(the_geom_orig, 4326)")
196
257
  @db_connection.run("CREATE INDEX \"#{random_table_name}_the_geom_gist\" ON \"#{random_table_name}\" USING GIST (the_geom)")
197
258
  rescue Exception => msg
198
259
  runlog.err << msg
@@ -1,6 +1,6 @@
1
1
  module CartoDB
2
2
  class Importer
3
- VERSION = "0.2.11"
3
+ VERSION = "0.2.12"
4
4
  end
5
5
  end
6
6
 
data/spec/import_spec.rb CHANGED
@@ -197,6 +197,46 @@ describe CartoDB::Importer do
197
197
  end
198
198
  end
199
199
 
200
+ describe "#KML" do
201
+ it "should import KML file rmnp.kml" do
202
+ importer = CartoDB::Importer.new :import_from_file => File.expand_path("../support/data/rmnp.kml", __FILE__),
203
+ :database => "cartodb_importer_test", :username => 'postgres', :password => '',
204
+ :host => 'localhost', :port => 5432
205
+ result = importer.import!
206
+ result.name.should == 'rmnp'
207
+ result.rows_imported.should == 1
208
+ result.import_type.should == '.kml'
209
+ end
210
+ it "should import KML file rmnp.zip" do
211
+ importer = CartoDB::Importer.new :import_from_file => File.expand_path("../support/data/rmnp.zip", __FILE__),
212
+ :database => "cartodb_importer_test", :username => 'postgres', :password => '',
213
+ :host => 'localhost', :port => 5432
214
+ result = importer.import!
215
+ result.name.should == 'rmnp'
216
+ result.rows_imported.should == 1
217
+ result.import_type.should == '.kml'
218
+ end
219
+ it "should import KMZ file rmnp.kmz" do
220
+ importer = CartoDB::Importer.new :import_from_file => File.expand_path("../support/data/rmnp.kmz", __FILE__),
221
+ :database => "cartodb_importer_test", :username => 'postgres', :password => '',
222
+ :host => 'localhost', :port => 5432
223
+ result = importer.import!
224
+ result.name.should == 'rmnp'
225
+ result.rows_imported.should == 1
226
+ result.import_type.should == '.kml'
227
+ end
228
+ end
229
+ describe "#GeoJSON" do
230
+ it "should import GeoJSON file simple.json" do
231
+ importer = CartoDB::Importer.new :import_from_file => File.expand_path("../support/data/simple.json", __FILE__),
232
+ :database => "cartodb_importer_test", :username => 'postgres', :password => '',
233
+ :host => 'localhost', :port => 5432
234
+ result = importer.import!
235
+ result.name.should == 'simple'
236
+ result.rows_imported.should == 11
237
+ result.import_type.should == '.json'
238
+ end
239
+ end
200
240
  describe "#SHP" do
201
241
  it "should import a SHP file in the given database in a table named like the file" do
202
242
  options = { :import_from_file => File.expand_path("../support/data/EjemploVizzuality.zip", __FILE__),
@@ -227,6 +267,7 @@ describe CartoDB::Importer do
227
267
  result.rows_imported.should == 246
228
268
  result.import_type.should == '.shp'
229
269
  end
270
+
230
271
 
231
272
  it "should import SHP file TM_WORLD_BORDERS_SIMPL-0.3.zip but set the given name" do
232
273
  importer = CartoDB::Importer.new :import_from_file => File.expand_path("../support/data/TM_WORLD_BORDERS_SIMPL-0.3.zip", __FILE__),
@@ -282,4 +323,14 @@ describe CartoDB::Importer do
282
323
  end
283
324
  end
284
325
 
326
+ describe "Import from Simon file" do
327
+ it "should import a shapefile from Simon" do
328
+ importer = CartoDB::Importer.new :import_from_file => File.expand_path("../support/data/simon-search-spain-1297870422647.zip", __FILE__),
329
+ :database => "cartodb_importer_test", :username => 'postgres', :password => '',
330
+ :host => 'localhost', :port => 5432
331
+ result = importer.import!
332
+ #result.rows_imported.should == 312
333
+ result.import_type.should == '.shp'
334
+ end
335
+ end
285
336
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cartodb-importer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.11
4
+ version: 0.2.12
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -11,11 +11,11 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2011-09-20 00:00:00.000000000Z
14
+ date: 2011-09-26 00:00:00.000000000Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: pg
18
- requirement: &70275501630760 !ruby/object:Gem::Requirement
18
+ requirement: &70120001441940 !ruby/object:Gem::Requirement
19
19
  none: false
20
20
  requirements:
21
21
  - - ~>
@@ -23,10 +23,10 @@ dependencies:
23
23
  version: '0.11'
24
24
  type: :runtime
25
25
  prerelease: false
26
- version_requirements: *70275501630760
26
+ version_requirements: *70120001441940
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: sequel
29
- requirement: &70275501630140 !ruby/object:Gem::Requirement
29
+ requirement: &70120001425220 !ruby/object:Gem::Requirement
30
30
  none: false
31
31
  requirements:
32
32
  - - ! '>='
@@ -34,10 +34,10 @@ dependencies:
34
34
  version: '0'
35
35
  type: :runtime
36
36
  prerelease: false
37
- version_requirements: *70275501630140
37
+ version_requirements: *70120001425220
38
38
  - !ruby/object:Gem::Dependency
39
39
  name: roo
40
- requirement: &70275501629380 !ruby/object:Gem::Requirement
40
+ requirement: &70120001424340 !ruby/object:Gem::Requirement
41
41
  none: false
42
42
  requirements:
43
43
  - - ! '>='
@@ -45,10 +45,10 @@ dependencies:
45
45
  version: '0'
46
46
  type: :runtime
47
47
  prerelease: false
48
- version_requirements: *70275501629380
48
+ version_requirements: *70120001424340
49
49
  - !ruby/object:Gem::Dependency
50
50
  name: spreadsheet
51
- requirement: &70275501616740 !ruby/object:Gem::Requirement
51
+ requirement: &70120001423720 !ruby/object:Gem::Requirement
52
52
  none: false
53
53
  requirements:
54
54
  - - ! '>='
@@ -56,10 +56,10 @@ dependencies:
56
56
  version: '0'
57
57
  type: :runtime
58
58
  prerelease: false
59
- version_requirements: *70275501616740
59
+ version_requirements: *70120001423720
60
60
  - !ruby/object:Gem::Dependency
61
61
  name: google-spreadsheet-ruby
62
- requirement: &70275501616240 !ruby/object:Gem::Requirement
62
+ requirement: &70120001422940 !ruby/object:Gem::Requirement
63
63
  none: false
64
64
  requirements:
65
65
  - - ! '>='
@@ -67,10 +67,10 @@ dependencies:
67
67
  version: '0'
68
68
  type: :runtime
69
69
  prerelease: false
70
- version_requirements: *70275501616240
70
+ version_requirements: *70120001422940
71
71
  - !ruby/object:Gem::Dependency
72
72
  name: rubyzip
73
- requirement: &70275501615640 !ruby/object:Gem::Requirement
73
+ requirement: &70120001421960 !ruby/object:Gem::Requirement
74
74
  none: false
75
75
  requirements:
76
76
  - - ! '>='
@@ -78,10 +78,10 @@ dependencies:
78
78
  version: '0'
79
79
  type: :runtime
80
80
  prerelease: false
81
- version_requirements: *70275501615640
81
+ version_requirements: *70120001421960
82
82
  - !ruby/object:Gem::Dependency
83
83
  name: builder
84
- requirement: &70275501614920 !ruby/object:Gem::Requirement
84
+ requirement: &70120001421380 !ruby/object:Gem::Requirement
85
85
  none: false
86
86
  requirements:
87
87
  - - ! '>='
@@ -89,10 +89,10 @@ dependencies:
89
89
  version: '0'
90
90
  type: :runtime
91
91
  prerelease: false
92
- version_requirements: *70275501614920
92
+ version_requirements: *70120001421380
93
93
  - !ruby/object:Gem::Dependency
94
94
  name: rspec
95
- requirement: &70275501614360 !ruby/object:Gem::Requirement
95
+ requirement: &70120001420760 !ruby/object:Gem::Requirement
96
96
  none: false
97
97
  requirements:
98
98
  - - ! '>='
@@ -100,10 +100,10 @@ dependencies:
100
100
  version: '0'
101
101
  type: :development
102
102
  prerelease: false
103
- version_requirements: *70275501614360
103
+ version_requirements: *70120001420760
104
104
  - !ruby/object:Gem::Dependency
105
105
  name: mocha
106
- requirement: &70275501613760 !ruby/object:Gem::Requirement
106
+ requirement: &70120001420080 !ruby/object:Gem::Requirement
107
107
  none: false
108
108
  requirements:
109
109
  - - ! '>='
@@ -111,10 +111,10 @@ dependencies:
111
111
  version: '0'
112
112
  type: :development
113
113
  prerelease: false
114
- version_requirements: *70275501613760
114
+ version_requirements: *70120001420080
115
115
  - !ruby/object:Gem::Dependency
116
116
  name: ruby-debug19
117
- requirement: &70275501613100 !ruby/object:Gem::Requirement
117
+ requirement: &70120001419420 !ruby/object:Gem::Requirement
118
118
  none: false
119
119
  requirements:
120
120
  - - ! '>='
@@ -122,7 +122,7 @@ dependencies:
122
122
  version: '0'
123
123
  type: :development
124
124
  prerelease: false
125
- version_requirements: *70275501613100
125
+ version_requirements: *70120001419420
126
126
  description: Import CSV, SHP, and other files with data into a PostgreSQL table
127
127
  email:
128
128
  - andrew@vizzuality.com