carrierwave-ftp 0.1.2 → 0.2.0
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.
- data/README.md +29 -2
- data/carrerwave-ftp.gemspec +2 -1
- data/lib/carrierwave/storage/ftp/all.rb +2 -0
- data/lib/carrierwave/storage/ftp/ex_sftp.rb +20 -0
- data/lib/carrierwave/storage/ftp/version.rb +1 -1
- data/lib/carrierwave/storage/sftp.rb +107 -0
- data/spec/sftp_spec.rb +95 -0
- metadata +25 -4
data/README.md
CHANGED
@@ -14,9 +14,11 @@ Require it in your code:
|
|
14
14
|
|
15
15
|
Or, in Rails you can add it to your Gemfile:
|
16
16
|
|
17
|
-
gem 'carrierwave-ftp', :require => 'carrierwave/storage/
|
17
|
+
gem 'carrierwave-ftp', :require => 'carrierwave/storage/all' # both FTP/SFTP
|
18
|
+
gem 'carrierwave-ftp', :require => 'carrierwave/storage/ftp' # FTP only
|
19
|
+
gem 'carrierwave-ftp', :require => 'carrierwave/storage/sftp' # SFTP only
|
18
20
|
|
19
|
-
## Getting Started
|
21
|
+
## Getting Started (FTP)
|
20
22
|
|
21
23
|
First configure CarrierWave with your FTP credentials:
|
22
24
|
|
@@ -38,3 +40,28 @@ class AvatarUploader < CarrierWave::Uploader::Base
|
|
38
40
|
storage :ftp
|
39
41
|
end
|
40
42
|
```
|
43
|
+
|
44
|
+
## Getting Started (SFTP)
|
45
|
+
|
46
|
+
First configure CarrierWave with your SFTP credentials:
|
47
|
+
|
48
|
+
```ruby
|
49
|
+
CarrierWave.configure do |config|
|
50
|
+
config.sftp_host = "example.com"
|
51
|
+
config.sftp_user = "example"
|
52
|
+
config.sftp_folder = "public_html/uploads"
|
53
|
+
config.sftp_url = "http://example.com/uploads"
|
54
|
+
config.sftp_options = {
|
55
|
+
:password => "secret",
|
56
|
+
:port => 22
|
57
|
+
}
|
58
|
+
end
|
59
|
+
```
|
60
|
+
|
61
|
+
And then in your uploader, set the storage to `:sftp`:
|
62
|
+
|
63
|
+
```ruby
|
64
|
+
class AvatarUploader < CarrierWave::Uploader::Base
|
65
|
+
storage :sftp
|
66
|
+
end
|
67
|
+
```
|
data/carrerwave-ftp.gemspec
CHANGED
@@ -12,7 +12,7 @@ Gem::Specification.new do |s|
|
|
12
12
|
s.summary = %q{FTP support for CarrierWave}
|
13
13
|
s.description = %q{Allows file upload using FTP for CarrierWave uploaders.}
|
14
14
|
|
15
|
-
s.rubyforge_project = "carrierwave-
|
15
|
+
s.rubyforge_project = "carrierwave-ftp"
|
16
16
|
|
17
17
|
s.files = `git ls-files`.split("\n")
|
18
18
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
@@ -20,6 +20,7 @@ Gem::Specification.new do |s|
|
|
20
20
|
s.require_paths = ["lib"]
|
21
21
|
|
22
22
|
s.add_dependency "carrierwave", ["~> 0.6.2"]
|
23
|
+
s.add_dependency "net-sftp", ["~> 2.0.5"]
|
23
24
|
s.add_development_dependency "rspec", ["~> 2.6"]
|
24
25
|
s.add_development_dependency "rake", ["~> 0.9"]
|
25
26
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'net/sftp'
|
2
|
+
|
3
|
+
class Net::SFTP::Session
|
4
|
+
def mkdir_p!(dir)
|
5
|
+
parts = dir.split("/")
|
6
|
+
growing_path = ""
|
7
|
+
for part in parts
|
8
|
+
next if part == ""
|
9
|
+
if growing_path == ""
|
10
|
+
growing_path = part
|
11
|
+
else
|
12
|
+
growing_path = File.join(growing_path, part)
|
13
|
+
end
|
14
|
+
begin
|
15
|
+
mkdir!(growing_path)
|
16
|
+
rescue
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
require 'carrierwave'
|
2
|
+
require 'carrierwave/storage/ftp/ex_sftp'
|
3
|
+
|
4
|
+
module CarrierWave
|
5
|
+
module Storage
|
6
|
+
class SFTP < Abstract
|
7
|
+
def store!(file)
|
8
|
+
f = CarrierWave::Storage::SFTP::File.new(uploader, self, uploader.store_path)
|
9
|
+
f.store(file)
|
10
|
+
f
|
11
|
+
end
|
12
|
+
|
13
|
+
def retrieve!(identifier)
|
14
|
+
CarrierWave::Storage::SFTP::File.new(uploader, self, uploader.store_path(identifier))
|
15
|
+
end
|
16
|
+
|
17
|
+
class File
|
18
|
+
attr_reader :path
|
19
|
+
|
20
|
+
def initialize(uploader, base, path)
|
21
|
+
@uploader, @base, @path = uploader, base, path
|
22
|
+
end
|
23
|
+
|
24
|
+
def store(file)
|
25
|
+
connection do |sftp|
|
26
|
+
sftp.mkdir_p!(::File.dirname full_path)
|
27
|
+
sftp.upload!(file.path, full_path)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def url
|
32
|
+
"#{@uploader.sftp_url}/#{path}"
|
33
|
+
end
|
34
|
+
|
35
|
+
def filename(options = {})
|
36
|
+
url.gsub(/.*\/(.*?$)/, '\1')
|
37
|
+
end
|
38
|
+
|
39
|
+
def size
|
40
|
+
size = nil
|
41
|
+
|
42
|
+
connection do |sftp|
|
43
|
+
size = sftp.stat!(full_path).size
|
44
|
+
end
|
45
|
+
|
46
|
+
size
|
47
|
+
end
|
48
|
+
|
49
|
+
def exists?
|
50
|
+
size ? true : false
|
51
|
+
end
|
52
|
+
|
53
|
+
def read
|
54
|
+
http_get_body(url)
|
55
|
+
end
|
56
|
+
|
57
|
+
def delete
|
58
|
+
connection do |sftp|
|
59
|
+
sftp.remove!(full_path)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
private
|
64
|
+
|
65
|
+
def full_path
|
66
|
+
"#{@uploader.sftp_folder}/#{path}"
|
67
|
+
end
|
68
|
+
|
69
|
+
def http_get_body(url)
|
70
|
+
require 'net/http'
|
71
|
+
url = URI.parse(url)
|
72
|
+
req = Net::HTTP::Get.new(url.path)
|
73
|
+
res = Net::HTTP.start(url.host, url.port) do |http|
|
74
|
+
http.request(req)
|
75
|
+
end
|
76
|
+
|
77
|
+
res.body
|
78
|
+
end
|
79
|
+
|
80
|
+
def connection
|
81
|
+
sftp = Net::SFTP.start(@uploader.sftp_host, @uploader.sftp_user, @uploader.sftp_options)
|
82
|
+
yield sftp
|
83
|
+
sftp.close_channel
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
CarrierWave::Storage.autoload :SFTP, 'carrierwave/storage/sftp'
|
91
|
+
|
92
|
+
class CarrierWave::Uploader::Base
|
93
|
+
add_config :sftp_host
|
94
|
+
add_config :sftp_user
|
95
|
+
add_config :sftp_options
|
96
|
+
add_config :sftp_folder
|
97
|
+
add_config :sftp_url
|
98
|
+
|
99
|
+
configure do |config|
|
100
|
+
config.storage_engines[:sftp] = "CarrierWave::Storage::SFTP"
|
101
|
+
config.sftp_host = "localhost"
|
102
|
+
config.sftp_user = "anonymous"
|
103
|
+
config.sftp_options = {}
|
104
|
+
config.sftp_folder = ""
|
105
|
+
config.sftp_url = "http://localhost"
|
106
|
+
end
|
107
|
+
end
|
data/spec/sftp_spec.rb
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'carrierwave/storage/sftp'
|
3
|
+
|
4
|
+
class SftpUploader < CarrierWave::Uploader::Base
|
5
|
+
storage :sftp
|
6
|
+
end
|
7
|
+
|
8
|
+
describe CarrierWave::Storage::SFTP do
|
9
|
+
before do
|
10
|
+
CarrierWave.configure do |config|
|
11
|
+
config.reset_config
|
12
|
+
config.sftp_host = 'testcarrierwave.dev'
|
13
|
+
config.sftp_user = 'test_user'
|
14
|
+
config.sftp_folder = '/home/test_user/public_html'
|
15
|
+
config.sftp_url = 'http://testcarrierwave.dev'
|
16
|
+
config.sftp_options = {
|
17
|
+
:password => 'test_passwd',
|
18
|
+
:port => 22
|
19
|
+
}
|
20
|
+
end
|
21
|
+
|
22
|
+
@file = CarrierWave::SanitizedFile.new(file_path('test.jpg'))
|
23
|
+
SftpUploader.stub!(:store_path).and_return('uploads/test.jpg')
|
24
|
+
@storage = CarrierWave::Storage::SFTP.new(SftpUploader)
|
25
|
+
end
|
26
|
+
|
27
|
+
it "opens/closes an ftp connection to the given host" do
|
28
|
+
sftp = double(:sftp_connection)
|
29
|
+
sftp_params = [
|
30
|
+
'testcarrierwave.dev',
|
31
|
+
'test_user',
|
32
|
+
{
|
33
|
+
:password => 'test_passwd',
|
34
|
+
:port => 22
|
35
|
+
}
|
36
|
+
]
|
37
|
+
|
38
|
+
Net::SFTP.should_receive(:start).with(*sftp_params).and_return(sftp)
|
39
|
+
sftp.should_receive(:mkdir_p!).with('/home/test_user/public_html/uploads')
|
40
|
+
sftp.should_receive(:upload!).with(@file.path, '/home/test_user/public_html/uploads/test.jpg')
|
41
|
+
sftp.should_receive(:close_channel)
|
42
|
+
@stored = @storage.store!(@file)
|
43
|
+
end
|
44
|
+
|
45
|
+
describe 'after upload' do
|
46
|
+
before do
|
47
|
+
sftp = double(:sftp_connection)
|
48
|
+
Net::SFTP.stub(:start).and_return(sftp)
|
49
|
+
sftp.stub(:mkdir_p!)
|
50
|
+
sftp.stub(:upload!)
|
51
|
+
sftp.stub(:close_channel)
|
52
|
+
@stored = @storage.store!(@file)
|
53
|
+
end
|
54
|
+
|
55
|
+
it "returns a url based on directory" do
|
56
|
+
@stored.url.should == 'http://testcarrierwave.dev/uploads/test.jpg'
|
57
|
+
end
|
58
|
+
|
59
|
+
it "returns a path based on directory" do
|
60
|
+
@stored.path.should == 'uploads/test.jpg'
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe 'other operations' do
|
65
|
+
before do
|
66
|
+
@sftp = double(:sftp_connection)
|
67
|
+
Net::SFTP.stub(:start).and_return(@sftp)
|
68
|
+
@sftp.stub(:mkdir_p!)
|
69
|
+
@sftp.stub(:upload!)
|
70
|
+
@sftp.stub(:close_channel)
|
71
|
+
@stored = @storage.store!(@file)
|
72
|
+
end
|
73
|
+
|
74
|
+
it "deletes a file" do
|
75
|
+
@sftp.should_receive(:remove!).with('/home/test_user/public_html/uploads/test.jpg')
|
76
|
+
@stored.delete
|
77
|
+
end
|
78
|
+
|
79
|
+
it "checks whether a file exists" do
|
80
|
+
@stored.should_receive(:size).and_return(10)
|
81
|
+
@stored.exists?.should == true
|
82
|
+
end
|
83
|
+
|
84
|
+
it "returns the size of the file" do
|
85
|
+
@sftp.should_receive(:stat!).with('/home/test_user/public_html/uploads/test.jpg')
|
86
|
+
.and_return(Struct.new(:size).new(14))
|
87
|
+
@stored.size.should == 14
|
88
|
+
end
|
89
|
+
|
90
|
+
it "returns the content of the file" do
|
91
|
+
@stored.should_receive(:http_get_body).with(@stored.url).and_return('some content')
|
92
|
+
@stored.read.should == 'some content'
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: carrierwave-ftp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -27,6 +27,22 @@ dependencies:
|
|
27
27
|
- - ~>
|
28
28
|
- !ruby/object:Gem::Version
|
29
29
|
version: 0.6.2
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: net-sftp
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ~>
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: 2.0.5
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 2.0.5
|
30
46
|
- !ruby/object:Gem::Dependency
|
31
47
|
name: rspec
|
32
48
|
requirement: !ruby/object:Gem::Requirement
|
@@ -73,9 +89,13 @@ files:
|
|
73
89
|
- Rakefile
|
74
90
|
- carrerwave-ftp.gemspec
|
75
91
|
- lib/carrierwave/storage/ftp.rb
|
92
|
+
- lib/carrierwave/storage/ftp/all.rb
|
76
93
|
- lib/carrierwave/storage/ftp/ex_ftp.rb
|
94
|
+
- lib/carrierwave/storage/ftp/ex_sftp.rb
|
77
95
|
- lib/carrierwave/storage/ftp/version.rb
|
96
|
+
- lib/carrierwave/storage/sftp.rb
|
78
97
|
- spec/ftp_spec.rb
|
98
|
+
- spec/sftp_spec.rb
|
79
99
|
- spec/spec_helper.rb
|
80
100
|
homepage: https://github.com/luan/carrierwave-ftp
|
81
101
|
licenses: []
|
@@ -91,7 +111,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
91
111
|
version: '0'
|
92
112
|
segments:
|
93
113
|
- 0
|
94
|
-
hash:
|
114
|
+
hash: 290347820507570724
|
95
115
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
96
116
|
none: false
|
97
117
|
requirements:
|
@@ -100,13 +120,14 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
100
120
|
version: '0'
|
101
121
|
segments:
|
102
122
|
- 0
|
103
|
-
hash:
|
123
|
+
hash: 290347820507570724
|
104
124
|
requirements: []
|
105
|
-
rubyforge_project: carrierwave-
|
125
|
+
rubyforge_project: carrierwave-ftp
|
106
126
|
rubygems_version: 1.8.23
|
107
127
|
signing_key:
|
108
128
|
specification_version: 3
|
109
129
|
summary: FTP support for CarrierWave
|
110
130
|
test_files:
|
111
131
|
- spec/ftp_spec.rb
|
132
|
+
- spec/sftp_spec.rb
|
112
133
|
- spec/spec_helper.rb
|