Generate content addressable locations for shrine uploads.
Add this line to your application's Gemfile:
And then execute:
Or install it yourself as:
$ gem install shrine-content_addressable
This plugin depends on the
require 'shrine/plugins/content_addressable' require 'shrine/plugins/signature' class MyUploader < Shrine plugin :signature plugin :content_addressable, hash: :sha256, prefix: '/' end
Currently you can enter
hash:. If you have a different algorithm that is
correctly supported by the
signature plugin, and has a
multihash code, add the multihash code mapping:
# Let's say the signature plugin starts supporting blake 2b as :blake2_b, # the multihash code is 'blake2b' plugin :content_addressable, hash: :blake2_b, multihash: 'blake2b'
Your uploaded files will be extended with some multihash capability:
uploader = Uploader.new(:cache) uploaded_file = uploader.upload(my_file) uploaded_file.content_addressable # => the content addressable hash, regardless of location uploaded_file.decode # => the decoded multihash uploaded_file.digest # => the decoded digest (in bytes. Use .unpack('H*') to turn into hex) uploaded_file.digest_function # => the digest function used to create the multihash uploaded_file.to_content_addressable! # => ContentAddressableFile, and auto registers the storage
Since a content-addressable stored file is the same across whichever storage, it MUST not matter what storage the file is accessed from when it comes to reading. A wrapper is provided so files can be looked up by their content-addressable id / hash, instead of a data hash (default for Shrine).
require 'content_addressable_file' # You currently need to register the storages, unless you use uploaded_file.to_content_addressable! ContentAddressableFile.register_storage(lookup, lookup, lookup) # You can disallow deletion ContentAddressableFile.register_read_only_storage(lookup, lookup, lookup) file = ContentAddressableFile.new(content_addressable_hash) # Shares the interface with UploadedFile # => file methods like open, rewind, read, close and eof? are available # => file.url gives the first url that exists # => file.exists? is true if it exists in any storage # => file.delete attempts to delete it from ALL storages
To reset known storages use:
Registration is only automatic when using
#to_content_addressable!. Do not rely on that behaviour
if you're not always uploading files, but trying to retrieve them.
A lookup storage needs to respond to:
lookup = Shrine::Storage::Memory.new content_addressable = content_addressable_hash lookup.open(content_addressable) # IO.open lookup.exists?(content_addressable) # true if storage has it (and can open) # optional lookup.url(content_addressable) # url to the io (only if storage has it) lookup.delete(content_addressable) # delete from storage lookup.download(content_addressable) # download the io
Note that you input the hash, and not some arbitrary path.
After checking out the repo, run
bin/setup to install dependencies. Then, run
rake test to run the tests. You can
bin/console for an interactive prompt that will allow you to experiment.
To install this gem onto your local machine, run
bundle exec rake install. To release a new version, update the
version number in
shrine-configurable_storage.gemspec.rb, and then run
bundle exec rake release, which will create
a git tag for the version, push git commits and tags, and push the
.gem file to rubygems.org.
Bug reports and pull requests are welcome on GitHub at SleeplessByte/shrine-configurable_storage. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the Contributor Covenant code of conduct.
The gem is available as open source under the terms of the MIT License.
Code of Conduct
Everyone interacting in the
Shrine::Plugins::ContentAddressable project’s codebases, issue trackers, chat rooms and
mailing lists is expected to follow the code of conduct.