ar_loader 0.0.6 → 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. data/LICENSE +9 -9
  2. data/README.markdown +268 -221
  3. data/Rakefile +76 -76
  4. data/lib/VERSION +1 -1
  5. data/lib/ar_loader.rb +87 -66
  6. data/lib/ar_loader/exceptions.rb +2 -0
  7. data/lib/{engine → ar_loader}/file_definitions.rb +353 -353
  8. data/lib/{engine → ar_loader}/mapping_file_definitions.rb +87 -87
  9. data/lib/ar_loader/method_detail.rb +257 -0
  10. data/lib/ar_loader/method_mapper.rb +213 -0
  11. data/lib/helpers/jruby/jexcel_file.rb +187 -0
  12. data/lib/{engine → helpers/jruby}/word.rb +79 -70
  13. data/lib/helpers/spree_helper.rb +85 -0
  14. data/lib/loaders/csv_loader.rb +87 -0
  15. data/lib/loaders/excel_loader.rb +132 -0
  16. data/lib/loaders/loader_base.rb +205 -73
  17. data/lib/loaders/spree/image_loader.rb +45 -41
  18. data/lib/loaders/spree/product_loader.rb +140 -91
  19. data/lib/to_b.rb +24 -24
  20. data/spec/csv_loader_spec.rb +27 -0
  21. data/spec/database.yml +19 -6
  22. data/spec/db/migrate/20110803201325_create_test_bed.rb +78 -0
  23. data/spec/excel_loader_spec.rb +113 -98
  24. data/spec/fixtures/BadAssociationName.xls +0 -0
  25. data/spec/fixtures/DemoNegativeTesting.xls +0 -0
  26. data/spec/fixtures/DemoTestModelAssoc.xls +0 -0
  27. data/spec/fixtures/ProjectsMultiCategories.xls +0 -0
  28. data/spec/fixtures/SimpleProjects.xls +0 -0
  29. data/spec/fixtures/SpreeProducts.xls +0 -0
  30. data/spec/fixtures/SpreeZoneExample.csv +5 -0
  31. data/spec/fixtures/SpreeZoneExample.xls +0 -0
  32. data/spec/loader_spec.rb +116 -0
  33. data/spec/logs/test.log +5000 -0
  34. data/spec/method_mapper_spec.rb +222 -0
  35. data/spec/models.rb +55 -0
  36. data/spec/spec_helper.rb +85 -18
  37. data/spec/spree_loader_spec.rb +223 -157
  38. data/tasks/config/seed_fu_product_template.erb +15 -15
  39. data/tasks/config/tidy_config.txt +12 -12
  40. data/tasks/db_tasks.rake +64 -64
  41. data/tasks/excel_loader.rake +63 -113
  42. data/tasks/file_tasks.rake +36 -37
  43. data/tasks/loader.rake +45 -0
  44. data/tasks/spree/image_load.rake +108 -107
  45. data/tasks/spree/product_loader.rake +49 -107
  46. data/tasks/word_to_seedfu.rake +166 -166
  47. metadata +66 -61
  48. data/lib/engine/jruby/jexcel_file.rb +0 -182
  49. data/lib/engine/jruby/method_mapper_excel.rb +0 -44
  50. data/lib/engine/method_detail.rb +0 -140
  51. data/lib/engine/method_mapper.rb +0 -157
  52. data/lib/engine/method_mapper_csv.rb +0 -28
  53. data/spec/db/migrate/20110803201325_create_testbed.rb +0 -25
@@ -1,108 +1,109 @@
1
- # Copyright:: (c) Autotelik Media Ltd 2011
2
- # Author :: Tom Statter
3
- # Date :: Feb 2011
4
- # License:: MIT. Free, Open Source.
5
- #
6
- # Usage from rake : rake image_load input=path_to_images
7
- #
8
- # => rake image_load input=vendor\extensions\autotelik\fixtures\
9
- # => rake image_load input="C:\images\photos large' dummy=true
10
- # => rake image_load input="C:\images\taxon_icons" skip_if_no_assoc=true klass=Taxon
11
-
12
- namespace :autotelik do
13
-
14
- namespace :spree do
15
-
16
- desc "Populate the DB with images.\nDefault location db/image_seeds, or specify :input=<path> or dir under db/image_seeds with :folder"
17
- # :dummy => dummy run without actual saving to DB
18
- task :image_load, :input, :folder, :dummy, :sku, :skip_if_no_assoc, :skip_if_loaded, :model, :needs => :environment do |t, args|
19
-
20
- require 'image_loader'
21
-
22
- raise "USAGE: Please specify one of :input or :folder" if(args[:input] && args[:folder])
23
- puts "SKU not specified " if(args[:input] && args[:folder])
24
-
25
- if args[:input]
26
- @image_cache = args[:input]
27
- else
28
- @image_cache = File.join(Rails.root, "db", "image_seeds")
29
- @image_cache = File.join(@image_cache, args[:folder]) if(args[:folder])
30
- end
31
-
32
- attachment_klazz = Product
33
-
34
- begin
35
- attachment_klazz = Kernel.const_get(args[:model]) if(args[:model])
36
- rescue NameError
37
- attachment_klazz = Product
38
- end
39
-
40
- image_loader = ImageLoader.new
41
-
42
- if(File.exists? @image_cache )
43
- puts "Loading images from #{@image_cache}"
44
-
45
- missing_records = []
46
- Dir.glob("#{@image_cache}/*.{jpg,png,gif}") do |image_name|
47
-
48
- puts "Processing #{image_name} : #{File.exists?(image_name)}"
49
- base_name = File.basename(image_name, '.*')
50
-
51
- record = nil
52
- if(attachment_klazz == Product && args[:sku])
53
- sku = base_name.slice!(/\w+/)
54
- sku.strip!
55
- base_name.strip!
56
-
57
- puts "Looking fo SKU #{sku}"
58
- record = Variant.find_by_sku(sku)
59
- if record
60
- record = record.product # SKU stored on Variant but we want it's master Product
61
- else
62
- puts "Looking for NAME [#{base_name}]"
63
- record = attachment_klazz.find_by_name(base_name)
64
- end
65
- else
66
- puts "Looking for #{attachment_klazz.name} with NAME [#{base_name}]"
67
- record = attachment_klazz.find_by_name(base_name)
68
- end
69
-
70
- if(record)
71
- puts "Found record for attachment : #{record.inspect}"
72
- exists = record.images.detect {|i| puts "COMPARE #{i.attachment_file_name} => #{image_name}"; i.attachment_file_name == image_name }
73
- puts "Found existing attachments [#{exists}]" unless(exists.nil?)
74
- if(args[:skip_if_loaded] && !exists.nil?)
75
- puts "Skipping - Image #{image_name} already loaded for #{attachment_klazz}"
76
- next
77
- end
78
- else
79
- missing_records << image_name
80
- end
81
-
82
- # Now do actual upload to DB unless we are doing a dummy run,
83
- # or the Image must have an associated record
84
- unless(args[:dummy] == 'true' || (args[:skip_if_no_assoc] && record.nil?))
85
- image_loader.reset()
86
- puts "Process Image"
87
- image_loader.process( image_name, record )
88
- end
89
-
90
- end
91
-
92
- unless missing_records.empty?
93
- FileUtils.mkdir_p('MissingRecords') unless File.directory?('MissingRecords')
94
-
95
- puts '\nMISSING Records Report>>'
96
- missing_records.each do |i|
97
- puts "Copy #{i} to MissingRecords folder"
98
- FileUtils.cp( i, 'MissingRecords') unless(args[:dummy] == 'true')
99
- end
100
- end
101
-
102
- else
103
- puts "ERROR: Supplied Path #{@image_cache} not accesible"
104
- exit(-1)
105
- end
106
- end
107
- end
1
+ # Copyright:: (c) Autotelik Media Ltd 2011
2
+ # Author :: Tom Statter
3
+ # Date :: Feb 2011
4
+ # License:: MIT
5
+ #
6
+ # Usage::
7
+ #
8
+ # => rake ar_loader:spree:images input=vendor/extensions/site/fixtures/images
9
+ # => rake ar_loader:spree:images input=C:\images\photos large dummy=true
10
+ #
11
+ # => rake ar_loader:spree:images input=C:\images\taxon_icons skip_if_no_assoc=true klass=Taxon
12
+ #
13
+ namespace :ar_loader do
14
+
15
+ namespace :spree do
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"
18
+ # :dummy => dummy run without actual saving to DB
19
+ task :images, :input, :folder, :dummy, :sku, :skip_if_no_assoc, :skip_if_loaded, :model, :needs => :environment do |t, args|
20
+
21
+ require 'image_loader'
22
+
23
+ raise "USAGE: Please specify one of :input or :folder" if(args[:input] && args[:folder])
24
+ puts "SKU not specified " if(args[:input] && args[:folder])
25
+
26
+ if args[:input]
27
+ @image_cache = args[:input]
28
+ else
29
+ @image_cache = File.join(Rails.root, "db", "image_seeds")
30
+ @image_cache = File.join(@image_cache, args[:folder]) if(args[:folder])
31
+ end
32
+
33
+ attachment_klazz = Product
34
+
35
+ begin
36
+ attachment_klazz = Kernel.const_get(args[:model]) if(args[:model])
37
+ rescue NameError
38
+ attachment_klazz = Product
39
+ end
40
+
41
+ image_loader = ImageLoader.new
42
+
43
+ if(File.exists? @image_cache )
44
+ puts "Loading images from #{@image_cache}"
45
+
46
+ missing_records = []
47
+ Dir.glob("#{@image_cache}/*.{jpg,png,gif}") do |image_name|
48
+
49
+ puts "Processing #{image_name} : #{File.exists?(image_name)}"
50
+ base_name = File.basename(image_name, '.*')
51
+
52
+ record = nil
53
+ if(attachment_klazz == Product && args[:sku])
54
+ sku = base_name.slice!(/\w+/)
55
+ sku.strip!
56
+ base_name.strip!
57
+
58
+ puts "Looking fo SKU #{sku}"
59
+ record = Variant.find_by_sku(sku)
60
+ if record
61
+ record = record.product # SKU stored on Variant but we want it's master Product
62
+ else
63
+ puts "Looking for NAME [#{base_name}]"
64
+ record = attachment_klazz.find_by_name(base_name)
65
+ end
66
+ else
67
+ puts "Looking for #{attachment_klazz.name} with NAME [#{base_name}]"
68
+ record = attachment_klazz.find_by_name(base_name)
69
+ end
70
+
71
+ if(record)
72
+ puts "Found record for attachment : #{record.inspect}"
73
+ exists = record.images.detect {|i| puts "COMPARE #{i.attachment_file_name} => #{image_name}"; i.attachment_file_name == image_name }
74
+ puts "Found existing attachments [#{exists}]" unless(exists.nil?)
75
+ if(args[:skip_if_loaded] && !exists.nil?)
76
+ puts "Skipping - Image #{image_name} already loaded for #{attachment_klazz}"
77
+ next
78
+ end
79
+ else
80
+ missing_records << image_name
81
+ end
82
+
83
+ # Now do actual upload to DB unless we are doing a dummy run,
84
+ # or the Image must have an associated record
85
+ unless(args[:dummy] == 'true' || (args[:skip_if_no_assoc] && record.nil?))
86
+ image_loader.reset()
87
+ puts "Process Image"
88
+ image_loader.process( image_name, record )
89
+ end
90
+
91
+ end
92
+
93
+ unless missing_records.empty?
94
+ FileUtils.mkdir_p('MissingRecords') unless File.directory?('MissingRecords')
95
+
96
+ puts '\nMISSING Records Report>>'
97
+ missing_records.each do |i|
98
+ puts "Copy #{i} to MissingRecords folder"
99
+ FileUtils.cp( i, 'MissingRecords') unless(args[:dummy] == 'true')
100
+ end
101
+ end
102
+
103
+ else
104
+ puts "ERROR: Supplied Path #{@image_cache} not accesible"
105
+ exit(-1)
106
+ end
107
+ end
108
+ end
108
109
  end
@@ -1,108 +1,50 @@
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
-
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 ar_loader:spree:products input=vendor/extensions/autotelik/fixtures/SiteSpreadsheetInfo.xls
11
+ # => jruby -S rake ar_loader:spree:products input=C:\MyProducts.xls verbose=true
12
+ #
13
+ require 'ar_loader'
14
+ require 'product_loader'
15
+ require 'csv_loader'
16
+
17
+ namespace :ar_loader do
18
+
19
+ namespace :spree do
20
+
21
+ desc "Populate Spree db with Product/Variant data from .xls (Excel) file"
22
+ task :products, [:input, :verbose, :sku_prefix] => :environment do |t, args|
23
+
24
+ input = ENV['input']
25
+
26
+ raise "USAGE: jruby -S rake ar_loader:spree:products input=excel_file.xls" unless input
27
+ raise "ERROR: Could not find file #{args[:input]}" unless File.exists?(input)
28
+
29
+ require 'product_loader'
30
+
31
+ # COLUMNS WITH DEFAULTS - TODO create YAML configuration file to drive defaults etc
32
+
33
+ ARLoader::MethodDetail.set_default_value('available_on', Time.now.to_s(:db) )
34
+ ARLoader::MethodDetail.set_default_value('cost_price', 0.0 )
35
+
36
+ ARLoader::MethodDetail.set_prefix('sku', args[:sku_prefix] ) if args[:sku_prefix]
37
+
38
+ if(File.extname(input) == '.xls' and Guards::jruby?)
39
+ loader = ARLoader::ProductLoader.new
40
+ else
41
+ loader = ARLoader::CSVLoader.new
42
+ end
43
+
44
+ puts "Loading from file: #{input}"
45
+
46
+ loader.load(input, :mandatory => ['sku', 'name', 'price'] )
47
+ end
48
+ end
49
+
108
50
  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 :ar_loader 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 ar_loader: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