Shrine::Plugins::ContentAddressable
Generate content addressable locations for shrine uploads.
Installation
Add this line to your application's Gemfile:
gem 'shrine-content_addressable'
And then execute:
$ bundle
Or install it yourself as:
$ gem install shrine-content_addressable
Usage
This plugin depends on the signature
plugin:
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 :md5
, :sha
, :sha256
and :sha512
for 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
ContentAddressable IO
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:
ContentAddressableFile.reset
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.
Development
After checking out the repo, run bin/setup
to install dependencies. Then, run rake test
to run the tests. You can
also run 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.
Contributing
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.
License
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.