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.
- data/README.markdown +15 -3
- data/VERSION +1 -1
- data/datashift.gemspec +11 -3
- data/lib/applications/jruby/jexcel_file.rb +10 -3
- data/lib/datashift.rb +25 -62
- data/lib/datashift/exceptions.rb +1 -0
- data/lib/datashift/logging.rb +58 -0
- data/lib/datashift/method_detail.rb +6 -45
- data/lib/datashift/method_details_manager.rb +54 -0
- data/lib/datashift/method_dictionary.rb +6 -1
- data/lib/datashift/method_mapper.rb +12 -5
- data/lib/datashift/populator.rb +46 -0
- data/lib/exporters/excel_exporter.rb +1 -1
- data/lib/generators/excel_generator.rb +48 -44
- data/lib/helpers/spree_helper.rb +14 -3
- data/lib/loaders/csv_loader.rb +9 -6
- data/lib/loaders/excel_loader.rb +5 -1
- data/lib/loaders/loader_base.rb +28 -14
- data/lib/loaders/spree/image_loader.rb +36 -34
- data/lib/loaders/spree/product_loader.rb +17 -7
- data/lib/thor/generate_excel.thor +35 -15
- data/lib/thor/import_excel.thor +84 -0
- data/lib/thor/spree/bootstrap_cleanup.thor +33 -0
- data/lib/thor/spree/products_images.thor +171 -0
- data/spec/datashift_spec.rb +19 -0
- data/spec/excel_exporter_spec.rb +3 -3
- data/spec/fixtures/datashift_Spree_db.sqlite +0 -0
- data/spec/fixtures/datashift_test_models_db.sqlite +0 -0
- data/spec/fixtures/spree/SpreeProductsDefaults.yml +15 -0
- data/spec/fixtures/spree/SpreeProductsMandatoryOnly.xls +0 -0
- data/spec/fixtures/spree/SpreeProductsWithImages.xls +0 -0
- data/spec/spec_helper.rb +2 -2
- data/spec/spree_generator_spec.rb +14 -0
- data/spec/spree_images_loader_spec.rb +73 -0
- data/spec/spree_loader_spec.rb +53 -19
- data/tasks/spree/image_load.rake +18 -13
- metadata +11 -3
- data/tasks/spree/product_loader.rake +0 -44
data/spec/datashift_spec.rb
CHANGED
@@ -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
|
data/spec/excel_exporter_spec.rb
CHANGED
@@ -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 =
|
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 =
|
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
|
78
|
+
puts "WARNING: skipped excel_exporter_spec : Requires JRUBY - JExcelFile requires JAVA"
|
79
79
|
end # jruby
|
Binary file
|
Binary file
|
@@ -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
|
+
|
Binary file
|
Binary file
|
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
|
-
|
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
|
data/spec/spree_loader_spec.rb
CHANGED
@@ -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('
|
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)
|
data/tasks/spree/image_load.rake
CHANGED
@@ -14,7 +14,8 @@ namespace :datashift do
|
|
14
14
|
|
15
15
|
namespace :spree do
|
16
16
|
|
17
|
-
|
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
|
-
|
34
|
+
|
35
|
+
attachment_klazz = SpreeHelper::get_spree_class('Product' )
|
36
|
+
sku_klazz = SpreeHelper::get_spree_class('Variant' )
|
34
37
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
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.
|
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}
|
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(
|
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 =
|
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.
|
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-
|
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
|