datashift 0.9.0 → 0.10.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 +63 -64
- data/Rakefile +4 -7
- data/VERSION +1 -1
- data/datashift.gemspec +92 -62
- data/lib/applications/apache_poi_extensions.rb +62 -0
- data/lib/applications/excel.rb +78 -0
- data/lib/applications/excel_base.rb +65 -0
- data/lib/applications/jexcel_file.rb +222 -0
- data/lib/applications/jexcel_file_extensions.rb +244 -0
- data/lib/applications/jruby/{jexcel_file.rb → old_pre_proxy_jexcel_file.rb} +0 -0
- data/lib/applications/ruby_poi_translations.rb +64 -0
- data/lib/applications/spreadsheet_extensions.rb +31 -0
- data/lib/datashift/method_details_manager.rb +4 -0
- data/lib/exporters/csv_exporter.rb +3 -1
- data/lib/exporters/excel_exporter.rb +59 -74
- data/lib/generators/excel_generator.rb +70 -74
- data/lib/guards.rb +57 -0
- data/lib/loaders/excel_loader.rb +105 -105
- data/lib/loaders/loader_base.rb +43 -21
- data/lib/loaders/paperclip/attachment_loader.rb +104 -0
- data/lib/loaders/paperclip/datashift_paperclip.rb +78 -0
- data/lib/loaders/paperclip/{image_loader.rb → image_loading.rb} +2 -18
- data/lib/thor/{generate_excel.thor → generate.thor} +48 -0
- data/lib/thor/paperclip.thor +85 -0
- data/lib/thor/tools.thor +23 -2
- data/spec/Gemfile +1 -7
- data/spec/csv_exporter_spec.rb +4 -4
- data/spec/csv_loader_spec.rb +1 -1
- data/spec/excel_exporter_spec.rb +43 -45
- data/spec/excel_generator_spec.rb +132 -60
- data/spec/excel_loader_spec.rb +134 -140
- data/spec/excel_spec.rb +179 -0
- data/spec/fixtures/ProjectsMultiCategoriesHeaderLookup.xls +0 -0
- data/spec/fixtures/config/database.yml +2 -2
- data/spec/fixtures/db/datashift_test_models_db.sqlite +0 -0
- data/spec/{db → fixtures/db}/migrate/20110803201325_create_test_bed.rb +0 -0
- data/spec/fixtures/load_datashift.thor +3 -0
- data/spec/fixtures/models/category.rb +7 -0
- data/spec/fixtures/models/empty.rb +2 -0
- data/spec/fixtures/models/loader_release.rb +10 -0
- data/spec/fixtures/models/long_and_complex_table_linked_to_version.rb +6 -0
- data/spec/fixtures/models/milestone.rb +8 -0
- data/spec/fixtures/models/owner.rb +5 -0
- data/spec/fixtures/models/project.rb +26 -0
- data/spec/fixtures/models/test_model_defs.rb +67 -0
- data/spec/fixtures/models/version.rb +7 -0
- data/spec/loader_spec.rb +4 -3
- data/spec/method_dictionary_spec.rb +7 -6
- data/spec/method_mapper_spec.rb +3 -2
- data/spec/rails_sandbox/.gitignore +15 -0
- data/spec/rails_sandbox/Gemfile +40 -0
- data/spec/rails_sandbox/README.rdoc +261 -0
- data/spec/rails_sandbox/Rakefile +7 -0
- data/spec/rails_sandbox/app/assets/images/rails.png +0 -0
- data/spec/rails_sandbox/app/assets/javascripts/application.js +15 -0
- data/spec/rails_sandbox/app/assets/stylesheets/application.css +13 -0
- data/spec/rails_sandbox/app/controllers/application_controller.rb +3 -0
- data/spec/rails_sandbox/app/helpers/application_helper.rb +2 -0
- data/spec/rails_sandbox/app/mailers/.gitkeep +0 -0
- data/spec/rails_sandbox/app/models/.gitkeep +0 -0
- data/spec/rails_sandbox/app/models/category.rb +7 -0
- data/spec/rails_sandbox/app/models/empty.rb +2 -0
- data/spec/rails_sandbox/app/models/loader_release.rb +10 -0
- data/spec/rails_sandbox/app/models/long_and_complex_table_linked_to_version.rb +6 -0
- data/spec/rails_sandbox/app/models/milestone.rb +8 -0
- data/spec/rails_sandbox/app/models/owner.rb +5 -0
- data/spec/rails_sandbox/app/models/project.rb +26 -0
- data/spec/rails_sandbox/app/models/test_model_defs.rb +67 -0
- data/spec/rails_sandbox/app/models/version.rb +7 -0
- data/spec/rails_sandbox/app/views/layouts/application.html.erb +14 -0
- data/spec/rails_sandbox/config.ru +4 -0
- data/spec/rails_sandbox/config/application.rb +62 -0
- data/spec/rails_sandbox/config/boot.rb +6 -0
- data/spec/rails_sandbox/config/database.yml +20 -0
- data/spec/rails_sandbox/config/environment.rb +5 -0
- data/spec/rails_sandbox/config/environments/development.rb +37 -0
- data/spec/rails_sandbox/config/environments/production.rb +67 -0
- data/spec/rails_sandbox/config/environments/test.rb +37 -0
- data/spec/rails_sandbox/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/rails_sandbox/config/initializers/inflections.rb +15 -0
- data/spec/rails_sandbox/config/initializers/mime_types.rb +5 -0
- data/spec/rails_sandbox/config/initializers/secret_token.rb +7 -0
- data/spec/rails_sandbox/config/initializers/session_store.rb +8 -0
- data/spec/rails_sandbox/config/initializers/wrap_parameters.rb +14 -0
- data/spec/rails_sandbox/config/locales/en.yml +5 -0
- data/spec/rails_sandbox/config/routes.rb +58 -0
- data/spec/rails_sandbox/db/migrate/20110803201325_create_test_bed.rb +96 -0
- data/spec/rails_sandbox/db/schema.rb +81 -0
- data/spec/rails_sandbox/db/seeds.rb +7 -0
- data/spec/rails_sandbox/lib/assets/.gitkeep +0 -0
- data/spec/rails_sandbox/lib/tasks/.gitkeep +0 -0
- data/spec/rails_sandbox/log/.gitkeep +0 -0
- data/spec/rails_sandbox/public/404.html +26 -0
- data/spec/rails_sandbox/public/422.html +26 -0
- data/spec/rails_sandbox/public/500.html +25 -0
- data/spec/rails_sandbox/public/favicon.ico +0 -0
- data/spec/rails_sandbox/public/index.html +241 -0
- data/spec/rails_sandbox/public/robots.txt +5 -0
- data/spec/rails_sandbox/script/rails +6 -0
- data/spec/rails_sandbox/test/fixtures/.gitkeep +0 -0
- data/spec/rails_sandbox/test/functional/.gitkeep +0 -0
- data/spec/rails_sandbox/test/integration/.gitkeep +0 -0
- data/spec/rails_sandbox/test/performance/browsing_test.rb +12 -0
- data/spec/rails_sandbox/test/test_helper.rb +13 -0
- data/spec/rails_sandbox/test/unit/.gitkeep +0 -0
- data/spec/rails_sandbox/vendor/assets/javascripts/.gitkeep +0 -0
- data/spec/rails_sandbox/vendor/assets/stylesheets/.gitkeep +0 -0
- data/spec/rails_sandbox/vendor/plugins/.gitkeep +0 -0
- data/spec/spec_helper.rb +144 -121
- data/spec/thor_spec.rb +34 -14
- metadata +207 -194
- data/lib/helpers/spree_helper.rb +0 -213
- data/lib/loaders/spreadsheet_loader.rb +0 -144
- data/lib/loaders/spree/image_loader.rb +0 -90
- data/lib/loaders/spree/product_loader.rb +0 -354
- data/lib/thor/spree/bootstrap_cleanup.thor +0 -61
- data/lib/thor/spree/products_images.thor +0 -252
- data/lib/thor/spree/reports.thor +0 -56
- data/public/spree/products/large/DEMO_001_ror_bag.jpeg +0 -0
- data/public/spree/products/large/DEMO_002_Powerstation.jpg +0 -0
- data/public/spree/products/large/DEMO_003_ror_mug.jpeg +0 -0
- data/public/spree/products/mini/DEMO_001_ror_bag.jpeg +0 -0
- data/public/spree/products/mini/DEMO_002_Powerstation.jpg +0 -0
- data/public/spree/products/mini/DEMO_003_ror_mug.jpeg +0 -0
- data/public/spree/products/original/DEMO_001_ror_bag.jpeg +0 -0
- data/public/spree/products/original/DEMO_002_Powerstation.jpg +0 -0
- data/public/spree/products/original/DEMO_003_ror_mug.jpeg +0 -0
- data/public/spree/products/product/DEMO_001_ror_bag.jpeg +0 -0
- data/public/spree/products/product/DEMO_002_Powerstation.jpg +0 -0
- data/public/spree/products/product/DEMO_003_ror_mug.jpeg +0 -0
- data/public/spree/products/small/DEMO_001_ror_bag.jpeg +0 -0
- data/public/spree/products/small/DEMO_002_Powerstation.jpg +0 -0
- data/public/spree/products/small/DEMO_003_ror_mug.jpeg +0 -0
- data/spec/fixtures/datashift_Spree_db.sqlite +0 -0
- data/spec/fixtures/datashift_test_models_db.sqlite +0 -0
- data/spec/fixtures/negative/SpreeProdMiss1Mandatory.csv +0 -4
- data/spec/fixtures/negative/SpreeProdMiss1Mandatory.xls +0 -0
- data/spec/fixtures/negative/SpreeProdMissManyMandatory.csv +0 -4
- data/spec/fixtures/negative/SpreeProdMissManyMandatory.xls +0 -0
- data/spec/fixtures/spree/SpreeImages.xls +0 -0
- data/spec/fixtures/spree/SpreeMultiVariant.csv +0 -4
- data/spec/fixtures/spree/SpreeProducts.csv +0 -4
- data/spec/fixtures/spree/SpreeProducts.xls +0 -0
- data/spec/fixtures/spree/SpreeProductsDefaults.yml +0 -15
- data/spec/fixtures/spree/SpreeProductsMandatoryOnly.xls +0 -0
- data/spec/fixtures/spree/SpreeProductsMultiColumn.csv +0 -4
- data/spec/fixtures/spree/SpreeProductsMultiColumn.xls +0 -0
- data/spec/fixtures/spree/SpreeProductsSimple.csv +0 -4
- data/spec/fixtures/spree/SpreeProductsSimple.xls +0 -0
- data/spec/fixtures/spree/SpreeProductsWithImages.csv +0 -4
- data/spec/fixtures/spree/SpreeProductsWithImages.xls +0 -0
- data/spec/fixtures/spree/SpreeZoneExample.csv +0 -5
- data/spec/fixtures/spree/SpreeZoneExample.xls +0 -0
- data/spec/spree_exporter_spec.rb +0 -72
- data/spec/spree_generator_spec.rb +0 -96
- data/spec/spree_images_loader_spec.rb +0 -107
- data/spec/spree_loader_spec.rb +0 -375
- data/spec/spree_method_mapping_spec.rb +0 -226
- data/spec/spree_variants_loader_spec.rb +0 -189
- data/tasks/export/excel_generator.rake +0 -102
- data/tasks/import/excel.rake +0 -75
- data/test/helper.rb +0 -18
- data/test/test_interact.rb +0 -7
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# Copyright:: (c) Autotelik Media Ltd 2012
|
|
2
|
+
# Author :: Tom Statter
|
|
3
|
+
# Date :: Sept 2012
|
|
4
|
+
# License:: MIT. Free, Open Source.
|
|
5
|
+
#
|
|
6
|
+
# => Provides facilities for bulk uploading/exporting attachments provided by PaperClip gem
|
|
7
|
+
#
|
|
8
|
+
require 'loader_base'
|
|
9
|
+
require 'datashift_paperclip'
|
|
10
|
+
|
|
11
|
+
module DataShift
|
|
12
|
+
|
|
13
|
+
class AttachmentLoader < LoaderBase
|
|
14
|
+
|
|
15
|
+
include DataShift::Paperclip
|
|
16
|
+
|
|
17
|
+
attr_accessor :attach_to_klass
|
|
18
|
+
|
|
19
|
+
def initialize(attachment_klazz, attachment = nil, options = {})
|
|
20
|
+
|
|
21
|
+
opts = options.merge(:load => false)
|
|
22
|
+
|
|
23
|
+
super( attachment_klazz, attachment, opts )
|
|
24
|
+
|
|
25
|
+
@attach_to_klass = options[:attach_to_klass]
|
|
26
|
+
|
|
27
|
+
puts "Attachment Class is #{@attachment_klazz}" if(@verbose)
|
|
28
|
+
|
|
29
|
+
raise "Failed to create Attachment for loading" unless @load_object
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# :split_file_name_on
|
|
33
|
+
|
|
34
|
+
def process_from_filesystem(path, options )
|
|
35
|
+
|
|
36
|
+
@attach_to_klass = options[:attach_to_klazz] if(options[:attach_to_klazz])
|
|
37
|
+
|
|
38
|
+
raise "The class that attachments belong to has not set" unless(@attach_to_klass)
|
|
39
|
+
|
|
40
|
+
@attachment_path = path
|
|
41
|
+
|
|
42
|
+
missing_records = []
|
|
43
|
+
|
|
44
|
+
# try splitting up filename in various ways looking for the SKU
|
|
45
|
+
split_search_term = @config['split_file_name_on'] || options[:split_file_name_on]
|
|
46
|
+
|
|
47
|
+
cache = Paperclip::get_files(@attachment_path, options)
|
|
48
|
+
|
|
49
|
+
puts "Found #{cache.size} files - splitting names on delimiter [#{split_search_term}]"
|
|
50
|
+
|
|
51
|
+
lookup_field = options[:attach_to_lookup_field]
|
|
52
|
+
|
|
53
|
+
cache.each do |file_name|
|
|
54
|
+
|
|
55
|
+
attachment_name = File.basename(file_name)
|
|
56
|
+
|
|
57
|
+
logger.info "Processing attachment file #{attachment_name} "
|
|
58
|
+
|
|
59
|
+
base_name = File.basename(file_name, '.*')
|
|
60
|
+
base_name.strip!
|
|
61
|
+
|
|
62
|
+
record = nil
|
|
63
|
+
|
|
64
|
+
record = get_record_by(@attach_to_klass, lookup_field, base_name, split_search_term)
|
|
65
|
+
|
|
66
|
+
if(record)
|
|
67
|
+
logger.info "Found record for attachment : #{record.inspect}"
|
|
68
|
+
else
|
|
69
|
+
missing_records << file_name
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
next if(options[:dummy]) # Don't actually create/upload to DB if we are doing dummy run
|
|
73
|
+
|
|
74
|
+
# Check if attachment must have an associated record
|
|
75
|
+
if(record)
|
|
76
|
+
reset()
|
|
77
|
+
|
|
78
|
+
create_attachment(@load_object_class, file_name, record, options[:attach_to_klass_field], options)
|
|
79
|
+
|
|
80
|
+
puts "Added Attachment #{File.basename(file_name)} to #{record.send(lookup_field)} : #{record.id}" if(@verbose)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
unless missing_records.empty?
|
|
86
|
+
FileUtils.mkdir_p('MissingAttachmentRecords') unless File.directory?('MissingAttachmentRecords')
|
|
87
|
+
|
|
88
|
+
puts "WARNING : #{missing_records.size} of #{cache.size} files could not be attached to a #{@load_object_class}"
|
|
89
|
+
puts "For your convenience a copy of files with MISSING #{@load_object_class} : ./MissingAttachmentRecords"
|
|
90
|
+
missing_records.each do |i|
|
|
91
|
+
puts "Copying #{i} to MissingAttachmentRecords folder" if(options[:verbose])
|
|
92
|
+
FileUtils.cp( i, 'MissingAttachmentRecords') unless(options[:dummy] == 'true')
|
|
93
|
+
end
|
|
94
|
+
else
|
|
95
|
+
puts "All files (#{cache.size}) were succesfully attached to a #{@load_object_class}"
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
puts "Dummy Run Complete- if happy run without -d" if(options[:dummy])
|
|
99
|
+
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
end
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# Copyright:: (c) Autotelik Media Ltd 2012
|
|
2
|
+
# Author :: Tom Statter
|
|
3
|
+
# Date :: Sept 2012
|
|
4
|
+
# License:: MIT. Free, Open Source.
|
|
5
|
+
#
|
|
6
|
+
# Details:: Module containing common functionality for working with Paperclip attachments
|
|
7
|
+
#
|
|
8
|
+
require 'logging'
|
|
9
|
+
|
|
10
|
+
module DataShift
|
|
11
|
+
|
|
12
|
+
module Paperclip
|
|
13
|
+
|
|
14
|
+
include DataShift::Logging
|
|
15
|
+
|
|
16
|
+
# Get all image files (based on file extensions) from supplied path.
|
|
17
|
+
# Options :
|
|
18
|
+
# :glob : The glob to use to find files
|
|
19
|
+
# => :recursive : Descend tree looking for files rather than just supplied path
|
|
20
|
+
|
|
21
|
+
def self.get_files(path, options = {})
|
|
22
|
+
glob = options[:glob] ? options[:glob] : '*.*'
|
|
23
|
+
glob = (options['recursive'] || options[:recursive]) ? "**/#{glob}" : glob
|
|
24
|
+
|
|
25
|
+
Dir.glob("#{path}/#{glob}", File::FNM_CASEFOLD)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def get_file( attachment_path )
|
|
29
|
+
|
|
30
|
+
unless File.exists?(attachment_path) && File.readable?(attachment_path)
|
|
31
|
+
logger.error("Cannot process Image from #{Dir.pwd}: Invalid Path #{attachment_path}")
|
|
32
|
+
raise "Cannot process Image : Invalid Path #{attachment_path}"
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
file = begin
|
|
36
|
+
File.new(attachment_path, "rb")
|
|
37
|
+
rescue => e
|
|
38
|
+
puts e.inspect
|
|
39
|
+
raise "ERROR : Failed to read image #{attachment_path}"
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
file
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Note the paperclip attachment model defines the storage path via something like :
|
|
46
|
+
# => :path => ":rails_root/public/blah/blahs/:id/:style/:basename.:extension"
|
|
47
|
+
# Options
|
|
48
|
+
# has_attached_file_name : Paperclip attachment name defined with macro 'has_attached_file :name'
|
|
49
|
+
# e.g
|
|
50
|
+
# has_attached_file :avatar => options[:has_attached_file_name] = :avatar
|
|
51
|
+
# has_attached_file :icon => options[:has_attached_file_name] = :icon
|
|
52
|
+
#
|
|
53
|
+
# alt : Alternatice text for images
|
|
54
|
+
|
|
55
|
+
def create_attachment(klass, attachment_path, record = nil, attach_to_record_field = nil, options = {})
|
|
56
|
+
|
|
57
|
+
has_attached_file = options[:has_attached_file_name] ? options[:has_attached_file_name].to_sym : :attachment
|
|
58
|
+
|
|
59
|
+
file = get_file(attachment_path)
|
|
60
|
+
|
|
61
|
+
begin
|
|
62
|
+
|
|
63
|
+
attachment = if(record && attach_to_record_field)
|
|
64
|
+
klass.new( {has_attached_file => file}, :without_protection => true)
|
|
65
|
+
else
|
|
66
|
+
klass.new( {has_attached_file => file, attach_to_record_field.to_sym => record}, :without_protection => true)
|
|
67
|
+
end
|
|
68
|
+
puts attachment.save ? "Success: Created #{attachment.id} : #{attachment.attachment_file_name}" : "ERROR : Problem saving to DB : #{attachment.inspect}"
|
|
69
|
+
rescue => e
|
|
70
|
+
puts "PaperClip error - Problem creating Attachment from : #{attachment_path}"
|
|
71
|
+
puts e.inspect, e.backtrace
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
end
|
|
@@ -5,13 +5,13 @@
|
|
|
5
5
|
#
|
|
6
6
|
# => Provides facilities for bulk uploading/exporting attachments provided by PaperClip
|
|
7
7
|
# gem
|
|
8
|
-
require '
|
|
8
|
+
require 'datashift_paperclip'
|
|
9
9
|
|
|
10
10
|
module DataShift
|
|
11
11
|
|
|
12
12
|
module ImageLoading
|
|
13
13
|
|
|
14
|
-
include DataShift::
|
|
14
|
+
include DataShift::Paperclip
|
|
15
15
|
|
|
16
16
|
# Get all image files (based on file extensions) from supplied path.
|
|
17
17
|
# Options :
|
|
@@ -25,22 +25,6 @@ module DataShift
|
|
|
25
25
|
Dir.glob("#{path}/#{glob}", File::FNM_CASEFOLD)
|
|
26
26
|
end
|
|
27
27
|
|
|
28
|
-
def get_file( attachment_path )
|
|
29
|
-
|
|
30
|
-
unless File.exists?(attachment_path) && File.readable?(attachment_path)
|
|
31
|
-
logger.error("Cannot process Image from #{Dir.pwd}: Invalid Path #{attachment_path}")
|
|
32
|
-
raise "Cannot process Image : Invalid Path #{attachment_path}"
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
file = begin
|
|
36
|
-
File.new(attachment_path, "rb")
|
|
37
|
-
rescue => e
|
|
38
|
-
puts e.inspect
|
|
39
|
-
raise "ERROR : Failed to read image #{attachment_path}"
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
file
|
|
43
|
-
end
|
|
44
28
|
|
|
45
29
|
# Note the paperclip attachment model defines the storage path via something like :
|
|
46
30
|
# => :path => ":rails_root/public/blah/blahs/:id/:style/:basename.:extension"
|
|
@@ -72,6 +72,54 @@ module Datashift
|
|
|
72
72
|
end
|
|
73
73
|
|
|
74
74
|
end
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
desc "csv", "generate a template from an active record model (with optional associations)"
|
|
78
|
+
method_option :model, :aliases => '-m', :required => true, :desc => "The active record model to export"
|
|
79
|
+
method_option :result, :aliases => '-r', :required => true, :desc => "Create template of model in supplied file"
|
|
80
|
+
method_option :assoc, :aliases => '-a', :type => :boolean, :desc => "Include all associations in the template"
|
|
81
|
+
method_option :exclude, :aliases => '-e', :type => :array, :desc => "Use with -a : Exclude association types. Any from #{DataShift::MethodDetail::supported_types_enum.to_a.inspect}"
|
|
82
|
+
|
|
83
|
+
def csv()
|
|
84
|
+
|
|
85
|
+
# TODO - We're assuming run from a rails app/top level dir...
|
|
86
|
+
# ...can we make this more robust ? e.g what about when using active record but not in Rails app,
|
|
87
|
+
require File.expand_path('config/environment.rb')
|
|
88
|
+
|
|
89
|
+
require 'csv_generator'
|
|
90
|
+
|
|
91
|
+
model = options[:model]
|
|
92
|
+
result = options[:result]
|
|
93
|
+
|
|
94
|
+
logger.info "Datashift: Start CSV template generation in #{result}"
|
|
95
|
+
|
|
96
|
+
begin
|
|
97
|
+
# support modules e.g "Spree::Property")
|
|
98
|
+
klass = ModelMapper::class_from_string(model) #Kernel.const_get(model)
|
|
99
|
+
rescue NameError => e
|
|
100
|
+
puts e
|
|
101
|
+
raise Thor::Error.new("ERROR: No such Model [#{model}] found - check valid model supplied")
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
raise Thor::Error.new("ERROR: No such Model [#{model}] found - check valid model supplied") unless(klass)
|
|
105
|
+
|
|
106
|
+
begin
|
|
107
|
+
gen = DataShift::CsvGenerator.new(result)
|
|
108
|
+
|
|
109
|
+
if(options[:assoc])
|
|
110
|
+
opts = (options[:exclude]) ? {:exclude => options[:exclude]} : {}
|
|
111
|
+
logger.info("Datashift: Generating with associations")
|
|
112
|
+
gen.generate_with_associations(klass, opts)
|
|
113
|
+
else
|
|
114
|
+
gen.generate(klass)
|
|
115
|
+
end
|
|
116
|
+
rescue => e
|
|
117
|
+
puts e
|
|
118
|
+
puts e.backtrace
|
|
119
|
+
puts "Warning: Error during generation, template may be incomplete"
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
end
|
|
75
123
|
end
|
|
76
124
|
|
|
77
125
|
end
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# Copyright:: (c) Autotelik Media Ltd 2012
|
|
2
|
+
# Author :: Tom Statter
|
|
3
|
+
# Date :: Sept 2012
|
|
4
|
+
# License:: MIT.
|
|
5
|
+
#
|
|
6
|
+
# Usage::
|
|
7
|
+
#
|
|
8
|
+
# To pull Datashift commands into your main application :
|
|
9
|
+
#
|
|
10
|
+
# require 'datashift'
|
|
11
|
+
#
|
|
12
|
+
# DataShift::load_commands
|
|
13
|
+
#
|
|
14
|
+
# thor help datashift:paperclip:attach
|
|
15
|
+
#
|
|
16
|
+
require 'datashift'
|
|
17
|
+
|
|
18
|
+
# Note, not DataShift, case sensitive, create namespace for command line : datashift
|
|
19
|
+
module Datashift
|
|
20
|
+
|
|
21
|
+
class Paperclip < Thor
|
|
22
|
+
|
|
23
|
+
include DataShift::Logging
|
|
24
|
+
|
|
25
|
+
desc "attach", "Attach files from a directory\nwhere file names contain somewhere the lookup info"
|
|
26
|
+
|
|
27
|
+
# :dummy => dummy run without actual saving to DB
|
|
28
|
+
method_option :input, :aliases => '-i', :required => true, :desc => "The input path containing images "
|
|
29
|
+
|
|
30
|
+
method_option :glob, :aliases => '-g', :desc => 'The glob to use to find files e.g. \'{*.jpg,*.gif,*.png}\' '
|
|
31
|
+
method_option :recursive, :aliases => '-r', :type => :boolean, :desc => "Scan sub directories of input for images"
|
|
32
|
+
|
|
33
|
+
method_option :attachment_klass, :required => true, :aliases => '-a', :desc => "Ruby Class name of the Attachment e.g Image, Icon"
|
|
34
|
+
method_option :attach_to_klass, :required => true, :aliases => '-k', :desc => "Ruby Class name attachment belongs to e.g Product, Blog"
|
|
35
|
+
method_option :attach_to_klass_field, :required => true, :aliases => '-f', :desc => "Attachment belongs to field e.g Product.image, Blog.digital"
|
|
36
|
+
|
|
37
|
+
method_option :attach_to_lookup_field, :required => true, :aliases => '-l', :desc => "The field to use to find the :attach_to_klass record"
|
|
38
|
+
|
|
39
|
+
method_option :split_file_name_on, :type => :string, :desc => "delimiter to progressivley split filename for lookup", :default => ' '
|
|
40
|
+
method_option :case_sensitive, :type => :boolean, :desc => "Use case sensitive where clause to find :attach_to_klass"
|
|
41
|
+
method_option :use_like, :type => :boolean, :desc => "Use :lookup_field LIKE 'string%' instead of :lookup_field = 'string' in where clauses to find :attach_to_klass"
|
|
42
|
+
|
|
43
|
+
method_option :dummy, :aliases => '-d', :type => :boolean, :desc => "Dummy run, do not actually save attachment"
|
|
44
|
+
|
|
45
|
+
method_option :skip_when_assoc, :aliases => '-x', :type => :boolean, :desc => "Do not process if :attach_to_klass already has an attachment"
|
|
46
|
+
|
|
47
|
+
method_option :verbose, :aliases => '-v', :type => :boolean, :desc => "Verbose logging"
|
|
48
|
+
|
|
49
|
+
def attach()
|
|
50
|
+
|
|
51
|
+
@attachment_path = options[:input]
|
|
52
|
+
|
|
53
|
+
unless(File.exists?(@attachment_path))
|
|
54
|
+
puts "ERROR: Supplied Path [#{@attachment_path}] not accesible"
|
|
55
|
+
exit(-1)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
require File.expand_path('config/environment.rb')
|
|
59
|
+
|
|
60
|
+
require 'paperclip/attachment_loader'
|
|
61
|
+
|
|
62
|
+
@verbose = options[:verbose]
|
|
63
|
+
|
|
64
|
+
puts "Using Field #{options[:attach_to_field]} for lookup"
|
|
65
|
+
|
|
66
|
+
klazz = ModelMapper::class_from_string( options[:attachment_klass] )
|
|
67
|
+
raise "Cannot find Attachment Class #{options[:attachment_klass]}" unless klazz
|
|
68
|
+
|
|
69
|
+
attachment_klazz = ModelMapper::class_from_string( options[:attach_to_klass] )
|
|
70
|
+
raise "Cannot find Attach to Class #{options[:attach_to_klass]}" unless klazz
|
|
71
|
+
|
|
72
|
+
opts = options.dup
|
|
73
|
+
|
|
74
|
+
opts[:attach_to_klass] = attachment_klazz # Pass in real Ruby class not string class name
|
|
75
|
+
|
|
76
|
+
loader = DataShift::Paperclip::AttachmentLoader.new(klazz, nil, opts)
|
|
77
|
+
|
|
78
|
+
logger.info "Loading attachments from #{@attachment_path}"
|
|
79
|
+
|
|
80
|
+
loader.process_from_filesystem(@attachment_path, opts)
|
|
81
|
+
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
end
|
data/lib/thor/tools.thor
CHANGED
|
@@ -19,16 +19,36 @@ module Datashift
|
|
|
19
19
|
|
|
20
20
|
include DataShift::Logging
|
|
21
21
|
|
|
22
|
-
desc "zip", "Create zip of
|
|
22
|
+
desc "zip", "Create zip of files"
|
|
23
23
|
|
|
24
24
|
method_option :path, :aliases => '-p', :required => true, :desc => "The path to the digital files"
|
|
25
|
-
method_option :
|
|
25
|
+
method_option :output, :aliases => '-o', :required => true, :desc => "The resulting zip file name"
|
|
26
26
|
|
|
27
27
|
def zip()
|
|
28
28
|
|
|
29
29
|
require 'zip/zip'
|
|
30
30
|
require 'zip/zipfilesystem'
|
|
31
31
|
|
|
32
|
+
output = options[:output]
|
|
33
|
+
|
|
34
|
+
Zip::ZipOutputStream.open(output) do |zos|
|
|
35
|
+
Dir[File.join(options[:path], '**', '*.*')].each do |p|
|
|
36
|
+
zos.put_next_entry(File.basename(p))
|
|
37
|
+
zos.print IO.read(p)
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
desc "zip_matching", "Create zip of matching digital files e.g zip up pdf, jpg and png versions of a file"
|
|
43
|
+
|
|
44
|
+
method_option :path, :aliases => '-p', :required => true, :desc => "The path to the digital files"
|
|
45
|
+
method_option :results, :aliases => '-r', :required => true, :desc => "The path to store resulting zip files"
|
|
46
|
+
|
|
47
|
+
def zip_matching()
|
|
48
|
+
|
|
49
|
+
require 'zip/zip'
|
|
50
|
+
require 'zip/zipfilesystem'
|
|
51
|
+
|
|
32
52
|
ready_to_zip = {}
|
|
33
53
|
Dir[File.join(options[:path], '**', '*.*')].each do |p|
|
|
34
54
|
next if File.directory? p
|
|
@@ -57,6 +77,7 @@ module Datashift
|
|
|
57
77
|
end
|
|
58
78
|
|
|
59
79
|
end
|
|
80
|
+
|
|
60
81
|
end
|
|
61
82
|
|
|
62
83
|
end
|
data/spec/Gemfile
CHANGED
data/spec/csv_exporter_spec.rb
CHANGED
|
@@ -10,14 +10,14 @@ require File.dirname(__FILE__) + '/spec_helper'
|
|
|
10
10
|
require 'erb'
|
|
11
11
|
require 'csv_exporter'
|
|
12
12
|
|
|
13
|
-
describe 'CSV
|
|
13
|
+
describe 'CSV Exporter' do
|
|
14
14
|
|
|
15
15
|
before(:all) do
|
|
16
16
|
|
|
17
|
+
# load our test model definitions - Project etc
|
|
18
|
+
require ifixture_file('test_model_defs')
|
|
19
|
+
|
|
17
20
|
db_connect( 'test_file' ) # , test_memory, test_mysql
|
|
18
|
-
|
|
19
|
-
# load our test model definitions - Project etc
|
|
20
|
-
require File.join($DataShiftFixturePath, 'test_model_defs')
|
|
21
21
|
|
|
22
22
|
# handle migration changes or reset of test DB
|
|
23
23
|
migrate_up
|
data/spec/csv_loader_spec.rb
CHANGED
|
@@ -15,7 +15,7 @@ describe 'CSV Loader' do
|
|
|
15
15
|
before(:all) do
|
|
16
16
|
|
|
17
17
|
# load our test model definitions - Project etc
|
|
18
|
-
require
|
|
18
|
+
require ifixture_file('test_model_defs')
|
|
19
19
|
|
|
20
20
|
db_connect( 'test_file' ) # , test_memory, test_mysql
|
|
21
21
|
migrate_up
|