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