cartodb-importer 0.2.11 → 0.2.12

Sign up to get free protection for your applications and to get access to all the features.
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