forked from refile/refile-s3
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit ad51adc
Showing
9 changed files
with
247 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
/.bundle/ | ||
/.yardoc | ||
/Gemfile.lock | ||
/_yardoc/ | ||
/coverage/ | ||
/doc/ | ||
/pkg/ | ||
/spec/reports/ | ||
/tmp/ | ||
*.bundle | ||
*.so | ||
*.o | ||
*.a | ||
mkmf.log | ||
s3.yml |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
source 'https://rubygems.org' | ||
|
||
# Specify your gem's dependencies in refile-s3.gemspec | ||
gemspec | ||
|
||
gem "refile", github: "refile/refile" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
Copyright (c) 2015 Jonas Nicklas | ||
|
||
MIT License | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining | ||
a copy of this software and associated documentation files (the | ||
"Software"), to deal in the Software without restriction, including | ||
without limitation the rights to use, copy, modify, merge, publish, | ||
distribute, sublicense, and/or sell copies of the Software, and to | ||
permit persons to whom the Software is furnished to do so, subject to | ||
the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be | ||
included in all copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE | ||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | ||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
# Refile::S3 | ||
|
||
Amazon S3 backend for the [Refile][gh] gem. See the Refile documentation for | ||
more details. | ||
|
||
## License | ||
|
||
[MIT](LICENSE.txt) | ||
|
||
[gh]: http://github.com/refile/refile |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
require "bundler/gem_tasks" | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
require "aws-sdk" | ||
require "open-uri" | ||
require "refile" | ||
require "refile/s3/version" | ||
|
||
module Refile | ||
# A refile backend which stores files in Amazon S3 | ||
# | ||
# @example | ||
# backend = Refile::Backend::S3.new( | ||
# access_key_id: "xyz", | ||
# secret_access_key: "abcd1234", | ||
# region: "sa-east-1", | ||
# bucket: "my-bucket", | ||
# prefix: "files" | ||
# ) | ||
# file = backend.upload(StringIO.new("hello")) | ||
# backend.read(file.id) # => "hello" | ||
class S3 | ||
extend Refile::BackendMacros | ||
|
||
attr_reader :access_key_id, :max_size | ||
|
||
# Sets up an S3 backend with the given credentials. | ||
# | ||
# @param [String] access_key_id | ||
# @param [String] secret_access_key | ||
# @param [String] region The AWS region to connect to | ||
# @param [String] bucket The name of the bucket where files will be stored | ||
# @param [String] prefix A prefix to add to all files. Prefixes on S3 are kind of like folders. | ||
# @param [Integer, nil] max_size The maximum size of an uploaded file | ||
# @param [#hash] hasher A hasher which is used to generate ids from files | ||
# @param [Hash] s3_options Additional options to initialize S3 with | ||
# @see http://docs.aws.amazon.com/AWSRubySDK/latest/AWS/Core/Configuration.html | ||
# @see http://docs.aws.amazon.com/AWSRubySDK/latest/AWS/S3.html | ||
def initialize(access_key_id:, secret_access_key:, region:, bucket:, max_size: nil, prefix: nil, hasher: Refile::RandomHasher.new, **s3_options) | ||
@access_key_id = access_key_id | ||
@secret_access_key = secret_access_key | ||
@s3_options = { access_key_id: access_key_id, secret_access_key: secret_access_key, region: region }.merge s3_options | ||
@s3 = Aws::S3::Resource.new @s3_options | ||
@bucket_name = bucket | ||
@bucket = @s3.bucket @bucket_name | ||
@hasher = hasher | ||
@prefix = prefix | ||
@max_size = max_size | ||
end | ||
|
||
# Upload a file into this backend | ||
# | ||
# @param [IO] uploadable An uploadable IO-like object. | ||
# @return [Refile::File] The uploaded file | ||
verify_uploadable def upload(uploadable) | ||
id = @hasher.hash(uploadable) | ||
|
||
if uploadable.is_a?(Refile::File) and uploadable.backend.is_a?(S3) and uploadable.backend.access_key_id == access_key_id | ||
object(id).copy_from(copy_source: [@bucket_name, uploadable.backend.object(uploadable.id).key].join("/")) | ||
else | ||
object(id).put(body: uploadable, content_length: uploadable.size) | ||
end | ||
|
||
Refile::File.new(self, id) | ||
end | ||
|
||
# Get a file from this backend. | ||
# | ||
# Note that this method will always return a {Refile::File} object, even | ||
# if a file with the given id does not exist in this backend. Use | ||
# {FileSystem#exists?} to check if the file actually exists. | ||
# | ||
# @param [Sring] id The id of the file | ||
# @return [Refile::File] The retrieved file | ||
verify_id def get(id) | ||
Refile::File.new(self, id) | ||
end | ||
|
||
# Delete a file from this backend | ||
# | ||
# @param [Sring] id The id of the file | ||
# @return [void] | ||
verify_id def delete(id) | ||
object(id).delete | ||
end | ||
|
||
# Return an IO object for the uploaded file which can be used to read its | ||
# content. | ||
# | ||
# @param [Sring] id The id of the file | ||
# @return [IO] An IO object containing the file contents | ||
verify_id def open(id) | ||
Kernel.open(object(id).presigned_url(:get)) | ||
end | ||
|
||
# Return the entire contents of the uploaded file as a String. | ||
# | ||
# @param [String] id The id of the file | ||
# @return [String] The file's contents | ||
verify_id def read(id) | ||
object(id).get.body.read | ||
rescue Aws::S3::Errors::NoSuchKey | ||
nil | ||
end | ||
|
||
# Return the size in bytes of the uploaded file. | ||
# | ||
# @param [Sring] id The id of the file | ||
# @return [Integer] The file's size | ||
verify_id def size(id) | ||
object(id).get.content_length | ||
rescue Aws::S3::Errors::NoSuchKey | ||
nil | ||
end | ||
|
||
# Return whether the file with the given id exists in this backend. | ||
# | ||
# @param [Sring] id The id of the file | ||
# @return [Boolean] | ||
verify_id def exists?(id) | ||
object(id).exists? | ||
end | ||
|
||
# Remove all files in this backend. You must confirm the deletion by | ||
# passing the symbol `:confirm` as an argument to this method. | ||
# | ||
# @example | ||
# backend.clear!(:confirm) | ||
# @raise [Refile::Confirm] Unless the `:confirm` symbol has been passed. | ||
# @param [:confirm] confirm Pass the symbol `:confirm` to confirm deletion. | ||
# @return [void] | ||
def clear!(confirm = nil) | ||
raise Refile::Confirm unless confirm == :confirm | ||
@bucket.objects(prefix: @prefix).delete | ||
end | ||
|
||
# Return a presign signature which can be used to upload a file into this | ||
# backend directly. | ||
# | ||
# @return [Refile::Signature] | ||
def presign | ||
id = RandomHasher.new.hash | ||
signature = @bucket.presigned_post(key: [*@prefix, id].join("/")) | ||
signature.content_length_range(0..@max_size) if @max_size | ||
Signature.new(as: "file", id: id, url: signature.url.to_s, fields: signature.fields) | ||
end | ||
|
||
verify_id def object(id) | ||
@bucket.object([*@prefix, id].join("/")) | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
module Refile | ||
class S3 | ||
VERSION = "0.0.1" | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
# coding: utf-8 | ||
lib = File.expand_path('../lib', __FILE__) | ||
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) | ||
require 'refile/s3/version' | ||
|
||
Gem::Specification.new do |spec| | ||
spec.name = "refile-s3" | ||
spec.version = Refile::S3::VERSION | ||
spec.authors = ["Jonas Nicklas"] | ||
spec.email = ["jonas.nicklas@gmail.com"] | ||
spec.summary = "Amazon S3 backend for the Refile gem" | ||
spec.homepage = "" | ||
spec.license = "MIT" | ||
|
||
spec.files = `git ls-files -z`.split("\x0") | ||
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) } | ||
spec.test_files = spec.files.grep(%r{^(test|spec|features)/}) | ||
spec.require_paths = ["lib"] | ||
|
||
spec.add_dependency "refile", "~> 0.5.0" | ||
spec.add_dependency "aws-sdk", "~> 2.0" | ||
spec.add_development_dependency "bundler", "~> 1.7" | ||
spec.add_development_dependency "rake", "~> 10.0" | ||
spec.add_development_dependency "rspec", "~> 3.0" | ||
spec.add_development_dependency "webmock" | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
require "refile/spec_helper" | ||
require "refile/s3" | ||
|
||
WebMock.allow_net_connect! | ||
|
||
config = YAML.load_file("s3.yml").map { |k, v| [k.to_sym, v] }.to_h | ||
|
||
RSpec.describe Refile::S3 do | ||
let(:backend) { Refile::S3.new(max_size: 100, **config) } | ||
|
||
it_behaves_like :backend | ||
end |