{"id":17472454,"url":"https://github.com/sleeplessbyte/shrine-content_addressable","last_synced_at":"2025-09-22T04:31:43.373Z","repository":{"id":54942499,"uuid":"136750303","full_name":"SleeplessByte/shrine-content_addressable","owner":"SleeplessByte","description":":1234: Generate content addressable locations for shrine uploads.","archived":false,"fork":false,"pushed_at":"2024-05-06T09:25:20.000Z","size":35,"stargazers_count":3,"open_issues_count":2,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-10-18T19:46:20.424Z","etag":null,"topics":["content-addressable-storage","hash","shrine","storage"],"latest_commit_sha":null,"homepage":"https://rubygems.org/gems/shrine-content_addressable","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/SleeplessByte.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-06-09T19:03:08.000Z","updated_at":"2023-03-24T12:56:56.000Z","dependencies_parsed_at":"2024-11-11T06:18:21.956Z","dependency_job_id":"93934e9a-27f2-4bf2-b050-f02a30978c35","html_url":"https://github.com/SleeplessByte/shrine-content_addressable","commit_stats":{"total_commits":25,"total_committers":2,"mean_commits":12.5,"dds":"0.19999999999999996","last_synced_commit":"e51bfa94273cb05427b2e29df635b2c4aad7f0d2"},"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SleeplessByte%2Fshrine-content_addressable","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SleeplessByte%2Fshrine-content_addressable/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SleeplessByte%2Fshrine-content_addressable/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SleeplessByte%2Fshrine-content_addressable/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/SleeplessByte","download_url":"https://codeload.github.com/SleeplessByte/shrine-content_addressable/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":233824409,"owners_count":18736001,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["content-addressable-storage","hash","shrine","storage"],"created_at":"2024-10-18T17:17:53.411Z","updated_at":"2025-09-22T04:31:38.108Z","avatar_url":"https://github.com/SleeplessByte.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Shrine::Plugins::ContentAddressable\n[![Build Status](https://travis-ci.com/SleeplessByte/shrine-content_addressable.svg?branch=master)](https://travis-ci.com/SleeplessByte/shrine-content_addressable)\n[![Gem Version](https://badge.fury.io/rb/shrine-content_addressable.svg)](https://badge.fury.io/rb/shrine-content_addressable)\n[![MIT license](http://img.shields.io/badge/license-MIT-brightgreen.svg)](http://opensource.org/licenses/MIT)\n[![Maintainability](https://api.codeclimate.com/v1/badges/69fd01f1de440703eb7d/maintainability)](https://codeclimate.com/github/SleeplessByte/shrine-content_addressable/maintainability)\n\nGenerate content addressable locations for shrine uploads.\n\n## Installation\n\nAdd this line to your application's Gemfile:\n\n```ruby\ngem 'shrine-content_addressable'\n```\n\nAnd then execute:\n\n    $ bundle\n\nOr install it yourself as:\n\n    $ gem install shrine-content_addressable\n\n## Usage\n\nThis plugin depends on the `signature` plugin:\n\n```Ruby\nrequire 'shrine/plugins/content_addressable'\nrequire 'shrine/plugins/signature'\n\nclass MyUploader \u003c Shrine\n  plugin :signature\n  plugin :content_addressable, hash: :sha256, prefix: '/'\nend\n```\n\nCurrently you can enter `:md5`, `:sha`, `:sha256` and `:sha512` for `hash:`. If you have a different algorithm that is\ncorrectly supported by the `signature` plugin, and has a `multihash` code, add the multihash code mapping:\n\n```Ruby\n# Let's say the signature plugin starts supporting blake 2b as :blake2_b,\n#   the multihash code is 'blake2b'\nplugin :content_addressable, hash: :blake2_b, multihash: 'blake2b'\n```\n\nYour uploaded files will be extended with some multihash capability:\n\n```Ruby\nuploader = Uploader.new(:cache)\nuploaded_file = uploader.upload(my_file)\n\nuploaded_file.content_addressable # =\u003e the content addressable hash, regardless of location\nuploaded_file.decode # =\u003e the decoded multihash\nuploaded_file.digest # =\u003e the decoded digest (in bytes. Use .unpack('H*') to turn into hex)\nuploaded_file.digest_function # =\u003e the digest function used to create the multihash\nuploaded_file.to_content_addressable! # =\u003e ContentAddressableFile, and auto registers the storage\n```\n\n### ContentAddressable IO\nSince a content-addressable stored file is the same across whichever storage, it *MUST* not matter what storage the file\nis accessed from when it comes to reading. A wrapper is provided so files can be looked up by their content-addressable\nid / hash, instead of a data hash (default for Shrine).\n\n```Ruby\nrequire 'content_addressable_file'\n\n# You currently need to register the storages, unless you use uploaded_file.to_content_addressable!\nContentAddressableFile.register_storage(lookup, lookup, lookup)\n\n# You can disallow deletion\nContentAddressableFile.register_read_only_storage(lookup, lookup, lookup)\n\nfile = ContentAddressableFile.new(content_addressable_hash)\n\n# Shares the interface with UploadedFile\n# =\u003e file methods like open, rewind, read, close and eof? are available\n# =\u003e file.url gives the first url that exists\n# =\u003e file.exists? is true if it exists in any storage\n# =\u003e file.delete attempts to delete it from ALL storages\n```\n\nTo reset known storages use:\n```Ruby\nContentAddressableFile.reset\n```\n\nRegistration is only automatic when using `#to_content_addressable!`. Do not rely on that behaviour\nif you're not always uploading files, but trying to retrieve them.\n\nA lookup storage needs to respond to:\n```Ruby\nlookup = Shrine::Storage::Memory.new\ncontent_addressable = content_addressable_hash\n\nlookup.open(content_addressable) # IO.open\nlookup.exists?(content_addressable) # true if storage has it (and can open)\n\n# optional\nlookup.url(content_addressable) # url to the io (only if storage has it)\nlookup.delete(content_addressable) # delete from storage\nlookup.download(content_addressable) # download the io\n```\n\nNote that you input the hash, and not some arbitrary path.\n\n## Development\n\nAfter checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can\nalso run `bin/console` for an interactive prompt that will allow you to experiment.\n\nTo install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the\nversion number in `shrine-configurable_storage.gemspec.rb`, and then run `bundle exec rake release`, which will create\na git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).\n\n## Contributing\n\nBug reports and pull requests are welcome on GitHub at [SleeplessByte/shrine-configurable_storage](https://github.com/SleeplessByte/shrine-configurable_storage).\nThis project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to\nthe [Contributor Covenant](http://contributor-covenant.org) code of conduct.\n\n## License\n\nThe gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).\n\n## Code of Conduct\n\nEveryone interacting in the `Shrine::Plugins::ContentAddressable` project’s codebases, issue trackers, chat rooms and\nmailing lists is expected to follow the [code of conduct](https://github.com/SleeplessByte/shrine-configurable_storage/blob/master/CODE_OF_CONDUCT.md).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsleeplessbyte%2Fshrine-content_addressable","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsleeplessbyte%2Fshrine-content_addressable","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsleeplessbyte%2Fshrine-content_addressable/lists"}