ar_loader 0.0.4 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,107 +1,108 @@
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 from rake : jruby -S rake excel_loader input=<file.xls>
9
- #
10
- # e.g. => jruby -S rake excel_load input=vendor\extensions\autotelik\fixtures\ExampleInfoWeb.xls
11
- # => jruby -S rake excel_load input=C:\MyProducts.xls verbose=true
12
- #
13
- namespace :autotelik do
14
-
15
- desc "Populate a Spree database with Product/Varient data stored in Excel"
16
- task :product_load, :input, :verbose, :sku_prefix, :needs => :environment do |t, args|
17
-
18
- raise "USAGE: jruby -S rake product_load input=excel_file.xls" unless args[:input]
19
- raise "ERROR: Could not find file #{args[:input]}" unless File.exists?(args[:input])
20
-
21
- require 'product_loader'
22
- require 'method_mapper_excel'
23
-
24
- @method_mapper = MethodMapperExcel.new(args[:input], Product)
25
-
26
- @excel = @method_mapper.excel
27
-
28
- if(args[:verbose])
29
- puts "Loading from Excel file: #{args[:input]}"
30
- puts "Processing #{@excel.num_rows} rows"
31
- end
32
-
33
- # REQUIRED 'set' methods on Product i.e will not validate/save without these
34
- required_methods = ['sku', 'name', 'price']
35
-
36
- @method_mapper.check_mandatory( required_methods )
37
-
38
- # COLUMNS WITH DEFAULTS - TODO create YAML configuration file to drive defaults etc
39
-
40
- MethodDetail.set_default_value('available_on', Time.now.to_s(:db) )
41
- MethodDetail.set_default_value('cost_price', 0.0 )
42
-
43
- MethodDetail.set_prefix('sku', args[:sku_prefix] ) if args[:sku_prefix]
44
-
45
- # Process spreadsheet and create Products
46
- method_names = @method_mapper.method_names
47
-
48
- sku_index = method_names.index('sku')
49
-
50
- Product.transaction do
51
- @products = []
52
-
53
- (1..@excel.num_rows).collect do |row|
54
-
55
- product_data_row = @excel.sheet.getRow(row)
56
- break if product_data_row.nil?
57
-
58
- # Excel num_rows seems to return all 'visible' rows so,
59
- # we have to manually detect when actual data ends and all the empty rows start
60
- contains_data = required_methods.find { |mthd| ! product_data_row.getCell(method_names.index(mthd)).to_s.empty? }
61
- break unless contains_data
62
-
63
- @assoc_classes = {}
64
-
65
- loader = ProductLoader.new()
66
-
67
- # TODO - Smart sorting of column processing order ....
68
- # Does not currently ensure mandatory columns (for valid?) processed first but Product needs saving
69
- # before associations can be processed so user should ensure SKU, name, price columns are among first columns
70
-
71
- @method_mapper.methods.each_with_index do |method_map, col|
72
- product_data_row.getCell(col).setCellType(JExcelFile::HSSFCell::CELL_TYPE_STRING) if(col == sku_index)
73
- loader.process(method_map, @excel.value(product_data_row, col))
74
- begin
75
- prod = loader.load_object
76
- if( prod.valid? && prod.new_record? )
77
- prod.save
78
- end
79
- rescue
80
- raise "Error processing Product"
81
- end
82
- end
83
-
84
- product = loader.load_object
85
-
86
- product.available_on ||= Time.now.to_s(:db)
87
-
88
- # TODO - handle when it's not valid ?
89
- # Process rest and dump out an exception list of Products
90
- #unless(product.valid?)
91
- #end
92
-
93
- puts "SAVING ROW #{row} : #{product.inspect}" if args[:verbose]
94
-
95
- unless(product.save)
96
- puts product.errors.inspect
97
- puts product.errors.full_messages.inspect
98
- raise "Error Saving Product: #{product.sku} :#{product.name}"
99
- else
100
- @products << product
101
- end
102
- end
103
- end # TRANSACTION
104
-
105
- end
106
-
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 from rake : jruby -S rake excel_loader input=<file.xls>
9
+ #
10
+ # e.g. => jruby -S rake autotelik:product_load input=vendor\extensions\autotelik\fixtures\ExampleInfoWeb.xls
11
+ # => jruby -S rake autotelik:product_load input=C:\MyProducts.xls verbose=true
12
+ #
13
+ namespace :autotelik do
14
+
15
+ desc "Populate Spree db with Product/Varient data from .xls (Excel) file"
16
+ task :product_load, :input, :verbose, :sku_prefix, :needs => :environment do |t, args|
17
+
18
+ raise "USAGE: jruby -S rake product_load input=excel_file.xls" unless args[:input]
19
+ raise "ERROR: Could not find file #{args[:input]}" unless File.exists?(args[:input])
20
+
21
+ require 'product_loader'
22
+ require 'method_mapper_excel'
23
+
24
+ @method_mapper = MethodMapperExcel.new(args[:input], Product)
25
+
26
+ @excel = @method_mapper.excel
27
+
28
+ if(args[:verbose])
29
+ puts "Loading from Excel file: #{args[:input]}"
30
+ puts "Processing #{@excel.num_rows} rows"
31
+ end
32
+
33
+ # REQUIRED 'set' methods on Product i.e will not validate/save without these
34
+ required_methods = ['sku', 'name', 'price']
35
+
36
+ @method_mapper.check_mandatory( required_methods )
37
+
38
+ # COLUMNS WITH DEFAULTS - TODO create YAML configuration file to drive defaults etc
39
+
40
+ MethodDetail.set_default_value('available_on', Time.now.to_s(:db) )
41
+ MethodDetail.set_default_value('cost_price', 0.0 )
42
+
43
+ MethodDetail.set_prefix('sku', args[:sku_prefix] ) if args[:sku_prefix]
44
+
45
+ # Process spreadsheet and create Products
46
+ method_names = @method_mapper.method_names
47
+
48
+ sku_index = method_names.index('sku')
49
+
50
+ Product.transaction do
51
+ @products = []
52
+
53
+ (1..@excel.num_rows).collect do |row|
54
+
55
+ product_data_row = @excel.sheet.getRow(row)
56
+ break if product_data_row.nil?
57
+
58
+ # Excel num_rows seems to return all 'visible' rows so,
59
+ # we have to manually detect when actual data ends and all the empty rows start
60
+ contains_data = required_methods.find { |mthd| ! product_data_row.getCell(method_names.index(mthd)).to_s.empty? }
61
+ break unless contains_data
62
+
63
+ @assoc_classes = {}
64
+
65
+ loader = ProductLoader.new()
66
+
67
+ # TODO - Smart sorting of column processing order ....
68
+ # Does not currently ensure mandatory columns (for valid?) processed first but Product needs saving
69
+ # before associations can be processed so user should ensure SKU, name, price columns are among first columns
70
+
71
+ @method_mapper.methods.each_with_index do |method_map, col|
72
+ product_data_row.getCell(col).setCellType(JExcelFile::HSSFCell::CELL_TYPE_STRING) if(col == sku_index)
73
+ loader.process(method_map, @excel.value(product_data_row, col))
74
+ begin
75
+ prod = loader.load_object
76
+ if( prod.valid? && prod.new_record? )
77
+ prod.save
78
+ end
79
+ rescue => e
80
+ puts "ERROR: Product save #{e.inspect}"
81
+ raise "Error processing Product"
82
+ end
83
+ end
84
+
85
+ product = loader.load_object
86
+
87
+ product.available_on ||= Time.now.to_s(:db)
88
+
89
+ # TODO - handle when it's not valid ?
90
+ # Process rest and dump out an exception list of Products
91
+ #unless(product.valid?)
92
+ #end
93
+
94
+ puts "SAVING ROW #{row} : #{product.inspect}" if args[:verbose]
95
+
96
+ unless(product.save)
97
+ puts product.errors.inspect
98
+ puts product.errors.full_messages.inspect
99
+ raise "Error Saving Product: #{product.sku} :#{product.name}"
100
+ else
101
+ @products << product
102
+ end
103
+ end
104
+ end # TRANSACTION
105
+
106
+ end
107
+
107
108
  end
@@ -1,167 +1,167 @@
1
- # Copyright:: (c) Autotelik Media Ltd 2011
2
- # Author :: Tom Statter
3
- # Date :: Aug 2010
4
- #
5
- # License:: Free, OpenSource... MIT ?
6
- #
7
- # About:: Rake tasks to read Word documents, containing product descriptions,
8
- # convert to HTML, tidy the HTML and then create seed_fu ready fixtures,
9
- # from a template, with product description supplied by the HTML
10
- #
11
- # Note cleanest HTML is produced by this combination : saving with WdFormatHTML
12
- # not WdFormatFilteredHTML and using the '--word-2000', 'y' option to tidy
13
- # (don't use the '--bare' option)
14
- #
15
- # Not currently available for JRuby due to Win32Ole requirement
16
- #
17
- # Requires local exes available in PATH for :
18
- # Microsoft Word
19
- # HTML Tidy - http://tidy.sourceforge.net (Free)
20
- #
21
- require 'erb'
22
-
23
- namespace :autotelik do
24
-
25
- desc "Convert MS Word to HTML and seed_fu fixtures. help=true for detailed usage."
26
-
27
- task :word2html, :help, :needs => [:environment] do |t, args|
28
- x =<<-EOS
29
-
30
- USAGE::
31
- Convert MS Word docs to HTML and seed_fu fixtures, by default searches for docs
32
- in RAILS_ROOT/doc/copy
33
-
34
- You can change the directory where Word document files are located
35
- with the COPY_PATH environment variable.
36
-
37
- Examples:
38
- # default, to convert all Word files for the current environment
39
- rake autotelik:word2seedfu
40
-
41
- # to load seed files matching orders or customers
42
- rake db:seed SEED=orders,customers
43
-
44
- # to load files from RAILS_ROOT/features/fixtures
45
- rake db:seed FIXTURE_PATH=features/fixtures
46
- EOS
47
-
48
- if(args[:help])
49
- puts x
50
- exit(0)
51
- end
52
-
53
- site_extension_lib = File.join(SiteExtension.root, 'lib')
54
-
55
- require File.join(site_extension_lib, 'word')
56
-
57
- copy_path = ENV["COPY_PATH"] ? ENV["COPY_PATH"] : File.join(RAILS_ROOT, "doc", "copy")
58
- fixtures_path = ENV["FIXTURES_PATH"] ? ENV["FIXTURES_PATH"] : File.join(RAILS_ROOT, "db", "fixtures")
59
-
60
- copy_files = Dir[File.join(copy_path, '*.doc')]
61
-
62
- copy_files.each do |file|
63
-
64
- name = File.basename(file, '.doc')
65
-
66
- puts "\n== Generate raw HTML from #{name}.doc =="
67
-
68
- @word = Word.new(true)
69
-
70
- @word.open( file )
71
-
72
- html_file = File.join(copy_path, "#{name}.ms.html")
73
-
74
- @word.save_as_html( html_file )
75
-
76
- tidy_file = File.join(copy_path, "#{name}.html")
77
-
78
- tidy_config = File.join(site_extension_lib, 'tasks', 'tidy_config.txt')
79
-
80
- puts "tidy cmd line:", "tidy -config #{tidy_config} -clean --show-body-only y --word-2000 y --indent-spaces 2 -output #{tidy_file} #{html_file}"
81
-
82
- result = system("tidy", '-config', "#{tidy_config}", '-clean', '--show-body-only', 'y', '--word-2000', 'y', '--indent-spaces', '2', '-output', "#{tidy_file}", "#{html_file}")
83
-
84
- # TODO maybe report on result, $?
85
-
86
- File.open( tidy_file ) do |f|
87
- puts f.read
88
- end
89
-
90
- @word.quit
91
- end
92
- end
93
-
94
- desc "Convert MS Word to HTML and seed_fu fixtures. help=true for detailed usage."
95
- task :word2seedfu => :environment do
96
- site_extension_lib = File.join(SiteExtension.root, 'lib')
97
-
98
- require File.join(site_extension_lib, 'word')
99
-
100
- sku_id = ENV["INITIAL_SKU_ID"] ? ENV["INITIAL_SKU_ID"] : 0
101
- sku_prefix = ENV["SKU_PREFIX"] ? ENV["SKU_PREFIX"] : File.basename( RAILS_ROOT )
102
-
103
- seedfu_template = File.join(site_extension_lib, 'tasks', 'seed_fu_product_template.erb')
104
-
105
- begin
106
- File.open( seedfu_template ) do |f|
107
- @template = ERB.new(f.read)
108
- end
109
- rescue => e
110
- puts "ERROR: #{e.inspect}"
111
- puts "Cannot open or read template #{seedfu_template}"
112
- raise e
113
- end
114
-
115
- copy_path = ENV["COPY_PATH"] ? ENV["COPY_PATH"] : File.join(RAILS_ROOT, "doc", "copy")
116
- fixtures_path = ENV["FIXTURES_PATH"] ? ENV["FIXTURES_PATH"] : File.join(RAILS_ROOT, "db", "fixtures")
117
-
118
- copy_files = Dir[File.join(copy_path, '*.doc')]
119
-
120
- copy_files.each do |file|
121
-
122
- name = File.basename(file, '.doc')
123
-
124
- puts "\n== Generate raw HTML from #{name}.doc =="
125
-
126
- @word = Word.new(true)
127
-
128
- @word.open( file )
129
-
130
- html_file = File.join(copy_path, "#{name}.ms.html")
131
-
132
- @word.save_as_html( html_file )
133
-
134
- tidy_file = File.join(copy_path, "#{name}.html")
135
-
136
- tidy_config = File.join(site_extension_lib, 'tasks', 'tidy_config.txt')
137
-
138
- puts "tidy cmd line:", "tidy -config #{tidy_config} -clean --show-body-only y --word-2000 y --indent-spaces 2 -output #{tidy_file} #{html_file}"
139
-
140
- result = system("tidy", '-config', "#{tidy_config}", '-clean', '--show-body-only', 'y', '--word-2000', 'y', '--indent-spaces', '2', '-output', "#{tidy_file}", "#{html_file}")
141
-
142
- # TODO maybe report on result, $?
143
-
144
- File.open( tidy_file ) do |f|
145
- @description = f.read
146
- end
147
-
148
- sku_id_str = "%03d" % sku_id
149
-
150
- seed_file = "#{sku_id_str}_#{name.gsub(' ', '_')}.rb"
151
- puts "\n== Generate seed fu file #{seed_file} =="
152
-
153
- @sku = "#{sku_prefix}_#{sku_id_str}"
154
- @name = 'TODO'
155
-
156
- File.open( File.join(fixtures_path, seed_file), 'w' ) do |f|
157
- f.write @template.result(binding)
158
- puts "\nFile created: #{File.join(fixtures_path, seed_file)}"
159
- end
160
-
161
- sku_id += 1
162
-
163
- @word.quit
164
- end
165
-
166
- end
1
+ # Copyright:: (c) Autotelik Media Ltd 2011
2
+ # Author :: Tom Statter
3
+ # Date :: Aug 2010
4
+ #
5
+ # License:: Free, OpenSource... MIT ?
6
+ #
7
+ # About:: Rake tasks to read Word documents, containing product descriptions,
8
+ # convert to HTML, tidy the HTML and then create seed_fu ready fixtures,
9
+ # from a template, with product description supplied by the HTML
10
+ #
11
+ # Note cleanest HTML is produced by this combination : saving with WdFormatHTML
12
+ # not WdFormatFilteredHTML and using the '--word-2000', 'y' option to tidy
13
+ # (don't use the '--bare' option)
14
+ #
15
+ # Not currently available for JRuby due to Win32Ole requirement
16
+ #
17
+ # Requires local exes available in PATH for :
18
+ # Microsoft Word
19
+ # HTML Tidy - http://tidy.sourceforge.net (Free)
20
+ #
21
+ require 'erb'
22
+
23
+ namespace :autotelik do
24
+
25
+ desc "Convert MS Word to HTML and seed_fu fixtures. help=true for detailed usage."
26
+
27
+ task :word2html, :help, :needs => [:environment] do |t, args|
28
+ x =<<-EOS
29
+
30
+ USAGE::
31
+ Convert MS Word docs to HTML and seed_fu fixtures, by default searches for docs
32
+ in RAILS_ROOT/doc/copy
33
+
34
+ You can change the directory where Word document files are located
35
+ with the COPY_PATH environment variable.
36
+
37
+ Examples:
38
+ # default, to convert all Word files for the current environment
39
+ rake autotelik:word2seedfu
40
+
41
+ # to load seed files matching orders or customers
42
+ rake db:seed SEED=orders,customers
43
+
44
+ # to load files from RAILS_ROOT/features/fixtures
45
+ rake db:seed FIXTURE_PATH=features/fixtures
46
+ EOS
47
+
48
+ if(args[:help])
49
+ puts x
50
+ exit(0)
51
+ end
52
+
53
+ site_extension_lib = File.join(SiteExtension.root, 'lib')
54
+
55
+ require File.join(site_extension_lib, 'word')
56
+
57
+ copy_path = ENV["COPY_PATH"] ? ENV["COPY_PATH"] : File.join(RAILS_ROOT, "doc", "copy")
58
+ fixtures_path = ENV["FIXTURES_PATH"] ? ENV["FIXTURES_PATH"] : File.join(RAILS_ROOT, "db", "fixtures")
59
+
60
+ copy_files = Dir[File.join(copy_path, '*.doc')]
61
+
62
+ copy_files.each do |file|
63
+
64
+ name = File.basename(file, '.doc')
65
+
66
+ puts "\n== Generate raw HTML from #{name}.doc =="
67
+
68
+ @word = Word.new(true)
69
+
70
+ @word.open( file )
71
+
72
+ html_file = File.join(copy_path, "#{name}.ms.html")
73
+
74
+ @word.save_as_html( html_file )
75
+
76
+ tidy_file = File.join(copy_path, "#{name}.html")
77
+
78
+ tidy_config = File.join(site_extension_lib, 'tasks', 'tidy_config.txt')
79
+
80
+ puts "tidy cmd line:", "tidy -config #{tidy_config} -clean --show-body-only y --word-2000 y --indent-spaces 2 -output #{tidy_file} #{html_file}"
81
+
82
+ result = system("tidy", '-config', "#{tidy_config}", '-clean', '--show-body-only', 'y', '--word-2000', 'y', '--indent-spaces', '2', '-output', "#{tidy_file}", "#{html_file}")
83
+
84
+ # TODO maybe report on result, $?
85
+
86
+ File.open( tidy_file ) do |f|
87
+ puts f.read
88
+ end
89
+
90
+ @word.quit
91
+ end
92
+ end
93
+
94
+ desc "Convert MS Word to HTML and seed_fu fixtures. help=true for detailed usage."
95
+ task :word2seedfu => :environment do
96
+ site_extension_lib = File.join(SiteExtension.root, 'lib')
97
+
98
+ require File.join(site_extension_lib, 'word')
99
+
100
+ sku_id = ENV["INITIAL_SKU_ID"] ? ENV["INITIAL_SKU_ID"] : 0
101
+ sku_prefix = ENV["SKU_PREFIX"] ? ENV["SKU_PREFIX"] : File.basename( RAILS_ROOT )
102
+
103
+ seedfu_template = File.join(site_extension_lib, 'tasks', 'seed_fu_product_template.erb')
104
+
105
+ begin
106
+ File.open( seedfu_template ) do |f|
107
+ @template = ERB.new(f.read)
108
+ end
109
+ rescue => e
110
+ puts "ERROR: #{e.inspect}"
111
+ puts "Cannot open or read template #{seedfu_template}"
112
+ raise e
113
+ end
114
+
115
+ copy_path = ENV["COPY_PATH"] ? ENV["COPY_PATH"] : File.join(RAILS_ROOT, "doc", "copy")
116
+ fixtures_path = ENV["FIXTURES_PATH"] ? ENV["FIXTURES_PATH"] : File.join(RAILS_ROOT, "db", "fixtures")
117
+
118
+ copy_files = Dir[File.join(copy_path, '*.doc')]
119
+
120
+ copy_files.each do |file|
121
+
122
+ name = File.basename(file, '.doc')
123
+
124
+ puts "\n== Generate raw HTML from #{name}.doc =="
125
+
126
+ @word = Word.new(true)
127
+
128
+ @word.open( file )
129
+
130
+ html_file = File.join(copy_path, "#{name}.ms.html")
131
+
132
+ @word.save_as_html( html_file )
133
+
134
+ tidy_file = File.join(copy_path, "#{name}.html")
135
+
136
+ tidy_config = File.join(site_extension_lib, 'tasks', 'tidy_config.txt')
137
+
138
+ puts "tidy cmd line:", "tidy -config #{tidy_config} -clean --show-body-only y --word-2000 y --indent-spaces 2 -output #{tidy_file} #{html_file}"
139
+
140
+ result = system("tidy", '-config', "#{tidy_config}", '-clean', '--show-body-only', 'y', '--word-2000', 'y', '--indent-spaces', '2', '-output', "#{tidy_file}", "#{html_file}")
141
+
142
+ # TODO maybe report on result, $?
143
+
144
+ File.open( tidy_file ) do |f|
145
+ @description = f.read
146
+ end
147
+
148
+ sku_id_str = "%03d" % sku_id
149
+
150
+ seed_file = "#{sku_id_str}_#{name.gsub(' ', '_')}.rb"
151
+ puts "\n== Generate seed fu file #{seed_file} =="
152
+
153
+ @sku = "#{sku_prefix}_#{sku_id_str}"
154
+ @name = 'TODO'
155
+
156
+ File.open( File.join(fixtures_path, seed_file), 'w' ) do |f|
157
+ f.write @template.result(binding)
158
+ puts "\nFile created: #{File.join(fixtures_path, seed_file)}"
159
+ end
160
+
161
+ sku_id += 1
162
+
163
+ @word.quit
164
+ end
165
+
166
+ end
167
167
  end