file_model 0.0.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/Rakefile +10 -0
- data/lib/file_model/file_model.rb +120 -0
- data/lib/file_model/gems.rb +5 -0
- data/lib/file_model/helper.rb +28 -0
- data/lib/file_model/spec/shared_crud/invalid.txt +0 -0
- data/lib/file_model/spec/shared_crud/ship.jpg +0 -0
- data/lib/file_model/spec/shared_crud/ship2.jpg +0 -0
- data/lib/file_model/spec/shared_crud.rb +93 -0
- data/lib/file_model/version.rb +22 -0
- data/lib/file_model.rb +11 -0
- data/readme.md +1 -0
- data/spec/abstract_model_spec.rb +35 -0
- data/spec/file_model_spec/file+name.txt +0 -0
- data/spec/file_model_spec/invalid.txt +0 -0
- data/spec/file_model_spec/ship.jpg +0 -0
- data/spec/file_model_spec/ship2.jpg +0 -0
- data/spec/file_model_spec//321/204/320/260/320/270/314/206/320/273 /321/201 /320/277/321/200/320/276/320/261/320/265/320/273/320/260/320/274/320/270.txt" +1 -0
- data/spec/file_model_spec.rb +174 -0
- data/spec/spec_helper/model_stub.rb +43 -0
- data/spec/spec_helper.rb +5 -0
- metadata +64 -0
data/Rakefile
ADDED
@@ -0,0 +1,120 @@
|
|
1
|
+
module FileModel
|
2
|
+
attr_reader :name
|
3
|
+
|
4
|
+
def read name
|
5
|
+
self.name = name
|
6
|
+
end
|
7
|
+
|
8
|
+
attr_reader :original
|
9
|
+
def original= something
|
10
|
+
@original = something.to_file
|
11
|
+
raise "file #{original.name} not exist!" if original and !original.exist?
|
12
|
+
original
|
13
|
+
end
|
14
|
+
|
15
|
+
def save
|
16
|
+
return false unless original
|
17
|
+
|
18
|
+
# validating
|
19
|
+
validate
|
20
|
+
raise "can't save invalid file!" unless errors.empty?
|
21
|
+
|
22
|
+
# deleting old files
|
23
|
+
destroy validate: false
|
24
|
+
|
25
|
+
# saving
|
26
|
+
self.name = build_name original.name
|
27
|
+
process do |file|
|
28
|
+
path = build_path name
|
29
|
+
file.copy_to self.class.box[path]
|
30
|
+
end
|
31
|
+
|
32
|
+
self.class.versions.each do |version_name, klass|
|
33
|
+
version = send version_name
|
34
|
+
version.process do |file|
|
35
|
+
path = build_path name, version_name
|
36
|
+
file.copy_to self.class.box[path]
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
true
|
41
|
+
end
|
42
|
+
|
43
|
+
def destroy options = {}
|
44
|
+
return false unless name
|
45
|
+
|
46
|
+
unless options[:validate] == false
|
47
|
+
self.validate
|
48
|
+
raise "can't save invalid file!" unless errors.empty?
|
49
|
+
end
|
50
|
+
|
51
|
+
path = build_path name
|
52
|
+
self.class.box[path].destroy
|
53
|
+
|
54
|
+
self.class.versions.each do |version_name, klass|
|
55
|
+
path = build_path name, version_name
|
56
|
+
self.class.box[path].destroy
|
57
|
+
end
|
58
|
+
|
59
|
+
true
|
60
|
+
end
|
61
|
+
|
62
|
+
def url
|
63
|
+
name && build_url(name)
|
64
|
+
end
|
65
|
+
|
66
|
+
def file
|
67
|
+
name && self.class.box[build_path(name)]
|
68
|
+
end
|
69
|
+
|
70
|
+
def process &block
|
71
|
+
block.call original
|
72
|
+
end
|
73
|
+
|
74
|
+
def build_path name, version = nil
|
75
|
+
base, extension = name.rsplit('.', 2)
|
76
|
+
%(/#{base}#{".#{version}" if version}#{".#{extension}" if extension})
|
77
|
+
end
|
78
|
+
|
79
|
+
def build_url name, version = nil
|
80
|
+
base, extension = name.rsplit('.', 2)
|
81
|
+
%(/#{base}#{".#{version}" if version}#{".#{extension}" if extension})
|
82
|
+
end
|
83
|
+
|
84
|
+
def build_name name
|
85
|
+
name
|
86
|
+
end
|
87
|
+
|
88
|
+
def errors
|
89
|
+
@errors ||= []
|
90
|
+
end
|
91
|
+
|
92
|
+
def validate
|
93
|
+
errors.clear
|
94
|
+
# errors << "file #{original.name} not exist!" if original and !original.file?
|
95
|
+
end
|
96
|
+
|
97
|
+
protected
|
98
|
+
attr_writer :name
|
99
|
+
|
100
|
+
module ClassMethods
|
101
|
+
inheritable_accessor :versions, {}
|
102
|
+
|
103
|
+
def version name, &block
|
104
|
+
klass = Class.new FileModel::Version, &block
|
105
|
+
versions[name] = klass
|
106
|
+
|
107
|
+
iv_name = :"@#{name}"
|
108
|
+
define_method name do
|
109
|
+
unless version = instance_variable_get(iv_name)
|
110
|
+
version = klass.new self, name
|
111
|
+
instance_variable_set iv_name, version
|
112
|
+
end
|
113
|
+
version
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
attr_accessor :box
|
118
|
+
attr_required :box
|
119
|
+
end
|
120
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module FileModel::Helper
|
2
|
+
module ClassMethods
|
3
|
+
def mount_file attr_name, file_model_class
|
4
|
+
attr_name.must_be.a Symbol
|
5
|
+
iv_name = :"@_#{attr_name}"
|
6
|
+
|
7
|
+
define_method attr_name do
|
8
|
+
unless file_model = instance_variable_get(iv_name)
|
9
|
+
file_name = attribute_get attr_name
|
10
|
+
|
11
|
+
file_model = file_model_class.new
|
12
|
+
file_model.read file_name
|
13
|
+
|
14
|
+
instance_variable_set iv_name, file_model
|
15
|
+
end
|
16
|
+
file_model
|
17
|
+
end
|
18
|
+
|
19
|
+
define_method :"#{attr_name}=" do |file|
|
20
|
+
file_model = send(attr_name)
|
21
|
+
file_model.original = file
|
22
|
+
|
23
|
+
file_name = file_model.build_name file_model.original.name
|
24
|
+
attribute_set attr_name, file_name
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
File without changes
|
Binary file
|
Binary file
|
@@ -0,0 +1,93 @@
|
|
1
|
+
require 'vos'
|
2
|
+
|
3
|
+
shared_examples_for 'file model crud' do
|
4
|
+
describe "file model crud" do
|
5
|
+
before :all do
|
6
|
+
class ImageFile
|
7
|
+
inherit FileModel
|
8
|
+
|
9
|
+
def build_path name, version = nil
|
10
|
+
'/storage/images' + super
|
11
|
+
end
|
12
|
+
|
13
|
+
def build_url name, version = nil
|
14
|
+
'/images' + super
|
15
|
+
end
|
16
|
+
|
17
|
+
def validate
|
18
|
+
super
|
19
|
+
errors << 'invalid name' if original and (original.name =~ /invalid/)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
after(:all){remove_constants :ImageFile}
|
24
|
+
|
25
|
+
before do
|
26
|
+
require 'tempfile'
|
27
|
+
@tmp_dir = Dir.tmpdir.to_dir.dir('/shard_crud').create.path
|
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
|
+
end
|
35
|
+
|
36
|
+
it 'CRUD' do
|
37
|
+
# read
|
38
|
+
model = @model_class.new
|
39
|
+
model.image.class.should == ImageFile
|
40
|
+
model.image.url.should be_nil
|
41
|
+
model.image.file.should be_nil
|
42
|
+
|
43
|
+
# preserving
|
44
|
+
file = "#{@shared_dir}/ship.jpg"
|
45
|
+
model.image = file
|
46
|
+
model.image.original.path.should == "#{@shared_dir}/ship.jpg"
|
47
|
+
model.instance_variable_get(:@image).should == 'ship.jpg'
|
48
|
+
model.image.url.should be_nil
|
49
|
+
model.image.file.should be_nil
|
50
|
+
|
51
|
+
# saving
|
52
|
+
model.save.should be_true
|
53
|
+
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
|
+
"#{@tmp_dir}/storage/images/ship.jpg".to_file.exist?.should be_true
|
57
|
+
|
58
|
+
# reading
|
59
|
+
model = @model_class.new
|
60
|
+
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"
|
63
|
+
|
64
|
+
# updating
|
65
|
+
file2 = "#{@shared_dir}/ship2.jpg".to_file
|
66
|
+
model.image = file2
|
67
|
+
model.instance_variable_get(:@image).should == 'ship2.jpg'
|
68
|
+
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"
|
71
|
+
|
72
|
+
model.save.should be_true
|
73
|
+
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
|
+
"#{@tmp_dir}/storage/images/ship.jpg".to_file.exist?.should be_false
|
77
|
+
"#{@tmp_dir}/storage/images/ship2.jpg".to_file.exist?.should be_true
|
78
|
+
|
79
|
+
# destroying
|
80
|
+
model.destroy.should be_true
|
81
|
+
"#{@tmp_dir}/storage/images/ship2.jpg".to_file.exist?.should be_false
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should be able to submit errors and interrupt model saving" do
|
85
|
+
file = "#{@shared_dir}/invalid.txt".to_file
|
86
|
+
model = @model_class.new
|
87
|
+
model.image = file
|
88
|
+
model.image.should_not_receive(:save)
|
89
|
+
model.save.should be_false
|
90
|
+
model.errors[:image].should == ['invalid name']
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
class FileModel::Version
|
2
|
+
def initialize model, version_name
|
3
|
+
@model, @version_name = model, version_name
|
4
|
+
end
|
5
|
+
|
6
|
+
def url
|
7
|
+
name && build_url(name, version_name)
|
8
|
+
end
|
9
|
+
|
10
|
+
def file
|
11
|
+
name && model.class.box[build_path(name, version_name)]
|
12
|
+
end
|
13
|
+
|
14
|
+
def process &block
|
15
|
+
block.call original
|
16
|
+
end
|
17
|
+
|
18
|
+
protected
|
19
|
+
attr_reader :model, :version_name
|
20
|
+
|
21
|
+
delegate :original, :name, :build_path, :build_url, to: :model
|
22
|
+
end
|
data/lib/file_model.rb
ADDED
data/readme.md
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
File storage for Models
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'file_model/spec/shared_crud'
|
3
|
+
|
4
|
+
describe 'Model Integration' do
|
5
|
+
it_should_behave_like "file model crud"
|
6
|
+
|
7
|
+
before :all do
|
8
|
+
class ImageFile; end
|
9
|
+
|
10
|
+
class TheModel < ModelStub
|
11
|
+
inherit FileModel::Helper
|
12
|
+
|
13
|
+
mount_file :image, ImageFile
|
14
|
+
|
15
|
+
def attribute_get name
|
16
|
+
instance_variable_get :"@#{name}"
|
17
|
+
end
|
18
|
+
def attribute_set name, value
|
19
|
+
instance_variable_set :"@#{name}", value
|
20
|
+
end
|
21
|
+
|
22
|
+
before_validate.push -> _self {
|
23
|
+
self.image.validate
|
24
|
+
self.errors[:image] = image.errors unless image.errors.empty?
|
25
|
+
}
|
26
|
+
|
27
|
+
after_save.push -> _self {self.image.save}
|
28
|
+
|
29
|
+
after_destroy.push -> _self {self.image.destroy}
|
30
|
+
end
|
31
|
+
end
|
32
|
+
after(:all){remove_constants :TheModel}
|
33
|
+
|
34
|
+
before{@model_class = TheModel}
|
35
|
+
end
|
File without changes
|
File without changes
|
Binary file
|
Binary file
|
@@ -0,0 +1 @@
|
|
1
|
+
1
|
@@ -0,0 +1,174 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe "File Model" do
|
6
|
+
with_tmp_spec_dir
|
7
|
+
|
8
|
+
before :all do
|
9
|
+
class ImageFile
|
10
|
+
inherit FileModel
|
11
|
+
|
12
|
+
def process &block
|
13
|
+
block.call original
|
14
|
+
end
|
15
|
+
|
16
|
+
version :icon do
|
17
|
+
def process &block
|
18
|
+
block.call original
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def build_path name, version = nil
|
23
|
+
'/storage/images' + super
|
24
|
+
end
|
25
|
+
|
26
|
+
def build_url name, version = nil
|
27
|
+
'/images' + super
|
28
|
+
end
|
29
|
+
|
30
|
+
def build_name name
|
31
|
+
name.gsub '+', ' '
|
32
|
+
end
|
33
|
+
|
34
|
+
def validate
|
35
|
+
super
|
36
|
+
errors << 'invalid name' if original and original.name =~ /invalid/
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
after(:all){remove_constants :ImageFile, :AvatarFile}
|
41
|
+
|
42
|
+
before do
|
43
|
+
ImageFile.box = Vos::Box.new(Vos::Drivers::Local.new(spec_dir))
|
44
|
+
@file = "#{spec_dir}/ship.jpg".to_file
|
45
|
+
end
|
46
|
+
|
47
|
+
it "CRUD" do
|
48
|
+
# blank
|
49
|
+
image = ImageFile.new
|
50
|
+
image.name.should be_nil
|
51
|
+
image.file.should be_nil
|
52
|
+
image.url.should == nil
|
53
|
+
image.icon.file.should be_nil
|
54
|
+
image.icon.url.should == nil
|
55
|
+
|
56
|
+
# preserving
|
57
|
+
image.original = @file
|
58
|
+
image.original.name.should == 'ship.jpg'
|
59
|
+
image.original.path.should == "#{spec_dir}/ship.jpg"
|
60
|
+
|
61
|
+
image.name.should be_nil
|
62
|
+
image.file.should be_nil
|
63
|
+
image.url.should == nil
|
64
|
+
|
65
|
+
image.icon.original.should == image.original
|
66
|
+
image.icon.name.should be_nil
|
67
|
+
image.icon.file.should be_nil
|
68
|
+
image.icon.url.should == nil
|
69
|
+
|
70
|
+
# writing
|
71
|
+
image.save.should be_true
|
72
|
+
image.name.should == 'ship.jpg'
|
73
|
+
image.file.name.should == 'ship.jpg'
|
74
|
+
image.file.path.should == "/storage/images/ship.jpg"
|
75
|
+
image.file.exist?.should be_true
|
76
|
+
image.url.should == '/images/ship.jpg'
|
77
|
+
|
78
|
+
image.icon.name.should == 'ship.jpg'
|
79
|
+
image.icon.file.name.should == 'ship.icon.jpg'
|
80
|
+
image.icon.file.path.should == "/storage/images/ship.icon.jpg"
|
81
|
+
image.icon.file.exist?.should be_true
|
82
|
+
image.icon.url.should == '/images/ship.icon.jpg'
|
83
|
+
|
84
|
+
# reading
|
85
|
+
image = ImageFile.new
|
86
|
+
image.read 'ship.jpg'
|
87
|
+
image.name.should == 'ship.jpg'
|
88
|
+
|
89
|
+
image.file.name.should == 'ship.jpg'
|
90
|
+
image.file.path.should == "/storage/images/ship.jpg"
|
91
|
+
image.file.exist?.should be_true
|
92
|
+
image.url.should == '/images/ship.jpg'
|
93
|
+
|
94
|
+
image.name.should == 'ship.jpg'
|
95
|
+
image.icon.file.name.should == 'ship.icon.jpg'
|
96
|
+
image.icon.file.path.should == "/storage/images/ship.icon.jpg"
|
97
|
+
image.icon.file.exist?.should be_true
|
98
|
+
image.icon.url.should == '/images/ship.icon.jpg'
|
99
|
+
|
100
|
+
# updating
|
101
|
+
image.original = "#{spec_dir}/ship2.jpg".to_file
|
102
|
+
image.original.name.should == 'ship2.jpg'
|
103
|
+
image.original.path.should == "#{spec_dir}/ship2.jpg"
|
104
|
+
|
105
|
+
image.save.should be_true
|
106
|
+
|
107
|
+
"#{spec_dir}/storage/images/ship.jpg".to_file.exist?.should be_false
|
108
|
+
"#{spec_dir}/storage/images/ship.icon.jpg".to_file.exist?.should be_false
|
109
|
+
|
110
|
+
image.name.should == 'ship2.jpg'
|
111
|
+
image.file.name.should == 'ship2.jpg'
|
112
|
+
image.file.path.should == "/storage/images/ship2.jpg"
|
113
|
+
image.file.exist?.should be_true
|
114
|
+
image.url.should == '/images/ship2.jpg'
|
115
|
+
|
116
|
+
image.icon.name.should == 'ship2.jpg'
|
117
|
+
image.icon.file.name.should == 'ship2.icon.jpg'
|
118
|
+
image.icon.file.path.should == "/storage/images/ship2.icon.jpg"
|
119
|
+
image.icon.file.exist?.should be_true
|
120
|
+
image.icon.url.should == '/images/ship2.icon.jpg'
|
121
|
+
|
122
|
+
# destroying
|
123
|
+
image = ImageFile.new
|
124
|
+
image.read 'ship2.jpg'
|
125
|
+
image.destroy
|
126
|
+
"#{spec_dir}/storage/images/ship2.jpg".to_file.exist?.should be_false
|
127
|
+
"#{spec_dir}/storage/images/ship2.icon.jpg".to_file.exist?.should be_false
|
128
|
+
end
|
129
|
+
|
130
|
+
it "should preserve spaces and unicode characters in filename" do
|
131
|
+
image = ImageFile.new
|
132
|
+
image.original = "#{spec_dir}/файл с пробелами.txt".to_file
|
133
|
+
image.save.should be_true
|
134
|
+
image.url.should =~ /\/файл с пробелами\.txt/
|
135
|
+
image.file.path.should =~ /\/файл с пробелами\.txt/
|
136
|
+
end
|
137
|
+
|
138
|
+
it "should escape + sign" do
|
139
|
+
image = ImageFile.new
|
140
|
+
image.original = "#{spec_dir}/file+name.txt".to_file
|
141
|
+
image.save.should be_true
|
142
|
+
image.url.should =~ /\/file name\.txt/
|
143
|
+
image.file.path.should =~ /\/file name\.txt/
|
144
|
+
end
|
145
|
+
|
146
|
+
it 'should raise error if file not exists' do
|
147
|
+
image = ImageFile.new
|
148
|
+
-> {image.original = "#{spec_dir}/non existing file.jpg".to_file}.should raise_error(/not exist/)
|
149
|
+
end
|
150
|
+
|
151
|
+
it 'should validate and not save invalid files' do
|
152
|
+
image = ImageFile.new
|
153
|
+
image.original = "#{spec_dir}/ship.jpg".to_file
|
154
|
+
image.validate
|
155
|
+
image.errors.should == []
|
156
|
+
|
157
|
+
image.original = "#{spec_dir}/invalid.txt".to_file
|
158
|
+
image.validate
|
159
|
+
image.errors.should == ['invalid name']
|
160
|
+
|
161
|
+
-> {image.save}.should raise_error(/invalid/)
|
162
|
+
end
|
163
|
+
|
164
|
+
it 'should accept anything responding to :to_file' do
|
165
|
+
file = "#{spec_dir}/ship.jpg".to_file
|
166
|
+
|
167
|
+
obj = mock
|
168
|
+
obj.should_receive(:to_file).and_return(file)
|
169
|
+
|
170
|
+
image = ImageFile.new
|
171
|
+
image.original = obj
|
172
|
+
image.original.should == file
|
173
|
+
end
|
174
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
class ModelStub
|
2
|
+
def errors
|
3
|
+
@errors ||= {}
|
4
|
+
end
|
5
|
+
|
6
|
+
def save
|
7
|
+
self.class.before_validate.each{|block| instance_eval &block}
|
8
|
+
|
9
|
+
if errors.empty?
|
10
|
+
# save
|
11
|
+
self.class.after_save.each{|block| instance_eval &block}
|
12
|
+
true
|
13
|
+
else
|
14
|
+
false
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def destroy
|
19
|
+
self.class.before_validate.each{|block| instance_eval &block}
|
20
|
+
|
21
|
+
if errors.empty?
|
22
|
+
# save
|
23
|
+
self.class.after_destroy.each{|block| instance_eval &block}
|
24
|
+
true
|
25
|
+
else
|
26
|
+
false
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class << self
|
31
|
+
def before_validate
|
32
|
+
@before_validate ||= []
|
33
|
+
end
|
34
|
+
|
35
|
+
def after_save
|
36
|
+
@after_save ||= []
|
37
|
+
end
|
38
|
+
|
39
|
+
def after_destroy
|
40
|
+
@after_destroy ||= []
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: file_model
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Alexey Petrushin
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2011-08-30 00:00:00.000000000Z
|
13
|
+
dependencies: []
|
14
|
+
description:
|
15
|
+
email:
|
16
|
+
executables: []
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- Rakefile
|
21
|
+
- readme.md
|
22
|
+
- lib/file_model/file_model.rb
|
23
|
+
- lib/file_model/gems.rb
|
24
|
+
- lib/file_model/helper.rb
|
25
|
+
- lib/file_model/spec/shared_crud/invalid.txt
|
26
|
+
- lib/file_model/spec/shared_crud/ship.jpg
|
27
|
+
- lib/file_model/spec/shared_crud/ship2.jpg
|
28
|
+
- lib/file_model/spec/shared_crud.rb
|
29
|
+
- lib/file_model/version.rb
|
30
|
+
- lib/file_model.rb
|
31
|
+
- spec/abstract_model_spec.rb
|
32
|
+
- spec/file_model_spec/file+name.txt
|
33
|
+
- spec/file_model_spec/invalid.txt
|
34
|
+
- spec/file_model_spec/ship.jpg
|
35
|
+
- spec/file_model_spec/ship2.jpg
|
36
|
+
- spec/file_model_spec/файл с пробелами.txt
|
37
|
+
- spec/file_model_spec.rb
|
38
|
+
- spec/spec_helper/model_stub.rb
|
39
|
+
- spec/spec_helper.rb
|
40
|
+
homepage: http://github.com/alexeypetrushin/file_model
|
41
|
+
licenses: []
|
42
|
+
post_install_message:
|
43
|
+
rdoc_options: []
|
44
|
+
require_paths:
|
45
|
+
- lib
|
46
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
47
|
+
none: false
|
48
|
+
requirements:
|
49
|
+
- - ! '>='
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: '0'
|
52
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
53
|
+
none: false
|
54
|
+
requirements:
|
55
|
+
- - ! '>='
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: '0'
|
58
|
+
requirements: []
|
59
|
+
rubyforge_project:
|
60
|
+
rubygems_version: 1.8.6
|
61
|
+
signing_key:
|
62
|
+
specification_version: 3
|
63
|
+
summary: File storage for Models
|
64
|
+
test_files: []
|