datashift 0.11.1 → 0.12.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +3 -2
- data/VERSION +1 -1
- data/datashift.gemspec +11 -174
- data/lib/datashift/column_packer.rb +64 -0
- data/lib/datashift/delimiters.rb +17 -1
- data/lib/datashift/exceptions.rb +7 -0
- data/lib/datashift/querying.rb +10 -4
- data/lib/loaders/csv_loader.rb +69 -32
- data/lib/loaders/excel_loader.rb +86 -53
- data/lib/loaders/loader_base.rb +32 -18
- data/lib/loaders/paperclip/attachment_loader.rb +11 -8
- data/lib/loaders/paperclip/datashift_paperclip.rb +21 -18
- data/lib/loaders/reporter.rb +48 -0
- data/spec/Gemfile.lock +129 -0
- data/spec/csv_exporter_spec.rb +1 -1
- metadata +121 -191
- data/.document +0 -5
- data/lib/java/poi-3.7/._poi-3.7-20101029.jar5645100390082102460.tmp +0 -0
- data/spec/MissingAttachmentRecords/DEMO_001_ror_bag.jpeg +0 -0
- data/spec/MissingAttachmentRecords/DEMO_002_Powerstation.jpeg +0 -0
- data/spec/MissingAttachmentRecords/DEMO_002_Powerstation.jpg +0 -0
- data/spec/MissingAttachmentRecords/DEMO_003_ror_mug.jpeg +0 -0
- data/spec/MissingAttachmentRecords/DEMO_004_ror_ringer.jpeg +0 -0
- data/spec/fixtures/BadAssociationName.xls +0 -0
- data/spec/fixtures/DemoNegativeTesting.xls +0 -0
- data/spec/fixtures/ProjectsDefaults.yml +0 -29
- data/spec/fixtures/ProjectsMultiCategories.xls +0 -0
- data/spec/fixtures/ProjectsMultiCategoriesHeaderLookup.xls +0 -0
- data/spec/fixtures/ProjectsSingleCategories.xls +0 -0
- data/spec/fixtures/SimpleProjects.xls +0 -0
- data/spec/fixtures/config/database.yml +0 -28
- data/spec/fixtures/db/datashift_test_models_db.sqlite +0 -0
- data/spec/fixtures/db/migrate/20110803201325_create_test_bed.rb +0 -96
- data/spec/fixtures/db/migrate/20121009161700_add_digitals.rb +0 -24
- data/spec/fixtures/images/DEMO_001_ror_bag.jpeg +0 -0
- data/spec/fixtures/images/DEMO_002_Powerstation.jpeg +0 -0
- data/spec/fixtures/images/DEMO_003_ror_mug.jpeg +0 -0
- data/spec/fixtures/images/DEMO_004_ror_ringer.jpeg +0 -0
- data/spec/fixtures/load_datashift.thor +0 -3
- data/spec/fixtures/models/category.rb +0 -7
- data/spec/fixtures/models/digital.rb +0 -14
- data/spec/fixtures/models/empty.rb +0 -2
- data/spec/fixtures/models/loader_release.rb +0 -10
- data/spec/fixtures/models/long_and_complex_table_linked_to_version.rb +0 -6
- data/spec/fixtures/models/milestone.rb +0 -8
- data/spec/fixtures/models/owner.rb +0 -7
- data/spec/fixtures/models/project.rb +0 -26
- data/spec/fixtures/models/version.rb +0 -7
- data/spec/fixtures/simple_export_spec.xls +0 -0
- data/spec/fixtures/simple_template_spec.xls +0 -0
- data/spec/fixtures/test_model_defs.rb +0 -9
- data/spec/rails_sandbox/.gitignore +0 -15
- data/spec/rails_sandbox/Gemfile +0 -40
- data/spec/rails_sandbox/README.rdoc +0 -261
- data/spec/rails_sandbox/Rakefile +0 -7
- data/spec/rails_sandbox/app/assets/images/rails.png +0 -0
- data/spec/rails_sandbox/app/assets/javascripts/application.js +0 -15
- data/spec/rails_sandbox/app/assets/stylesheets/application.css +0 -13
- data/spec/rails_sandbox/app/controllers/application_controller.rb +0 -3
- data/spec/rails_sandbox/app/helpers/application_helper.rb +0 -2
- 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 +0 -7
- data/spec/rails_sandbox/app/models/empty.rb +0 -2
- data/spec/rails_sandbox/app/models/loader_release.rb +0 -10
- data/spec/rails_sandbox/app/models/long_and_complex_table_linked_to_version.rb +0 -6
- data/spec/rails_sandbox/app/models/milestone.rb +0 -8
- data/spec/rails_sandbox/app/models/owner.rb +0 -5
- data/spec/rails_sandbox/app/models/project.rb +0 -26
- data/spec/rails_sandbox/app/models/test_model_defs.rb +0 -67
- data/spec/rails_sandbox/app/models/version.rb +0 -7
- data/spec/rails_sandbox/app/views/layouts/application.html.erb +0 -14
- data/spec/rails_sandbox/config.ru +0 -4
- data/spec/rails_sandbox/config/application.rb +0 -62
- data/spec/rails_sandbox/config/boot.rb +0 -6
- data/spec/rails_sandbox/config/database.yml +0 -20
- data/spec/rails_sandbox/config/environment.rb +0 -5
- data/spec/rails_sandbox/config/environments/development.rb +0 -37
- data/spec/rails_sandbox/config/environments/production.rb +0 -67
- data/spec/rails_sandbox/config/environments/test.rb +0 -37
- data/spec/rails_sandbox/config/initializers/backtrace_silencers.rb +0 -7
- data/spec/rails_sandbox/config/initializers/inflections.rb +0 -15
- data/spec/rails_sandbox/config/initializers/mime_types.rb +0 -5
- data/spec/rails_sandbox/config/initializers/secret_token.rb +0 -7
- data/spec/rails_sandbox/config/initializers/session_store.rb +0 -8
- data/spec/rails_sandbox/config/initializers/wrap_parameters.rb +0 -14
- data/spec/rails_sandbox/config/locales/en.yml +0 -5
- data/spec/rails_sandbox/config/routes.rb +0 -58
- data/spec/rails_sandbox/db/migrate/20110803201325_create_test_bed.rb +0 -96
- data/spec/rails_sandbox/db/schema.rb +0 -81
- data/spec/rails_sandbox/db/seeds.rb +0 -7
- 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 +0 -26
- data/spec/rails_sandbox/public/422.html +0 -26
- data/spec/rails_sandbox/public/500.html +0 -25
- data/spec/rails_sandbox/public/favicon.ico +0 -0
- data/spec/rails_sandbox/public/index.html +0 -241
- data/spec/rails_sandbox/public/robots.txt +0 -5
- data/spec/rails_sandbox/script/rails +0 -6
- 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 +0 -12
- data/spec/rails_sandbox/test/test_helper.rb +0 -13
- 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/lib/loaders/excel_loader.rb
CHANGED
@@ -22,6 +22,8 @@ module DataShift
|
|
22
22
|
module ExcelLoading
|
23
23
|
|
24
24
|
# Options:
|
25
|
+
# [:dummy] : Perform a dummy run - attempt to load everything but then roll back
|
26
|
+
#
|
25
27
|
# [:sheet_number] : Default is 0. The index of the Excel Worksheet to use.
|
26
28
|
# [:header_row] : Default is 0. Use alternative row as header definition.
|
27
29
|
#
|
@@ -72,77 +74,108 @@ module DataShift
|
|
72
74
|
|
73
75
|
logger.info "Excel Loader processing #{@sheet.num_rows} rows"
|
74
76
|
|
75
|
-
|
76
|
-
|
77
|
-
|
77
|
+
@reporter.reset
|
78
|
+
|
79
|
+
begin
|
80
|
+
puts "Dummy Run - Changes will be rolled back" if options[:dummy]
|
81
|
+
|
82
|
+
load_object_class.transaction do
|
78
83
|
|
79
|
-
|
80
|
-
|
81
|
-
|
84
|
+
@sheet.each_with_index do |row, i|
|
85
|
+
|
86
|
+
@current_row = row
|
87
|
+
|
88
|
+
next if(i == header_row_index)
|
82
89
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
contains_data = false
|
90
|
+
# Excel num_rows seems to return all 'visible' rows, which appears to be greater than the actual data rows
|
91
|
+
# (TODO - write spec to process .xls with a huge number of rows)
|
92
|
+
#
|
93
|
+
# This is rubbish but currently manually detect when actual data ends, this isn't very smart but
|
94
|
+
# got no better idea than ending once we hit the first completely empty row
|
95
|
+
break if @current_row.nil?
|
91
96
|
|
92
|
-
|
93
|
-
|
97
|
+
logger.info "Processing Row #{i} : #{@current_row}"
|
98
|
+
|
99
|
+
contains_data = false
|
100
|
+
|
101
|
+
begin
|
102
|
+
# First assign any default values for columns not included in parsed_file
|
103
|
+
process_missing_columns_with_defaults
|
94
104
|
|
95
|
-
|
96
|
-
|
97
|
-
|
105
|
+
# TODO - Smart sorting of column processing order ....
|
106
|
+
# Does not currently ensure mandatory columns (for valid?) processed first but model needs saving
|
107
|
+
# before associations can be processed so user should ensure mandatory columns are prior to associations
|
98
108
|
|
99
|
-
|
100
|
-
|
109
|
+
# as part of this we also attempt to save early, for example before assigning to
|
110
|
+
# has_and_belongs_to associations which require the load_object has an id for the join table
|
101
111
|
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
112
|
+
# Iterate over method_details, working on data out of associated Excel column
|
113
|
+
@method_mapper.method_details.each do |method_detail|
|
114
|
+
|
115
|
+
next unless method_detail # TODO populate unmapped with a real MethodDetail that is 'null' and create is_nil
|
106
116
|
|
107
|
-
|
117
|
+
logger.info "Processing Column #{method_detail.column_index}"
|
118
|
+
|
119
|
+
value = @current_row[method_detail.column_index]
|
108
120
|
|
109
|
-
|
121
|
+
contains_data = true unless(value.nil? || value.to_s.empty?)
|
110
122
|
|
111
|
-
|
123
|
+
prepare_data(method_detail, value)
|
112
124
|
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
125
|
+
process()
|
126
|
+
end
|
127
|
+
|
128
|
+
rescue => e
|
129
|
+
@reporter.processed_object_count += 1
|
130
|
+
|
131
|
+
failure(@current_row, true)
|
132
|
+
logger.error "Failed to process row [#{i}] (#{@current_row})"
|
133
|
+
# don't forget to reset the load object
|
134
|
+
new_load_object
|
135
|
+
next
|
136
|
+
end
|
137
|
+
|
138
|
+
break unless(contains_data == true)
|
139
|
+
|
140
|
+
# currently here as we can only identify the end of a speadsheet by first empty row
|
141
|
+
@reporter.processed_object_count += 1
|
142
|
+
|
143
|
+
# TODO - make optional - all or nothing or carry on and dump out the exception list at end
|
128
144
|
|
129
|
-
|
130
|
-
|
145
|
+
unless(save)
|
146
|
+
failure
|
147
|
+
logger.error "Failed to save row [#{@current_row}]"
|
148
|
+
logger.error load_object.errors.inspect if(load_object)
|
149
|
+
else
|
150
|
+
logger.info "Row #{@current_row} succesfully SAVED : ID #{load_object.id}"
|
151
|
+
@reporter.add_loaded_object(@load_object)
|
152
|
+
end
|
153
|
+
|
154
|
+
# don't forget to reset the object or we'll update rather than create
|
155
|
+
new_load_object
|
131
156
|
|
157
|
+
end
|
158
|
+
|
159
|
+
raise ActiveRecord::Rollback if(options[:dummy]) # Don't actually create/upload to DB if we are doing dummy run
|
132
160
|
end
|
133
|
-
end
|
134
|
-
|
135
|
-
loaded_objects.compact! if(loaded_objects)
|
136
161
|
|
137
|
-
|
138
|
-
puts "There were NO failures." if failed_objects.empty?
|
162
|
+
rescue => e
|
139
163
|
|
140
|
-
|
164
|
+
if e.is_a?(ActiveRecord::Rollback) && options[:dummy]
|
165
|
+
puts "Excel loading stage complete - Dummy run so Rolling Back."
|
166
|
+
else
|
167
|
+
raise e
|
168
|
+
end
|
169
|
+
ensure
|
170
|
+
report
|
171
|
+
end
|
172
|
+
|
141
173
|
end
|
142
|
-
|
174
|
+
|
143
175
|
def value_at(row, column)
|
144
176
|
@excel[row, column]
|
145
177
|
end
|
178
|
+
|
146
179
|
end
|
147
180
|
|
148
181
|
|
@@ -159,7 +192,7 @@ module DataShift
|
|
159
192
|
def perform_load( file_name, options = {} )
|
160
193
|
perform_excel_load( file_name, options )
|
161
194
|
|
162
|
-
puts "Excel loading stage complete - #{
|
195
|
+
puts "Excel loading stage complete - #{loaded_count} rows added."
|
163
196
|
end
|
164
197
|
|
165
198
|
end
|
data/lib/loaders/loader_base.rb
CHANGED
@@ -28,7 +28,7 @@ module DataShift
|
|
28
28
|
attr_accessor :load_object_class, :load_object
|
29
29
|
attr_accessor :current_value, :current_method_detail
|
30
30
|
|
31
|
-
attr_accessor :
|
31
|
+
attr_accessor :reporter
|
32
32
|
|
33
33
|
attr_accessor :config, :verbose
|
34
34
|
|
@@ -51,7 +51,7 @@ module DataShift
|
|
51
51
|
|
52
52
|
# Gather names of all possible 'setter' methods on AR class (instance variables and associations)
|
53
53
|
if((find_operators && !MethodDictionary::for?(object_class)) || options[:reload])
|
54
|
-
puts "Building Method Dictionary for class #{object_class}"
|
54
|
+
#puts "DEBUG Building Method Dictionary for class #{object_class}"
|
55
55
|
DataShift::MethodDictionary.find_operators( @load_object_class, :reload => options[:reload], :instance_methods => options[:instance_methods] )
|
56
56
|
|
57
57
|
# Create dictionary of data on all possible 'setter' methods which can be used to
|
@@ -73,9 +73,7 @@ module DataShift
|
|
73
73
|
@prefixes = {}
|
74
74
|
@postfixes = {}
|
75
75
|
|
76
|
-
|
77
|
-
@loaded_objects = []
|
78
|
-
@failed_objects = []
|
76
|
+
@reporter = DataShift::Reporter.new
|
79
77
|
|
80
78
|
reset(object)
|
81
79
|
end
|
@@ -88,6 +86,8 @@ module DataShift
|
|
88
86
|
#
|
89
87
|
# OPTIONS :
|
90
88
|
#
|
89
|
+
# [:dummy] : Perform a dummy run - attempt to load everything but then roll back
|
90
|
+
#
|
91
91
|
# strict : Raise an exception of any headers can't be mapped to an attribute/association
|
92
92
|
# ignore : List of column headers to ignore when building operator map
|
93
93
|
# mandatory : List of columns that must be present in headers
|
@@ -100,8 +100,12 @@ module DataShift
|
|
100
100
|
|
101
101
|
raise DataShift::BadFile, "Cannot load #{file_name} file not found." unless(File.exists?(file_name))
|
102
102
|
|
103
|
+
logger.info("Perform Load Options:\n#{options.inspect}")
|
104
|
+
|
103
105
|
ext = File.extname(file_name)
|
104
|
-
|
106
|
+
|
107
|
+
# TODO - make more modular - these methods doing too much, for example move the object creation/reset
|
108
|
+
# out of these perform... methods to make it easier to over ride that behaviour
|
105
109
|
if(ext.casecmp('.xls') == 0)
|
106
110
|
perform_excel_load(file_name, options)
|
107
111
|
elsif(ext.casecmp('.csv') == 0)
|
@@ -111,7 +115,9 @@ module DataShift
|
|
111
115
|
end
|
112
116
|
end
|
113
117
|
|
114
|
-
|
118
|
+
def report
|
119
|
+
@reporter.report
|
120
|
+
end
|
115
121
|
|
116
122
|
# Core API
|
117
123
|
#
|
@@ -166,6 +172,7 @@ module DataShift
|
|
166
172
|
def process_missing_columns_with_defaults()
|
167
173
|
inbound_ops = @method_mapper.operator_names
|
168
174
|
@default_values.each do |dn, dv|
|
175
|
+
logger.debug "Processing default value #{dn} : #{dv}"
|
169
176
|
assignment(dn, @load_object, dv) unless(inbound_ops.include?(dn))
|
170
177
|
end
|
171
178
|
end
|
@@ -382,20 +389,27 @@ module DataShift
|
|
382
389
|
end
|
383
390
|
end
|
384
391
|
|
385
|
-
|
386
|
-
|
392
|
+
|
393
|
+
# Loading failed. Store a failed object and if requested roll back (destroy) the current load object
|
394
|
+
# For use case where object saved early but subsequent required columns fail to process
|
395
|
+
# so the load object is invalid
|
396
|
+
|
397
|
+
def failure( object = @load_object, rollback = false)
|
398
|
+
if(object)
|
399
|
+
@reporter.add_failed_object(object)
|
400
|
+
|
401
|
+
@load_object.destroy if(rollback && ! @load_object.new_record?)
|
402
|
+
|
403
|
+
new_load_object # don't forget to reset the load object
|
404
|
+
end
|
387
405
|
end
|
388
406
|
|
389
407
|
def save
|
390
408
|
return unless( @load_object )
|
391
409
|
|
392
|
-
puts "DEBUG: SAVING #{@load_object.class} : #{@load_object.inspect}" if(@verbose)
|
410
|
+
#puts "DEBUG: SAVING #{@load_object.class} : #{@load_object.inspect}" if(@verbose)
|
393
411
|
begin
|
394
|
-
|
395
|
-
|
396
|
-
@loaded_objects << @load_object unless(@loaded_objects.include?(@load_object))
|
397
|
-
|
398
|
-
return result
|
412
|
+
return @load_object.save
|
399
413
|
rescue => e
|
400
414
|
failure
|
401
415
|
puts "Error saving #{@load_object.class} : #{e.inspect}"
|
@@ -447,7 +461,7 @@ module DataShift
|
|
447
461
|
#
|
448
462
|
def reset(object = nil)
|
449
463
|
@load_object = object || new_load_object
|
450
|
-
@
|
464
|
+
@reporter.reset
|
451
465
|
@current_value = nil
|
452
466
|
end
|
453
467
|
|
@@ -462,11 +476,11 @@ module DataShift
|
|
462
476
|
end
|
463
477
|
|
464
478
|
def loaded_count
|
465
|
-
|
479
|
+
reporter.loaded_objects.size
|
466
480
|
end
|
467
481
|
|
468
482
|
def failed_count
|
469
|
-
|
483
|
+
reporter.failed_objects.size
|
470
484
|
end
|
471
485
|
|
472
486
|
|
@@ -98,10 +98,14 @@ module DataShift
|
|
98
98
|
|
99
99
|
# This version creates attachments and also attaches them to instances of :attach_to_klazz
|
100
100
|
#
|
101
|
+
# Each file found in PATH will be processed - it's filename being used to scan for
|
102
|
+
# a matching record to attach the file to.
|
103
|
+
#
|
101
104
|
# Options
|
102
105
|
# :split_file_name_on Used in scan process to progresivly split filename to find
|
103
106
|
# :attach_to_klass with matching :attach_to_find_by_field
|
104
107
|
#
|
108
|
+
# :add_prefix
|
105
109
|
#
|
106
110
|
def process_from_filesystem(path, options = {} )
|
107
111
|
|
@@ -135,12 +139,11 @@ module DataShift
|
|
135
139
|
|
136
140
|
record = nil
|
137
141
|
|
138
|
-
puts "Attempting
|
142
|
+
puts "Attempting fo find Record for file name : #{base_name}"
|
139
143
|
record = get_record_by(attach_to_klass, attach_to_find_by_field, base_name, split_on, options)
|
140
144
|
|
141
145
|
if(record)
|
142
|
-
puts "Found record
|
143
|
-
logger.info "Found record for attachment : #{record.inspect}"
|
146
|
+
puts "Found #{record.class} where : #{attach_to_find_by_field} = #{record.send(attach_to_find_by_field)}(id : #{record.id})"
|
144
147
|
else
|
145
148
|
missing_records << file_name
|
146
149
|
end
|
@@ -162,15 +165,15 @@ module DataShift
|
|
162
165
|
FileUtils.mkdir_p('MissingAttachmentRecords') unless File.directory?('MissingAttachmentRecords')
|
163
166
|
|
164
167
|
puts "WARNING : #{missing_records.size} of #{loading_files_cache.size} files could not be attached to a #{@load_object_class}"
|
165
|
-
puts "For your convenience files with MISSING #{attach_to_klass}
|
166
|
-
missing_records.each do |i|
|
167
|
-
puts "Copying #{i} to MissingAttachmentRecords folder" if(options[:verbose])
|
168
|
+
puts "For your convenience copying files with MISSING #{attach_to_klass} to : MissingAttachmentRecords"
|
169
|
+
missing_records.each do |i|
|
168
170
|
FileUtils.cp( i, 'MissingAttachmentRecords') unless(options[:dummy] == 'true')
|
171
|
+
puts "Copyied #{i} to MissingAttachmentRecords folder" if(options[:verbose])
|
169
172
|
end
|
170
|
-
else
|
171
|
-
puts "Created #{loading_files_cache.size} #{@load_object_class} attachments and succesfully attached to a #{@attach_to_klass}"
|
172
173
|
end
|
173
174
|
|
175
|
+
puts "Created #{loading_files_cache.size - missing_records.size} of #{loading_files_cache.size} #{@load_object_class} attachments and succesfully attached to a #{@attach_to_klass}"
|
176
|
+
|
174
177
|
puts "Dummy Run Complete- if happy run without -d" if(options[:dummy])
|
175
178
|
|
176
179
|
end
|
@@ -13,7 +13,7 @@ module DataShift
|
|
13
13
|
module Paperclip
|
14
14
|
|
15
15
|
include DataShift::Logging
|
16
|
-
|
16
|
+
|
17
17
|
require 'paperclip/attachment_loader'
|
18
18
|
|
19
19
|
attr_accessor :attachment
|
@@ -34,14 +34,14 @@ module DataShift
|
|
34
34
|
|
35
35
|
unless File.exists?(attachment_path) && File.readable?(attachment_path)
|
36
36
|
logger.error("Cannot process Image from #{Dir.pwd}: Invalid Path #{attachment_path}")
|
37
|
-
raise "Cannot process Image : Invalid Path #{attachment_path}"
|
37
|
+
raise PathError.new("Cannot process Image : Invalid Path #{attachment_path}")
|
38
38
|
end
|
39
39
|
|
40
40
|
file = begin
|
41
41
|
File.new(attachment_path, "rb")
|
42
42
|
rescue => e
|
43
43
|
puts e.inspect
|
44
|
-
raise "ERROR : Failed to read image #{attachment_path}"
|
44
|
+
raise PathError.new("ERROR : Failed to read image from #{attachment_path}")
|
45
45
|
end
|
46
46
|
|
47
47
|
file
|
@@ -54,11 +54,13 @@ module DataShift
|
|
54
54
|
#
|
55
55
|
# :attributes
|
56
56
|
#
|
57
|
-
# Pass through hash of attributes to klass initializer
|
57
|
+
# Pass through a hash of attributes to the Paperclip klass's initializer
|
58
58
|
#
|
59
59
|
# :has_attached_file_name
|
60
60
|
#
|
61
61
|
# Paperclip attachment name defined with macro 'has_attached_file :name'
|
62
|
+
#
|
63
|
+
# This is usually called/defaults :attachment
|
62
64
|
#
|
63
65
|
# e.g
|
64
66
|
# When : has_attached_file :avatar
|
@@ -73,19 +75,21 @@ module DataShift
|
|
73
75
|
|
74
76
|
has_attached_file_attribute = options[:has_attached_file_name] ? options[:has_attached_file_name].to_sym : :attachment
|
75
77
|
|
76
|
-
|
77
|
-
|
78
|
-
|
78
|
+
# e.g (:attachment => File.read)
|
79
|
+
paperclip_attributes = { has_attached_file_attribute => get_file(attachment_path) }
|
80
|
+
|
81
|
+
paperclip_attributes.merge!(options[:attributes]) if(options[:attributes])
|
79
82
|
|
80
|
-
|
83
|
+
begin
|
84
|
+
@attachment = klass.new(paperclip_attributes, :without_protection => true)
|
85
|
+
rescue => e
|
86
|
+
puts e.inspect
|
87
|
+
logger.error("Failed to create PaperClip Attachment : #{e.inspect}")
|
88
|
+
raise CreateAttachmentFailed.new("Failed to create PaperClip Attachment from : #{attachment_path}")
|
89
|
+
end
|
81
90
|
|
82
|
-
#attributes.merge!(attach_to_record_field.to_sym => record) if(record && attach_to_record_field)
|
83
|
-
|
84
|
-
puts attributes.inspect
|
85
91
|
begin
|
86
92
|
|
87
|
-
@attachment = klass.new(attributes, :without_protection => true)
|
88
|
-
|
89
93
|
if(@attachment.save)
|
90
94
|
puts "Success: Created Attachment #{@attachment.id} : #{@attachment.attachment_file_name}"
|
91
95
|
|
@@ -103,12 +107,11 @@ module DataShift
|
|
103
107
|
|
104
108
|
@attachment
|
105
109
|
rescue => e
|
106
|
-
|
107
|
-
puts e.inspect
|
110
|
+
logger.error("Problem saving Paperclip Attachment: #{e.inspect}")
|
111
|
+
puts e.inspect
|
112
|
+
raise CreateAttachmentFailed.new("PaperClip error - Problem saving Attachment")
|
108
113
|
end
|
109
|
-
end
|
110
|
-
|
114
|
+
end
|
111
115
|
end
|
112
116
|
|
113
|
-
|
114
117
|
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# Copyright:: (c) Autotelik Media Ltd 2011
|
2
|
+
# Author :: Tom Statter
|
3
|
+
# Date :: Dec 2012
|
4
|
+
# License:: MIT
|
5
|
+
#
|
6
|
+
# Details:: Store and report stats
|
7
|
+
#
|
8
|
+
module DataShift
|
9
|
+
|
10
|
+
|
11
|
+
class Reporter
|
12
|
+
|
13
|
+
include DataShift::Logging
|
14
|
+
|
15
|
+
attr_accessor :processed_object_count, :loaded_objects, :failed_objects
|
16
|
+
|
17
|
+
|
18
|
+
def initialize()
|
19
|
+
reset
|
20
|
+
end
|
21
|
+
|
22
|
+
def reset()
|
23
|
+
@processed_object_count = 0
|
24
|
+
@loaded_objects, @failed_objects = [], []
|
25
|
+
end
|
26
|
+
|
27
|
+
def add_loaded_object(object)
|
28
|
+
@loaded_objects << object unless(object.nil? || @loaded_objects.include?(object))
|
29
|
+
end
|
30
|
+
|
31
|
+
def add_failed_object(object)
|
32
|
+
@failed_objects << object unless( object.nil? || @failed_objects.include?(object))
|
33
|
+
end
|
34
|
+
|
35
|
+
def report
|
36
|
+
loaded_objects.compact! if(loaded_objects)
|
37
|
+
|
38
|
+
puts "Processing complete:"
|
39
|
+
puts "Processed total of #{processed_object_count} entries"
|
40
|
+
puts "#{loaded_objects.size} objects were succesfully processed."
|
41
|
+
|
42
|
+
puts "There were NO failures." if failed_objects.empty?
|
43
|
+
|
44
|
+
puts "WARNING : Check logs : #{failed_objects.size} rows contained errors and #{failed_objects.size} records NOT created." unless failed_objects.empty?
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
end
|