xls_porter 0.0.7

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.
Files changed (2) hide show
  1. data/lib/xls_porter.rb +133 -0
  2. metadata +77 -0
data/lib/xls_porter.rb ADDED
@@ -0,0 +1,133 @@
1
+ module XlsPorter
2
+
3
+ class XlsUploader < CarrierWave::Uploader::Base
4
+ include CarrierWave::MimeTypes
5
+ process :set_content_type
6
+
7
+ # Include the Sprockets helpers for Rails 3.1+ asset pipeline compatibility:
8
+ include Sprockets::Helpers::RailsHelper
9
+ include Sprockets::Helpers::IsolatedHelper
10
+
11
+ # Choose what kind of storage to use for this uploader:
12
+ storage :file
13
+ # storage :fog
14
+
15
+ # Override the directory where uploaded files will be stored.
16
+ # This is a sensible default for uploaders that are meant to be mounted:
17
+ def store_dir
18
+ "#{Rails.root}/tmp/upload/"
19
+ end
20
+
21
+ # Override the filename of the uploaded files:
22
+ # Avoid using model.id or version_name here, see uploader/store.rb for details.
23
+ # def filename
24
+ # "something.jpg" if original_filename
25
+ # end
26
+
27
+ def extension_white_list
28
+ known=%w(xls xlsx)
29
+ known << /\w+/
30
+ end
31
+ end
32
+
33
+ def to_xls(list, columns, name)
34
+ book = Spreadsheet::Workbook.new
35
+ sheet = book.create_worksheet :name => name
36
+ row = sheet.row(0)
37
+ columns.each {|column| row.push(column)}
38
+ idx = 0
39
+ list.each do |it|
40
+ row = sheet.row(idx += 1)
41
+ columns.each {|column| row.push(it[column])}
42
+ end
43
+ return book
44
+ end
45
+
46
+ def model_to_xls(model)
47
+ to_xls(model.all, model.column_names, model.name)
48
+ end
49
+
50
+ # sanitize and prefix filename with timestamp
51
+ # store the uploaded file
52
+ def store_uploaded_file(uploaded_file)
53
+ uploaded_file.original_filename = "#{Time.now.to_i}_#{File.basename(uploaded_file.original_filename)}"
54
+ file = XlsUploader.new
55
+ file.store!(uploaded_file)
56
+ return file
57
+ end
58
+
59
+ def xls_to_model(xls_file_path, model, ignore=[])
60
+ #TODO exception handling
61
+
62
+ book = Spreadsheet.open(xls_file_path)
63
+ sheet = book.worksheet(0)
64
+ columns = sheet.row(0)
65
+ ignore_columns = (columns - model.column_names) + ignore
66
+ id_idx = columns.find_index("id")
67
+ updates = []
68
+ # Read each row, skip the first (column names)
69
+ sheet.each 1 do |row|
70
+ id = row[id_idx]
71
+ record = nil
72
+ if id.nil?
73
+ record = model.new
74
+ record["update"] = "new"
75
+ else
76
+ begin
77
+ record = model.find(id)
78
+ record["update"] = "exist"
79
+ rescue
80
+ record = model.new
81
+ record["update"] = "new"
82
+ end
83
+ end
84
+ (0..(columns.size - 1)).each do |i|
85
+ value = row[i]
86
+ value = value.strip if value.is_a?(String)
87
+ column = columns[i]
88
+ if column == "id" and record["update"] == "new"
89
+ record["id"] = value
90
+ elsif ignore_columns.include?(column)
91
+ #skip if column is ignored
92
+ elsif record[column].blank? and value.blank?
93
+ #skip if both are either nil or empty
94
+ elsif [DateTime, Time, Date].include?(value.class)
95
+ #puts "#{column} #{record[column]} == #{value} ? #{record[column].to_i == value.to_i}"
96
+ #TODO comparator and assigner for date types
97
+ else
98
+ if record[column] != value
99
+ record[column] = value
100
+ record["update"] = "updated" if record["update"] == "exist"
101
+ record["update_notes"] = [] if record["update_notes"].nil?
102
+ record["update_notes"] << column
103
+ end
104
+ end
105
+ end
106
+ #track all updates
107
+ updates << record if %w(new updated).include?(record["update"]) #not record.changed.empty?
108
+ end
109
+ #commit changes only after processing all updates
110
+ updates.each do |update|
111
+ begin
112
+ update.save
113
+ rescue Exception => exception
114
+ #track validation exception
115
+ update["update"] = "exception"
116
+ update["update_notes"] = exception.to_s
117
+ end
118
+ end
119
+ return {:columns => (%w(update update_notes) + columns), :updates => updates, :model => model.name}
120
+ end
121
+
122
+ def cleanup_tmp_file(file_path)
123
+ File.delete(file_path) if File.exist?(file_path)
124
+ end
125
+
126
+ def xls_upload_and_update_model(uploaded_file, model)
127
+ file_path = store_uploaded_file(uploaded_file).store_path
128
+ model_updates = xls_to_model(file_path, model)
129
+ cleanup_tmp_file(file_path)
130
+ return model_updates
131
+ end
132
+
133
+ end
metadata ADDED
@@ -0,0 +1,77 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: xls_porter
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.7
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Michael Reyes
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-10-23 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: carrierwave
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: sprockets
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ description: Export to and Import from XLS for Ruby and Rails apps
47
+ email: mikereyes.kg77@gmail.com
48
+ executables: []
49
+ extensions: []
50
+ extra_rdoc_files: []
51
+ files:
52
+ - lib/xls_porter.rb
53
+ homepage: http://rubygems.org/gems/xls_porter
54
+ licenses: []
55
+ post_install_message:
56
+ rdoc_options: []
57
+ require_paths:
58
+ - lib
59
+ required_ruby_version: !ruby/object:Gem::Requirement
60
+ none: false
61
+ requirements:
62
+ - - ! '>='
63
+ - !ruby/object:Gem::Version
64
+ version: 1.9.2
65
+ required_rubygems_version: !ruby/object:Gem::Requirement
66
+ none: false
67
+ requirements:
68
+ - - ! '>='
69
+ - !ruby/object:Gem::Version
70
+ version: '0'
71
+ requirements: []
72
+ rubyforge_project:
73
+ rubygems_version: 1.8.24
74
+ signing_key:
75
+ specification_version: 3
76
+ summary: Export to and Import from XLS
77
+ test_files: []