file_model 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/file_model/file_model.rb +38 -12
- data/lib/file_model/helper.rb +1 -0
- data/lib/file_model/mini_magic.rb +14 -0
- data/lib/file_model/spec/shared_crud.rb +20 -23
- data/lib/file_model/spec.rb +27 -0
- data/lib/file_model/version.rb +6 -6
- data/lib/file_model.rb +5 -1
- data/spec/abstract_model_spec.rb +3 -1
- data/spec/file_model_spec.rb +12 -14
- data/spec/mini_magic_spec/bos.jpg +0 -0
- data/spec/mini_magic_spec.rb +38 -0
- data/spec/spec_helper.rb +1 -0
- metadata +6 -2
@@ -1,5 +1,6 @@
|
|
1
1
|
module FileModel
|
2
2
|
attr_reader :name
|
3
|
+
attr_accessor :model
|
3
4
|
|
4
5
|
def read name
|
5
6
|
self.name = name
|
@@ -12,12 +13,11 @@ module FileModel
|
|
12
13
|
original
|
13
14
|
end
|
14
15
|
|
15
|
-
def save
|
16
|
+
def save options = {}
|
16
17
|
return false unless original
|
17
18
|
|
18
19
|
# validating
|
19
|
-
validate
|
20
|
-
raise "can't save invalid file!" unless errors.empty?
|
20
|
+
return false unless options[:validate] == false or valid?
|
21
21
|
|
22
22
|
# deleting old files
|
23
23
|
destroy validate: false
|
@@ -40,13 +40,14 @@ module FileModel
|
|
40
40
|
true
|
41
41
|
end
|
42
42
|
|
43
|
+
def save! options = {}
|
44
|
+
save(options) || raise("can't save #{self}!")
|
45
|
+
end
|
46
|
+
|
43
47
|
def destroy options = {}
|
44
48
|
return false unless name
|
45
49
|
|
46
|
-
unless options[:validate] == false
|
47
|
-
self.validate
|
48
|
-
raise "can't save invalid file!" unless errors.empty?
|
49
|
-
end
|
50
|
+
return false unless options[:validate] == false or valid?
|
50
51
|
|
51
52
|
path = build_path name
|
52
53
|
self.class.box[path].destroy
|
@@ -59,6 +60,10 @@ module FileModel
|
|
59
60
|
true
|
60
61
|
end
|
61
62
|
|
63
|
+
def destroy! options = {}
|
64
|
+
destroy(options) || raise("can't destroy #{self}!")
|
65
|
+
end
|
66
|
+
|
62
67
|
def url
|
63
68
|
name && build_url(name)
|
64
69
|
end
|
@@ -68,7 +73,7 @@ module FileModel
|
|
68
73
|
end
|
69
74
|
|
70
75
|
def process &block
|
71
|
-
block.call original
|
76
|
+
block.call original if original
|
72
77
|
end
|
73
78
|
|
74
79
|
def build_path name, version = nil
|
@@ -89,9 +94,17 @@ module FileModel
|
|
89
94
|
@errors ||= []
|
90
95
|
end
|
91
96
|
|
92
|
-
def
|
97
|
+
def valid?
|
93
98
|
errors.clear
|
94
|
-
|
99
|
+
run_validations
|
100
|
+
errors.empty?
|
101
|
+
end
|
102
|
+
|
103
|
+
def run_validations; end
|
104
|
+
|
105
|
+
class << self
|
106
|
+
attr_accessor :box
|
107
|
+
attr_required :box
|
95
108
|
end
|
96
109
|
|
97
110
|
protected
|
@@ -114,7 +127,20 @@ module FileModel
|
|
114
127
|
end
|
115
128
|
end
|
116
129
|
|
117
|
-
|
118
|
-
|
130
|
+
inheritable_accessor :_box, nil
|
131
|
+
def box= v
|
132
|
+
self._box = v.is_a?(::Proc) ? v : -> {v}
|
133
|
+
end
|
134
|
+
|
135
|
+
def box *args, &block
|
136
|
+
if block
|
137
|
+
self.box = block
|
138
|
+
elsif !args.empty?
|
139
|
+
args.size.must == 1
|
140
|
+
self.box = args.first
|
141
|
+
else
|
142
|
+
(_box && _box.call) || ::FileModel.box
|
143
|
+
end
|
144
|
+
end
|
119
145
|
end
|
120
146
|
end
|
data/lib/file_model/helper.rb
CHANGED
@@ -0,0 +1,14 @@
|
|
1
|
+
module FileModel::MiniMagic
|
2
|
+
def mini_magic callback, &block
|
3
|
+
return unless original
|
4
|
+
|
5
|
+
require 'mini_magick'
|
6
|
+
image = MiniMagick::Image.open(original.file.path)
|
7
|
+
block.call image
|
8
|
+
'/'.to_entry.tmp do |dir|
|
9
|
+
output = dir / :tmp_image
|
10
|
+
image.write output.path
|
11
|
+
callback.call output
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -1,21 +1,23 @@
|
|
1
1
|
require 'vos'
|
2
|
+
require 'file_model/spec'
|
2
3
|
|
3
4
|
shared_examples_for 'file model crud' do
|
4
5
|
describe "file model crud" do
|
6
|
+
with_file_model
|
7
|
+
|
5
8
|
before :all do
|
6
9
|
class ImageFile
|
7
10
|
inherit FileModel
|
8
11
|
|
9
12
|
def build_path name, version = nil
|
10
|
-
|
13
|
+
"/storage/images/#{model.name}" + super
|
11
14
|
end
|
12
15
|
|
13
16
|
def build_url name, version = nil
|
14
|
-
|
17
|
+
"/images/#{model.name}" + super
|
15
18
|
end
|
16
19
|
|
17
|
-
def
|
18
|
-
super
|
20
|
+
def run_validations
|
19
21
|
errors << 'invalid name' if original and (original.name =~ /invalid/)
|
20
22
|
end
|
21
23
|
end
|
@@ -23,19 +25,13 @@ shared_examples_for 'file model crud' do
|
|
23
25
|
after(:all){remove_constants :ImageFile}
|
24
26
|
|
25
27
|
before do
|
26
|
-
require 'tempfile'
|
27
|
-
@tmp_dir = Dir.tmpdir.to_dir.dir('/shard_crud').create.path
|
28
28
|
@shared_dir = __FILE__.to_entry.parent.dir(:shared_crud).path
|
29
|
-
|
30
|
-
ImageFile.box = Vos::Box.new(Vos::Drivers::Local.new(@tmp_dir))
|
31
|
-
end
|
32
|
-
after do
|
33
|
-
@tmp_dir.to_dir.destroy
|
34
29
|
end
|
35
30
|
|
36
31
|
it 'CRUD' do
|
37
32
|
# read
|
38
33
|
model = @model_class.new
|
34
|
+
model.name = 'sea'
|
39
35
|
model.image.class.should == ImageFile
|
40
36
|
model.image.url.should be_nil
|
41
37
|
model.image.file.should be_nil
|
@@ -51,34 +47,35 @@ shared_examples_for 'file model crud' do
|
|
51
47
|
# saving
|
52
48
|
model.save.should be_true
|
53
49
|
model.instance_variable_get(:@image).should == 'ship.jpg'
|
54
|
-
model.image.url.should == '/images/ship.jpg'
|
55
|
-
model.image.file.path.should == "/storage/images/ship.jpg"
|
56
|
-
|
50
|
+
model.image.url.should == '/images/sea/ship.jpg'
|
51
|
+
model.image.file.path.should == "/storage/images/sea/ship.jpg"
|
52
|
+
file_model_storage['storage/images/sea/ship.jpg'].exist?.should be_true
|
57
53
|
|
58
54
|
# reading
|
59
55
|
model = @model_class.new
|
56
|
+
model.name = 'sea'
|
60
57
|
model.instance_variable_set(:@image, 'ship.jpg')
|
61
|
-
model.image.url.should == '/images/ship.jpg'
|
62
|
-
model.image.file.path.should == "/storage/images/ship.jpg"
|
58
|
+
model.image.url.should == '/images/sea/ship.jpg'
|
59
|
+
model.image.file.path.should == "/storage/images/sea/ship.jpg"
|
63
60
|
|
64
61
|
# updating
|
65
62
|
file2 = "#{@shared_dir}/ship2.jpg".to_file
|
66
63
|
model.image = file2
|
67
64
|
model.instance_variable_get(:@image).should == 'ship2.jpg'
|
68
65
|
model.image.original.path.should == "#{@shared_dir}/ship2.jpg"
|
69
|
-
model.image.url.should == '/images/ship.jpg'
|
70
|
-
model.image.file.path.should == "/storage/images/ship.jpg"
|
66
|
+
model.image.url.should == '/images/sea/ship.jpg'
|
67
|
+
model.image.file.path.should == "/storage/images/sea/ship.jpg"
|
71
68
|
|
72
69
|
model.save.should be_true
|
73
70
|
model.instance_variable_get(:@image).should == 'ship2.jpg'
|
74
|
-
model.image.url.should == '/images/ship2.jpg'
|
75
|
-
model.image.file.path.should == "/storage/images/ship2.jpg"
|
76
|
-
|
77
|
-
|
71
|
+
model.image.url.should == '/images/sea/ship2.jpg'
|
72
|
+
model.image.file.path.should == "/storage/images/sea/ship2.jpg"
|
73
|
+
file_model_storage['storage/images/sea/ship.jpg'].exist?.should be_false
|
74
|
+
file_model_storage['storage/images/sea/ship2.jpg'].exist?.should be_true
|
78
75
|
|
79
76
|
# destroying
|
80
77
|
model.destroy.should be_true
|
81
|
-
|
78
|
+
file_model_storage['storage/images/sea/ship2.jpg'].exist?.should be_false
|
82
79
|
end
|
83
80
|
|
84
81
|
it "should be able to submit errors and interrupt model saving" do
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'file_model'
|
2
|
+
require 'vos'
|
3
|
+
|
4
|
+
rspec do
|
5
|
+
def file_model_storage
|
6
|
+
'/tmp/file_model'.to_dir
|
7
|
+
end
|
8
|
+
|
9
|
+
class << self
|
10
|
+
def with_file_model
|
11
|
+
::FileModel::ClassMethods.class_eval do
|
12
|
+
def box
|
13
|
+
::FileModel.box
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
tmp = '/tmp/file_model'.to_dir
|
18
|
+
|
19
|
+
before do
|
20
|
+
tmp.destroy.create
|
21
|
+
FileModel.box = Vos::Box.new(Vos::Drivers::Local.new(tmp.path))
|
22
|
+
end
|
23
|
+
|
24
|
+
after{tmp.destroy}
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/lib/file_model/version.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
class FileModel::Version
|
2
|
-
def initialize
|
3
|
-
@
|
2
|
+
def initialize main, version_name
|
3
|
+
@main, @version_name = main, version_name
|
4
4
|
end
|
5
5
|
|
6
6
|
def url
|
@@ -8,15 +8,15 @@ class FileModel::Version
|
|
8
8
|
end
|
9
9
|
|
10
10
|
def file
|
11
|
-
name &&
|
11
|
+
name && main.class.box[build_path(name, version_name)]
|
12
12
|
end
|
13
13
|
|
14
14
|
def process &block
|
15
|
-
block.call original
|
15
|
+
block.call original if original
|
16
16
|
end
|
17
17
|
|
18
18
|
protected
|
19
|
-
attr_reader :
|
19
|
+
attr_reader :main, :version_name
|
20
20
|
|
21
|
-
delegate :original, :name, :build_path, :build_url, to: :
|
21
|
+
delegate :original, :name, :build_path, :build_url, to: :main
|
22
22
|
end
|
data/lib/file_model.rb
CHANGED
data/spec/abstract_model_spec.rb
CHANGED
@@ -10,6 +10,8 @@ describe 'Model Integration' do
|
|
10
10
|
class TheModel < ModelStub
|
11
11
|
inherit FileModel::Helper
|
12
12
|
|
13
|
+
attr_accessor :name
|
14
|
+
|
13
15
|
mount_file :image, ImageFile
|
14
16
|
|
15
17
|
def attribute_get name
|
@@ -20,7 +22,7 @@ describe 'Model Integration' do
|
|
20
22
|
end
|
21
23
|
|
22
24
|
before_validate.push -> _self {
|
23
|
-
self.image.
|
25
|
+
self.image.run_validations
|
24
26
|
self.errors[:image] = image.errors unless image.errors.empty?
|
25
27
|
}
|
26
28
|
|
data/spec/file_model_spec.rb
CHANGED
@@ -3,19 +3,19 @@
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
5
|
describe "File Model" do
|
6
|
-
|
6
|
+
with_file_model
|
7
7
|
|
8
8
|
before :all do
|
9
9
|
class ImageFile
|
10
10
|
inherit FileModel
|
11
11
|
|
12
12
|
def process &block
|
13
|
-
block.call original
|
13
|
+
block.call original if original
|
14
14
|
end
|
15
15
|
|
16
16
|
version :icon do
|
17
17
|
def process &block
|
18
|
-
block.call original
|
18
|
+
block.call original if original
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
@@ -31,8 +31,7 @@ describe "File Model" do
|
|
31
31
|
name.gsub '+', ' '
|
32
32
|
end
|
33
33
|
|
34
|
-
def
|
35
|
-
super
|
34
|
+
def run_validations
|
36
35
|
errors << 'invalid name' if original and original.name =~ /invalid/
|
37
36
|
end
|
38
37
|
end
|
@@ -40,7 +39,6 @@ describe "File Model" do
|
|
40
39
|
after(:all){remove_constants :ImageFile, :AvatarFile}
|
41
40
|
|
42
41
|
before do
|
43
|
-
ImageFile.box = Vos::Box.new(Vos::Drivers::Local.new(spec_dir))
|
44
42
|
@file = "#{spec_dir}/ship.jpg".to_file
|
45
43
|
end
|
46
44
|
|
@@ -104,8 +102,8 @@ describe "File Model" do
|
|
104
102
|
|
105
103
|
image.save.should be_true
|
106
104
|
|
107
|
-
|
108
|
-
|
105
|
+
file_model_storage['storage/images/ship.jpg'].exist?.should be_false
|
106
|
+
file_model_storage['storage/images/ship.icon.jpg'].exist?.should be_false
|
109
107
|
|
110
108
|
image.name.should == 'ship2.jpg'
|
111
109
|
image.file.name.should == 'ship2.jpg'
|
@@ -123,8 +121,8 @@ describe "File Model" do
|
|
123
121
|
image = ImageFile.new
|
124
122
|
image.read 'ship2.jpg'
|
125
123
|
image.destroy
|
126
|
-
|
127
|
-
|
124
|
+
file_model_storage['storage/images/ship2.jpg'].exist?.should be_false
|
125
|
+
file_model_storage['storage/images/ship2.icon.jpg'].exist?.should be_false
|
128
126
|
end
|
129
127
|
|
130
128
|
it "should preserve spaces and unicode characters in filename" do
|
@@ -151,14 +149,14 @@ describe "File Model" do
|
|
151
149
|
it 'should validate and not save invalid files' do
|
152
150
|
image = ImageFile.new
|
153
151
|
image.original = "#{spec_dir}/ship.jpg".to_file
|
154
|
-
image.
|
155
|
-
image.errors.should == []
|
152
|
+
image.valid?.should be_true
|
156
153
|
|
157
154
|
image.original = "#{spec_dir}/invalid.txt".to_file
|
158
|
-
image.
|
155
|
+
image.valid?.should be_false
|
159
156
|
image.errors.should == ['invalid name']
|
160
157
|
|
161
|
-
|
158
|
+
image.save.should be_false
|
159
|
+
image.errors.should == ['invalid name']
|
162
160
|
end
|
163
161
|
|
164
162
|
it 'should accept anything responding to :to_file' do
|
Binary file
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "MiniMagic" do
|
4
|
+
with_file_model
|
5
|
+
|
6
|
+
before :all do
|
7
|
+
class ImageFile
|
8
|
+
inherit FileModel
|
9
|
+
|
10
|
+
def process &block
|
11
|
+
mini_magic block do |image|
|
12
|
+
image.resize '150x150'
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
version :icon do
|
17
|
+
def process &block
|
18
|
+
mini_magic block do |image|
|
19
|
+
image.resize '50x50'
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
after(:all){remove_constants :ImageFile}
|
26
|
+
|
27
|
+
before do
|
28
|
+
@file = "#{spec_dir}/bos.jpg".to_file
|
29
|
+
end
|
30
|
+
|
31
|
+
it "resizing" do
|
32
|
+
image = ImageFile.new
|
33
|
+
image.original = @file
|
34
|
+
image.save!
|
35
|
+
|
36
|
+
image.file.size.should > image.icon.file.size
|
37
|
+
end
|
38
|
+
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: file_model
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2011-
|
12
|
+
date: 2011-09-06 00:00:00.000000000Z
|
13
13
|
dependencies: []
|
14
14
|
description:
|
15
15
|
email:
|
@@ -22,10 +22,12 @@ files:
|
|
22
22
|
- lib/file_model/file_model.rb
|
23
23
|
- lib/file_model/gems.rb
|
24
24
|
- lib/file_model/helper.rb
|
25
|
+
- lib/file_model/mini_magic.rb
|
25
26
|
- lib/file_model/spec/shared_crud/invalid.txt
|
26
27
|
- lib/file_model/spec/shared_crud/ship.jpg
|
27
28
|
- lib/file_model/spec/shared_crud/ship2.jpg
|
28
29
|
- lib/file_model/spec/shared_crud.rb
|
30
|
+
- lib/file_model/spec.rb
|
29
31
|
- lib/file_model/version.rb
|
30
32
|
- lib/file_model.rb
|
31
33
|
- spec/abstract_model_spec.rb
|
@@ -35,6 +37,8 @@ files:
|
|
35
37
|
- spec/file_model_spec/ship2.jpg
|
36
38
|
- spec/file_model_spec/файл с пробелами.txt
|
37
39
|
- spec/file_model_spec.rb
|
40
|
+
- spec/mini_magic_spec/bos.jpg
|
41
|
+
- spec/mini_magic_spec.rb
|
38
42
|
- spec/spec_helper/model_stub.rb
|
39
43
|
- spec/spec_helper.rb
|
40
44
|
homepage: http://github.com/alexeypetrushin/file_model
|