datashift 0.7.0 → 0.8.0
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 +14 -98
- data/VERSION +1 -1
- data/datashift.gemspec +6 -4
- data/lib/applications/jruby/jexcel_file.rb +69 -52
- data/lib/datashift/method_detail.rb +3 -2
- data/lib/datashift/method_dictionary.rb +7 -2
- data/lib/datashift/method_mapper.rb +12 -3
- data/lib/datashift/model_mapper.rb +4 -4
- data/lib/generators/excel_generator.rb +17 -6
- data/lib/loaders/excel_loader.rb +3 -2
- data/lib/loaders/loader_base.rb +62 -27
- data/lib/loaders/paperclip/image_loader.rb +75 -0
- data/lib/loaders/spree/image_loader.rb +11 -42
- data/lib/loaders/spree/product_loader.rb +94 -52
- data/lib/thor/generate_excel.thor +5 -2
- data/lib/thor/spree/bootstrap_cleanup.thor +22 -16
- data/lib/thor/spree/products_images.thor +58 -45
- data/lib/thor/spree/reports.thor +66 -0
- data/spec/db/migrate/20110803201325_create_test_bed.rb +12 -1
- data/spec/excel_generator_spec.rb +39 -1
- data/spec/excel_loader_spec.rb +1 -0
- data/spec/fixtures/datashift_Spree_db.sqlite +0 -0
- data/spec/fixtures/datashift_test_models_db.sqlite +0 -0
- data/spec/fixtures/spree/SpreeMultiVariant.csv +4 -0
- data/spec/fixtures/spree/SpreeProductsSimple.csv +1 -1
- data/spec/fixtures/spree/SpreeProductsSimple.xls +0 -0
- data/spec/fixtures/test_model_defs.rb +4 -0
- data/spec/spree_images_loader_spec.rb +11 -29
- data/spec/spree_loader_spec.rb +60 -15
- data/tasks/db_tasks.rake +45 -0
- metadata +6 -4
- data/datashift-0.6.0.gem +0 -0
- data/datashift-0.6.1.gem +0 -0
@@ -39,6 +39,12 @@ module DataShift
|
|
39
39
|
logger.debug "PRODUCT #{@load_object.inspect} MASTER: #{@load_object.master.inspect}"
|
40
40
|
end
|
41
41
|
|
42
|
+
def perform_load( file_name, options = {} )
|
43
|
+
# In >= 1.1.0 Image moved to master Variant from Product so no association called Images on Product anymore
|
44
|
+
options[:force_inclusion] = options[:force_inclusion] ? ['images'] : [*options[:force_inclusion]] << 'images'
|
45
|
+
|
46
|
+
super(file_name, options)
|
47
|
+
end
|
42
48
|
|
43
49
|
# Over ride base class process with some Spree::Product specifics
|
44
50
|
#
|
@@ -120,68 +126,100 @@ module DataShift
|
|
120
126
|
# Special case for OptionTypes as it's two stage process
|
121
127
|
# First add the possible option_types to Product, then we are able
|
122
128
|
# to define Variants on those options values.
|
129
|
+
# To defiene a Variant :
|
130
|
+
# 1) define at least one OptionType on Product, for example Size
|
131
|
+
# 2) Provide a value for at least one of these OptionType
|
132
|
+
# 3) A composite Variant can be created by supplyiung a vlaue for more than one OptionType
|
133
|
+
# fro example Colour : Red and Size Medium
|
134
|
+
# Supported Syntax :
|
135
|
+
# '|' seperates Variants
|
136
|
+
# ',' list of option values
|
137
|
+
# Examples :
|
138
|
+
# mime_type:jpeg;print_type:black_white|mime_type:jpeg|mime_type:png, PDF;print_type:colour
|
123
139
|
#
|
124
140
|
def add_options
|
125
141
|
|
126
142
|
# TODO smart column ordering to ensure always valid by time we get to associations
|
127
143
|
save_if_new
|
128
144
|
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
oname, value_str = ostr.split(LoaderBase::name_value_delim)
|
145
|
+
# example : mime_type:jpeg;print_type:black_white|mime_type:jpeg|mime_type:png, PDF;print_type:colour
|
146
|
+
|
147
|
+
variants = get_each_assoc#current_value.split( LoaderBase::multi_assoc_delim )
|
133
148
|
|
134
|
-
|
149
|
+
# 1) mime_type:jpeg;print_type:black_white 2) mime_type:jpeg 3) mime_type:png, PDF;print_type:colour
|
135
150
|
|
136
|
-
|
137
|
-
|
138
|
-
|
151
|
+
variants.each do |per_variant|
|
152
|
+
|
153
|
+
option_types = per_variant.split(';') # [mime_type:jpeg, print_type:black_white]
|
154
|
+
|
155
|
+
optiontype_vlist_map = {}
|
156
|
+
|
157
|
+
option_types.each do |ostr|
|
158
|
+
|
159
|
+
oname, value_str = ostr.split(LoaderBase::name_value_delim)
|
160
|
+
|
161
|
+
option_type = @@option_type_klass.find_by_name(oname)
|
139
162
|
|
140
163
|
unless option_type
|
141
|
-
|
142
|
-
|
164
|
+
option_type = @@option_type_klass.create( :name => oname, :presentation => oname.humanize)
|
165
|
+
# TODO - dynamic creation should be an option
|
166
|
+
|
167
|
+
unless option_type
|
168
|
+
puts "WARNING: OptionType #{oname} NOT found and could not create - Not set Product"
|
169
|
+
next
|
170
|
+
end
|
171
|
+
puts "Created missing OptionType #{option_type.inspect}"
|
143
172
|
end
|
144
|
-
puts "Created missing OptionType #{option_type.inspect}"
|
145
|
-
end
|
146
173
|
|
147
|
-
|
174
|
+
# OptionTypes must be specified first on Product to enable Variants to be created
|
175
|
+
# TODO - is include? very inefficient ??
|
176
|
+
@load_object.option_types << option_type unless @load_object.option_types.include?(option_type)
|
148
177
|
|
149
|
-
|
150
|
-
|
178
|
+
# Can be simply list of OptionTypes, some or all without values
|
179
|
+
next unless(value_str)
|
151
180
|
|
152
|
-
|
153
|
-
|
181
|
+
optiontype_vlist_map[option_type] = []
|
182
|
+
|
183
|
+
# Now get the value(s) for the option e.g red,blue,green for OptType 'colour'
|
184
|
+
optiontype_vlist_map[option_type] = value_str.split(',')
|
185
|
+
end
|
186
|
+
|
187
|
+
next if(optiontype_vlist_map.empty?) # only option types specified - no values
|
154
188
|
|
189
|
+
# Now create set of Variants, some of which maybe composites
|
190
|
+
# Find the longest set of OVs to use as base for combining with the rest
|
191
|
+
sorted_map = optiontype_vlist_map.sort_by { |k,v| v.size }.reverse
|
192
|
+
|
193
|
+
# ovalues = 'pdf','jpeg','png'
|
194
|
+
option_type, ovalues = sorted_map.shift
|
155
195
|
# TODO .. benchmarking to find most efficient way to create these but ensure Product.variants list
|
156
196
|
# populated .. currently need to call reload to ensure this (seems reqd for Spree 1/Rails 3, wasn't required b4
|
157
|
-
ovalues.
|
158
|
-
ovname.strip!
|
159
|
-
ov = @@option_value_klass.find_or_create_by_name_and_option_type_id(ovname, option_type.id)
|
160
|
-
if ov
|
161
|
-
begin
|
162
|
-
# This one line seems to works for 1.1.0 - 3.2 but not 1.0.0 - 3.1 ??
|
163
|
-
if(SpreeHelper::version.to_f >= 1.1)
|
164
|
-
variant = @load_object.variants.create( :sku => "#{@load_object.sku}_#{i}", :price => @load_object.price)
|
165
|
-
else
|
166
|
-
variant = @@variant_klass.create( :product => @load_object, :sku => "#{@load_object.sku}_#{i}", :price => @load_object.price, :available_on => @load_object.available_on)
|
167
|
-
#if(variant.valid?)
|
168
|
-
# variant.save
|
169
|
-
# @load_object.variants << variant
|
170
|
-
|
171
|
-
#else
|
172
|
-
#puts "WARNING: For Option #{ovname} - Variant creation failed #{variant.errors.inspect}"
|
173
|
-
end
|
174
|
-
variant.option_values << ov
|
175
|
-
rescue => e
|
176
|
-
puts "Failed to create a Variant for Product #{@load_object.name}"
|
177
|
-
puts e.inspect
|
178
|
-
#puts e.backtrace
|
179
|
-
end
|
197
|
+
ovalues.each do |ovname|
|
180
198
|
|
181
|
-
|
199
|
+
ov_list = []
|
200
|
+
|
201
|
+
ov = @@option_value_klass.find_or_create_by_name_and_option_type_id(ovname.strip, option_type.id)
|
202
|
+
|
203
|
+
ov_list << ov if ov
|
182
204
|
|
183
|
-
|
184
|
-
|
205
|
+
sorted_map.each do |ot, ovlist| ovlist.each do |for_composite|
|
206
|
+
ov = @@option_value_klass.find_or_create_by_name_and_option_type_id(for_composite.strip, ot.id)
|
207
|
+
|
208
|
+
ov_list << ov if(ov)
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
unless(ov_list.empty?)
|
213
|
+
i = @load_object.variants.size + 1
|
214
|
+
|
215
|
+
# This one line seems to works for 1.1.0 - 3.2 but not 1.0.0 - 3.1 ??
|
216
|
+
if(SpreeHelper::version.to_f >= 1.1)
|
217
|
+
variant = @load_object.variants.create( :sku => "#{@load_object.sku}_#{i}", :price => @load_object.price)
|
218
|
+
else
|
219
|
+
variant = @@variant_klass.create( :product => @load_object, :sku => "#{@load_object.sku}_#{i}", :price => @load_object.price, :available_on => @load_object.available_on)
|
220
|
+
end
|
221
|
+
|
222
|
+
variant.option_values << ov_list if(variant)
|
185
223
|
end
|
186
224
|
end
|
187
225
|
|
@@ -190,7 +228,7 @@ module DataShift
|
|
190
228
|
#puts "DEBUG Load Object now has Variants : #{@load_object.variants.inspect}"
|
191
229
|
end
|
192
230
|
|
193
|
-
end
|
231
|
+
end # each Variant
|
194
232
|
|
195
233
|
# Special case for Images
|
196
234
|
# A list of paths to Images with a optional 'alt' value - supplied in form :
|
@@ -203,10 +241,13 @@ module DataShift
|
|
203
241
|
images = get_each_assoc#current_value.split(LoaderBase::multi_assoc_delim)
|
204
242
|
|
205
243
|
images.each do |image|
|
206
|
-
|
244
|
+
puts "Add Image #{image}"
|
207
245
|
img_path, alt_text = image.split(LoaderBase::name_value_delim)
|
208
246
|
|
209
|
-
|
247
|
+
# moved from Prod to Variant in spree 1.x.x
|
248
|
+
attachment = (SpreeHelper::version.to_f > 1) ? @load_object.master : @load_object
|
249
|
+
|
250
|
+
image = create_image(@@image_klass, img_path, attachment, :alt => alt_text)
|
210
251
|
logger.debug("Product assigned an Image : #{image.inspect}")
|
211
252
|
end
|
212
253
|
|
@@ -226,12 +267,13 @@ module DataShift
|
|
226
267
|
property_list = get_each_assoc#current_value.split(LoaderBase::multi_assoc_delim)
|
227
268
|
|
228
269
|
property_list.each do |pstr|
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
270
|
+
|
271
|
+
# Special case, we know we lookup on name so operator is effectively the name to lookup
|
272
|
+
find_by_name, find_by_value = get_find_operator_and_rest( pstr )
|
273
|
+
|
274
|
+
raise "Cannot find Property via #{find_by_name} (with value #{find_by_value})" unless(find_by_name)
|
233
275
|
|
234
|
-
|
276
|
+
property = @@property_klass.find_by_name(find_by_name)
|
235
277
|
|
236
278
|
unless property
|
237
279
|
property = @@property_klass.create( :name => find_by_name, :presentation => find_by_name.humanize)
|
@@ -244,8 +286,8 @@ module DataShift
|
|
244
286
|
x = @@product_property_klass.new( :value => find_by_value )
|
245
287
|
x.property = property
|
246
288
|
x.save
|
247
|
-
logger.info "Created New ProductProperty #{x.inspect}"
|
248
289
|
@load_object.product_properties << x
|
290
|
+
logger.info "Created New ProductProperty #{x.inspect}"
|
249
291
|
else
|
250
292
|
@load_object.product_properties << @@product_property_klass.create( :property => property, :value => find_by_values)
|
251
293
|
end
|
@@ -13,7 +13,8 @@
|
|
13
13
|
#
|
14
14
|
# Cmd Line:
|
15
15
|
#
|
16
|
-
# => bundle exec thor datashift
|
16
|
+
# => bundle exec thor list datashift
|
17
|
+
# bundle exec thor help datashift:generate:excel
|
17
18
|
#
|
18
19
|
require 'datashift'
|
19
20
|
|
@@ -49,9 +50,11 @@ module Datashift
|
|
49
50
|
klass = ModelMapper::class_from_string(model) #Kernel.const_get(model)
|
50
51
|
rescue NameError => e
|
51
52
|
puts e
|
52
|
-
raise "ERROR: No such Model [#{model}] found - check valid model supplied
|
53
|
+
raise Thor::Error.new("ERROR: No such Model [#{model}] found - check valid model supplied")
|
53
54
|
end
|
54
55
|
|
56
|
+
raise Thor::Error.new("ERROR: No such Model [#{model}] found - check valid model supplied") unless(klass)
|
57
|
+
|
55
58
|
begin
|
56
59
|
gen = DataShift::ExcelGenerator.new(result)
|
57
60
|
|
@@ -8,6 +8,10 @@
|
|
8
8
|
# bundle exec thor datashift:spreeboot:cleanup
|
9
9
|
#
|
10
10
|
# Note, not DataShift, case sensitive, create namespace for command line : datashift
|
11
|
+
|
12
|
+
require File.expand_path('config/environment.rb')
|
13
|
+
|
14
|
+
|
11
15
|
module Datashift
|
12
16
|
|
13
17
|
class Spreeboot < Thor
|
@@ -22,31 +26,33 @@ module Datashift
|
|
22
26
|
|
23
27
|
require File.expand_path('config/environment.rb')
|
24
28
|
|
29
|
+
ActiveRecord::Base.connection.execute("TRUNCATE spree_products_taxons")
|
30
|
+
|
25
31
|
cleanup = %w{ Image OptionType OptionValue
|
26
32
|
Product Property ProductGroup ProductProperty ProductOptionType
|
27
|
-
Variant Taxonomy Taxon
|
33
|
+
Variant Taxonomy Taxon
|
28
34
|
}
|
29
35
|
|
30
36
|
cleanup.each do |k|
|
31
37
|
klass = DataShift::SpreeHelper::get_spree_class(k)
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
38
|
+
if(klass)
|
39
|
+
puts "Clearing model #{klass}"
|
40
|
+
klass.delete_all
|
41
|
+
else
|
42
|
+
puts "WARNING - Could not find AR model for class name #{k}"
|
43
|
+
end
|
37
44
|
end
|
38
|
-
|
39
|
-
end
|
40
45
|
|
41
|
-
|
42
|
-
puts "Removing old Product assets from 'public/spree/products'"
|
43
|
-
FileUtils::rm_rf('public/public/spree/products')
|
44
|
-
end
|
46
|
+
image_bank = 'public/spree/products'
|
45
47
|
|
46
|
-
|
48
|
+
if(File.exists?(image_bank) )
|
49
|
+
puts "Removing old Product assets from '#{image_bank}'"
|
50
|
+
FileUtils::rm_rf(image_bank)
|
51
|
+
end
|
47
52
|
|
48
|
-
|
53
|
+
FileUtils::rm_rf('MissingRecords') if(File.exists?('MissingRecords') )
|
54
|
+
|
55
|
+
end
|
49
56
|
|
50
|
-
end
|
51
|
-
|
57
|
+
end
|
52
58
|
end
|
@@ -21,7 +21,7 @@ module Datashift
|
|
21
21
|
desc "products", "Populate Spree Product/Variant data from .xls (Excel) or CSV file"
|
22
22
|
|
23
23
|
method_option :input, :aliases => '-i', :required => true, :desc => "The import file (.xls or .csv)"
|
24
|
-
method_option :sku_prefix, :aliases => '-s', :desc => "Prefix to add to each SKU
|
24
|
+
method_option :sku_prefix, :aliases => '-s', :desc => "Prefix to add to each SKU before saving Product"
|
25
25
|
method_option :verbose, :aliases => '-v', :type => :boolean, :desc => "Verbose logging"
|
26
26
|
method_option :config, :aliases => '-c', :type => :string, :desc => "Configuration file containg defaults or over rides in YAML"
|
27
27
|
|
@@ -53,7 +53,12 @@ module Datashift
|
|
53
53
|
|
54
54
|
puts "DataShift::Product starting upload from file: #{input}"
|
55
55
|
|
56
|
-
|
56
|
+
options = {:mandatory => ['sku', 'name', 'price']}
|
57
|
+
|
58
|
+
# In >= 1.1.0 Image moved to master Variant from Product
|
59
|
+
options[:force_inclusion] = ['images'] if(DataShift::SpreeHelper::version.to_f > 1 )
|
60
|
+
|
61
|
+
loader.perform_load(input, options)
|
57
62
|
end
|
58
63
|
|
59
64
|
|
@@ -79,32 +84,36 @@ module Datashift
|
|
79
84
|
|
80
85
|
|
81
86
|
#
|
82
|
-
# =>
|
87
|
+
# => thor datashift:spree:images input=vendor/extensions/site/fixtures/images
|
83
88
|
# => rake datashift:spree:images input=C:\images\photos large dummy=true
|
84
89
|
#
|
85
90
|
# => rake datashift:spree:images input=C:\images\taxon_icons skip_if_no_assoc=true klass=Taxon
|
86
91
|
#
|
87
|
-
desc "images", "Populate the DB with images from a directory
|
92
|
+
desc "images", "Populate the DB with images from a directory\nwhere image names contain somewhere the Product Sku/Name"
|
88
93
|
|
89
94
|
# :dummy => dummy run without actual saving to DB
|
90
|
-
method_option :input, :aliases => '-i', :required => true, :desc => "The
|
91
|
-
|
92
|
-
method_option :process_when_no_assoc, :aliases => '-f', :type => :boolean, :desc => "Process image even if no Product found - force loading"
|
95
|
+
method_option :input, :aliases => '-i', :required => true, :desc => "The input path containing images (.jpg, .gif, .png)"
|
93
96
|
|
97
|
+
method_option :recursive, :aliases => '-r', :type => :boolean, :desc => "Scan sub directories of input for images"
|
98
|
+
|
94
99
|
method_option :sku, :aliases => '-s', :desc => "Lookup Product based on image name starting with sku"
|
95
|
-
method_option :sku_prefix, :aliases => '-p', :desc => "Prefix to add to each SKU in import file"
|
100
|
+
method_option :sku_prefix, :aliases => '-p', :desc => "Prefix to add to each SKU in import file before attempting lookup"
|
96
101
|
method_option :dummy, :aliases => '-d', :type => :boolean, :desc => "Dummy run, do not actually save Image or Product"
|
102
|
+
|
103
|
+
method_option :process_when_no_assoc, :aliases => '-f', :type => :boolean, :desc => "Process image even if no Product found - force loading"
|
104
|
+
method_option :skip_when_assoc, :aliases => '-x', :type => :boolean, :desc => "DO not process image if Product already has image"
|
105
|
+
|
97
106
|
method_option :verbose, :aliases => '-v', :type => :boolean, :desc => "Verbose logging"
|
98
107
|
method_option :config, :aliases => '-c', :type => :string, :desc => "Configuration file for Image Loader in YAML"
|
99
108
|
method_option :split_file_name_on, :type => :string, :desc => "delimiter to progressivley split filename for Prod lookup", :default => '_'
|
100
109
|
method_option :case_sensitive, :type => :boolean, :desc => "Use case sensitive where clause to find Product"
|
101
|
-
method_option :use_like, :type => :boolean, :desc => "Use LIKE 'string%' instead of = 'string' in where clauses"
|
110
|
+
method_option :use_like, :type => :boolean, :desc => "Use sku/name LIKE 'string%' instead of sku/name = 'string' in where clauses to find Product"
|
102
111
|
|
103
112
|
def images()
|
104
113
|
|
105
114
|
require File.expand_path('config/environment.rb')
|
106
115
|
|
107
|
-
require 'image_loader'
|
116
|
+
require 'spree/image_loader'
|
108
117
|
|
109
118
|
@verbose = options[:verbose]
|
110
119
|
|
@@ -116,59 +125,53 @@ module Datashift
|
|
116
125
|
attachment_klazz = DataShift::SpreeHelper::get_spree_class('Product' )
|
117
126
|
attachment_field = 'name'
|
118
127
|
|
119
|
-
if(options[:sku])
|
128
|
+
if(options[:sku] || SpreeHelper::version.to_f > 1)
|
120
129
|
attachment_klazz = DataShift::SpreeHelper::get_spree_class('Variant' )
|
121
130
|
attachment_field = 'sku'
|
122
131
|
end
|
123
|
-
|
124
|
-
# TODO generalise for any paperclip project, for now just Spree
|
125
|
-
#begin
|
126
|
-
# attachment_klazz = Kernel.const_get(args[:model]) if(args[:model])
|
127
|
-
# rescue NameError
|
128
|
-
# raise "Could not find contant for model #{args[:model]}"
|
129
|
-
#end
|
130
132
|
|
131
|
-
image_loader = DataShift::SpreeHelper::ImageLoader.new(nil, options
|
132
|
-
|
133
|
-
@loader_config = {}
|
134
|
-
|
133
|
+
image_loader = DataShift::SpreeHelper::ImageLoader.new(nil, options)
|
134
|
+
|
135
135
|
if(options[:config])
|
136
136
|
raise "Bad Config - Cannot find specified file #{options[:config]}" unless File.exists?(options[:config])
|
137
137
|
|
138
138
|
image_loader.configure_from( options[:config] )
|
139
|
-
|
140
|
-
@loader_config = YAML::load( File.open(options[:config]) )
|
141
|
-
|
142
|
-
@loader_config = @loader_config['ImageLoader']
|
143
139
|
end
|
140
|
+
|
141
|
+
loader_config = image_loader.options
|
142
|
+
|
143
|
+
puts "CONFIG: #{loader_config.inspect}"
|
144
|
+
puts "OPTIONS #{options.inspect}"
|
144
145
|
|
145
|
-
|
146
|
-
|
147
|
-
@image_cache = options[:input]
|
146
|
+
@image_path = options[:input]
|
148
147
|
|
149
|
-
unless(File.
|
150
|
-
puts "ERROR: Supplied Path #{@
|
148
|
+
unless(File.exists?(@image_path))
|
149
|
+
puts "ERROR: Supplied Path [#{@image_path}] not accesible"
|
151
150
|
exit(-1)
|
152
151
|
end
|
153
152
|
|
154
|
-
logger.info "Loading Spree images from #{@
|
153
|
+
logger.info "Loading Spree images from #{@image_path}"
|
155
154
|
|
156
155
|
missing_records = []
|
157
156
|
|
158
|
-
#
|
159
|
-
split_on =
|
160
|
-
|
161
|
-
|
157
|
+
# try splitting up filename in various ways looking for the SKU
|
158
|
+
split_on = loader_config['split_file_name_on'] || options[:split_file_name_on]
|
159
|
+
|
160
|
+
puts "Will scan image names splitting on delimiter : #{split_on}"
|
161
|
+
|
162
|
+
image_cache = DataShift::ImageLoading::get_files(@image_path, options)
|
163
|
+
|
164
|
+
image_cache.each do |image_name|
|
162
165
|
|
166
|
+
image_base_name = File.basename(image_name)
|
167
|
+
|
163
168
|
base_name = File.basename(image_name, '.*')
|
164
169
|
base_name.strip!
|
165
170
|
|
166
171
|
logger.info "Processing image file #{base_name} : #{File.exists?(image_name)}"
|
167
172
|
|
168
173
|
record = nil
|
169
|
-
|
170
|
-
puts "Search for product for image file [#{base_name}]" if(@verbose)
|
171
|
-
|
174
|
+
|
172
175
|
record = image_loader.get_record_by(attachment_klazz, attachment_field, base_name)
|
173
176
|
|
174
177
|
# try seperate portions of the filename, front -> back
|
@@ -189,11 +192,17 @@ module Datashift
|
|
189
192
|
if(record)
|
190
193
|
logger.info "Found record for attachment : #{record.inspect}"
|
191
194
|
|
192
|
-
if(options[:
|
193
|
-
exists = record.images.detect {|i| i.attachment_file_name == image_name }
|
195
|
+
if(options[:skip_when_assoc])
|
194
196
|
|
195
|
-
|
196
|
-
|
197
|
+
paper_clip_name = image_base_name.gsub(Paperclip::Attachment::default_options[:restricted_characters], '_')
|
198
|
+
|
199
|
+
exists = record.images.detect {|i| puts "Check #{paper_clip_name} matches #{i.attachment_file_name}"; i.attachment_file_name == paper_clip_name }
|
200
|
+
if(exists)
|
201
|
+
rid = record.respond_to?(:name) ? record.name : record.id
|
202
|
+
puts "Skipping Image #{image_name} already loaded for #{rid}"
|
203
|
+
logger.info "Skipping - Image #{image_name} already loaded for #{attachment_klazz}"
|
204
|
+
next
|
205
|
+
end
|
197
206
|
end
|
198
207
|
else
|
199
208
|
missing_records << image_name
|
@@ -204,9 +213,10 @@ module Datashift
|
|
204
213
|
# Check if Image must have an associated record
|
205
214
|
if(record || (record.nil? && options[:process_when_no_assoc]))
|
206
215
|
image_loader.reset()
|
207
|
-
|
216
|
+
|
208
217
|
logger.info("Adding Image #{image_name} to Product #{record.name}")
|
209
218
|
image_loader.create_image(image_klazz, image_name, record)
|
219
|
+
puts "Added Image #{File.basename(image_name)} to Product #{record.sku} : #{record.name}" if(@verbose)
|
210
220
|
end
|
211
221
|
|
212
222
|
end
|
@@ -214,11 +224,14 @@ module Datashift
|
|
214
224
|
unless missing_records.empty?
|
215
225
|
FileUtils.mkdir_p('MissingRecords') unless File.directory?('MissingRecords')
|
216
226
|
|
217
|
-
puts
|
227
|
+
puts "WARNING : #{missing_records.size} of #{image_cache.size} images could not be attached to a Product"
|
228
|
+
puts 'Copying all images with MISSING Records to ./MissingRecords >>'
|
218
229
|
missing_records.each do |i|
|
219
230
|
puts "Copy #{i} to MissingRecords folder"
|
220
231
|
FileUtils.cp( i, 'MissingRecords') unless(options[:dummy] == 'true')
|
221
232
|
end
|
233
|
+
else
|
234
|
+
puts "All images (#{image_cache.size}) were succesfully attached to a Product"
|
222
235
|
end
|
223
236
|
|
224
237
|
puts "Dummy Run Complete- if happy run without -d" if(options[:dummy])
|