csv_validator 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (5) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README.md +43 -0
  3. data/Rakefile +27 -0
  4. data/lib/csv_validator.rb +116 -0
  5. metadata +157 -0
@@ -0,0 +1,20 @@
1
+ Copyright 2012 YOURNAME
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,43 @@
1
+ ## Usage
2
+
3
+ Add to your Gemfile:
4
+
5
+ ```ruby
6
+ gem 'csv_validator'
7
+ ```
8
+
9
+ Run:
10
+
11
+ ```
12
+ bundle install
13
+ ```
14
+
15
+ Then add the following to your model:
16
+
17
+ ```ruby
18
+ attr_accessor :my_csv_file
19
+
20
+ validates :my_csv_file, :csv => true
21
+ ```
22
+
23
+ This will check to see if it is a properly formed CSV file.
24
+
25
+ In this case, csv_validator expects :my_csv_file to be an instance of ActionDispatch::Http::UploadedFile, which is created by default for Rails uploads.
26
+
27
+ ## Other validation options
28
+
29
+ There are a handful of other options for more specific validation too. A complete list is below... note that you wouldn't use all simultaneously.
30
+
31
+ ```ruby
32
+ validates :my_csv_file, :csv => {
33
+ :columns => 3, # an exact number of columns
34
+ :max_columns => 10, # a maximum number of columns
35
+ :min_columns => 1, # a minimum number of columns
36
+ :rows => 20, # an exact number of rows
37
+ :max_rows => 30, # a maximum number of rows
38
+ :min_rows => 2, # a minimum number of rows
39
+ :email => 0, # will check to make sure all emails in specified column are valid email addresses
40
+ :numericality => 0, # will check to make sure all values in specified column are numerical
41
+ }
42
+ ```
43
+
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env rake
2
+ begin
3
+ require 'bundler/setup'
4
+ rescue LoadError
5
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
6
+ end
7
+ begin
8
+ require 'rdoc/task'
9
+ rescue LoadError
10
+ require 'rdoc/rdoc'
11
+ require 'rake/rdoctask'
12
+ RDoc::Task = Rake::RDocTask
13
+ end
14
+
15
+ RDoc::Task.new(:rdoc) do |rdoc|
16
+ rdoc.rdoc_dir = 'rdoc'
17
+ rdoc.title = 'CsvValidator'
18
+ rdoc.options << '--line-numbers'
19
+ rdoc.rdoc_files.include('README.rdoc')
20
+ rdoc.rdoc_files.include('lib/**/*.rb')
21
+ end
22
+
23
+
24
+
25
+
26
+ Bundler::GemHelper.install_tasks
27
+
@@ -0,0 +1,116 @@
1
+ require 'active_model'
2
+ require 'active_model/validations'
3
+ require 'csv'
4
+ require 'mail'
5
+
6
+ class CsvValidator < ActiveModel::EachValidator
7
+ @@default_options = {}
8
+
9
+ def self.default_options
10
+ @@default_options
11
+ end
12
+
13
+ def validate_each(record, attribute, value)
14
+ options = @@default_options.merge(self.options)
15
+
16
+ unless value
17
+ record.errors.add(attribute, options[:message] || "must be present")
18
+ return
19
+ end
20
+
21
+ begin
22
+ csv = CSV.read(value.path)
23
+ rescue CSV::MalformedCSVError
24
+ record.errors.add(attribute, options[:message] || "is not a valid CSV file")
25
+ return
26
+ end
27
+
28
+ if options[:columns]
29
+ unless csv[0].length == options[:columns]
30
+ record.errors.add(attribute, options[:message] || "should have #{options[:columns]} columns")
31
+ end
32
+ end
33
+
34
+ if options[:max_columns]
35
+ if csv[0].length > options[:max_columns]
36
+ record.errors.add(attribute, options[:message] || "should have no more than #{options[:max_columns]} columns")
37
+ end
38
+ end
39
+
40
+ if options[:min_columns]
41
+ if csv[0].length < options[:min_columns]
42
+ record.errors.add(attribute, options[:message] || "should have at least #{options[:min_columns]} columns")
43
+ end
44
+ end
45
+
46
+ if options[:rows]
47
+ unless csv.length == options[:rows]
48
+ record.errors.add(attribute, options[:message] || "should have #{options[:rows]} rows")
49
+ end
50
+ end
51
+
52
+ if options[:min_rows]
53
+ if csv.length < options[:min_rows]
54
+ record.errors.add(attribute, options[:message] || "should have at least #{options[:min_rows]} rows")
55
+ end
56
+ end
57
+
58
+ if options[:max_rows]
59
+ if csv.length > options[:max_rows]
60
+ record.errors.add(attribute, options[:message] || "should have no more than #{options[:max_rows]} rows")
61
+ end
62
+ end
63
+
64
+ if options[:email]
65
+ emails = column_to_array(csv, options[:email])
66
+ invalid_emails = []
67
+ emails.each do |email|
68
+ begin
69
+ address = Mail::Address.new email
70
+ valid = address.address == email && address.domain
71
+ tree = address.__send__(:tree)
72
+ valid &&= (tree.domain.dot_atom_text.elements.size > 1)
73
+ rescue
74
+ valid = false
75
+ end
76
+ unless valid
77
+ invalid_emails << email
78
+ end
79
+ end
80
+
81
+ if invalid_emails.length > 0
82
+ record.errors.add(attribute, options[:message] || "contains invalid emails (#{invalid_emails.join(', ')})")
83
+ end
84
+ end
85
+
86
+ if options[:numericality]
87
+ numbers = column_to_array(csv, options[:numericality])
88
+ numbers.each do |number|
89
+ unless is_numeric?(number)
90
+ record.errors.add(attribute, options[:message] || "contains non-numeric content in column #{options[:numericality]}")
91
+ return
92
+ end
93
+ end
94
+ end
95
+
96
+ end
97
+
98
+ private
99
+
100
+ def column_to_array(csv, column_index)
101
+ column_contents = []
102
+ csv.each do |column|
103
+ column_contents << column[column_index].strip
104
+ end
105
+ column_contents
106
+ end
107
+
108
+ def is_numeric?(string)
109
+ Float(string)
110
+ true
111
+ rescue
112
+ false
113
+ end
114
+
115
+
116
+ end
metadata ADDED
@@ -0,0 +1,157 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: csv_validator
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.0.2
6
+ platform: ruby
7
+ authors:
8
+ - Matt Fordham
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2012-06-05 00:00:00 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: activemodel
17
+ prerelease: false
18
+ requirement: &id001 !ruby/object:Gem::Requirement
19
+ none: false
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ type: :runtime
25
+ version_requirements: *id001
26
+ - !ruby/object:Gem::Dependency
27
+ name: actionpack
28
+ prerelease: false
29
+ requirement: &id002 !ruby/object:Gem::Requirement
30
+ none: false
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: "0"
35
+ type: :runtime
36
+ version_requirements: *id002
37
+ - !ruby/object:Gem::Dependency
38
+ name: mail
39
+ prerelease: false
40
+ requirement: &id003 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ version: "0"
46
+ type: :runtime
47
+ version_requirements: *id003
48
+ - !ruby/object:Gem::Dependency
49
+ name: rake
50
+ prerelease: false
51
+ requirement: &id004 !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: "0"
57
+ type: :development
58
+ version_requirements: *id004
59
+ - !ruby/object:Gem::Dependency
60
+ name: rspec
61
+ prerelease: false
62
+ requirement: &id005 !ruby/object:Gem::Requirement
63
+ none: false
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: "0"
68
+ type: :development
69
+ version_requirements: *id005
70
+ - !ruby/object:Gem::Dependency
71
+ name: rspec-rails
72
+ prerelease: false
73
+ requirement: &id006 !ruby/object:Gem::Requirement
74
+ none: false
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ version: "0"
79
+ type: :development
80
+ version_requirements: *id006
81
+ - !ruby/object:Gem::Dependency
82
+ name: ruby-debug19
83
+ prerelease: false
84
+ requirement: &id007 !ruby/object:Gem::Requirement
85
+ none: false
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: "0"
90
+ type: :development
91
+ version_requirements: *id007
92
+ - !ruby/object:Gem::Dependency
93
+ name: guard
94
+ prerelease: false
95
+ requirement: &id008 !ruby/object:Gem::Requirement
96
+ none: false
97
+ requirements:
98
+ - - ">="
99
+ - !ruby/object:Gem::Version
100
+ version: "0"
101
+ type: :development
102
+ version_requirements: *id008
103
+ - !ruby/object:Gem::Dependency
104
+ name: guard-rspec
105
+ prerelease: false
106
+ requirement: &id009 !ruby/object:Gem::Requirement
107
+ none: false
108
+ requirements:
109
+ - - ">="
110
+ - !ruby/object:Gem::Version
111
+ version: "0"
112
+ type: :development
113
+ version_requirements: *id009
114
+ description: "A CVS validator for Rails 3. See homepage for details: http://github.com/mattfordham/csv_validator."
115
+ email:
116
+ - matt@revolvercreative.com
117
+ executables: []
118
+
119
+ extensions: []
120
+
121
+ extra_rdoc_files: []
122
+
123
+ files:
124
+ - lib/csv_validator.rb
125
+ - MIT-LICENSE
126
+ - Rakefile
127
+ - README.md
128
+ homepage: http://github.com/mattfordham/csv_validator
129
+ licenses: []
130
+
131
+ post_install_message:
132
+ rdoc_options: []
133
+
134
+ require_paths:
135
+ - lib
136
+ required_ruby_version: !ruby/object:Gem::Requirement
137
+ none: false
138
+ requirements:
139
+ - - ">="
140
+ - !ruby/object:Gem::Version
141
+ version: "0"
142
+ required_rubygems_version: !ruby/object:Gem::Requirement
143
+ none: false
144
+ requirements:
145
+ - - ">="
146
+ - !ruby/object:Gem::Version
147
+ version: "0"
148
+ requirements: []
149
+
150
+ rubyforge_project:
151
+ rubygems_version: 1.8.24
152
+ signing_key:
153
+ specification_version: 3
154
+ summary: A CVS validator for Rails 3.
155
+ test_files: []
156
+
157
+ has_rdoc: