tori 0.0.4 → 0.0.5
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 +4 -4
- data/README.md +10 -6
- data/lib/tori/backend/filesystem.rb +7 -2
- data/lib/tori/backend/s3.rb +65 -22
- data/lib/tori/define.rb +1 -1
- data/lib/tori/file.rb +9 -9
- data/lib/tori/rails.rb +1 -28
- data/lib/tori/version.rb +1 -1
- data/lib/tori.rb +2 -2
- data/test/test_tori_backend_filesystem.rb +19 -9
- data/test/test_tori_backend_s3.rb +59 -0
- data/test/test_tori_define.rb +4 -2
- data/test/test_tori_file.rb +5 -5
- data/tori.gemspec +2 -1
- metadata +18 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 59a3b8e9df440e4db765dc69951b55887020ef62
|
4
|
+
data.tar.gz: 0bd333e1b30fc39dec35d15978474617c375f920
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b536f7ab3b27b688618990d810dfc75a8c06e6f4bb4e4fabc5f6f60c04c60503926f5b834027a6d0bbe35e95a506ee946008fc38b5a45a1ddfb272a2f87cdc95
|
7
|
+
data.tar.gz: 54772f385b31c5d82878758951746738cc94b84d7df984f29179f0c8b3f8ac3edc26ba32045fc688eabf1a1d0a3b7658f0debb90e68290d6593c7c906b9b3166
|
data/README.md
CHANGED
@@ -24,6 +24,14 @@ app/models/photo.rb
|
|
24
24
|
```ruby
|
25
25
|
class Photo < ActiveRecord::Base
|
26
26
|
tori :image
|
27
|
+
|
28
|
+
after_save do
|
29
|
+
image.write if image.from?
|
30
|
+
end
|
31
|
+
|
32
|
+
after_destroy do
|
33
|
+
image.delete
|
34
|
+
end
|
27
35
|
end
|
28
36
|
```
|
29
37
|
|
@@ -61,7 +69,7 @@ You can read file.
|
|
61
69
|
```ruby
|
62
70
|
photo.image.read #=> image bin
|
63
71
|
photo.image.exist? #=> exist check
|
64
|
-
photo.image.
|
72
|
+
photo.image.name #=> filename
|
65
73
|
```
|
66
74
|
|
67
75
|
# Custom configure example
|
@@ -69,7 +77,7 @@ photo.image.to_s #=> filename
|
|
69
77
|
```ruby
|
70
78
|
# Save to S3 bucket.
|
71
79
|
require 'tori/backend/s3'
|
72
|
-
Tori.config.backend = Tori::Backend::S3.new('tori_bucket')
|
80
|
+
Tori.config.backend = Tori::Backend::S3.new(bucket: 'tori_bucket')
|
73
81
|
|
74
82
|
# Filename decided by model.class.name,id and hidden words.
|
75
83
|
Tori.config.filename_callback do |model|
|
@@ -82,7 +90,3 @@ end
|
|
82
90
|
[https://github.com/ksss/tori/blob/master/lib/tori.rb](https://github.com/ksss/tori/blob/master/lib/tori.rb)
|
83
91
|
|
84
92
|
You can change configure any time.
|
85
|
-
|
86
|
-
# future TODO
|
87
|
-
|
88
|
-
- support background S3 Storage
|
@@ -7,8 +7,13 @@ module Tori
|
|
7
7
|
FileUtils.mkdir_p @root.to_s
|
8
8
|
end
|
9
9
|
|
10
|
-
def
|
11
|
-
|
10
|
+
def write(filename, resource)
|
11
|
+
case resource
|
12
|
+
when String
|
13
|
+
::File.open(path(filename), 'w'){ |f| f.write resource }
|
14
|
+
else
|
15
|
+
::IO.copy_stream resource, path(filename)
|
16
|
+
end
|
12
17
|
end
|
13
18
|
|
14
19
|
def delete(filename)
|
data/lib/tori/backend/s3.rb
CHANGED
@@ -1,46 +1,89 @@
|
|
1
|
-
require 'aws-sdk'
|
1
|
+
require 'aws-sdk-core'
|
2
2
|
|
3
3
|
module Tori
|
4
4
|
module Backend
|
5
5
|
class S3
|
6
|
-
|
7
|
-
#
|
8
|
-
#
|
6
|
+
attr_accessor :bucket, :client
|
7
|
+
# Must be set bucket name.
|
8
|
+
# And it use aws-sdk-core >= 2.0
|
9
|
+
# ENV["TORI_ACCESS_KEY"] > aws-sdk credentials
|
9
10
|
#
|
10
11
|
# example:
|
11
|
-
# Tori.config.backend = Tori::Backend::S3.new(
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
12
|
+
# Tori.config.backend = Tori::Backend::S3.new(bucket: 'tori_bucket')
|
13
|
+
def initialize(bucket:)
|
14
|
+
@bucket = bucket
|
15
|
+
@client = if ENV["TORI_AWS_ACCESS_KEY_ID"] && ENV["TORI_AWS_SECRET_ACCESS_KEY"]
|
16
|
+
Aws::S3::Client.new(
|
17
|
+
access_key_id: ENV["TORI_AWS_ACCESS_KEY_ID"],
|
18
|
+
secret_access_key: ENV["TORI_AWS_SECRET_ACCESS_KEY"],
|
19
|
+
region: ENV["TORI_AWS_REGION"] || ENV['AWS_REGION'] || Aws.config[:region],
|
20
|
+
)
|
21
|
+
else
|
22
|
+
Aws::S3::Client.new(
|
23
|
+
region: ENV["TORI_AWS_REGION"] || ENV['AWS_REGION'] || Aws.config[:region]
|
24
|
+
)
|
25
|
+
end
|
19
26
|
end
|
20
27
|
|
21
|
-
def
|
22
|
-
|
28
|
+
def write(filename, resource)
|
29
|
+
case resource
|
30
|
+
when IO
|
31
|
+
put filename, f
|
32
|
+
when String
|
33
|
+
put filename, resource
|
34
|
+
else
|
35
|
+
::File.open(resource.to_path) { |f| put filename, f }
|
36
|
+
end
|
23
37
|
end
|
24
38
|
|
25
39
|
def delete(filename)
|
26
|
-
|
40
|
+
@client.delete_object(
|
41
|
+
bucket: @bucket,
|
42
|
+
key: filename
|
43
|
+
)
|
27
44
|
end
|
28
45
|
|
29
|
-
def exist?(filename)
|
30
|
-
|
46
|
+
def exist?(filename = nil)
|
47
|
+
head filename
|
48
|
+
rescue Aws::S3::Errors::NoSuchKey, Aws::S3::Errors::NotFound
|
49
|
+
false
|
50
|
+
else
|
51
|
+
true
|
31
52
|
end
|
32
53
|
alias exists? exist?
|
33
54
|
|
34
55
|
def read(filename)
|
35
|
-
|
56
|
+
@client.get_object(
|
57
|
+
bucket: @bucket,
|
58
|
+
key: filename
|
59
|
+
)[:body].read
|
36
60
|
end
|
37
61
|
|
38
|
-
def
|
39
|
-
|
62
|
+
def public_url(filename, params={})
|
63
|
+
"#{@client.config.endpoint}/#{@bucket}/#{filename}"
|
40
64
|
end
|
41
65
|
|
42
|
-
def
|
43
|
-
@
|
66
|
+
def url_for(filename, method)
|
67
|
+
signer = Aws::S3::Presigner.new(client: @client)
|
68
|
+
signer.presigned_url(method, bucket: @bucket, key: filename)
|
69
|
+
end
|
70
|
+
|
71
|
+
private
|
72
|
+
|
73
|
+
def put(filename, body)
|
74
|
+
@client.put_object(
|
75
|
+
bucket: @bucket,
|
76
|
+
key: filename,
|
77
|
+
body: body
|
78
|
+
)
|
79
|
+
end
|
80
|
+
|
81
|
+
def head(filename = nil)
|
82
|
+
if filename
|
83
|
+
@client.head_object bucket: @bucket, key: filename
|
84
|
+
else
|
85
|
+
@client.head_bucket bucket: @bucket
|
86
|
+
end
|
44
87
|
end
|
45
88
|
end
|
46
89
|
end
|
data/lib/tori/define.rb
CHANGED
data/lib/tori/file.rb
CHANGED
@@ -10,14 +10,14 @@ module Tori
|
|
10
10
|
end
|
11
11
|
alias to_s name
|
12
12
|
|
13
|
-
def
|
14
|
-
!@
|
15
|
-
rescue NameError => e
|
16
|
-
false
|
13
|
+
def from?
|
14
|
+
!@from.nil? && @from.respond_to?(:path)
|
17
15
|
end
|
18
16
|
|
19
|
-
def
|
20
|
-
|
17
|
+
def write
|
18
|
+
path = @from.path
|
19
|
+
path = Pathname.new(path) if path.kind_of?(String)
|
20
|
+
Tori.config.backend.write name, path
|
21
21
|
end
|
22
22
|
|
23
23
|
def delete
|
@@ -28,11 +28,11 @@ module Tori
|
|
28
28
|
Tori.config.backend.respond_to?(sym, include_private)
|
29
29
|
end
|
30
30
|
|
31
|
-
def method_missing(sym)
|
31
|
+
def method_missing(sym, *args)
|
32
32
|
if respond_to_missing?(sym, false)
|
33
|
-
Tori.config.backend.__send__ sym, name
|
33
|
+
Tori.config.backend.__send__ sym, name, *args
|
34
34
|
else
|
35
|
-
fail NameError, "undefined
|
35
|
+
fail NameError, "undefined method `#{sym}' for #{Tori.config.backend.inspect}"
|
36
36
|
end
|
37
37
|
end
|
38
38
|
end
|
data/lib/tori/rails.rb
CHANGED
@@ -1,29 +1,2 @@
|
|
1
1
|
require 'tori'
|
2
|
-
|
3
|
-
module Tori
|
4
|
-
module ActiveRecord
|
5
|
-
include Define
|
6
|
-
|
7
|
-
# Filename hash usgin `id` attribute by default.
|
8
|
-
# And you can change this attribute, But it's should be record unique.
|
9
|
-
#
|
10
|
-
# @example:
|
11
|
-
# class Photo < ActiveRecord::Base
|
12
|
-
# tori :image
|
13
|
-
# end
|
14
|
-
def tori(name)
|
15
|
-
super
|
16
|
-
|
17
|
-
after_save do
|
18
|
-
file = __send__ name
|
19
|
-
file.copy
|
20
|
-
end
|
21
|
-
|
22
|
-
after_destroy do
|
23
|
-
file = __send__ name
|
24
|
-
file.delete
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
::ActiveRecord::Base.extend(Tori::ActiveRecord)
|
2
|
+
::ActiveRecord::Base.extend(Tori::Define)
|
data/lib/tori/version.rb
CHANGED
data/lib/tori.rb
CHANGED
@@ -19,10 +19,10 @@ module Tori
|
|
19
19
|
config.backend = Tori::Backend::FileSystem.new(Pathname("tmp/tori"))
|
20
20
|
|
21
21
|
# You can also use S3 backend.
|
22
|
-
# It take 'aws-sdk' gem.
|
22
|
+
# It take 'aws-sdk-core' gem.
|
23
23
|
# S3 example
|
24
24
|
# require 'tori/backend/s3'
|
25
|
-
# config.backend = Tori::Backend::S3.new('tori_bucket')
|
25
|
+
# config.backend = Tori::Backend::S3.new(bucket: 'tori_bucket')
|
26
26
|
|
27
27
|
# Filename hashing method
|
28
28
|
# It's call when decide filename hash.
|
@@ -1,15 +1,10 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
3
|
class TestToriBackendFileSystem < Test::Unit::TestCase
|
4
|
-
class Uploader
|
5
|
-
def path
|
6
|
-
"test/tmp/uploader"
|
7
|
-
end
|
8
|
-
end
|
9
|
-
|
10
4
|
setup do
|
11
5
|
path = Pathname("test/tmp/tori/store")
|
12
6
|
@filesystem = Tori::Backend::FileSystem.new(path)
|
7
|
+
File.open(@filesystem.root.join("testfile"), 'w+'){ |f| f.write('text') }
|
13
8
|
end
|
14
9
|
|
15
10
|
teardown do
|
@@ -27,9 +22,24 @@ class TestToriBackendFileSystem < Test::Unit::TestCase
|
|
27
22
|
end
|
28
23
|
|
29
24
|
test "#read" do
|
30
|
-
|
31
|
-
assert { "" == @filesystem.read("readfile") }
|
32
|
-
File.unlink @filesystem.root.join("readfile")
|
25
|
+
assert { "text" == @filesystem.read("testfile") }
|
33
26
|
assert_raise(Errno::ENOENT){ @filesystem.read("nothing_file") }
|
34
27
|
end
|
28
|
+
|
29
|
+
test "#path" do
|
30
|
+
assert { Pathname.new("test/tmp/tori/store/testfile") == @filesystem.path("testfile") }
|
31
|
+
end
|
32
|
+
|
33
|
+
test "#write" do
|
34
|
+
@filesystem.write("copyfile", @filesystem.path("testfile"))
|
35
|
+
assert { "text" == @filesystem.read("copyfile") }
|
36
|
+
|
37
|
+
File.open(@filesystem.path("testfile")) do |f|
|
38
|
+
@filesystem.write("copyfile", f)
|
39
|
+
end
|
40
|
+
assert { "text" == @filesystem.read("copyfile") }
|
41
|
+
|
42
|
+
@filesystem.write("copyfile", "string")
|
43
|
+
assert { "string" == @filesystem.read("copyfile") }
|
44
|
+
end
|
35
45
|
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'tori/backend/s3'
|
3
|
+
|
4
|
+
if ENV["TORI_TEST_BUCKET"]
|
5
|
+
|
6
|
+
class TestToriBackendS3 < Test::Unit::TestCase
|
7
|
+
BucketNotFoundError = Class.new(StandardError)
|
8
|
+
setup do
|
9
|
+
@backend = Tori::Backend::S3.new(bucket: ENV["TORI_TEST_BUCKET"])
|
10
|
+
fail BucketNotFoundError, "S3 test need make s3 bucket '#{@backend.bucket}'" unless @backend.exists?
|
11
|
+
|
12
|
+
@testfile_path = Pathname.new("test/tmp/testfile")
|
13
|
+
FileUtils.mkdir_p "test/tmp"
|
14
|
+
File.open(@testfile_path.to_s, 'w+'){ |f| f.write('text') }
|
15
|
+
@backend.write("testfile", @testfile_path)
|
16
|
+
end
|
17
|
+
|
18
|
+
teardown do
|
19
|
+
FileUtils.rm_rf("test/tmp")
|
20
|
+
@backend.delete("testfile")
|
21
|
+
end
|
22
|
+
|
23
|
+
test "#initialize" do
|
24
|
+
assert_instance_of Tori::Backend::S3, @backend
|
25
|
+
assert_raise(ArgumentError){ Tori::Backend::S3.new }
|
26
|
+
end
|
27
|
+
|
28
|
+
test "#respond_to_missing?" do
|
29
|
+
%i(exists? read delete).each do |m|
|
30
|
+
assert { true == @backend.respond_to?(m) }
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
test "#write" do
|
35
|
+
assert_nothing_raised { @backend.write("testfile", @testfile_path) }
|
36
|
+
end
|
37
|
+
|
38
|
+
test "#read" do
|
39
|
+
assert { "test" == @backend.read("testfile") }
|
40
|
+
end
|
41
|
+
|
42
|
+
test "#exists?" do
|
43
|
+
assert_nothing_raised { @backend.exists?("nothingfile") }
|
44
|
+
assert { true == @backend.exists?("testfile") }
|
45
|
+
end
|
46
|
+
|
47
|
+
test "#delete" do
|
48
|
+
assert_nothing_raised { @backend.delete("testfile") }
|
49
|
+
assert { false == @backend.exists?("testfile") }
|
50
|
+
end
|
51
|
+
|
52
|
+
test "#public_url" do
|
53
|
+
assert_match %r!https?://s3-!, @backend.public_url("testfile")
|
54
|
+
assert_match @backend.bucket, @backend.public_url("testfile")
|
55
|
+
assert_match "testfile", @backend.public_url("testfile")
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
data/test/test_tori_define.rb
CHANGED
@@ -15,7 +15,9 @@ class TestToriDefine < Test::Unit::TestCase
|
|
15
15
|
end
|
16
16
|
|
17
17
|
test "defined methods" do
|
18
|
-
|
19
|
-
assert_instance_of Tori::File,
|
18
|
+
dammy = Dammy.new
|
19
|
+
assert_instance_of Tori::File, dammy.test_image
|
20
|
+
assert_instance_of Uploader, dammy.test_image = Uploader.new
|
21
|
+
assert_instance_of Tori::File, dammy.test_image
|
20
22
|
end
|
21
23
|
end
|
data/test/test_tori_file.rb
CHANGED
@@ -34,14 +34,14 @@ class TestToriDefine < Test::Unit::TestCase
|
|
34
34
|
assert { false == Tori::File.new("nothing_file").exist? }
|
35
35
|
end
|
36
36
|
|
37
|
-
test "#
|
38
|
-
assert { false == Tori::File.new(__FILE__).
|
39
|
-
assert { true == Tori::File.new(__FILE__, from: From.new).
|
37
|
+
test "#from?" do
|
38
|
+
assert { false == Tori::File.new(__FILE__).from? }
|
39
|
+
assert { true == Tori::File.new(__FILE__, from: From.new).from? }
|
40
40
|
end
|
41
41
|
|
42
|
-
test "
|
42
|
+
test "write" do
|
43
43
|
assert { false == File.exist?("test/tmp/copy") }
|
44
|
-
Tori::File.new("copy", from: From.new).
|
44
|
+
Tori::File.new("copy", from: From.new).write
|
45
45
|
assert { true == File.exist?("test/tmp/copy") }
|
46
46
|
end
|
47
47
|
|
data/tori.gemspec
CHANGED
@@ -19,5 +19,6 @@ Gem::Specification.new do |spec|
|
|
19
19
|
|
20
20
|
spec.add_development_dependency "bundler"
|
21
21
|
spec.add_development_dependency "rake"
|
22
|
-
spec.add_development_dependency
|
22
|
+
spec.add_development_dependency "test-unit"
|
23
|
+
spec.add_development_dependency "aws-sdk-core", ">= 2.0"
|
23
24
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tori
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- ksss
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-02-
|
11
|
+
date: 2015-02-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -52,6 +52,20 @@ dependencies:
|
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: aws-sdk-core
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '2.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '2.0'
|
55
69
|
description: Simple file uploader
|
56
70
|
email:
|
57
71
|
- co000ri@gmail.com
|
@@ -75,6 +89,7 @@ files:
|
|
75
89
|
- test/test_helper.rb
|
76
90
|
- test/test_tori.rb
|
77
91
|
- test/test_tori_backend_filesystem.rb
|
92
|
+
- test/test_tori_backend_s3.rb
|
78
93
|
- test/test_tori_config.rb
|
79
94
|
- test/test_tori_define.rb
|
80
95
|
- test/test_tori_file.rb
|
@@ -107,6 +122,7 @@ test_files:
|
|
107
122
|
- test/test_helper.rb
|
108
123
|
- test/test_tori.rb
|
109
124
|
- test/test_tori_backend_filesystem.rb
|
125
|
+
- test/test_tori_backend_s3.rb
|
110
126
|
- test/test_tori_config.rb
|
111
127
|
- test/test_tori_define.rb
|
112
128
|
- test/test_tori_file.rb
|