saviour 0.6.2 → 0.6.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +37 -1
- data/lib/saviour/file.rb +10 -10
- data/lib/saviour/integrator.rb +6 -1
- data/lib/saviour/read_only_file.rb +6 -6
- data/lib/saviour/version.rb +1 -1
- data/spec/feature/read_only_file_spec.rb +28 -0
- data/spec/feature/storage_overriding_spec.rb +3 -3
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 518c8ff0b7b4f9109e1639526b4ff4d25e1878b9e0a4e572cbaab60321788f58
|
4
|
+
data.tar.gz: bfba0fd29fc19d8464e9c4aac30e8b100c029b2a034dba3bc44a62fc36d2cd94
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6b3d3a893c42fdc9cec9eeb661955f2c43be8540f8175772bb4d8086de9625bb86026ee2038fa1566fc8db81996f42d17107620abfddb7a6f65061adeb54e72d
|
7
|
+
data.tar.gz: c1b569e988c4a515289ea4cbabe48ba6ad3ab739bd791b19cefd2168ba0c81f6c148aef3745fdb3b8c0e55e8581700090abc14866ec4705463a250ff87cff80e
|
data/README.md
CHANGED
@@ -817,11 +817,14 @@ as in the processor's case.
|
|
817
817
|
|
818
818
|
### Introspection
|
819
819
|
|
820
|
-
|
820
|
+
Three methods are added to any class including `Saviour::Model` to give you information about what attachments
|
821
821
|
have been defined in that class.
|
822
822
|
|
823
823
|
`Model.attached_files` will give an array of symbols, representing all the attachments declared in that class.
|
824
824
|
|
825
|
+
`Model.uploader_classes` will give you a hash with all the uploader classes being used in that model, key-ed by
|
826
|
+
the name of each attachment.
|
827
|
+
|
825
828
|
`Model.attached_followers_per_leader` will give a hash where the keys are attachments that have versions
|
826
829
|
assigned, and the values being an array of symbols, representing the attachments that are following that attachment.
|
827
830
|
|
@@ -837,6 +840,7 @@ end
|
|
837
840
|
|
838
841
|
Post.attached_files # => [:image, :image_thumb, :image_thumb_2, :cover]
|
839
842
|
Post.attached_followers_per_leader # => { image: [:image_thumb, :image_thumb_2] }
|
843
|
+
Post.uploader_classes # => { image: SomeUploader, image_thumb: SomeUploader, ... }
|
840
844
|
```
|
841
845
|
|
842
846
|
|
@@ -964,6 +968,38 @@ Any additional information the storage may require can be provided on instance c
|
|
964
968
|
this is not used by Saviour.
|
965
969
|
|
966
970
|
|
971
|
+
### Using `ReadOnlyFile`
|
972
|
+
|
973
|
+
Sometimes you may find the need to have a saviour `File`-like object but you don't have the original model available.
|
974
|
+
|
975
|
+
For example, if you're working directly fetching data from database, you have the `path` to an asset but you're not
|
976
|
+
loading an ActiveRecord object.
|
977
|
+
|
978
|
+
In such cases you can use the class `ReadOnlyFile`, like this:
|
979
|
+
|
980
|
+
```ruby
|
981
|
+
class Product
|
982
|
+
# ...
|
983
|
+
attach_file :image
|
984
|
+
end
|
985
|
+
|
986
|
+
my_cheap_products = ActiveRecord::Base.connection.select_all "select image, ... from products"
|
987
|
+
|
988
|
+
# In this case, you have the path to the assets and want to convert it into an object so that the
|
989
|
+
# rest of the application can work normally with it, you can do:
|
990
|
+
|
991
|
+
storage = Product.uploader_classes[:image].storage
|
992
|
+
file = Saviour::ReadOnlyFile.new(path, storage)
|
993
|
+
|
994
|
+
file.read # -> contents
|
995
|
+
file.public_url # -> url
|
996
|
+
# etc ...
|
997
|
+
```
|
998
|
+
|
999
|
+
You'll need to get the appropriate storage object from the same uploader that attachment is using,
|
1000
|
+
and create a new `ReadOnlyFile` instance only with the asset's path and the storage.
|
1001
|
+
|
1002
|
+
|
967
1003
|
### Bypassing Saviour
|
968
1004
|
|
969
1005
|
The only reference to stored files Saviour holds and uses is the path persisted in the database. If you want to,
|
data/lib/saviour/file.rb
CHANGED
@@ -2,26 +2,26 @@ require 'securerandom'
|
|
2
2
|
|
3
3
|
module Saviour
|
4
4
|
class File
|
5
|
-
attr_reader :persisted_path
|
6
|
-
attr_reader :source
|
5
|
+
attr_reader :persisted_path, :source, :storage
|
7
6
|
|
8
7
|
def initialize(uploader_klass, model, attached_as, persisted_path = nil)
|
9
8
|
@uploader_klass, @model, @attached_as = uploader_klass, model, attached_as
|
10
9
|
@source_was = @source = nil
|
11
10
|
@persisted_path = persisted_path
|
11
|
+
@storage = @uploader_klass.storage
|
12
12
|
|
13
13
|
if persisted_path
|
14
|
-
@model.instance_variable_set("@__uploader_#{@attached_as}_was", ReadOnlyFile.new(persisted_path, @uploader_klass))
|
14
|
+
@model.instance_variable_set("@__uploader_#{@attached_as}_was", ReadOnlyFile.new(persisted_path, @uploader_klass.storage))
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
18
|
def exists?
|
19
|
-
persisted? && @
|
19
|
+
persisted? && @storage.exists?(@persisted_path)
|
20
20
|
end
|
21
21
|
|
22
22
|
def read
|
23
23
|
return nil unless persisted?
|
24
|
-
@
|
24
|
+
@storage.read(@persisted_path)
|
25
25
|
end
|
26
26
|
|
27
27
|
def delete
|
@@ -32,7 +32,7 @@ module Saviour
|
|
32
32
|
|
33
33
|
def public_url
|
34
34
|
return nil unless persisted?
|
35
|
-
@
|
35
|
+
@storage.public_url(@persisted_path)
|
36
36
|
end
|
37
37
|
|
38
38
|
def ==(another_file)
|
@@ -111,7 +111,7 @@ module Saviour
|
|
111
111
|
temp_file.binmode
|
112
112
|
|
113
113
|
begin
|
114
|
-
@
|
114
|
+
@storage.read_to_file(@persisted_path, temp_file)
|
115
115
|
|
116
116
|
yield(temp_file)
|
117
117
|
ensure
|
@@ -154,13 +154,13 @@ module Saviour
|
|
154
154
|
|
155
155
|
case source_type
|
156
156
|
when :stream
|
157
|
-
@
|
157
|
+
@storage.write(contents, path)
|
158
158
|
when :file
|
159
|
-
@
|
159
|
+
@storage.write_from_file(contents, path)
|
160
160
|
end
|
161
161
|
|
162
162
|
@persisted_path = path
|
163
|
-
@model.instance_variable_set("@__uploader_#{@attached_as}_was", ReadOnlyFile.new(persisted_path, @
|
163
|
+
@model.instance_variable_set("@__uploader_#{@attached_as}_was", ReadOnlyFile.new(persisted_path, @storage))
|
164
164
|
path
|
165
165
|
end
|
166
166
|
end
|
data/lib/saviour/integrator.rb
CHANGED
@@ -12,6 +12,8 @@ module Saviour
|
|
12
12
|
@klass.attached_files = []
|
13
13
|
@klass.class_attribute :followers_per_leader_config
|
14
14
|
@klass.followers_per_leader_config = {}
|
15
|
+
@klass.class_attribute :uploader_classes
|
16
|
+
@klass.uploader_classes = {}
|
15
17
|
|
16
18
|
persistence_klass = @persistence_klass
|
17
19
|
|
@@ -36,10 +38,13 @@ module Saviour
|
|
36
38
|
raise ConfigurationError, "you must provide either an UploaderClass or a block to define it."
|
37
39
|
end
|
38
40
|
|
41
|
+
uploader_klass = Class.new(Saviour::BaseUploader, &block) if block
|
42
|
+
|
43
|
+
self.uploader_classes[attach_as] = uploader_klass
|
44
|
+
|
39
45
|
mod = Module.new do
|
40
46
|
define_method(attach_as) do
|
41
47
|
instance_variable_get("@__uploader_#{attach_as}") || begin
|
42
|
-
uploader_klass = Class.new(Saviour::BaseUploader, &block) if block
|
43
48
|
layer = persistence_klass.new(self)
|
44
49
|
new_file = ::Saviour::File.new(uploader_klass, self, attach_as, layer.read(attach_as))
|
45
50
|
|
@@ -1,24 +1,24 @@
|
|
1
1
|
module Saviour
|
2
2
|
class ReadOnlyFile
|
3
|
-
attr_reader :persisted_path
|
3
|
+
attr_reader :persisted_path, :storage
|
4
4
|
|
5
|
-
def initialize(persisted_path,
|
5
|
+
def initialize(persisted_path, storage)
|
6
6
|
@persisted_path = persisted_path
|
7
|
-
@
|
7
|
+
@storage = storage
|
8
8
|
end
|
9
9
|
|
10
10
|
def exists?
|
11
|
-
persisted? &&
|
11
|
+
persisted? && @storage.exists?(@persisted_path)
|
12
12
|
end
|
13
13
|
|
14
14
|
def read
|
15
15
|
return nil unless persisted?
|
16
|
-
@
|
16
|
+
@storage.read(@persisted_path)
|
17
17
|
end
|
18
18
|
|
19
19
|
def public_url
|
20
20
|
return nil unless persisted?
|
21
|
-
@
|
21
|
+
@storage.public_url(@persisted_path)
|
22
22
|
end
|
23
23
|
alias_method :url, :public_url
|
24
24
|
|
data/lib/saviour/version.rb
CHANGED
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "direct usage of ReadOnlyFile" do
|
4
|
+
before { allow(Saviour::Config).to receive(:storage).and_return(Saviour::LocalStorage.new(local_prefix: @tmpdir, public_url_prefix: "http://domain.com")) }
|
5
|
+
|
6
|
+
let(:uploader) {
|
7
|
+
Class.new(Saviour::BaseUploader) do
|
8
|
+
store_dir { "/store/dir" }
|
9
|
+
end
|
10
|
+
}
|
11
|
+
|
12
|
+
let(:klass) {
|
13
|
+
klass = Class.new(Test) { include Saviour::Model }
|
14
|
+
klass.attach_file :file, uploader
|
15
|
+
klass
|
16
|
+
}
|
17
|
+
|
18
|
+
it "can be created" do
|
19
|
+
a = klass.create! file: Saviour::StringSource.new("contents", "file.txt")
|
20
|
+
|
21
|
+
path = a[:file]
|
22
|
+
|
23
|
+
read_only_file = Saviour::ReadOnlyFile.new(path, klass.uploader_classes[:file].storage)
|
24
|
+
|
25
|
+
expect(read_only_file.read).to eq "contents"
|
26
|
+
expect(read_only_file.public_url).to eq "http://domain.com/store/dir/file.txt"
|
27
|
+
end
|
28
|
+
end
|
@@ -8,7 +8,7 @@ describe "uploader declaration" do
|
|
8
8
|
)
|
9
9
|
end
|
10
10
|
|
11
|
-
let!(:
|
11
|
+
let!(:another_storage) do
|
12
12
|
Saviour::LocalStorage.new(
|
13
13
|
local_prefix: @tmpdir,
|
14
14
|
public_url_prefix: "http://custom-domain.com"
|
@@ -19,7 +19,7 @@ describe "uploader declaration" do
|
|
19
19
|
|
20
20
|
it "lets you override storage on attachment basis" do
|
21
21
|
klass = Class.new(Test) { include Saviour::Model }
|
22
|
-
|
22
|
+
custom_storage = another_storage
|
23
23
|
|
24
24
|
klass.attach_file(:file) do
|
25
25
|
store_dir { "/store/dir" }
|
@@ -27,7 +27,7 @@ describe "uploader declaration" do
|
|
27
27
|
|
28
28
|
klass.attach_file(:file_thumb) do
|
29
29
|
store_dir { "/store/dir" }
|
30
|
-
with_storage
|
30
|
+
with_storage custom_storage
|
31
31
|
end
|
32
32
|
|
33
33
|
a = klass.create!(
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: saviour
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.6.
|
4
|
+
version: 0.6.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Roger Campos
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-06-
|
11
|
+
date: 2019-06-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -211,6 +211,7 @@ files:
|
|
211
211
|
- spec/feature/original_assigned_file_is_not_modified_spec.rb
|
212
212
|
- spec/feature/persisted_path_spec.rb
|
213
213
|
- spec/feature/processors_api_spec.rb
|
214
|
+
- spec/feature/read_only_file_spec.rb
|
214
215
|
- spec/feature/reload_model_spec.rb
|
215
216
|
- spec/feature/remove_attachment_spec.rb
|
216
217
|
- spec/feature/reopens_file_at_every_process_spec.rb
|