file_storage 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.
@@ -0,0 +1,10 @@
1
+ require 'rake_ext'
2
+
3
+ project(
4
+ name: "file_storage",
5
+ gem: true,
6
+ summary: "File storage for Models",
7
+
8
+ author: "Alexey Petrushin",
9
+ homepage: "http://github.com/alexeypetrushin/file_storage"
10
+ )
@@ -0,0 +1,11 @@
1
+ require 'carrierwave'
2
+
3
+ %w(
4
+ fixes
5
+ miscellaneous
6
+ mongo_model
7
+ ).each{|f| require "carrierwave_ext/#{f}"}
8
+
9
+ CarrierWave::Uploader::Base.class_eval do
10
+ def name; model.send("#{mounted_as}_filename") end
11
+ end
@@ -0,0 +1,12 @@
1
+ CarrierWave::SanitizedFile.class_eval do
2
+ def sanitize_regexp
3
+ /[^[:word:]\.\-\+\s_]/i
4
+ end
5
+ end
6
+
7
+ CarrierWave::Uploader::Cache.class_eval do
8
+ def original_filename=(filename)
9
+ raise CarrierWave::InvalidParameter, "invalid filename" unless filename =~ /\A[[:word:]\.\-\+\s_]+\z/i
10
+ @original_filename = filename
11
+ end
12
+ end
@@ -0,0 +1,26 @@
1
+ #
2
+ # Changing filename format from <version>_<filename_with_extension> to <name>.<version>.<extension>
3
+ #
4
+ CarrierWave::Uploader::Versions.class_eval do
5
+ def full_filename(for_file)
6
+ name = super
7
+ if version_name
8
+ ext = File.extname name
9
+ base = File.basename name, ext
10
+ "#{base}.#{version_name}#{ext}"
11
+ else
12
+ name
13
+ end
14
+ end
15
+
16
+ def full_original_filename
17
+ name = super
18
+ if version_name
19
+ ext = File.extname name
20
+ base = File.basename name, ext
21
+ "#{base}.#{version_name}#{ext}"
22
+ else
23
+ name
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,40 @@
1
+ # encoding: utf-8
2
+
3
+ require 'mongo_db/model'
4
+
5
+ module CarrierWave
6
+ module MongoModel
7
+ def read_uploader name
8
+ send name
9
+ end
10
+
11
+ def write_uploader name, value
12
+ send :"#{name}=", value
13
+ end
14
+
15
+ module ClassMethods
16
+ include CarrierWave::Mount
17
+ ##
18
+ # See +CarrierWave::Mount#mount_uploader+ for documentation
19
+ #
20
+ def mount_uploader(column, uploader, options={}, &block)
21
+ fname_attribute = :"#{column}_filename"
22
+ attr_accessor fname_attribute
23
+
24
+ options[:mount_on] ||= fname_attribute
25
+
26
+ super
27
+
28
+ # include CarrierWave::Validations::ActiveModel
29
+ # validates_integrity_of column if uploader_option(column.to_sym, :validate_integrity)
30
+ # validates_processing_of column if uploader_option(column.to_sym, :validate_processing)
31
+
32
+ after_save "store_#{column}!".to_sym
33
+ before_save "write_#{column}_identifier".to_sym
34
+ after_destroy "remove_#{column}!".to_sym
35
+ end
36
+ end
37
+ end
38
+ end
39
+
40
+ Mongo::Model.inherit CarrierWave::MongoModel
@@ -0,0 +1,23 @@
1
+ module CarrierWaveExtSpecHelper
2
+ TEST_PATH, TEST_CACHE_PATH = '/tmp/spec_fs', '/tmp/spec_fs_cache'
3
+
4
+ def with_files
5
+ before do
6
+ CarrierWave.configure do |config|
7
+ config.storage = :file
8
+ config.enable_processing = false
9
+
10
+ config.cache_dir = TEST_CACHE_PATH
11
+ config.root = TEST_PATH
12
+ end
13
+ end
14
+
15
+ before do
16
+ [TEST_PATH, TEST_CACHE_PATH].each{|p| FileUtils.rm_r(p) if File.exist?(p)}
17
+ end
18
+ before do
19
+ [TEST_PATH, TEST_CACHE_PATH].each{|p| FileUtils.rm_r(p) if File.exist?(p)}
20
+ end
21
+ end
22
+ end
23
+ rspec.extend CarrierWaveExtSpecHelper
@@ -0,0 +1 @@
1
+ File storage for Models
@@ -0,0 +1,145 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+ require 'mini_magick'
5
+
6
+ describe "File Storage" do
7
+ before :all do
8
+ class ImageFile
9
+ include FileStorage
10
+
11
+ process do
12
+ end
13
+
14
+ version :icon do
15
+ process do
16
+ end
17
+ # process convert: :png
18
+ # process resize_to_fit: [50, 50]
19
+ end
20
+
21
+ def path_prefix
22
+ self.class.path_prefix
23
+ end
24
+
25
+ def url_prefix
26
+ '/'
27
+ end
28
+
29
+ def validate
30
+ errors << 'invalid name' if original and original.name =~ /invalid/
31
+ end
32
+
33
+ class << self
34
+ attr_accessor :path_prefix
35
+ end
36
+ end
37
+ end
38
+ after(:all){remove_constants :ImageFile}
39
+
40
+ before do
41
+ ImageFile.path_prefix = "#{spec_dir}/storage"
42
+ @file = "#{spec_dir}/ship.jpg".to_file
43
+ end
44
+
45
+ it "CRUD" do
46
+ # blank
47
+ image = ImageFile.new
48
+ image.file.should be_nil
49
+ image.url.should == nil
50
+ image.icon.file.should be_nil
51
+ image.icon.url.should == nil
52
+
53
+ # preserving
54
+ image.original = @file
55
+ image.original.name.should == 'ship.jpg'
56
+ image.original.path.should == "#{spec_dir}/ship.jpg"
57
+
58
+ image.file.should be_nil
59
+ image.url.should == nil
60
+ image.icon.file.should be_nil
61
+ image.icon.url.should == nil
62
+
63
+ # writing
64
+ image.save
65
+ image.file.name.should == 'ship.jpg'
66
+ image.file.path.should == "#{spec_dir}/storage/ship.jpg"
67
+ image.file.exist?.should be_true
68
+ image.url.should == '/ship.jpg'
69
+
70
+ image.icon.file.name.should == 'ship.jpg'
71
+ image.icon.file.path.should == "#{spec_dir}/storage/ship.icon.jpg"
72
+ image.icon.file.exist?.should be_true
73
+ image.icon.url.should == '/ship.icon.jpg'
74
+
75
+ # reading
76
+ image = ImageFile.new
77
+ image.read 'ship.jpg'
78
+
79
+ image.file.name.should == 'ship.jpg'
80
+ image.file.path.should == "#{spec_dir}/storage/ship.jpg"
81
+ image.file.exist?.should be_true
82
+ image.url.should == '/ship.jpg'
83
+
84
+ image.icon.file.name.should == 'ship.jpg'
85
+ image.icon.file.path.should == "#{spec_dir}/storage/ship.icon.jpg"
86
+ image.icon.file.exist?.should be_true
87
+ image.icon.url.should == '/ship.icon.jpg'
88
+
89
+ # updating
90
+ image.original = @file
91
+ image.original.name.should == 'ship2.jpg'
92
+ image.original.path.should == "#{spec_dir}/ship2.jpg"
93
+
94
+ image.save
95
+
96
+ "#{spec_dir}/storage/ship.jpg".to_file.exist?.should be_false
97
+ "#{spec_dir}/storage/ship.icon.jpg".to_file.exist?.should be_false
98
+
99
+ image.file.name.should == 'ship2.jpg'
100
+ image.file.path.should == "#{spec_dir}/storage/ship2.jpg"
101
+ image.file.exist?.should be_true
102
+ image.url.should == '/ship2.jpg'
103
+
104
+ image.icon.file.name.should == 'ship2.jpg'
105
+ image.icon.file.path.should == "#{spec_dir}/storage/ship2.icon.jpg"
106
+ image.icon.file.exist?.should be_true
107
+ image.icon.url.should == '/ship.icon2.jpg'
108
+
109
+ # destroying
110
+ image = ImageFile.new
111
+ image.read 'ship.jpg'
112
+ image.destroy
113
+ "#{spec_dir}/storage/ship2.jpg".to_file.exist?.should be_false
114
+ "#{spec_dir}/storage/ship2.icon.jpg".to_file.exist?.should be_false
115
+ end
116
+
117
+ it "should preserve spaces and unicode characters in filename" do
118
+ file = "#{spec_dir}/файл с пробелами.txt".to_file
119
+
120
+ image = ImageFile.new
121
+ image.save file
122
+ image.url.should =~ /\/файл с пробелами\.txt/
123
+ image.file.path.should =~ /\/файл с пробелами\.txt/
124
+ end
125
+
126
+ it 'should raise error if file not exists' do
127
+ image = ImageFile.new
128
+ image.original = "#{spec_dir}/non existing file.jpg".to_file
129
+ image.validate
130
+ image.errors.first.should =~ /not exist/
131
+ end
132
+
133
+ it 'should validate and not save invalid files' do
134
+ image = ImageFile.new
135
+ image.original = "#{spec_dir}/ship.jpg".to_file
136
+ image.validate
137
+ image.errors.should == []
138
+
139
+ image.original == "#{spec_dir}/invalid.jpg".to_file
140
+ image.validate
141
+ image.errors.should == ['invalid filename']
142
+
143
+ -> {image.save}.should raise_error(/invalid/)
144
+ end
145
+ end
File without changes
@@ -0,0 +1,89 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Model Integration' do
4
+ before :all do
5
+ class ImageFile
6
+ inherit FileStorage
7
+
8
+ def validate
9
+ errors << 'invalid name' if original and (original.name =~ /invalid/)
10
+ end
11
+ end
12
+
13
+ class TheModel < ModelStub
14
+ inherit FileStorage::Helper
15
+
16
+ mount_file :image, ImageFile
17
+
18
+ alias_method :attribute_get, :instance_variable_get
19
+ alias_method :attribute_set, :instance_variable_set
20
+
21
+ before_validate.push -> {|_self|
22
+ self.image.validate
23
+ self.errors[:image] = image.errors unless image.errors.empty?
24
+ end
25
+
26
+ after_save.push -> {|_self| self.image.save}
27
+
28
+ after_destroy.push -> {|_self| self.image.destroy}
29
+ end
30
+ end
31
+
32
+ after(:all){remove_constants :ImageFile, :TheModel}
33
+
34
+ it 'CRUD' do
35
+ # read
36
+ model = TheModel.new
37
+ model.image.class.should == ImageStorage
38
+ model.image.url.should be_nil
39
+ model.image.file.should be_nil
40
+
41
+ # preserving
42
+ file = spec_dir.to_dir / 'ship.jpg'
43
+ model.image = file
44
+ model.image.original.path.should == "#{spec_dir}/ship.jpg"
45
+ model.instance_variable_get(:@image).should == 'ship.jpg'
46
+ model.image.url.should be_nil
47
+ model.image.file.path.should be_nil
48
+
49
+ # saving
50
+ model.save.should be_true
51
+ model.instance_variable_get(:@image).should == 'ship.jpg'
52
+ model.image.url.should == '/ship.jpg'
53
+ model.image.file.path.should == "#{spec_dir}/ship.jpg"
54
+ "#{spec_dir}/ship.jpg".to_file.exist?.should be_true
55
+
56
+ # reading
57
+ model = TheModel.new
58
+ model.instance_variable_set(:@image, 'ship.jpg')
59
+ model.image.url.should == '/ship.jpg'
60
+ model.image.file.path.should == "#{spec_dir}/ship.jpg"
61
+
62
+ # updating
63
+ file2 = spec_dir.to_dir / 'ship2.jpg'
64
+ model.image = file2
65
+ model.instance_variable_get(:@image).should == 'ship2.jpg'
66
+ model.image.original.path.should == "#{spec_dir}/ship2.jpg"
67
+ model.image.url.should == '/ship.jpg'
68
+ model.image.file.path.should == "#{spec_dir}/ship.jpg"
69
+
70
+ model.save.should be_true
71
+ model.instance_variable_get(:@image).should == 'ship2.jpg'
72
+ model.image.url.should == '/ship2.jpg'
73
+ model.image.file.path.should == "#{spec_dir}/ship2.jpg"
74
+ "#{spec_dir}/ship.jpg".to_file.exist?.should be_false
75
+ "#{spec_dir}/ship2.jpg".to_file.exist?.should be_true
76
+
77
+ # destroying
78
+ model.destroy.should be_false
79
+ "#{spec_dir}/ship2.jpg".to_file.exist?.should be_false
80
+ end
81
+
82
+ it "should be able to submit errors and interrupt model saving" do
83
+ file = spec_dir.to_dir / 'invalid.txt'
84
+ model.image = file
85
+ model.image.should_not_receive(:save)
86
+ model.save.should be_false
87
+ model.errors[:image].should == ['invalid name']
88
+ end
89
+ end
@@ -0,0 +1,3 @@
1
+ require 'rspec_ext'
2
+
3
+ require 'spec_helper/model_stub'
@@ -0,0 +1,43 @@
1
+ class ModelStub
2
+ def errors
3
+ @errors ||= {}
4
+ end
5
+
6
+ def save
7
+ before_validate.each{|m| send m}
8
+
9
+ if errors.empty?
10
+ # save
11
+ after_save.each{|m| send m}
12
+ true
13
+ else
14
+ false
15
+ end
16
+ end
17
+
18
+ def destroy
19
+ before_validate.each{|b| instance_eval &b}
20
+
21
+ if errors.empty?
22
+ # save
23
+ after_destroy.each{|b| instance_eval &b}
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 before_save
36
+ @before_save ||= []
37
+ end
38
+
39
+ def before_destroy
40
+ @before_destroy ||= []
41
+ end
42
+ end
43
+ end
metadata ADDED
@@ -0,0 +1,62 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: file_storage
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-27 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/carrierwave_ext/fixes.rb
23
+ - lib/carrierwave_ext/miscellaneous.rb
24
+ - lib/carrierwave_ext/mongo_model.rb
25
+ - lib/carrierwave_ext/spec.rb
26
+ - lib/carrierwave_ext.rb
27
+ - spec/file_storage_spec/invalid.txt
28
+ - spec/file_storage_spec/ship.jpg
29
+ - spec/file_storage_spec/ship2.jpg
30
+ - spec/file_storage_spec/файл с пробелами.txt
31
+ - spec/file_storage_spec.rb
32
+ - spec/model_integration_spec/invalid.txt
33
+ - spec/model_integration_spec/ship.jpg
34
+ - spec/model_integration_spec/ship2.jpg
35
+ - spec/model_integration_spec.rb
36
+ - spec/spec_helper/model_stub.rb
37
+ - spec/spec_helper.rb
38
+ homepage: http://github.com/alexeypetrushin/file_storage
39
+ licenses: []
40
+ post_install_message:
41
+ rdoc_options: []
42
+ require_paths:
43
+ - lib
44
+ required_ruby_version: !ruby/object:Gem::Requirement
45
+ none: false
46
+ requirements:
47
+ - - ! '>='
48
+ - !ruby/object:Gem::Version
49
+ version: '0'
50
+ required_rubygems_version: !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ! '>='
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ requirements: []
57
+ rubyforge_project:
58
+ rubygems_version: 1.8.6
59
+ signing_key:
60
+ specification_version: 3
61
+ summary: File storage for Models
62
+ test_files: []