datashift 0.7.0 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- 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])
|