datashift 0.2.2 → 0.4.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.
Files changed (38) hide show
  1. data/README.markdown +15 -3
  2. data/VERSION +1 -1
  3. data/datashift.gemspec +11 -3
  4. data/lib/applications/jruby/jexcel_file.rb +10 -3
  5. data/lib/datashift.rb +25 -62
  6. data/lib/datashift/exceptions.rb +1 -0
  7. data/lib/datashift/logging.rb +58 -0
  8. data/lib/datashift/method_detail.rb +6 -45
  9. data/lib/datashift/method_details_manager.rb +54 -0
  10. data/lib/datashift/method_dictionary.rb +6 -1
  11. data/lib/datashift/method_mapper.rb +12 -5
  12. data/lib/datashift/populator.rb +46 -0
  13. data/lib/exporters/excel_exporter.rb +1 -1
  14. data/lib/generators/excel_generator.rb +48 -44
  15. data/lib/helpers/spree_helper.rb +14 -3
  16. data/lib/loaders/csv_loader.rb +9 -6
  17. data/lib/loaders/excel_loader.rb +5 -1
  18. data/lib/loaders/loader_base.rb +28 -14
  19. data/lib/loaders/spree/image_loader.rb +36 -34
  20. data/lib/loaders/spree/product_loader.rb +17 -7
  21. data/lib/thor/generate_excel.thor +35 -15
  22. data/lib/thor/import_excel.thor +84 -0
  23. data/lib/thor/spree/bootstrap_cleanup.thor +33 -0
  24. data/lib/thor/spree/products_images.thor +171 -0
  25. data/spec/datashift_spec.rb +19 -0
  26. data/spec/excel_exporter_spec.rb +3 -3
  27. data/spec/fixtures/datashift_Spree_db.sqlite +0 -0
  28. data/spec/fixtures/datashift_test_models_db.sqlite +0 -0
  29. data/spec/fixtures/spree/SpreeProductsDefaults.yml +15 -0
  30. data/spec/fixtures/spree/SpreeProductsMandatoryOnly.xls +0 -0
  31. data/spec/fixtures/spree/SpreeProductsWithImages.xls +0 -0
  32. data/spec/spec_helper.rb +2 -2
  33. data/spec/spree_generator_spec.rb +14 -0
  34. data/spec/spree_images_loader_spec.rb +73 -0
  35. data/spec/spree_loader_spec.rb +53 -19
  36. data/tasks/spree/image_load.rake +18 -13
  37. metadata +11 -3
  38. data/tasks/spree/product_loader.rake +0 -44
@@ -7,62 +7,64 @@ require 'loader_base'
7
7
 
8
8
  module DataShift
9
9
 
10
- module ImageLoading
10
+
11
+ module ImageLoading
11
12
 
13
+ include DataShift::Logging
14
+
12
15
  # Note the Spree Image model sets default storage path to
13
16
  # => :path => ":rails_root/public/assets/products/:id/:style/:basename.:extension"
14
17
 
15
- def create_image(image_path, viewable_record = nil, options = {})
16
-
17
- @@image_klass ||= SpreeHelper::get_spree_class('Image')
18
-
19
- image = @@image_klass.new
20
-
21
- unless File.exists?(image_path)
22
- puts "ERROR : Invalid Path"
23
- return image
18
+ def create_image(klass, image_path, viewable_record = nil, options = {})
19
+
20
+ unless File.exists?(image_path) && File.readable?(image_path)
21
+ logger.error("Cannot process Image : Invalid Path #{image_path}")
22
+ raise "Cannot process Image : Invalid Path #{image_path}"
24
23
  end
25
-
24
+
26
25
  alt = if(options[:alt])
27
26
  options[:alt]
28
27
  else
29
28
  (viewable_record and viewable_record.respond_to? :name) ? viewable_record.name : ""
30
29
  end
31
-
32
- image.alt = alt
33
-
34
- begin
35
- image.attachment = File.new(image_path, "r")
30
+
31
+ file = begin
32
+ File.new(image_path, "rb")
36
33
  rescue => e
37
34
  puts e.inspect
38
- puts "ERROR : Failed to read image #{image_path}"
39
- return image
35
+ raise "ERROR : Failed to read image #{image_path}"
40
36
  end
41
37
 
42
- image.attachment.reprocess!
43
- image.viewable = viewable_record if viewable_record
38
+ position = (viewable_record and viewable_record.respond_to?(:images)) ? viewable_record.images.length : 0
39
+
40
+ image = klass.new( :attachment => file,:viewable => viewable_record, :alt => alt, :position => position)
41
+ #image.attachment.reprocess!
42
+
43
+ #image.viewable = viewable_record if viewable_record
44
44
 
45
45
  puts image.save ? "Success: Created Image: #{image.inspect}" : "ERROR : Problem saving to DB Image: #{image.inspect}"
46
46
  end
47
47
  end
48
-
49
- class ImageLoader < LoaderBase
50
48
 
51
- include DataShift::ImageLoading
49
+ module SpreeHelper
50
+
51
+ class ImageLoader < LoaderBase
52
+
53
+ include DataShift::ImageLoading
54
+
55
+ def initialize(image = nil)
56
+ puts SpreeHelper::get_spree_class('Image')
52
57
 
53
- def initialize(image = nil)
54
- @@image_klass ||= SpreeHelper::get_spree_class('Image')
58
+ @@image_klass ||= SpreeHelper::get_spree_class('Image')
55
59
 
56
- super( @@image_klass, image )
57
- raise "Failed to create Image for loading" unless @load_object
58
- end
59
-
60
- # Note the Spree Image model sets default storage path to
61
- # => :path => ":rails_root/public/assets/products/:id/:style/:basename.:extension"
60
+ super( @@image_klass, image )
61
+ raise "Failed to create Image for loading" unless @load_object
62
+ end
62
63
 
63
- def process( image_path, record = nil)
64
- @load_object = create_image(path, record)
64
+ # The path to the physical image on local disk
65
+ def process(image_path, record = nil)
66
+ @load_object = create_image(@@image_klass, image_path, record)
67
+ end
65
68
  end
66
69
  end
67
-
68
70
  end
@@ -25,6 +25,7 @@ module DataShift
25
25
  def initialize(product = nil)
26
26
  super( SpreeHelper::get_product_class(), product, :instance_methods => true )
27
27
 
28
+ @@image_klass ||= SpreeHelper::get_spree_class('Image')
28
29
  @@option_type_klass ||= SpreeHelper::get_spree_class('OptionType')
29
30
  @@option_value_klass ||= SpreeHelper::get_spree_class('OptionValue')
30
31
  @@property_klass ||= SpreeHelper::get_spree_class('Property')
@@ -42,6 +43,8 @@ module DataShift
42
43
  # CSV files
43
44
  def perform_load( file_name, options = {} )
44
45
 
46
+ raise DataShift::BadFile, "Cannot load #{file_name} file not found." unless(File.exists?(file_name))
47
+
45
48
  ext = File.extname(file_name)
46
49
 
47
50
  if(ext == '.xls')
@@ -50,7 +53,7 @@ module DataShift
50
53
  elsif(ext == '.csv')
51
54
  perform_csv_load(file_name, options)
52
55
  else
53
- raise DataShift::UnsupportedFileType, "#{ext} files not supported - Try CSV or OpenOffice/Excel .xls"
56
+ raise DataShift::UnsupportedFileType, "#{ext} files not supported - Try .csv or OpenOffice/Excel .xls"
54
57
  end
55
58
  end
56
59
 
@@ -95,7 +98,7 @@ module DataShift
95
98
 
96
99
  # Spree has some stock management stuff going on, so dont usually assign to column vut use
97
100
  # on_hand and on_hand=
98
- if(@load_object.variants.size > 0 && current_value.include?(LoaderBase::multi_assoc_delim))
101
+ if(@load_object.variants.size > 0 && current_value.to_s.include?(LoaderBase::multi_assoc_delim))
99
102
 
100
103
  #puts "DEBUG: COUNT_ON_HAND PER VARIANT",current_value.is_a?(String),
101
104
 
@@ -118,6 +121,13 @@ module DataShift
118
121
  end
119
122
 
120
123
  private
124
+
125
+ # Take current column data and split into each association
126
+ # Supported Syntax :
127
+ # assoc_find_name:value | assoc2_find_name:value | etc
128
+ def get_each_assoc
129
+ current_value.to_s.split( LoaderBase::multi_assoc_delim )
130
+ end
121
131
 
122
132
  # Special case for OptionTypes as it's two stage process
123
133
  # First add the possible option_types to Product, then we are able
@@ -128,7 +138,7 @@ module DataShift
128
138
  # TODO smart column ordering to ensure always valid by time we get to associations
129
139
  save_if_new
130
140
 
131
- option_types = current_value.split( LoaderBase::multi_assoc_delim )
141
+ option_types = get_each_assoc#current_value.split( LoaderBase::multi_assoc_delim )
132
142
 
133
143
  option_types.each do |ostr|
134
144
  oname, value_str = ostr.split(LoaderBase::name_value_delim)
@@ -182,13 +192,13 @@ module DataShift
182
192
  # TODO smart column ordering to ensure always valid by time we get to associations
183
193
  save_if_new
184
194
 
185
- images = current_value.split(LoaderBase::multi_assoc_delim)
195
+ images = get_each_assoc#current_value.split(LoaderBase::multi_assoc_delim)
186
196
 
187
197
  images.each do |image|
188
198
 
189
199
  img_path, alt_text = image.split(LoaderBase::name_value_delim)
190
200
 
191
- image = create_image(img_path, @load_object, :alt => alt_text)
201
+ image = create_image(@@image_klass, img_path, @load_object, :alt => alt_text)
192
202
  end
193
203
 
194
204
  end
@@ -202,7 +212,7 @@ module DataShift
202
212
  # TODO smart column ordering to ensure always valid by time we get to associations
203
213
  save_if_new
204
214
 
205
- property_list = current_value.split(LoaderBase::multi_assoc_delim)
215
+ property_list = get_each_assoc#current_value.split(LoaderBase::multi_assoc_delim)
206
216
 
207
217
  property_list.each do |pstr|
208
218
  pname, pvalue = pstr.split(LoaderBase::name_value_delim)
@@ -244,7 +254,7 @@ module DataShift
244
254
  # TODO smart column ordering to ensure always valid by time we get to associations
245
255
  save_if_new
246
256
 
247
- chain_list = current_value().split(LoaderBase::multi_assoc_delim)
257
+ chain_list = get_each_assoc#current_value().split(LoaderBase::multi_assoc_delim)
248
258
 
249
259
  chain_list.each do |chain|
250
260
 
@@ -3,7 +3,6 @@
3
3
  # Date :: Mar 2012
4
4
  # License:: MIT.
5
5
  #
6
- #
7
6
  # Usage::
8
7
  #
9
8
  # To pull Datashift commands into your main application :
@@ -14,29 +13,37 @@
14
13
  #
15
14
  # Cmd Line:
16
15
  #
17
- # => bundle exec thor datashift:generate:excel --model <active record class> --result <output_template.xls>
16
+ # => bundle exec thor datashift:generate:excel -m <active record class> -r <output_template.xls> -a
18
17
  #
19
-
18
+ require 'datashift'
19
+
20
+ # Note, not DataShift, case sensitive, create namespace for command line : datashift
20
21
  module Datashift
21
-
22
+
23
+
22
24
  class Generate < Thor
23
-
24
- desc "excel --model <Class> --result <file.xls>", "generate a template from an active record model"
25
+
26
+ include DataShift::Logging
27
+
28
+ desc "excel", "generate a template from an active record model (with optional associations)"
25
29
  method_option :model, :aliases => '-m', :required => true, :desc => "The active record model to export"
26
30
  method_option :result, :aliases => '-r', :required => true, :desc => "Create template of model in supplied file"
31
+ method_option :assoc, :aliases => '-a', :type => :boolean, :desc => "Include all associations in the template"
32
+ method_option :exclude, :aliases => '-e', :type => :array, :desc => "Use with -a : Exclude association types. Any from #{DataShift::MethodDetail::supported_types_enum.to_a.inspect}"
27
33
 
28
34
  def excel()
29
35
 
30
- # TODO - We're assuming run from a rails app/top level dir...
31
- # ...can we make this more robust ? e.g what about when using active record but not in Rails app,
32
- require File.expand_path('config/environment.rb')
33
-
34
-
35
- require 'excel_generator'
36
+ # TODO - We're assuming run from a rails app/top level dir...
37
+ # ...can we make this more robust ? e.g what about when using active record but not in Rails app,
38
+ require File.expand_path('config/environment.rb')
39
+
40
+ require 'excel_generator'
36
41
 
37
42
  model = options[:model]
38
43
  result = options[:result]
39
-
44
+
45
+ logger.info "Datashift: Start Excel template generation in #{result}"
46
+
40
47
  begin
41
48
  # support modules e.g "Spree::Property")
42
49
  klass = ModelMapper::class_from_string(model) #Kernel.const_get(model)
@@ -45,9 +52,22 @@ module Datashift
45
52
  raise "ERROR: No such Model [#{model}] found - check valid model supplied via -model <Class>"
46
53
  end
47
54
 
48
- gen = DataShift::ExcelGenerator.new(result)
55
+ begin
56
+ gen = DataShift::ExcelGenerator.new(result)
57
+
58
+ if(options[:assoc])
59
+ opts = (options[:exclude]) ? {:exclude => options[:exclude]} : {}
60
+ logger.info("Datashift: Generating with associations")
61
+ gen.generate_with_associations(klass, opts)
62
+ else
63
+ gen.generate(klass)
64
+ end
65
+ rescue => e
66
+ puts e
67
+ puts e.backtrace
68
+ puts "Warning: Error during generation, template may be incomplete"
69
+ end
49
70
 
50
- gen.generate(klass)
51
71
  end
52
72
  end
53
73
 
@@ -0,0 +1,84 @@
1
+ # Copyright:: (c) Autotelik Media Ltd 2012
2
+ # Author :: Tom Statter
3
+ # Date :: Mar 2012
4
+ # License:: MIT.
5
+ #
6
+ # Usage::
7
+ #
8
+ # To pull Datashift commands into your main application :
9
+ #
10
+ # require 'datashift'
11
+ #
12
+ # DataShift::load_commands
13
+ #
14
+ # Requires Jruby, cmd Line:
15
+ #
16
+ # => bundle exec thor datashift:import:excel -m <active record class> -r <output_template.xls> -a
17
+ #
18
+ # Cmd Line:
19
+ #
20
+ # => jruby -S rake datashift:import:excel model=<active record class> input=<file.xls>
21
+ # => jruby -S rake datashift:import:excel model=<active record class> input=C:\MyProducts.xlsverbose=true
22
+ #
23
+ require 'datashift'
24
+
25
+
26
+ # Note, not DataShift, case sensitive, create namespace for command line : datashift
27
+ module Datashift
28
+
29
+
30
+ class Import < Thor
31
+
32
+ include DataShift::Logging
33
+
34
+ desc "excel", "import .xls file for specifiec active record model"
35
+ method_option :model, :aliases => '-m', :required => true, :desc => "The related active record model"
36
+ method_option :input, :aliases => '-i', :required => true, :desc => "The input .xls file"
37
+ method_option :assoc, :aliases => '-a', :type => :boolean, :desc => "Include any associations supplied in the input"
38
+ method_option :exclude, :aliases => '-e', :type => :array, :desc => "Use with -a : Exclude association types. Any from #{DataShift::MethodDetail::supported_types_enum.to_a.inspect}"
39
+
40
+ def excel()
41
+
42
+ # TODO - We're assuming run from a rails app/top level dir...
43
+ # ...can we make this more robust ? e.g what about when using active record but not in Rails app,
44
+ require File.expand_path('config/environment.rb')
45
+
46
+ require 'excel_loader'
47
+
48
+ model = options[:model]
49
+ begin
50
+ # support modules e.g "Spree::Property")
51
+ klass = ModelMapper::class_from_string(model) #Kernel.const_get(model)
52
+ rescue NameError
53
+ raise "ERROR: No such AR Model found - check valid model supplied via model=<Class>"
54
+ end
55
+
56
+ if(ENV['loader'])
57
+ begin
58
+ #loader_klass = Kernel.const_get(ENV['loader'])
59
+ # support modules e.g "Spree::Property")
60
+ loader_klass = ModelMapper::class_from_string(ENV['loader']) #Kernel.const_get(model)
61
+
62
+ loader = loader_klass.new(klass)
63
+
64
+ logger.info("INFO: Using loader : #{loader.class}")
65
+ rescue
66
+ logger.error("INFO: No specific #{model}Loader found - using generic ExcelLoader")
67
+ loader = DataShift::ExcelLoader.new(klass)
68
+ end
69
+ else
70
+ logger.info("No Loader specified - using generic ExcelLoader")
71
+ loader = DataShift::ExcelLoader.new(klass)
72
+ end
73
+
74
+ logger.info("ARGS #{options.inspect} [#{options[:verbose]}]")
75
+ loader.logger.verbose if(ENV['verbose'])
76
+
77
+ loader.configure_from( ENV['config'] ) if(ENV['config'])
78
+
79
+ loader.perform_load(options[:input])
80
+ end
81
+ end
82
+
83
+ end
84
+
@@ -0,0 +1,33 @@
1
+ # Copyright:: (c) Autotelik Media Ltd 2012
2
+ # Author :: Tom Statter
3
+ # Date :: March 2012
4
+ # License:: MIT. Free, Open Source.
5
+ #
6
+ # Usage::
7
+ # bundle exec thor help datashift:spreeboot
8
+ # bundle exec thor datashift:spreeboot:cleanup
9
+ #
10
+ # Note, not DataShift, case sensitive, create namespace for command line : datashift
11
+ module Datashift
12
+
13
+ class Spreeboot < Thor
14
+
15
+ include DataShift::Logging
16
+
17
+ desc "cleanup", "Remove Spree Product/Variant data from DB"
18
+
19
+ def cleanup() #, [:input, :verbose, :sku_prefix] => :environment do |t, args|
20
+
21
+ require 'spree_helper'
22
+
23
+ require File.expand_path('config/environment.rb')
24
+
25
+ %w{Image OptionType OptionValue Product Property ProductProperty Variant Taxonomy Taxon Zone}.each do |k|
26
+ instance_variable_set("@#{k}_klass", DataShift::SpreeHelper::get_spree_class(k))
27
+ instance_variable_get("@#{k}_klass").delete_all
28
+ end
29
+ end
30
+
31
+ end
32
+
33
+ end
@@ -0,0 +1,171 @@
1
+ # Copyright:: (c) Autotelik Media Ltd 2012
2
+ # Author :: Tom Statter
3
+ # Date :: March 2012
4
+ # License:: MIT. Free, Open Source.
5
+ #
6
+ # Usage::
7
+ # bundle exec thor help datashift:spree
8
+ # bundle exec thor datashift:spree:products -i db/datashift/MegamanFozz20111115_load.xls -s 299S_
9
+ #
10
+ # bundle exec thor datashift:spree:images -i db/datashift/imagebank -s -p 299S_
11
+ #
12
+
13
+ # Note, not DataShift, case sensitive, create namespace for command line : datashift
14
+ module Datashift
15
+
16
+ class Spree < Thor
17
+
18
+ include DataShift::Logging
19
+
20
+ desc "products", "Populate Spree Product/Variant data from .xls (Excel) or CSV file"
21
+
22
+ method_option :input, :aliases => '-i', :required => true, :desc => "The import file (.xls or .csv)"
23
+ method_option :sku_prefix, :aliases => '-s', :desc => "Prefix to add to each SKU in import file"
24
+ method_option :verbose, :aliases => '-v', :type => :boolean, :desc => "Verbose logging"
25
+ method_option :config, :aliases => '-c', :type => :string, :desc => "Configuration file containg defaults or over rides in YAML"
26
+
27
+ def products() #, [:input, :verbose, :sku_prefix] => :environment do |t, args|
28
+
29
+ # TODO - We're assuming run from a rails app/top level dir...
30
+ # ...can we make this more robust ? e.g what about when using active record but not in Rails app,
31
+ require File.expand_path('config/environment.rb')
32
+
33
+ input = options[:input]
34
+
35
+ require 'product_loader'
36
+
37
+ loader = DataShift::SpreeHelper::ProductLoader.new
38
+
39
+ # YAML configuration file to drive defaults etc
40
+
41
+ if(options[:config])
42
+ raise "Bad Config - Cannot find specified file #{options[:config]}" unless File.exists?(options[:config])
43
+
44
+ loader.configure_from( options[:config] )
45
+ else
46
+ loader.set_default_value('available_on', Time.now.to_s(:db) )
47
+ loader.set_default_value('cost_price', 0.0 )
48
+ end
49
+
50
+ loader.set_prefix('sku', options[:sku_prefix] ) if(options[:sku_prefix])
51
+
52
+ puts "DataShift::Product starting upload from file: #{input}"
53
+
54
+ loader.perform_load(input, :mandatory => ['sku', 'name', 'price'] )
55
+ end
56
+
57
+
58
+ #
59
+ # => rake datashift:spree:images input=vendor/extensions/site/fixtures/images
60
+ # => rake datashift:spree:images input=C:\images\photos large dummy=true
61
+ #
62
+ # => rake datashift:spree:images input=C:\images\taxon_icons skip_if_no_assoc=true klass=Taxon
63
+ #
64
+ desc "images", "Populate the DB with images.\nDefault location db/image_seeds, or specify :input=<path> or dir under db/image_seeds with :folder"
65
+
66
+ # :dummy => dummy run without actual saving to DB
67
+ method_option :input, :aliases => '-i', :required => true, :desc => "The import file (.xls or .csv)"
68
+
69
+ method_option :process_when_no_assoc, :aliases => '-f', :type => :boolean, :desc => "Process image even if no Product found - force loading"
70
+
71
+
72
+ method_option :sku, :aliases => '-s', :desc => "Lookup Product based on image name starting with sku"
73
+ method_option :sku_prefix, :aliases => '-p', :desc => "Prefix to add to each SKU in import file"
74
+ method_option :dummy, :aliases => '-d', :type => :boolean, :desc => "Dummy run, do not actually save Image or Product"
75
+ method_option :verbose, :aliases => '-v', :type => :boolean, :desc => "Verbose logging"
76
+ #method_option :config, :aliases => '-c', :type => :string, :desc => "Configuration file containg defaults or over rides in YAML"
77
+
78
+ def images()#, [:input, :folder, :dummy, :sku, :skip_if_no_assoc, :skip_if_loaded, :model] => :environment do |t, args|
79
+
80
+ require File.expand_path('config/environment.rb')
81
+
82
+ require 'image_loader'
83
+
84
+ @image_cache = options[:input]
85
+
86
+ attachment_klazz = DataShift::SpreeHelper::get_spree_class('Product' )
87
+ sku_klazz = DataShift::SpreeHelper::get_spree_class('Variant' )
88
+
89
+ # TODO generalise for any paperclip project, for now just Spree
90
+ #begin
91
+ # attachment_klazz = Kernel.const_get(args[:model]) if(args[:model])
92
+ # rescue NameError
93
+ # raise "Could not find contant for model #{args[:model]}"
94
+ #end
95
+
96
+ image_loader = DataShift::SpreeHelper::ImageLoader.new
97
+
98
+ if(File.directory? @image_cache )
99
+ logger.info "Loading Spree images from #{@image_cache}"
100
+
101
+ missing_records = []
102
+ Dir.glob("#{@image_cache}/**/*.{jpg,png,gif}") do |image_name|
103
+
104
+ base_name = File.basename(image_name, '.*')
105
+
106
+ logger.info "Processing #{base_name} : #{File.exists?(image_name)}"
107
+
108
+ record = nil
109
+ if(options[:sku])
110
+ sku = base_name.slice!(/\w+/)
111
+ sku.strip!
112
+ base_name.strip!
113
+
114
+ sku = "#{options[:sku_prefix]}#{sku}" if(options[:sku_prefix])
115
+
116
+ record = sku_klazz.find_by_sku(sku)
117
+
118
+ unless record # try splitting up filename in various ways looking for the SKU
119
+ sku.split( '_' ).each do |x|
120
+ x = "#{options[:sku_prefix]}#{x}" if(options[:sku_prefix])
121
+ record = sku_klazz.find_by_sku(x)
122
+ break if record
123
+ end
124
+ end
125
+
126
+ record = record.product if(record) # SKU stored on Variant but we want it's master Product
127
+
128
+ else
129
+ record = attachment_klazz.find_by_name(base_name)
130
+ end
131
+
132
+ if(record)
133
+ logger.info "Found record for attachment : #{record.inspect}"
134
+ exists = record.images.detect {|i| puts "COMPARE #{i.attachment_file_name} => #{image_name}"; i.attachment_file_name == image_name }
135
+
136
+ if(options[:skip_if_loaded] && !exists.nil?)
137
+ logger.info "Skipping - Image #{image_name} already loaded for #{attachment_klazz}"
138
+ next
139
+ end
140
+ else
141
+ missing_records << image_name
142
+ end
143
+
144
+ # Now do actual upload to DB unless we are doing a dummy run,
145
+ # or the Image must have an associated record
146
+ unless(options[:dummy] == 'true' || (options[:process_when_no_assoc] && record.nil?))
147
+ image_loader.reset()
148
+ puts "Process Image"
149
+ image_loader.process( image_name, record )
150
+ end
151
+
152
+ end
153
+
154
+ unless missing_records.empty?
155
+ FileUtils.mkdir_p('MissingRecords') unless File.directory?('MissingRecords')
156
+
157
+ puts '\nMISSING Records Report>>'
158
+ missing_records.each do |i|
159
+ puts "Copy #{i} to MissingRecords folder"
160
+ FileUtils.cp( i, 'MissingRecords') unless(options[:dummy] == 'true')
161
+ end
162
+ end
163
+
164
+ else
165
+ puts "ERROR: Supplied Path #{@image_cache} not accesible"
166
+ exit(-1)
167
+ end
168
+ end
169
+ end
170
+
171
+ end