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