spreadsheet_importer 0.1.0 → 0.1.1

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.
@@ -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: []