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
@@ -23,5 +23,24 @@ describe 'DataShift' do
23
23
  it "should provide root_path" do
24
24
  DataShift.root_path.should_not be_empty
25
25
  end
26
+
27
+ it "should provide a log" do
28
+ class Blah
29
+ include DataShift::Logging
30
+
31
+ def try_me
32
+ logger.info "hello datashift spec"
33
+ end
34
+ end
35
+
36
+
37
+ b = Blah.new()
38
+
39
+ b.logger.info "try me"
40
+
41
+ b.try_me
42
+
43
+
44
+ end
26
45
 
27
46
  end
@@ -38,7 +38,7 @@ if(Guards::jruby?)
38
38
  end
39
39
 
40
40
  it "should be able to create a new excel generator" do
41
- generator = ExcelGenerator.new( 'dummy.xls' )
41
+ generator = ExcelExporter.new( 'dummy.xls' )
42
42
 
43
43
  generator.should_not be_nil
44
44
  end
@@ -47,7 +47,7 @@ if(Guards::jruby?)
47
47
 
48
48
  expect = result_file('project_template_spec.xls')
49
49
 
50
- gen = ExcelGenerator.new( expect )
50
+ gen = ExcelExporter.new( expect )
51
51
 
52
52
  gen.generate(Project)
53
53
 
@@ -75,5 +75,5 @@ if(Guards::jruby?)
75
75
 
76
76
  end
77
77
  else
78
- puts "WARNING: skipped excel_generator_spec : Requires JRUBY - JExcelFile requires JAVA"
78
+ puts "WARNING: skipped excel_exporter_spec : Requires JRUBY - JExcelFile requires JAVA"
79
79
  end # jruby
@@ -0,0 +1,15 @@
1
+ ## YAML Template.
2
+
3
+ # Format is :
4
+ # --- !ruby/object:ActiveRecordModel
5
+ # :datashift_defaults
6
+ # key: value
7
+ #
8
+
9
+ Spree::Product:
10
+ datashift_defaults:
11
+ available_on: Time.now.to_s(:db)
12
+ cost_price: 1.0
13
+ meta_description: 'super duper meta desc.'
14
+ meta_keywords: 'techno dubstep d&b'
15
+
data/spec/spec_helper.rb CHANGED
@@ -5,7 +5,7 @@ require File.dirname(__FILE__) + '/../lib/datashift'
5
5
 
6
6
  include DataShift
7
7
 
8
- #.# Copyright:: (c) Autotelik Media Ltd 2011
8
+ # Copyright:: (c) Autotelik Media Ltd 2011
9
9
  # Author :: Tom Statter
10
10
  # Date :: Aug 2011
11
11
  # License:: MIT
@@ -128,7 +128,7 @@ module SpecHelper
128
128
  @Taxon_klass.delete_all
129
129
  @zone_klass.delete_all
130
130
 
131
- %w{OptionType OptionValue Property ProductProperty Variant Taxonomy}.each do |k|
131
+ %w{Image OptionType OptionValue Property ProductProperty Variant Taxonomy}.each do |k|
132
132
  instance_variable_set("@#{k}_klass", SpreeHelper::get_spree_class(k))
133
133
  instance_variable_get("@#{k}_klass").delete_all
134
134
  end
@@ -75,4 +75,18 @@ describe 'SpreeLoader' do
75
75
 
76
76
  end
77
77
 
78
+ it "should be able to exclude single associations from template" do
79
+
80
+ expect = result_file('product_and_assoc_export_spec.xls')
81
+
82
+ excel = ExcelGenerator.new(expect)
83
+
84
+ excel.generate_with_associations(@klass, :exclude => :has_many)
85
+
86
+ File.exists?(expect).should be_true
87
+
88
+ puts "You can check results manually in file #{expect}"
89
+
90
+ end
91
+
78
92
  end
@@ -0,0 +1,73 @@
1
+ # Copyright:: (c) Autotelik Media Ltd 2011
2
+ # Author :: Tom Statter
3
+ # Date :: Summer 2011
4
+ #
5
+ # License:: MIT - Free, OpenSource
6
+ #
7
+ # Details:: Specification for Spree aspect of datashift gem.
8
+ #
9
+ # Provides Loaders and rake tasks specifically tailored for uploading or exporting
10
+ # Spree Products, associations and Images
11
+ #
12
+ require File.dirname(__FILE__) + '/spec_helper'
13
+
14
+ require 'spree_helper'
15
+ require 'product_loader'
16
+
17
+ include DataShift
18
+
19
+ describe 'SpreeLoader' do
20
+
21
+
22
+ before(:all) do
23
+ SpecHelper::before_all_spree
24
+ end
25
+
26
+ before(:each) do
27
+
28
+ begin
29
+
30
+ include SpecHelper
31
+ extend SpecHelper
32
+
33
+ before_each_spree
34
+
35
+ @klass.count.should == 0
36
+
37
+ MethodDictionary.clear
38
+ MethodDictionary.find_operators( @klass )
39
+
40
+ @product_loader = DataShift::SpreeHelper::ProductLoader.new
41
+ rescue => e
42
+ puts e.inspect
43
+ puts e.backtrace
44
+ end
45
+ end
46
+
47
+
48
+ it "should load Products with associated image" do
49
+
50
+ @product_loader.perform_load( SpecHelper::spree_fixture('SpreeProductsWithImages.csv'), :mandatory => ['sku', 'name', 'price'] )
51
+
52
+ p = @klass.find_by_name("Demo Product for AR Loader")
53
+
54
+ p.name.should == "Demo Product for AR Loader"
55
+ p.images.should have_exactly(1).items
56
+
57
+ @klass.all.each {|p| p.images.should have_exactly(1).items }
58
+ end
59
+
60
+
61
+ it "should be able to assign Images to preloaded Products" do
62
+
63
+ @product_loader.perform_load( SpecHelper::spree_fixture('SpreeProductsMultiColumn.csv'), :mandatory => ['sku', 'name', 'price'] )
64
+
65
+ @Image_klass.all.size.should == 0
66
+
67
+ @klass.all.each {|p| p.images.should have_exactly(0).items }
68
+
69
+ loader = DataShift::SpreeHelper::ImageLoader.new
70
+
71
+ end
72
+
73
+ end
@@ -83,12 +83,16 @@ describe 'SpreeLoader' do
83
83
  test_basic_product('SpreeProductsSimple.xls')
84
84
  end
85
85
 
86
- it "should load basic Products from .csv via Spree loader" do
86
+ it "should load basic Products from .csv via Spree loader", :csv => true do
87
87
  test_basic_product('SpreeProductsSimple.csv')
88
88
  end
89
89
 
90
+ it "should raise an error for missing file" do
91
+ lambda { test_basic_product('SpreeProductsSimple.txt') }.should raise_error BadFile
92
+ end
93
+
90
94
  it "should raise an error for unsupported file types" do
91
- lambda { test_basic_product('SpreeProductsSimple.xml') }.should raise_error UnsupportedFileType
95
+ lambda { test_basic_product('SpreeProductsDefaults.yml') }.should raise_error UnsupportedFileType
92
96
  end
93
97
 
94
98
  def test_basic_product( source )
@@ -116,6 +120,53 @@ describe 'SpreeLoader' do
116
120
  @klass.last.count_on_hand.should == 23
117
121
  end
118
122
 
123
+
124
+ it "should support default values for Spree Products loader", :fail => true do
125
+
126
+ @expected_time = Time.now.to_s(:db)
127
+
128
+ @product_loader.set_default_value('available_on', @expected_time)
129
+ @product_loader.set_default_value('cost_price', 1.0 )
130
+ @product_loader.set_default_value('meta_description', 'super duper meta desc.' )
131
+ @product_loader.set_default_value('meta_keywords', 'techno dubstep d&b' )
132
+
133
+
134
+ @product_loader.set_prefix('sku', 'SPEC_')
135
+
136
+ test_default_values
137
+
138
+ end
139
+
140
+ it "should support default values from config for Spree Products loader", :fail => true do
141
+
142
+ @product_loader.configure_from( SpecHelper::spree_fixture('SpreeProductsDefaults.yml') )
143
+
144
+ @product_loader.set_prefix('sku', 'SPEC_')
145
+
146
+ test_default_values
147
+
148
+ end
149
+
150
+ def test_default_values
151
+ @product_loader.perform_load( SpecHelper::spree_fixture('SpreeProductsMandatoryOnly.xls'), :mandatory => ['sku', 'name', 'price'] )
152
+
153
+ @klass.count.should == 3
154
+
155
+ @product_loader.failed_objects.size.should == 0
156
+ @product_loader.loaded_objects.size.should == 3
157
+
158
+ p = @klass.first
159
+
160
+ p.sku.should == "SPEC_SIMPLE_001"
161
+
162
+ @klass.all { |p|
163
+ p.sku.should.include "SPEC_"
164
+ p.cost_price = 1.0
165
+ p.available_on.should == @expected_time
166
+ p.meta_description.should == 'super duper meta desc.'
167
+ p.meta_keywords.should == 'techno dubstep d&b'
168
+ }
169
+ end
119
170
 
120
171
  # Operation and results should be identical when loading multiple associations
121
172
  # if using either single column embedded syntax, or one column per entry.
@@ -304,15 +355,6 @@ describe 'SpreeLoader' do
304
355
 
305
356
 
306
357
  end
307
-
308
- it "should load Products with associated image", :img => true do
309
- pending("embedded images")
310
- @product_loader.perform_load( SpecHelper::spree_fixture('SpreeProductsWithImages.csv'), :mandatory => ['sku', 'name', 'price'] )
311
-
312
- p = @klass.find_by_name("Demo Product for AR Loader")
313
-
314
- p.images.should have_exactly(1).items
315
- end
316
358
 
317
359
 
318
360
  # REPEAT THE WHOLE TEST SUITE VIA CSV
@@ -334,14 +376,6 @@ describe 'SpreeLoader' do
334
376
  expected_multi_column_taxons
335
377
  end
336
378
 
337
- it "should load Products with assoicated image" do
338
- test_variants_creation('SpreeProductsMultiColumn.csv')
339
-
340
- expected_multi_column_properties
341
-
342
- expected_multi_column_taxons
343
- end
344
-
345
379
 
346
380
  it "should raise exception when mandatory columns missing from .xls", :ex => true do
347
381
  expect {@product_loader.perform_load($SpreeNegativeFixturePath + '/SpreeProdMissManyMandatory.xls', :mandatory => ['sku', 'name', 'price'] )}.to raise_error(DataShift::MissingMandatoryError)
@@ -14,7 +14,8 @@ namespace :datashift do
14
14
 
15
15
  namespace :spree do
16
16
 
17
- desc "Populate the DB with images.\nDefault location db/image_seeds, or specify :input=<path> or dir under db/image_seeds with :folder"
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"
18
19
  # :dummy => dummy run without actual saving to DB
19
20
  task :images, [:input, :folder, :dummy, :sku, :skip_if_no_assoc, :skip_if_loaded, :model] => :environment do |t, args|
20
21
 
@@ -30,33 +31,37 @@ namespace :datashift do
30
31
  @image_cache = File.join(@image_cache, args[:folder]) if(args[:folder])
31
32
  end
32
33
 
33
- attachment_klazz = Product
34
+
35
+ attachment_klazz = SpreeHelper::get_spree_class('Product' )
36
+ sku_klazz = SpreeHelper::get_spree_class('Variant' )
34
37
 
35
- begin
36
- attachment_klazz = Kernel.const_get(args[:model]) if(args[:model])
37
- rescue NameError
38
- attachment_klazz = Product
39
- end
38
+ # TODO generalise for any paperclip project, for now just Spree
39
+ #begin
40
+ # attachment_klazz = Kernel.const_get(args[:model]) if(args[:model])
41
+ # rescue NameError
42
+ # raise "Could not find contant for model #{args[:model]}"
43
+ #end
40
44
 
41
45
  image_loader = ImageLoader.new
42
46
 
43
- if(File.exists? @image_cache )
47
+ if(File.directory? @image_cache )
44
48
  puts "Loading images from #{@image_cache}"
45
49
 
46
50
  missing_records = []
47
- Dir.glob("#{@image_cache}/*.{jpg,png,gif}") do |image_name|
51
+ Dir.glob("#{@image_cache}/**/*.{jpg,png,gif}") do |image_name|
48
52
 
49
- puts "Processing #{image_name} : #{File.exists?(image_name)}"
50
53
  base_name = File.basename(image_name, '.*')
51
-
54
+
55
+ puts "Processing #{base_name} : #{File.exists?(image_name)}"
56
+
52
57
  record = nil
53
- if(attachment_klazz == Product && args[:sku])
58
+ if(args[:sku])
54
59
  sku = base_name.slice!(/\w+/)
55
60
  sku.strip!
56
61
  base_name.strip!
57
62
 
58
63
  puts "Looking fo SKU #{sku}"
59
- record = Variant.find_by_sku(sku)
64
+ record = sku_klazz.find_by_sku(sku)
60
65
  if record
61
66
  record = record.product # SKU stored on Variant but we want it's master Product
62
67
  else
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: datashift
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.2.2
5
+ version: 0.4.0
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-03-05 00:00:00 Z
13
+ date: 2012-03-12 00:00:00 Z
14
14
  dependencies: []
15
15
 
16
16
  description: A suite of tools to move data between ActiveRecord models,databases,applications like Excel/Open Office, files and projects including Spree
@@ -36,11 +36,14 @@ files:
36
36
  - lib/datashift.rb
37
37
  - lib/datashift/exceptions.rb
38
38
  - lib/datashift/file_definitions.rb
39
+ - lib/datashift/logging.rb
39
40
  - lib/datashift/mapping_file_definitions.rb
40
41
  - lib/datashift/method_detail.rb
42
+ - lib/datashift/method_details_manager.rb
41
43
  - lib/datashift/method_dictionary.rb
42
44
  - lib/datashift/method_mapper.rb
43
45
  - lib/datashift/model_mapper.rb
46
+ - lib/datashift/populator.rb
44
47
  - lib/exporters/csv_exporter.rb
45
48
  - lib/exporters/excel_exporter.rb
46
49
  - lib/exporters/exporter_base.rb
@@ -72,6 +75,9 @@ files:
72
75
  - lib/loaders/spree/image_loader.rb
73
76
  - lib/loaders/spree/product_loader.rb
74
77
  - lib/thor/generate_excel.thor
78
+ - lib/thor/import_excel.thor
79
+ - lib/thor/spree/bootstrap_cleanup.thor
80
+ - lib/thor/spree/products_images.thor
75
81
  - public/spree/products/large/DEMO_001_ror_bag.jpeg
76
82
  - public/spree/products/large/DEMO_002_Powerstation.jpg
77
83
  - public/spree/products/large/DEMO_003_ror_mug.jpeg
@@ -122,6 +128,8 @@ files:
122
128
  - spec/fixtures/simple_template_spec.xls
123
129
  - spec/fixtures/spree/SpreeProducts.csv
124
130
  - spec/fixtures/spree/SpreeProducts.xls
131
+ - spec/fixtures/spree/SpreeProductsDefaults.yml
132
+ - spec/fixtures/spree/SpreeProductsMandatoryOnly.xls
125
133
  - spec/fixtures/spree/SpreeProductsMultiColumn.csv
126
134
  - spec/fixtures/spree/SpreeProductsMultiColumn.xls
127
135
  - spec/fixtures/spree/SpreeProductsSimple.csv
@@ -137,6 +145,7 @@ files:
137
145
  - spec/spec_helper.rb
138
146
  - spec/spree_exporter_spec.rb
139
147
  - spec/spree_generator_spec.rb
148
+ - spec/spree_images_loader_spec.rb
140
149
  - spec/spree_loader_spec.rb
141
150
  - spec/spree_method_mapping_spec.rb
142
151
  - tasks/config/seed_fu_product_template.erb
@@ -146,7 +155,6 @@ files:
146
155
  - tasks/import/csv.rake
147
156
  - tasks/import/excel.rake
148
157
  - tasks/spree/image_load.rake
149
- - tasks/spree/product_loader.rake
150
158
  - tasks/word_to_seedfu.rake
151
159
  - test/helper.rb
152
160
  - test/test_interact.rb
@@ -1,44 +0,0 @@
1
- # Copyright:: (c) Autotelik Media Ltd 2011
2
- # Author :: Tom Statter
3
- # Date :: Feb 2011
4
- # License:: MIT. Free, Open Source.
5
- #
6
- # REQUIRES: JRuby access to Java
7
- #
8
- # Usage::
9
- #
10
- # e.g. => jruby -S rake datashift:spree:products input=vendor/extensions/autotelik/fixtures/SiteSpreadsheetInfo.xls
11
- # => jruby -S rake datashift:spree:products input=C:\MyProducts.xls verbose=true
12
- #
13
- require 'datashift'
14
-
15
- namespace :datashift do
16
-
17
- namespace :spree do
18
-
19
- desc "Populate Spree Product/Variant data from .xls (Excel) or CSV file"
20
- task :products, [:input, :verbose, :sku_prefix] => :environment do |t, args|
21
-
22
- input = ENV['input']
23
-
24
- raise "USAGE: jruby -S rake datashift:spree:products input=excel_file.xls" unless input
25
- raise "ERROR: Could not find file #{args[:input]}" unless File.exists?(input)
26
-
27
- require 'product_loader'
28
-
29
- # COLUMNS WITH DEFAULTS - TODO create YAML configuration file to drive defaults etc
30
-
31
- loader = DataShift::ProductLoader.new
32
-
33
- loader.set_default_value('available_on', Time.now.to_s(:db) )
34
- loader.set_default_value('cost_price', 0.0 )
35
-
36
- loader.set_prefix('sku', args[:sku_prefix] ) if(args[:sku_prefix])
37
-
38
- puts "Loading from file: #{input}"
39
-
40
- loader.perform_load(input, :mandatory => ['sku', 'name', 'price'] )
41
- end
42
- end
43
-
44
- end