saviour 0.6.2 → 0.6.3

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 299270bf4c0f5d46a9fd7a57d51062a5a86a1c9216187baf3d0d3a6258295811
4
- data.tar.gz: a0ed19b72e62d0fc006698958bd057eaf0543c8595ae080e9279c07e33fddb95
3
+ metadata.gz: 518c8ff0b7b4f9109e1639526b4ff4d25e1878b9e0a4e572cbaab60321788f58
4
+ data.tar.gz: bfba0fd29fc19d8464e9c4aac30e8b100c029b2a034dba3bc44a62fc36d2cd94
5
5
  SHA512:
6
- metadata.gz: 90ac6353b42b4c3422bb3154b983422658837e9c0c307bb4871e2c3c0e50d7101286524984c036fcf68abb91b830d82aa39886f88d362490ddf86d459401c9a3
7
- data.tar.gz: 82d6cdeab9db03a38a8819109c2cf24d4824a9ca1a9c77830bdb8d95efb98c50664ad1eeb8862224f795e9c334d8d36a9f071955e0f232ae14d2198b95124720
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
- Two methods are added to any class including `Saviour::Model` to give you information about what attachments
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,
@@ -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? && @uploader_klass.storage.exists?(@persisted_path)
19
+ persisted? && @storage.exists?(@persisted_path)
20
20
  end
21
21
 
22
22
  def read
23
23
  return nil unless persisted?
24
- @uploader_klass.storage.read(@persisted_path)
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
- @uploader_klass.storage.public_url(@persisted_path)
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
- @uploader_klass.storage.read_to_file(@persisted_path, temp_file)
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
- @uploader_klass.storage.write(contents, path)
157
+ @storage.write(contents, path)
158
158
  when :file
159
- @uploader_klass.storage.write_from_file(contents, path)
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, @uploader_klass))
163
+ @model.instance_variable_set("@__uploader_#{@attached_as}_was", ReadOnlyFile.new(persisted_path, @storage))
164
164
  path
165
165
  end
166
166
  end
@@ -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, uploader_klass)
5
+ def initialize(persisted_path, storage)
6
6
  @persisted_path = persisted_path
7
- @uploader_klass = uploader_klass
7
+ @storage = storage
8
8
  end
9
9
 
10
10
  def exists?
11
- persisted? && Config.storage.exists?(@persisted_path)
11
+ persisted? && @storage.exists?(@persisted_path)
12
12
  end
13
13
 
14
14
  def read
15
15
  return nil unless persisted?
16
- @uploader_klass.storage.read(@persisted_path)
16
+ @storage.read(@persisted_path)
17
17
  end
18
18
 
19
19
  def public_url
20
20
  return nil unless persisted?
21
- @uploader_klass.storage.public_url(@persisted_path)
21
+ @storage.public_url(@persisted_path)
22
22
  end
23
23
  alias_method :url, :public_url
24
24
 
@@ -1,3 +1,3 @@
1
1
  module Saviour
2
- VERSION = "0.6.2"
2
+ VERSION = "0.6.3"
3
3
  end
@@ -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!(:custom_storage) do
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
- kustom_storage = custom_storage
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 kustom_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.2
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-16 00:00:00.000000000 Z
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