progstr-filer 0.8.0 → 0.8.1

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -19,6 +19,7 @@ group :development do
19
19
  end
20
20
 
21
21
  gem "activerecord", ">=3.0.0"
22
+ gem "activemodel", ">=3.0.0"
22
23
  gem "uuid"
23
24
  gem "rest-client"
24
25
  gem "multi_json"
data/Gemfile.lock CHANGED
@@ -16,10 +16,10 @@ GEM
16
16
  builder (3.0.0)
17
17
  ffi (1.0.11)
18
18
  git (1.2.5)
19
- guard (0.9.1)
19
+ guard (0.10.0)
20
20
  ffi (>= 0.5.0)
21
21
  thor (~> 0.14.6)
22
- guard-test (0.4.2)
22
+ guard-test (0.4.3)
23
23
  guard (>= 0.4)
24
24
  test-unit (~> 2.2)
25
25
  i18n (0.6.0)
@@ -27,8 +27,8 @@ GEM
27
27
  bundler (~> 1.0)
28
28
  git (>= 1.2.5)
29
29
  rake
30
- json (1.6.3)
31
- libnotify (0.6.0)
30
+ json (1.6.4)
31
+ libnotify (0.7.1)
32
32
  macaddr (1.5.0)
33
33
  systemu (>= 2.4.0)
34
34
  mime-types (1.17.2)
@@ -44,7 +44,7 @@ GEM
44
44
  shoulda (2.11.3)
45
45
  sqlite3 (1.3.5)
46
46
  systemu (2.4.2)
47
- test-unit (2.4.3)
47
+ test-unit (2.4.4)
48
48
  thor (0.14.6)
49
49
  tzinfo (0.3.31)
50
50
  uuid (2.3.4)
@@ -54,6 +54,7 @@ PLATFORMS
54
54
  ruby
55
55
 
56
56
  DEPENDENCIES
57
+ activemodel (>= 3.0.0)
57
58
  activerecord (>= 3.0.0)
58
59
  bundler (~> 1.0.0)
59
60
  guard-test
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.8.0
1
+ 0.8.1
@@ -3,6 +3,8 @@ require 'active_record'
3
3
  module Progstr
4
4
  module Filer
5
5
  module ActiveRecordClassMethods
6
+ include Validation
7
+
6
8
  def _uploaders
7
9
  if @uploaders.nil?
8
10
  @uploaders = {}
@@ -21,6 +23,12 @@ module Progstr
21
23
  def #{attribute}=(new_file)
22
24
  _set_attachment(:#{attribute}, new_file)
23
25
  end
26
+ def #{attribute}_file_size
27
+ _get_attachment(:#{attribute}).size
28
+ end
29
+ def #{attribute}_file_extension
30
+ _get_attachment(:#{attribute}).extension
31
+ end
24
32
  def upload_#{attribute}!
25
33
  _upload_attachment(:#{attribute})
26
34
  end
@@ -56,7 +64,7 @@ module Progstr
56
64
 
57
65
  def _set_attachment(attribute, file)
58
66
  old_attachment = _get_attachment(attribute)
59
- unless old_attachment.empty?
67
+ unless old_attachment.blank?
60
68
  _attachments_to_delete << old_attachment
61
69
  end
62
70
 
@@ -74,7 +82,7 @@ module Progstr
74
82
 
75
83
  def _upload_attachment(attribute)
76
84
  attachment = _get_attachment(attribute)
77
- if (!attachment.empty?) && (!attachment.file.nil?)
85
+ if (!attachment.blank?) && (!attachment.file.nil?)
78
86
  uploader = self.class._uploaders[attribute]
79
87
  uploader.upload_attachment(attachment) unless uploader.nil?
80
88
  end
@@ -5,10 +5,22 @@ module Progstr
5
5
 
6
6
  @@id_generator = ::UUID.new
7
7
 
8
- class EmptyAttachment
9
- def empty?
8
+ class EmptyAttachment < Attachment
9
+ def blank?
10
10
  true
11
11
  end
12
+
13
+ def size
14
+ 0
15
+ end
16
+
17
+ def path
18
+ ""
19
+ end
20
+
21
+ def extension
22
+ ""
23
+ end
12
24
  end
13
25
 
14
26
  def self.empty
@@ -28,6 +40,20 @@ module Progstr
28
40
  uuid.gsub("-", "")
29
41
  end
30
42
 
43
+ def size
44
+ file.size
45
+ end
46
+
47
+ def path
48
+ (file.original_filename if file.respond_to?(:original_filename)) ||
49
+ (file_path = file.path if file.respond_to?(:path))
50
+ end
51
+
52
+ def extension
53
+ from_file = File.extname(path) || ""
54
+ from_file.sub(".", "")
55
+ end
56
+
31
57
  def self.from_id(attribute, id)
32
58
  result = Attachment.new
33
59
  result.id = id
@@ -35,12 +61,12 @@ module Progstr
35
61
  result
36
62
  end
37
63
 
38
- def empty?
64
+ def blank?
39
65
  false
40
66
  end
41
67
 
42
68
  def url
43
- if !empty?
69
+ if !blank?
44
70
  "#{Progstr::Filer.url_prefix}files/data/#{Progstr::Filer.access_key}/#{id}"
45
71
  else
46
72
  ""
@@ -0,0 +1,51 @@
1
+ require 'active_model'
2
+
3
+ module Progstr
4
+ module Filer
5
+ module Validation
6
+ def validates_file_size_of(attribute, options)
7
+ range = options[:in] || (0..1.0/0)
8
+ min = options[:greater_than] || range.first
9
+ max = options[:less_than] || range.last
10
+ allowed_range = (min..max)
11
+
12
+ message = options[:message] || "File size not between #{min} and #{max} bytes."
13
+
14
+ validates_with PropertyValidator, :attributes => [attribute],
15
+ :property => :size,
16
+ :in => allowed_range,
17
+ :message => message,
18
+ :allow_blank => true,
19
+ :allow_nil => true
20
+ end
21
+
22
+ def validates_file_extension_of(attribute, options)
23
+ allowed = options[:allowed] || EverythingIncluded.new
24
+ message = options[:message] || "File extension not allowed."
25
+
26
+ validates_with PropertyValidator, :attributes => [attribute],
27
+ :property => :extension,
28
+ :in => allowed,
29
+ :message => message
30
+ end
31
+
32
+ class EverythingIncluded
33
+ def include?
34
+ true
35
+ end
36
+ end
37
+
38
+ class PropertyValidator < ActiveModel::Validations::InclusionValidator
39
+ def initialize(options)
40
+ @property = options[:property]
41
+ super(options)
42
+ end
43
+
44
+ def validate_each(record, attribute, value)
45
+ property_value = value.send(@property)
46
+ super(record, attribute, property_value) unless value.nil? || value.blank? || property_value.nil?
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
data/lib/progstr-filer.rb CHANGED
@@ -8,6 +8,7 @@ require 'filer/config'
8
8
  require 'filer/uploader'
9
9
  require 'filer/attachment'
10
10
  require 'filer/file_info'
11
+ require 'filer/validation'
11
12
  require 'filer/activerecord'
12
13
 
13
14
  class ApiError < StandardError
data/test/file_like.rb CHANGED
@@ -1,6 +1,15 @@
1
1
  class FileLike
2
+ attr_accessor :size, :path
3
+
2
4
  def read
3
5
  "contents"
4
6
  end
5
7
  end
6
8
 
9
+ class UploadedFileLike
10
+ attr_accessor :size, :original_filename
11
+
12
+ def read
13
+ "contents"
14
+ end
15
+ end
@@ -3,13 +3,13 @@ require 'test_helper'
3
3
  class TestFileMount < UserTest
4
4
  should "start with an empty uploader field" do
5
5
  empty = User.new
6
- assert_true empty.avatar.empty?
6
+ assert_true empty.avatar.blank?
7
7
  end
8
8
 
9
9
  should "create an uploader when given a file" do
10
10
  non_empty = User.new
11
11
  non_empty.avatar = FileLike.new
12
- assert_false non_empty.avatar.empty?
12
+ assert_false non_empty.avatar.blank?
13
13
  end
14
14
 
15
15
  should "save persist attachment id only" do
@@ -0,0 +1,57 @@
1
+ require 'test_helper'
2
+
3
+ class TestValidation < UserTest
4
+ test "don't store without attachment" do
5
+ u = ValidatedUser.new
6
+ assert_false u.valid?, "User not valid without an avatar"
7
+ end
8
+
9
+ test "don't store if size greater than 2MB" do
10
+ u = ValidatedUser.new
11
+ too_big = FileLike.new
12
+ too_big.path = "too_big.png"
13
+ too_big.size = 5 * 1024 * 1024
14
+ u.avatar = too_big
15
+ assert_false u.valid?, "User not valid with huge avatar"
16
+ assert_equal u.errors[:avatar], ["Not uploading more than 2 MB."]
17
+ end
18
+
19
+ test "don't store if extension not allowed" do
20
+ u = ValidatedUser.new
21
+ exe = FileLike.new
22
+ exe.path = "virus_infected.exe"
23
+ u.avatar = exe
24
+
25
+ assert_false u.valid?, "User not valid with 'exe' avatar extension."
26
+ assert_equal u.errors[:avatar], ["Avatar image extension not allowed."]
27
+ end
28
+
29
+ test "use original_filename on file objects if present" do
30
+ u = ValidatedUser.new
31
+ exe = UploadedFileLike.new
32
+ exe.original_filename = "virus_infected.exe"
33
+ u.avatar = exe
34
+
35
+ assert_false u.valid?, "User not valid with 'exe' avatar extension."
36
+ assert_equal u.errors[:avatar], ["Avatar image extension not allowed."]
37
+ end
38
+
39
+ test "don't store files without an extension" do
40
+ u = ValidatedUser.new
41
+ exe = FileLike.new
42
+ exe.path = "noextension"
43
+ u.avatar = exe
44
+
45
+ assert_false u.valid?, "User not valid with an avatar without a file extension."
46
+ assert_equal u.errors[:avatar], ["Avatar image extension not allowed."]
47
+ end
48
+
49
+ test "validation passes" do
50
+ u = ValidatedUser.new
51
+ jpg = FileLike.new
52
+ jpg.path = "avatar.jpg"
53
+ u.avatar = jpg
54
+
55
+ assert_true u.valid?, "Validation passed."
56
+ end
57
+ end
data/test/user_data.rb CHANGED
@@ -6,7 +6,7 @@ dbconfig = {
6
6
  ActiveRecord::Base.establish_connection(dbconfig)
7
7
  ActiveRecord::Migration.verbose = false
8
8
 
9
- class TestUserMigration < ActiveRecord::Migration
9
+ class UserMigration < ActiveRecord::Migration
10
10
  def self.up
11
11
  create_table :users, :force => true do |t|
12
12
  t.column :name, :string
@@ -36,13 +36,21 @@ class User < ActiveRecord::Base
36
36
  has_file :avatar, MockUploader
37
37
  end
38
38
 
39
+ class ValidatedUser < User
40
+ validates_presence_of :avatar
41
+ validates_file_size_of :avatar,
42
+ :less_than => 2 * 1024 * 1024,
43
+ :message => "Not uploading more than 2 MB."
44
+ validates_file_extension_of :avatar, :allowed => ["png", "jpg"],
45
+ :message => "Avatar image extension not allowed."
46
+ end
39
47
 
40
48
  class UserTest < Test::Unit::TestCase
41
49
  def setup
42
- TestUserMigration.up
50
+ UserMigration.up
43
51
  end
44
52
 
45
53
  def teardown
46
- TestUserMigration.down
54
+ UserMigration.down
47
55
  end
48
56
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: progstr-filer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.0
4
+ version: 0.8.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-12-22 00:00:00.000000000Z
12
+ date: 2012-01-06 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activerecord
16
- requirement: &15593540 !ruby/object:Gem::Requirement
16
+ requirement: &24667240 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,21 @@ dependencies:
21
21
  version: 3.0.0
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *15593540
24
+ version_requirements: *24667240
25
+ - !ruby/object:Gem::Dependency
26
+ name: activemodel
27
+ requirement: &24665880 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: 3.0.0
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *24665880
25
36
  - !ruby/object:Gem::Dependency
26
37
  name: uuid
27
- requirement: &15592400 !ruby/object:Gem::Requirement
38
+ requirement: &24663920 !ruby/object:Gem::Requirement
28
39
  none: false
29
40
  requirements:
30
41
  - - ! '>='
@@ -32,10 +43,10 @@ dependencies:
32
43
  version: '0'
33
44
  type: :runtime
34
45
  prerelease: false
35
- version_requirements: *15592400
46
+ version_requirements: *24663920
36
47
  - !ruby/object:Gem::Dependency
37
48
  name: rest-client
38
- requirement: &15591680 !ruby/object:Gem::Requirement
49
+ requirement: &24663080 !ruby/object:Gem::Requirement
39
50
  none: false
40
51
  requirements:
41
52
  - - ! '>='
@@ -43,10 +54,10 @@ dependencies:
43
54
  version: '0'
44
55
  type: :runtime
45
56
  prerelease: false
46
- version_requirements: *15591680
57
+ version_requirements: *24663080
47
58
  - !ruby/object:Gem::Dependency
48
59
  name: multi_json
49
- requirement: &15590700 !ruby/object:Gem::Requirement
60
+ requirement: &24659740 !ruby/object:Gem::Requirement
50
61
  none: false
51
62
  requirements:
52
63
  - - ! '>='
@@ -54,10 +65,10 @@ dependencies:
54
65
  version: '0'
55
66
  type: :runtime
56
67
  prerelease: false
57
- version_requirements: *15590700
68
+ version_requirements: *24659740
58
69
  - !ruby/object:Gem::Dependency
59
70
  name: sqlite3
60
- requirement: &15590140 !ruby/object:Gem::Requirement
71
+ requirement: &24659000 !ruby/object:Gem::Requirement
61
72
  none: false
62
73
  requirements:
63
74
  - - ! '>='
@@ -65,10 +76,10 @@ dependencies:
65
76
  version: '0'
66
77
  type: :development
67
78
  prerelease: false
68
- version_requirements: *15590140
79
+ version_requirements: *24659000
69
80
  - !ruby/object:Gem::Dependency
70
81
  name: guard-test
71
- requirement: &15556920 !ruby/object:Gem::Requirement
82
+ requirement: &24658260 !ruby/object:Gem::Requirement
72
83
  none: false
73
84
  requirements:
74
85
  - - ! '>='
@@ -76,10 +87,10 @@ dependencies:
76
87
  version: '0'
77
88
  type: :development
78
89
  prerelease: false
79
- version_requirements: *15556920
90
+ version_requirements: *24658260
80
91
  - !ruby/object:Gem::Dependency
81
92
  name: rb-inotify
82
- requirement: &15555680 !ruby/object:Gem::Requirement
93
+ requirement: &24657380 !ruby/object:Gem::Requirement
83
94
  none: false
84
95
  requirements:
85
96
  - - ! '>='
@@ -87,10 +98,10 @@ dependencies:
87
98
  version: '0'
88
99
  type: :development
89
100
  prerelease: false
90
- version_requirements: *15555680
101
+ version_requirements: *24657380
91
102
  - !ruby/object:Gem::Dependency
92
103
  name: libnotify
93
- requirement: &15554380 !ruby/object:Gem::Requirement
104
+ requirement: &24656540 !ruby/object:Gem::Requirement
94
105
  none: false
95
106
  requirements:
96
107
  - - ! '>='
@@ -98,10 +109,10 @@ dependencies:
98
109
  version: '0'
99
110
  type: :development
100
111
  prerelease: false
101
- version_requirements: *15554380
112
+ version_requirements: *24656540
102
113
  - !ruby/object:Gem::Dependency
103
114
  name: shoulda
104
- requirement: &15553320 !ruby/object:Gem::Requirement
115
+ requirement: &24652860 !ruby/object:Gem::Requirement
105
116
  none: false
106
117
  requirements:
107
118
  - - ! '>='
@@ -109,10 +120,10 @@ dependencies:
109
120
  version: '0'
110
121
  type: :development
111
122
  prerelease: false
112
- version_requirements: *15553320
123
+ version_requirements: *24652860
113
124
  - !ruby/object:Gem::Dependency
114
125
  name: bundler
115
- requirement: &15552060 !ruby/object:Gem::Requirement
126
+ requirement: &24651640 !ruby/object:Gem::Requirement
116
127
  none: false
117
128
  requirements:
118
129
  - - ~>
@@ -120,10 +131,10 @@ dependencies:
120
131
  version: 1.0.0
121
132
  type: :development
122
133
  prerelease: false
123
- version_requirements: *15552060
134
+ version_requirements: *24651640
124
135
  - !ruby/object:Gem::Dependency
125
136
  name: jeweler
126
- requirement: &15550400 !ruby/object:Gem::Requirement
137
+ requirement: &24648740 !ruby/object:Gem::Requirement
127
138
  none: false
128
139
  requirements:
129
140
  - - ~>
@@ -131,10 +142,10 @@ dependencies:
131
142
  version: 1.6.4
132
143
  type: :development
133
144
  prerelease: false
134
- version_requirements: *15550400
145
+ version_requirements: *24648740
135
146
  - !ruby/object:Gem::Dependency
136
147
  name: rcov
137
- requirement: &15549600 !ruby/object:Gem::Requirement
148
+ requirement: &24647720 !ruby/object:Gem::Requirement
138
149
  none: false
139
150
  requirements:
140
151
  - - ! '>='
@@ -142,10 +153,10 @@ dependencies:
142
153
  version: '0'
143
154
  type: :development
144
155
  prerelease: false
145
- version_requirements: *15549600
156
+ version_requirements: *24647720
146
157
  - !ruby/object:Gem::Dependency
147
158
  name: rdoc
148
- requirement: &15543260 !ruby/object:Gem::Requirement
159
+ requirement: &24646940 !ruby/object:Gem::Requirement
149
160
  none: false
150
161
  requirements:
151
162
  - - ! '>='
@@ -153,7 +164,7 @@ dependencies:
153
164
  version: '0'
154
165
  type: :development
155
166
  prerelease: false
156
- version_requirements: *15543260
167
+ version_requirements: *24646940
157
168
  description: Progstr Filer is a developer-friendly file and attachment hosting service
158
169
  that lets you easily build apps that store and share files.
159
170
  email: hristo@deshev.com
@@ -177,6 +188,7 @@ files:
177
188
  - lib/filer/config.rb
178
189
  - lib/filer/file_info.rb
179
190
  - lib/filer/uploader.rb
191
+ - lib/filer/validation.rb
180
192
  - lib/progstr-filer.rb
181
193
  - test/file_like.rb
182
194
  - test/test_attachment_url.rb
@@ -185,6 +197,7 @@ files:
185
197
  - test/test_http_upload.rb
186
198
  - test/test_id_generation.rb
187
199
  - test/test_upload_on_save.rb
200
+ - test/test_validation.rb
188
201
  - test/user_data.rb
189
202
  homepage: http://github.com/progstr/progstr-filer-gem
190
203
  licenses:
@@ -201,7 +214,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
201
214
  version: '0'
202
215
  segments:
203
216
  - 0
204
- hash: 2703032228924922704
217
+ hash: 1683985428954431553
205
218
  required_rubygems_version: !ruby/object:Gem::Requirement
206
219
  none: false
207
220
  requirements: