datashift 0.6.0 → 0.6.1
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/README.markdown +11 -9
- data/VERSION +1 -1
- data/datashift.gemspec +2 -3
- data/lib/loaders/excel_loader.rb +2 -0
- data/lib/loaders/loader_base.rb +40 -12
- data/lib/loaders/spree/product_loader.rb +16 -10
- data/lib/thor/spree/bootstrap_cleanup.thor +24 -14
- data/lib/thor/spree/products_images.thor +53 -29
- data/spec/fixtures/datashift_Spree_db.sqlite +0 -0
- data/spec/fixtures/datashift_test_models_db.sqlite +0 -0
- data/spec/spree_loader_spec.rb +7 -3
- data/spec/thor_spec.rb +4 -1
- metadata +2 -3
- data/tasks/spree/image_load.rake +0 -108
data/README.markdown
CHANGED
@@ -2,29 +2,31 @@
|
|
2
2
|
|
3
3
|
Provides tools to shift data between Ruby, external applications, files and ActiveRecord.
|
4
4
|
|
5
|
-
|
5
|
+
Specific loaders and command line tasks for Spree E-Commerce.
|
6
6
|
|
7
|
-
|
7
|
+
Wiki taking shape with more info here : **https://github.com/autotelik/datashift/wiki**
|
8
8
|
|
9
|
-
|
9
|
+
### Features
|
10
10
|
|
11
11
|
Import and Export ActiveRecord models through .xls or CSV files, including
|
12
12
|
all associations and with configurable defaults.
|
13
13
|
|
14
|
+
Export all data or simply generate a sample template with headers only.
|
15
|
+
|
14
16
|
Create, parse and use Excel/OpenOffice (.xls) documents dynamically from Ruby.
|
15
17
|
|
16
18
|
Easily extendable Loader functionality to deal with non trivial import cases, such
|
17
19
|
as complex association lookups.
|
18
20
|
|
19
|
-
High level rake
|
21
|
+
High level rake and thor command line tasks for import/export provided.
|
20
22
|
|
21
|
-
Specific loaders and
|
22
|
-
|
23
|
+
Specific loaders and command line tasks provided out the box for **Spree E-Commerce**,
|
24
|
+
enabling import/export of Product data including creating Variants with different
|
25
|
+
count on hands and all associations including Properties/Taxons/OptionTypes and Images.
|
23
26
|
|
24
|
-
|
25
|
-
enabling import/export of all data including Products with complex associations such as Options/Variants and Images.
|
27
|
+
Loaders can be configured via YAML with over ride values, default values and mandatory column settingss.
|
26
28
|
|
27
|
-
Many example Spreadsheets in spec/fixtures, fully documented with comments for each column.
|
29
|
+
Many example Spreadsheets/CSV files in spec/fixtures, fully documented with comments for each column.
|
28
30
|
|
29
31
|
## Installation
|
30
32
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.6.
|
1
|
+
0.6.1
|
data/datashift.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "datashift"
|
8
|
-
s.version = "0.6.
|
8
|
+
s.version = "0.6.1"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Thomas Statter"]
|
12
|
-
s.date = "2012-05-
|
12
|
+
s.date = "2012-05-24"
|
13
13
|
s.description = "A suite of tools to move data between ActiveRecord models,databases,applications like Excel/Open Office, files and projects including Spree"
|
14
14
|
s.email = "rubygems@autotelik.co.uk"
|
15
15
|
s.extra_rdoc_files = [
|
@@ -151,7 +151,6 @@ Gem::Specification.new do |s|
|
|
151
151
|
"tasks/file_tasks.rake",
|
152
152
|
"tasks/import/csv.rake",
|
153
153
|
"tasks/import/excel.rake",
|
154
|
-
"tasks/spree/image_load.rake",
|
155
154
|
"tasks/word_to_seedfu.rake",
|
156
155
|
"test/helper.rb",
|
157
156
|
"test/test_interact.rb"
|
data/lib/loaders/excel_loader.rb
CHANGED
@@ -124,6 +124,8 @@ module DataShift
|
|
124
124
|
end
|
125
125
|
end
|
126
126
|
puts "Excel loading stage complete - #{loaded_objects.size} rows added."
|
127
|
+
|
128
|
+
puts "WARNING : #{failed_objects.size} rows contained errors and #{failed_objects.size} records NOT created." unless failed_objects.empty?
|
127
129
|
end
|
128
130
|
|
129
131
|
def value_at(row, column)
|
data/lib/loaders/loader_base.rb
CHANGED
@@ -100,6 +100,7 @@ module DataShift
|
|
100
100
|
|
101
101
|
@method_mapper = DataShift::MethodMapper.new
|
102
102
|
@options = options.clone
|
103
|
+
@verbose_logging = @options[:verbose_logging]
|
103
104
|
@headers = []
|
104
105
|
|
105
106
|
@default_data_objects ||= {}
|
@@ -216,7 +217,11 @@ module DataShift
|
|
216
217
|
|
217
218
|
# Default values can be provided in YAML config file
|
218
219
|
# Format :
|
219
|
-
#
|
220
|
+
#
|
221
|
+
# LoaderClass:
|
222
|
+
# option: value
|
223
|
+
#
|
224
|
+
# Load Class: (e.g Spree:Product)
|
220
225
|
# atttribute: value
|
221
226
|
|
222
227
|
def configure_from( yaml_file )
|
@@ -251,6 +256,8 @@ module DataShift
|
|
251
256
|
|
252
257
|
if(data[load_object_class.name])
|
253
258
|
|
259
|
+
logger.info("Assigning defaults and over rides from config")
|
260
|
+
|
254
261
|
deflts = data[load_object_class.name]['datashift_defaults']
|
255
262
|
@default_values.merge!(deflts) if deflts
|
256
263
|
|
@@ -258,6 +265,11 @@ module DataShift
|
|
258
265
|
@override_values.merge!(ovrides) if ovrides
|
259
266
|
end
|
260
267
|
|
268
|
+
if(data['LoaderBase'])
|
269
|
+
@options.merge!(data['LoaderBase'])
|
270
|
+
end
|
271
|
+
|
272
|
+
logger.info("Loader Options : #{@options.inspect}")
|
261
273
|
end
|
262
274
|
|
263
275
|
# Set member variables to hold details and value.
|
@@ -285,13 +297,28 @@ module DataShift
|
|
285
297
|
@current_value
|
286
298
|
end
|
287
299
|
|
288
|
-
|
300
|
+
# return the find_by operator and the values to find
|
301
|
+
def get_find_operator_and_rest( column_data)
|
302
|
+
|
303
|
+
find_operator, col_values = "",nil
|
304
|
+
|
305
|
+
if(@current_method_detail.find_by_operator)
|
306
|
+
find_operator, col_values = @current_method_detail.find_by_operator, column_data
|
307
|
+
else
|
308
|
+
find_operator, col_values = column_data.split(LoaderBase::name_value_delim)
|
309
|
+
end
|
310
|
+
|
311
|
+
return find_operator, col_values
|
312
|
+
end
|
313
|
+
|
289
314
|
# Process a value string from a column.
|
290
315
|
# Assigning value(s) to correct association on @load_object.
|
291
316
|
# Method detail represents a column from a file and it's correlated AR associations.
|
292
317
|
# Value string which may contain multiple values for a collection association.
|
293
318
|
#
|
294
|
-
def process()
|
319
|
+
def process()
|
320
|
+
|
321
|
+
logger.info("Current value to assign : #{@current_value}") #if @options['verboose_logging']
|
295
322
|
|
296
323
|
if(@current_method_detail.operator_for(:has_many))
|
297
324
|
|
@@ -310,17 +337,18 @@ module DataShift
|
|
310
337
|
|
311
338
|
columns.each do |col_str|
|
312
339
|
|
313
|
-
find_operator, col_values =
|
314
|
-
|
315
|
-
if(@current_method_detail.find_by_operator)
|
316
|
-
find_operator, col_values = @current_method_detail.find_by_operator, col_str
|
317
|
-
else
|
318
|
-
find_operator, col_values = col_str.split(LoaderBase::name_value_delim)
|
319
|
-
raise "No key to find #{@current_method_detail.operator} in DB. Expected format key:value" unless(col_values)
|
320
|
-
end
|
340
|
+
find_operator, col_values = get_find_operator_and_rest( col_str )
|
321
341
|
|
342
|
+
#if(@current_method_detail.find_by_operator)
|
343
|
+
# find_operator, col_values = @current_method_detail.find_by_operator, col_str
|
344
|
+
# else
|
345
|
+
# find_operator, col_values = col_str.split(LoaderBase::name_value_delim)
|
346
|
+
# end
|
347
|
+
|
348
|
+
raise "Cannot perform DB find by #{find_operator}. Expected format key:value" unless(find_operator && col_values)
|
349
|
+
|
322
350
|
find_by_values = col_values.split(LoaderBase::multi_value_delim)
|
323
|
-
|
351
|
+
|
324
352
|
if(find_by_values.size > 1)
|
325
353
|
|
326
354
|
@current_value = @current_method_detail.operator_class.send("find_all_by_#{find_operator}", find_by_values )
|
@@ -215,8 +215,10 @@ module DataShift
|
|
215
215
|
|
216
216
|
# Special case for ProductProperties since it can have additional value applied.
|
217
217
|
# A list of Properties with a optional Value - supplied in form :
|
218
|
-
#
|
219
|
-
#
|
218
|
+
# property_name:value|property_name|property_name:value
|
219
|
+
# Example :
|
220
|
+
# test_pp_002|test_pp_003:Example free value|yet_another_property
|
221
|
+
|
220
222
|
def add_properties
|
221
223
|
# TODO smart column ordering to ensure always valid by time we get to associations
|
222
224
|
save_if_new
|
@@ -224,27 +226,31 @@ module DataShift
|
|
224
226
|
property_list = get_each_assoc#current_value.split(LoaderBase::multi_assoc_delim)
|
225
227
|
|
226
228
|
property_list.each do |pstr|
|
227
|
-
|
228
|
-
|
229
|
+
|
230
|
+
find_by_name, find_by_value = get_find_operator_and_rest( pstr )
|
231
|
+
|
232
|
+
raise "Cannot find Property via #{find_by_name} (with value #{find_by_value})" unless(find_by_name)
|
233
|
+
|
234
|
+
property = @@property_klass.find_by_name(find_by_name)
|
229
235
|
|
230
236
|
unless property
|
231
|
-
property = @@property_klass.create( :name =>
|
232
|
-
logger.
|
237
|
+
property = @@property_klass.create( :name => find_by_name, :presentation => find_by_name.humanize)
|
238
|
+
logger.info "Created New Property #{property.inspect}"
|
233
239
|
end
|
234
240
|
|
235
241
|
if(property)
|
236
242
|
if(SpreeHelper::version.to_f >= 1.1)
|
237
243
|
# Property now protected from mass assignment
|
238
|
-
x = @@product_property_klass.new( :value =>
|
244
|
+
x = @@product_property_klass.new( :value => find_by_value )
|
239
245
|
x.property = property
|
240
246
|
x.save
|
241
|
-
logger.
|
247
|
+
logger.info "Created New ProductProperty #{x.inspect}"
|
242
248
|
@load_object.product_properties << x
|
243
249
|
else
|
244
|
-
@load_object.product_properties << @@product_property_klass.create( :property => property, :value =>
|
250
|
+
@load_object.product_properties << @@product_property_klass.create( :property => property, :value => find_by_values)
|
245
251
|
end
|
246
252
|
else
|
247
|
-
puts "WARNING: Property #{
|
253
|
+
puts "WARNING: Property #{find_by_name} NOT found - Not set Product"
|
248
254
|
end
|
249
255
|
|
250
256
|
end
|
@@ -16,27 +16,37 @@ module Datashift
|
|
16
16
|
|
17
17
|
desc "cleanup", "Remove Spree Product/Variant data from DB"
|
18
18
|
|
19
|
-
def cleanup()
|
19
|
+
def cleanup()
|
20
20
|
|
21
|
-
|
21
|
+
require 'spree_helper'
|
22
22
|
|
23
23
|
require File.expand_path('config/environment.rb')
|
24
|
-
|
25
|
-
%w{Image OptionType OptionValue
|
26
|
-
|
27
|
-
|
28
|
-
|
24
|
+
|
25
|
+
cleanup = %w{ Image OptionType OptionValue
|
26
|
+
Product Property ProductGroup ProductProperty ProductOptionType
|
27
|
+
Variant Taxonomy Taxon Zone
|
28
|
+
}
|
29
|
+
|
30
|
+
cleanup.each do |k|
|
31
|
+
klass = DataShift::SpreeHelper::get_spree_class(k)
|
32
|
+
if(klass)
|
33
|
+
puts "Clearing model #{klass}"
|
34
|
+
klass.delete_all
|
35
|
+
else
|
36
|
+
puts "WARNING - Coulod not find AR model for class name #{k}"
|
29
37
|
end
|
38
|
+
|
39
|
+
end
|
30
40
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
41
|
+
if(File.exists?('public/spree/products') )
|
42
|
+
puts "Removing old Product assets from 'public/spree/products'"
|
43
|
+
FileUtils::rm_rf('public/public/spree/products')
|
44
|
+
end
|
35
45
|
|
36
|
-
|
46
|
+
FileUtils::rm_rf('MissingRecords') if(File.exists?('MissingRecords') )
|
37
47
|
|
38
|
-
end
|
39
|
-
|
40
48
|
end
|
49
|
+
|
50
|
+
end
|
41
51
|
|
42
52
|
end
|
@@ -75,24 +75,27 @@ module Datashift
|
|
75
75
|
method_option :sku_prefix, :aliases => '-p', :desc => "Prefix to add to each SKU in import file"
|
76
76
|
method_option :dummy, :aliases => '-d', :type => :boolean, :desc => "Dummy run, do not actually save Image or Product"
|
77
77
|
method_option :verbose, :aliases => '-v', :type => :boolean, :desc => "Verbose logging"
|
78
|
-
|
78
|
+
method_option :config, :aliases => '-c', :type => :string, :desc => "Configuration file for Image Loader in YAML"
|
79
|
+
|
79
80
|
|
80
81
|
def images()
|
81
82
|
|
82
83
|
require File.expand_path('config/environment.rb')
|
83
84
|
|
84
85
|
require 'image_loader'
|
85
|
-
|
86
|
-
@image_cache = options[:input]
|
87
86
|
|
88
87
|
puts "Using Product Name for lookup" unless(options[:sku])
|
89
88
|
puts "Using SKU for lookup" if(options[:sku])
|
90
|
-
|
91
|
-
|
89
|
+
|
92
90
|
attachment_klazz = DataShift::SpreeHelper::get_spree_class('Product' )
|
93
|
-
|
91
|
+
attachment_field = 'name'
|
94
92
|
image_klazz = DataShift::SpreeHelper::get_spree_class('Image' )
|
95
93
|
|
94
|
+
if(options[:sku])
|
95
|
+
attachment_klazz = DataShift::SpreeHelper::get_spree_class('Variant' )
|
96
|
+
attachment_field = 'sku'
|
97
|
+
end
|
98
|
+
|
96
99
|
# TODO generalise for any paperclip project, for now just Spree
|
97
100
|
#begin
|
98
101
|
# attachment_klazz = Kernel.const_get(args[:model]) if(args[:model])
|
@@ -102,6 +105,22 @@ module Datashift
|
|
102
105
|
|
103
106
|
image_loader = DataShift::SpreeHelper::ImageLoader.new
|
104
107
|
|
108
|
+
@loader_config = {}
|
109
|
+
|
110
|
+
if(options[:config])
|
111
|
+
raise "Bad Config - Cannot find specified file #{options[:config]}" unless File.exists?(options[:config])
|
112
|
+
|
113
|
+
image_loader.configure_from( options[:config] )
|
114
|
+
|
115
|
+
@loader_config = YAML::load( File.open(options[:config]) )
|
116
|
+
|
117
|
+
@loader_config = @loader_config['ImageLoader']
|
118
|
+
end
|
119
|
+
|
120
|
+
puts "CONFIG: #{@loader_config.inspect}"
|
121
|
+
|
122
|
+
@image_cache = options[:input]
|
123
|
+
|
105
124
|
if(File.directory? @image_cache )
|
106
125
|
logger.info "Loading Spree images from #{@image_cache}"
|
107
126
|
|
@@ -109,32 +128,23 @@ module Datashift
|
|
109
128
|
Dir.glob("#{@image_cache}/**/*.{jpg,png,gif}") do |image_name|
|
110
129
|
|
111
130
|
base_name = File.basename(image_name, '.*')
|
112
|
-
|
113
|
-
|
131
|
+
base_name.strip!
|
132
|
+
|
133
|
+
logger.info "Processing image #{base_name} : #{File.exists?(image_name)}"
|
114
134
|
|
115
135
|
record = nil
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
record =
|
124
|
-
|
125
|
-
unless record # try splitting up filename in various ways looking for the SKU
|
126
|
-
sku.split( '_' ).each do |x|
|
127
|
-
x = "#{options[:sku_prefix]}#{x}" if(options[:sku_prefix])
|
128
|
-
record = sku_klazz.find_by_sku(x)
|
129
|
-
break if record
|
130
|
-
end
|
131
|
-
end
|
132
|
-
|
133
|
-
record = record.product if(record) # SKU stored on Variant but we want it's master Product
|
134
|
-
|
135
|
-
else
|
136
|
-
record = attachment_klazz.find_by_name(base_name)
|
136
|
+
|
137
|
+
put "Processing image [#{base_name}]"
|
138
|
+
|
139
|
+
# unless record # try splitting up filename in various ways looking for the SKU
|
140
|
+
split_on = @loader_config[:split_file_name_on] || '_'
|
141
|
+
|
142
|
+
base_name.split(split_on).each do |x|
|
143
|
+
record = get_record_by(attachment_klazz, attachment_field, x)
|
144
|
+
break if record
|
137
145
|
end
|
146
|
+
|
147
|
+
record = record.product if(record) # SKU stored on Variant but we want it's master Product
|
138
148
|
|
139
149
|
if(record)
|
140
150
|
logger.info "Found record for attachment : #{record.inspect}"
|
@@ -175,6 +185,20 @@ module Datashift
|
|
175
185
|
exit(-1)
|
176
186
|
end
|
177
187
|
end
|
188
|
+
|
189
|
+
private
|
190
|
+
|
191
|
+
def get_record_by(klazz, field, value)
|
192
|
+
x = (options[:sku_prefix]) ? "#{options[:sku_prefix]}#{value}" : value
|
193
|
+
|
194
|
+
if(@loader_config['case_sensitive'])
|
195
|
+
puts "Search case sensitive for [#{x}] on #{field}"
|
196
|
+
return klazz.find(:first, :conditions => [ "? = ?", field, x ])
|
197
|
+
else
|
198
|
+
puts "Search for [#{x}] on #{field}"
|
199
|
+
return klazz.find(:first, :conditions => [ "lower(?) = ?", field, x.downcase ])
|
200
|
+
end
|
201
|
+
end
|
178
202
|
end
|
179
203
|
|
180
204
|
end
|
Binary file
|
Binary file
|
data/spec/spree_loader_spec.rb
CHANGED
@@ -83,11 +83,11 @@ describe 'SpreeLoader' do
|
|
83
83
|
|
84
84
|
# Loader should perform identically regardless of source, whether csv, .xls etc
|
85
85
|
|
86
|
-
it "should load basic Products .xls via Spree loader" do
|
86
|
+
it "should load basic Products .xls via Spree loader", :fail => true do
|
87
87
|
test_basic_product('SpreeProductsSimple.xls')
|
88
88
|
end
|
89
89
|
|
90
|
-
it "should load basic Products from .csv via Spree loader", :csv => true do
|
90
|
+
it "should load basic Products from .csv via Spree loader", :csv => true, :fail => true do
|
91
91
|
test_basic_product('SpreeProductsSimple.csv')
|
92
92
|
end
|
93
93
|
|
@@ -104,6 +104,10 @@ describe 'SpreeLoader' do
|
|
104
104
|
@product_loader.perform_load( SpecHelper::spree_fixture(source), :mandatory => ['sku', 'name', 'price'] )
|
105
105
|
|
106
106
|
@Product_klass.count.should == 3
|
107
|
+
|
108
|
+
# 2 products available_on set in past, 1 in future
|
109
|
+
@Product_klass.active.size.should == 2
|
110
|
+
@Product_klass.available.size.should == 2
|
107
111
|
|
108
112
|
@product_loader.failed_objects.size.should == 0
|
109
113
|
@product_loader.loaded_objects.size.should == 3
|
@@ -179,7 +183,7 @@ describe 'SpreeLoader' do
|
|
179
183
|
end
|
180
184
|
|
181
185
|
|
182
|
-
it "should load Products and create Variants from multiple column", :fail => true do
|
186
|
+
it "should load Products and create Variants from multiple column #{SpecHelper::spree_fixture('SpreeProductsMultiColumn.xls')}", :fail => true do
|
183
187
|
test_variants_creation('SpreeProductsMultiColumn.xls')
|
184
188
|
end
|
185
189
|
|
data/spec/thor_spec.rb
CHANGED
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: datashift
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.6.
|
5
|
+
version: 0.6.1
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Thomas Statter
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2012-05-
|
13
|
+
date: 2012-05-24 00:00:00 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: spreadsheet
|
@@ -167,7 +167,6 @@ files:
|
|
167
167
|
- tasks/file_tasks.rake
|
168
168
|
- tasks/import/csv.rake
|
169
169
|
- tasks/import/excel.rake
|
170
|
-
- tasks/spree/image_load.rake
|
171
170
|
- tasks/word_to_seedfu.rake
|
172
171
|
- test/helper.rb
|
173
172
|
- test/test_interact.rb
|
data/tasks/spree/image_load.rake
DELETED
@@ -1,108 +0,0 @@
|
|
1
|
-
# Copyright:: (c) Autotelik Media Ltd 2011
|
2
|
-
# Author :: Tom Statter
|
3
|
-
# Date :: Feb 2011
|
4
|
-
# License:: MIT
|
5
|
-
#
|
6
|
-
# Usage::
|
7
|
-
#
|
8
|
-
# => rake datashift:spree:images input=vendor/extensions/site/fixtures/images
|
9
|
-
# => rake datashift:spree:images input=C:\images\photos large dummy=true
|
10
|
-
#
|
11
|
-
# => rake datashift:spree:images input=C:\images\taxon_icons skip_if_no_assoc=true klass=Taxon
|
12
|
-
#
|
13
|
-
namespace :datashift do
|
14
|
-
|
15
|
-
namespace :spree do
|
16
|
-
|
17
|
-
#DEPRECATED FOTR THOR
|
18
|
-
#desc "Populate the DB with images.\nDefault location db/image_seeds, or specify :input=<path> or dir under db/image_seeds with :folder"
|
19
|
-
# :dummy => dummy run without actual saving to DB
|
20
|
-
task :images, [:input, :folder, :dummy, :sku, :skip_if_no_assoc, :skip_if_loaded, :model] => :environment do |t, args|
|
21
|
-
|
22
|
-
require 'image_loader'
|
23
|
-
|
24
|
-
raise "USAGE: Please specify one of :input or :folder" if(args[:input] && args[:folder])
|
25
|
-
puts "SKU not specified " if(args[:input] && args[:folder])
|
26
|
-
|
27
|
-
if args[:input]
|
28
|
-
@image_cache = args[:input]
|
29
|
-
else
|
30
|
-
@image_cache = File.join(Rails.root, "db", "image_seeds")
|
31
|
-
@image_cache = File.join(@image_cache, args[:folder]) if(args[:folder])
|
32
|
-
end
|
33
|
-
|
34
|
-
|
35
|
-
attachment_klazz = SpreeHelper::get_spree_class('Product' )
|
36
|
-
sku_klazz = SpreeHelper::get_spree_class('Variant' )
|
37
|
-
|
38
|
-
image_loader = ImageLoader.new
|
39
|
-
|
40
|
-
|
41
|
-
if(File.directory? @image_cache )
|
42
|
-
puts "Loading images from #{@image_cache}"
|
43
|
-
|
44
|
-
missing_records = []
|
45
|
-
Dir.glob("#{@image_cache}/**/*.{jpg,png,gif}") do |image_name|
|
46
|
-
|
47
|
-
base_name = File.basename(image_name, '.*')
|
48
|
-
|
49
|
-
puts "Processing #{base_name} : #{File.exists?(image_name)}"
|
50
|
-
|
51
|
-
record = nil
|
52
|
-
if(args[:sku])
|
53
|
-
sku = base_name.slice!(/\w+/)
|
54
|
-
sku.strip!
|
55
|
-
base_name.strip!
|
56
|
-
|
57
|
-
puts "Looking fo SKU #{sku}"
|
58
|
-
record = sku_klazz.find_by_sku(sku)
|
59
|
-
if record
|
60
|
-
record = record.product # SKU stored on Variant but we want it's master Product
|
61
|
-
else
|
62
|
-
puts "Looking for NAME [#{base_name}]"
|
63
|
-
record = attachment_klazz.find_by_name(base_name)
|
64
|
-
end
|
65
|
-
else
|
66
|
-
puts "Looking for #{attachment_klazz.name} with NAME [#{base_name}]"
|
67
|
-
record = attachment_klazz.find_by_name(base_name)
|
68
|
-
end
|
69
|
-
|
70
|
-
if(record)
|
71
|
-
puts "Found record for attachment : #{record.inspect}"
|
72
|
-
exists = record.images.detect {|i| puts "COMPARE #{i.attachment_file_name} => #{image_name}"; i.attachment_file_name == image_name }
|
73
|
-
puts "Found existing attachments [#{exists}]" unless(exists.nil?)
|
74
|
-
if(args[:skip_if_loaded] && !exists.nil?)
|
75
|
-
puts "Skipping - Image #{image_name} already loaded for #{attachment_klazz}"
|
76
|
-
next
|
77
|
-
end
|
78
|
-
else
|
79
|
-
missing_records << image_name
|
80
|
-
end
|
81
|
-
|
82
|
-
# Now do actual upload to DB unless we are doing a dummy run,
|
83
|
-
# or the Image must have an associated record
|
84
|
-
unless(args[:dummy] == 'true' || (args[:skip_if_no_assoc] && record.nil?))
|
85
|
-
image_loader.reset()
|
86
|
-
puts "Process Image"
|
87
|
-
image_loader.process( image_name, record )
|
88
|
-
end
|
89
|
-
|
90
|
-
end
|
91
|
-
|
92
|
-
unless missing_records.empty?
|
93
|
-
FileUtils.mkdir_p('MissingRecords') unless File.directory?('MissingRecords')
|
94
|
-
|
95
|
-
puts '\nMISSING Records Report>>'
|
96
|
-
missing_records.each do |i|
|
97
|
-
puts "Copy #{i} to MissingRecords folder"
|
98
|
-
FileUtils.cp( i, 'MissingRecords') unless(args[:dummy] == 'true')
|
99
|
-
end
|
100
|
-
end
|
101
|
-
|
102
|
-
else
|
103
|
-
puts "ERROR: Supplied Path #{@image_cache} not accesible"
|
104
|
-
exit(-1)
|
105
|
-
end
|
106
|
-
end
|
107
|
-
end
|
108
|
-
end
|