progstr-filer 0.8.0 → 0.8.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.
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: