spreadsheet_importer 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 4d394ba8cad7df71a772ef15e3011d6ae1966c9d
4
+ data.tar.gz: 431c1654b821b4a53537da0262d0a1c7256ca180
5
+ SHA512:
6
+ metadata.gz: 5451b7aba04813c408a5204922bf8291f1211aec11a0b9add3397b6a738b28c858dec3f6ebcbbd9f0a316dae0a38f37387bcb2d15ea179400014e6a76366ad51
7
+ data.tar.gz: d5aa427e390905dcfe84b44d09b1414cc3665760b920c4c82a453c5edb444353592ebc95203dda35d1f35735d4909d367ae6927b270fa037bd7cc4a204eaee18
data/README.md CHANGED
@@ -1,3 +1,32 @@
1
- = SpreadsheetImporter
1
+ # SpreadsheetImporter
2
2
 
3
- This project rocks and uses MIT-LICENSE.
3
+ ```ruby
4
+ gem 'spreadsheet_importer'
5
+ ```
6
+
7
+
8
+ ## Usage
9
+ ```ruby
10
+ SpreadsheetImporter::Import.from_spreadsheet(spreadsheet) do |row|
11
+ # Do some work on the row
12
+ end
13
+
14
+ # Starting at a custom offset
15
+ SpreadsheetImporter::Import.from_spreadsheet(spreadsheet, :start_row => 5) do |row|
16
+ ```
17
+
18
+ ### 2D Array
19
+ ```ruby
20
+ SpreadsheetImporter::Import.from_spreadsheet([["Bob", "Hoskins"], ["Roger", "Rabbit"]])
21
+ ```
22
+
23
+ ### CSV
24
+ ```ruby
25
+ SpreadsheetImporter::Import.from_csv("users.csv")
26
+ ```
27
+
28
+ ### .xlsx
29
+ ```
30
+ SpreadsheetImporter::Import.from_xlsx("users.xlsx")
31
+ SpreadsheetImporter::Import.from_xlsx("users.xlsx", :sheet_name => '2015') # Processing a single sheet
32
+ ```
@@ -1,6 +1,5 @@
1
1
  # GEMS
2
2
  require 'roo'
3
- require 'conformist'
4
3
  require 'charlock_holmes'
5
4
 
6
5
  # LIB
@@ -22,33 +22,81 @@ module SpreadsheetImporter
22
22
  # Determine whether the column separator is a tab or comma
23
23
  col_sep = csv.count("\t") > 0 ? "\t" : ","
24
24
 
25
- spreadsheet = CSV.parse(csv, :col_sep => col_sep, :headers => true, :header_converters => :downcase)
25
+ spreadsheet = CSV.parse(csv, :col_sep => col_sep, :headers => true, :header_converters => :downcase).to_a
26
26
  from_spreadsheet(spreadsheet, options, &block)
27
27
  end
28
28
 
29
+ # Returns 2D array of the spreadsheet, rows by columns
30
+ # If a block is given, yields each row to the block
31
+ # Exceptions during the iteration will collected along with their row number
32
+ # and re-raised at the end of processing
29
33
  def self.from_spreadsheet(spreadsheet, options = {}, &block)
30
34
  options = {:start_row => 1, :schema => nil}.merge(options)
31
35
 
32
- (options[:start_row] - 1).times { spreadsheet.shift } # Remove intro rows
33
- spreadsheet = options[:schema].conform(spreadsheet) if options[:schema] # If a Conformist schema is provided, use that to prepare rows
36
+ # Remove intro rows
37
+ (options[:start_row] - 1).times { spreadsheet.shift }
34
38
 
39
+ headers = spreadsheet.first
40
+ if options[:required_columns]
41
+ assert_required_columns!(headers, options[:required_columns])
42
+ end
43
+
44
+ if options[:schema] # If a Conformist schema is provided, use that to prepare rows
45
+ rows = options[:schema].conform(spreadsheet, :skip_first => true)
46
+ else
47
+ rows = spreadsheet
48
+ end
49
+
50
+ # Create an enumerator the standardizes the output from conformist or 2D array spreadsheet
35
51
  errors = []
36
- rowcount = 0
37
- spreadsheet.each do |row|
38
- rowcount += 1
39
- begin
40
- block.call(row)
41
- print '.'
42
- rescue => e
43
- progress_indicator = '!'
44
- errors << "Row #{rowcount}: #{e.message}"
45
- print '!'
52
+ spreadsheet = Spreadsheet.new do |yielder|
53
+ row_number = options[:start_row]
54
+ rows.each_with_index do |row, index|
55
+ begin
56
+ yielder.yield row_to_attributes(row, headers), index, row_number
57
+ rescue => e
58
+ errors << "Row #{row_number}: #{e.message}\n#{e.backtrace.join("\n")}"
59
+ end
60
+ row_number += 1
46
61
  end
47
62
  end
63
+ spreadsheet.errors = errors
64
+ spreadsheet.each(&block) if block_given?
65
+
66
+ return spreadsheet
67
+ end
68
+
69
+ private
70
+
71
+ def self.assert_required_columns!(headers, required_columns)
72
+ required_columns.each do |column_name|
73
+ raise MissingRequiredColumn, "Spreadsheet must include a '#{column_name}' column" unless column_present?(headers, column_name)
74
+ end
75
+ end
48
76
 
49
- rowcount += options[:start_row] if rowcount > 0
77
+ def self.column_present?(headers, column_name)
78
+ headers.collect{|c| c.downcase.squish}.include?(column_name.downcase.squish)
79
+ end
50
80
 
51
- return {:imported => rowcount - errors.count, :errors => errors, :total => rowcount}
81
+ # Returns an attributes hash for the given row
82
+ def self.row_to_attributes(row, headers)
83
+ case row
84
+ when Array
85
+ Hash[ItemSchema.attribute_names(headers).zip(row)]
86
+ else # Handle Conformist::HashStruct rows
87
+ row.attributes
88
+ end
52
89
  end
90
+
53
91
  end
92
+
93
+ # Spreadsheet
94
+
95
+ class Spreadsheet < Enumerator
96
+ attr_accessor :errors
97
+ end
98
+
99
+ # EXCEPTIONS
100
+
101
+ class MissingRequiredColumn < StandardError; end
54
102
  end
@@ -1,3 +1,3 @@
1
1
  module SpreadsheetImporter
2
- VERSION = "0.1.0"
2
+ VERSION = "0.1.1"
3
3
  end
metadata CHANGED
@@ -1,8 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spreadsheet_importer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
5
- prerelease:
4
+ version: 0.1.1
6
5
  platform: ruby
7
6
  authors:
8
7
  - Nicholas Jakobsen
@@ -10,12 +9,11 @@ authors:
10
9
  autorequire:
11
10
  bindir: bin
12
11
  cert_chain: []
13
- date: 2015-05-19 00:00:00.000000000 Z
12
+ date: 2015-06-26 00:00:00.000000000 Z
14
13
  dependencies:
15
14
  - !ruby/object:Gem::Dependency
16
15
  name: culturecode-roo
17
16
  requirement: !ruby/object:Gem::Requirement
18
- none: false
19
17
  requirements:
20
18
  - - "~>"
21
19
  - !ruby/object:Gem::Version
@@ -23,7 +21,6 @@ dependencies:
23
21
  type: :runtime
24
22
  prerelease: false
25
23
  version_requirements: !ruby/object:Gem::Requirement
26
- none: false
27
24
  requirements:
28
25
  - - "~>"
29
26
  - !ruby/object:Gem::Version
@@ -31,7 +28,6 @@ dependencies:
31
28
  - !ruby/object:Gem::Dependency
32
29
  name: charlock_holmes
33
30
  requirement: !ruby/object:Gem::Requirement
34
- none: false
35
31
  requirements:
36
32
  - - ">="
37
33
  - !ruby/object:Gem::Version
@@ -39,7 +35,6 @@ dependencies:
39
35
  type: :runtime
40
36
  prerelease: false
41
37
  version_requirements: !ruby/object:Gem::Requirement
42
- none: false
43
38
  requirements:
44
39
  - - ">="
45
40
  - !ruby/object:Gem::Version
@@ -52,35 +47,34 @@ executables: []
52
47
  extensions: []
53
48
  extra_rdoc_files: []
54
49
  files:
55
- - lib/spreadsheet_importer/import.rb
56
- - lib/spreadsheet_importer/version.rb
57
- - lib/spreadsheet_importer.rb
58
50
  - MIT-LICENSE
59
- - Rakefile
60
51
  - README.md
52
+ - Rakefile
53
+ - lib/spreadsheet_importer.rb
54
+ - lib/spreadsheet_importer/import.rb
55
+ - lib/spreadsheet_importer/version.rb
61
56
  homepage: https://github.com/culturecode/spreadsheet_importer
62
57
  licenses:
63
58
  - MIT
59
+ metadata: {}
64
60
  post_install_message:
65
61
  rdoc_options: []
66
62
  require_paths:
67
63
  - lib
68
64
  required_ruby_version: !ruby/object:Gem::Requirement
69
- none: false
70
65
  requirements:
71
66
  - - ">="
72
67
  - !ruby/object:Gem::Version
73
68
  version: '0'
74
69
  required_rubygems_version: !ruby/object:Gem::Requirement
75
- none: false
76
70
  requirements:
77
71
  - - ">="
78
72
  - !ruby/object:Gem::Version
79
73
  version: '0'
80
74
  requirements: []
81
75
  rubyforge_project:
82
- rubygems_version: 1.8.25
76
+ rubygems_version: 2.4.7
83
77
  signing_key:
84
- specification_version: 3
78
+ specification_version: 4
85
79
  summary: Makes it easy to import spreadsheets.
86
80
  test_files: []