paperclip-storage-ftp 1.0.0.rc3 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -9,9 +9,11 @@ to be stored on FTP servers.
9
9
 
10
10
  ## Installation
11
11
 
12
- Add this line to your application's Gemfile:
12
+ Add this line to your application's `Gemfile`:
13
13
 
14
- gem 'paperclip-storage-ftp'
14
+ ```ruby
15
+ gem "paperclip-storage-ftp"
16
+ ```
15
17
 
16
18
  And then execute:
17
19
 
@@ -25,40 +27,45 @@ Or install it yourself as:
25
27
 
26
28
  Somewhere in your code:
27
29
 
28
- require "paperclip/storage/ftp"
30
+ ```ruby
31
+ require "paperclip/storage/ftp"
32
+ ```
29
33
 
30
34
  In your model:
31
35
 
32
- class User < ActiveRecord::Base
33
- has_attached_file :avatar,
34
-
35
- # Choose the FTP storage backend
36
- :storage => :ftp,
37
-
38
- # Set where to store the file on the FTP server(s).
39
- # This supports Paperclip::Interpolations.
40
- :path => "/path_on_ftp_server/:attachment/:id/:style/:filename"
41
-
42
- # The full URL of where the attachment is publicly accessible.
43
- # This supports Paperclip::Interpolations.
44
- :url => "/url_prefix/:attachment/:id/:style/:filename"
45
-
46
- # The list of FTP servers to use
47
- :ftp_servers => [
48
- {
49
- :host => "ftp1.example.com",
50
- :user => "foo",
51
- :password => "bar",
52
- :port => 21 # optional
53
- },
54
- # Add more servers if needed
55
- {
56
- :host => "ftp2.example.com",
57
- :user => "foo",
58
- :password => "bar"
59
- }
60
- ]
61
- end
36
+ ```ruby
37
+ class User < ActiveRecord::Base
38
+ has_attached_file :avatar,
39
+
40
+ # Choose the FTP storage backend
41
+ :storage => :ftp,
42
+
43
+ # Set where to store the file on the FTP server(s).
44
+ # This supports Paperclip::Interpolations.
45
+ :path => "/path_on_ftp_server/:attachment/:id/:style/:filename",
46
+
47
+ # The full URL of where the attachment is publicly accessible.
48
+ # This supports Paperclip::Interpolations.
49
+ :url => "/url_prefix/:attachment/:id/:style/:filename",
50
+
51
+ # The list of FTP servers to use
52
+ :ftp_servers => [
53
+ {
54
+ :host => "ftp1.example.com",
55
+ :user => "foo",
56
+ :password => "bar",
57
+ :port => 21, # optional
58
+ },
59
+ # Add more servers if needed
60
+ {
61
+ :host => "ftp2.example.com",
62
+ :user => "foo",
63
+ :password => "bar",
64
+ :port => 2121
65
+ }
66
+ ]
67
+ end
68
+ ```
62
69
 
63
70
  ## Contributing
64
71
 
@@ -67,3 +74,15 @@ In your model:
67
74
  3. Commit your changes (`git commit -am 'Added some feature'`)
68
75
  4. Push to the branch (`git push origin my-new-feature`)
69
76
  5. Create new Pull Request
77
+
78
+ ## Authors
79
+
80
+ * [Sebastian Röbke](https://github.com/boosty)
81
+ * and other friendly [contributors](https://github.com/xing/paperclip-storage-ftp/graphs/contributors)
82
+
83
+ You can find out more about our work on our [dev blog](http://devblog.xing.com).
84
+
85
+ Copyright (c) 2012 [XING AG](http://www.xing.com)
86
+
87
+ Released under the MIT license. For full details see [LICENSE](https://github.com/xing/paperclip-storage-ftp/blob/master/LICENSE)
88
+ included in this distribution.
@@ -6,8 +6,14 @@ module Paperclip
6
6
  module Ftp
7
7
  class Server
8
8
 
9
+ @@connections = {}
10
+
11
+ def self.clear_connections
12
+ @@connections.clear
13
+ end
14
+
9
15
  attr_accessor :host, :user, :password
10
- attr_writer :connection, :port
16
+ attr_writer :port
11
17
 
12
18
  def initialize(options = {})
13
19
  options.each do |k,v|
@@ -35,12 +41,19 @@ module Paperclip
35
41
  end
36
42
 
37
43
  def connection
38
- @connection ||= begin
39
- connection = Net::FTP.new
44
+ connection = @@connections["#{host}:#{port}"] ||= build_connection
45
+ if connection.closed?
40
46
  connection.connect(host, port)
41
47
  connection.login(user, password)
42
- connection
43
48
  end
49
+ connection
50
+ end
51
+
52
+ def build_connection
53
+ connection = Net::FTP.new
54
+ connection.connect(host, port)
55
+ connection.login(user, password)
56
+ connection
44
57
  end
45
58
 
46
59
  def port
@@ -11,7 +11,7 @@ Gem::Specification.new do |gem|
11
11
  gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
12
12
  gem.name = "paperclip-storage-ftp"
13
13
  gem.require_paths = ["lib"]
14
- gem.version = "1.0.0.rc3"
14
+ gem.version = "1.0.0"
15
15
 
16
16
  gem.add_dependency("paperclip")
17
17
 
@@ -1,6 +1,10 @@
1
1
  require "spec_helper"
2
2
 
3
3
  describe Paperclip::Storage::Ftp::Server do
4
+ before(:each) do
5
+ Paperclip::Storage::Ftp::Server.clear_connections
6
+ end
7
+
4
8
  let(:server) { Paperclip::Storage::Ftp::Server.new }
5
9
 
6
10
  context "initialize" do
@@ -25,36 +29,43 @@ describe Paperclip::Storage::Ftp::Server do
25
29
  end
26
30
 
27
31
  context "#file_exists?" do
32
+ before do
33
+ server.stub(:connection).and_return(double("connection"))
34
+ end
35
+
28
36
  it "returns true if the file exists on the server" do
29
- server.connection = double("connection")
30
37
  server.connection.should_receive(:nlst).with("/files/original").and_return(["foo.jpg"])
31
38
  server.file_exists?("/files/original/foo.jpg").should be_true
32
39
  end
33
40
 
34
41
  it "recognizes complete file paths correctly" do
35
- server.connection = double("connection")
36
42
  server.connection.should_receive(:nlst).with("/files/original").and_return(["/files/original/foo.jpg"])
37
43
  server.file_exists?("/files/original/foo.jpg").should be_true
38
44
  end
39
45
 
40
46
  it "returns false if the file does not exist on the server" do
41
- server.connection = double("connection")
42
47
  server.connection.should_receive(:nlst).with("/files/original").and_return([])
43
48
  server.file_exists?("/files/original/foo.jpg").should be_false
44
49
  end
45
50
  end
46
51
 
47
52
  context "#get_file" do
53
+ before do
54
+ server.stub(:connection).and_return(double("connection"))
55
+ end
56
+
48
57
  it "returns the file object" do
49
- server.connection = double("connection")
50
58
  server.connection.should_receive(:getbinaryfile).with("/files/original.jpg", "/tmp/original.jpg")
51
59
  server.get_file("/files/original.jpg", "/tmp/original.jpg")
52
60
  end
53
61
  end
54
62
 
55
63
  context "#put_file" do
64
+ before do
65
+ server.stub(:connection).and_return(double("connection"))
66
+ end
67
+
56
68
  it "stores the file on the server" do
57
- server.connection = double("connection")
58
69
  server.should_receive(:mkdir_p).with("/files")
59
70
  server.connection.should_receive(:putbinaryfile).with("/tmp/original.jpg", "/files/original.jpg")
60
71
  server.put_file("/tmp/original.jpg", "/files/original.jpg")
@@ -62,31 +73,78 @@ describe Paperclip::Storage::Ftp::Server do
62
73
  end
63
74
 
64
75
  context "#delete_file" do
76
+ before do
77
+ server.stub(:connection).and_return(double("connection"))
78
+ end
79
+
65
80
  it "deletes the file on the server" do
66
- server.connection = double("connection")
67
81
  server.connection.should_receive(:delete).with("/files/original.jpg")
68
82
  server.delete_file("/files/original.jpg")
69
83
  end
70
84
  end
71
85
 
72
- context "#connection" do
73
- it "returns a memoized ftp connection to the given server" do
86
+ context "#build_connection" do
87
+ it "returns the ftp connection for the given server" do
74
88
  server.host = "ftp.example.com"
75
89
  server.user = "user"
76
90
  server.password = "password"
77
91
 
78
- connection = double("connection")
79
- Net::FTP.should_receive(:new).once.and_return(connection)
80
- connection.should_receive(:connect).once.with(server.host, server.port)
81
- connection.should_receive(:login).once.with(server.user, server.password)
92
+ ftp = double("ftp")
93
+ Net::FTP.should_receive(:new).and_return(ftp)
94
+ ftp.should_receive(:connect).with(server.host, server.port)
95
+ ftp.should_receive(:login).with(server.user, server.password)
96
+ server.build_connection.should == ftp
97
+ end
98
+ end
99
+
100
+ context "#connection" do
101
+ it "returns the memoized ftp connection for the given server" do
102
+ connection = double("connection", :closed? => false)
103
+ server.should_receive(:build_connection).once.and_return(connection)
104
+ server.connection.should == connection
105
+
106
+ # same host, same port => memoize
107
+ same_server = Paperclip::Storage::Ftp::Server.new(
108
+ :host => server.host,
109
+ :port => server.port
110
+ )
111
+ same_server.should_receive(:build_connection).never
112
+ same_server.connection.should == connection
82
113
 
83
- 2.times { server.connection.should == connection }
114
+ # different host => do not memoize
115
+ other_host_connection = double("other_host_connection", :closed? => false)
116
+ other_host_server = Paperclip::Storage::Ftp::Server.new(
117
+ :host => "other.#{server.host}",
118
+ :port => server.port
119
+ )
120
+ other_host_server.should_receive(:build_connection).once.and_return(other_host_connection)
121
+ other_host_server.connection.should == other_host_connection
122
+
123
+ # different port => do not memoize
124
+ other_port_connection = double("other_port_connection", :closed? => false)
125
+ other_port_server = Paperclip::Storage::Ftp::Server.new(
126
+ :host => server.host,
127
+ :port => server.port + 1
128
+ )
129
+ other_port_server.should_receive(:build_connection).once.and_return(other_port_connection)
130
+ other_port_server.connection.should == other_port_connection
131
+ end
132
+
133
+ it "reconnects if the connection is closed" do
134
+ connection = double("connection", :closed? => true)
135
+ server.stub(:build_connection) { connection }
136
+ connection.should_receive(:connect).with(server.host, server.port)
137
+ connection.should_receive(:login).with(server.user, server.password)
138
+ server.connection.should == connection
84
139
  end
85
140
  end
86
141
 
87
142
  context "mkdir_p" do
143
+ before do
144
+ server.stub(:connection).and_return(double("connection"))
145
+ end
146
+
88
147
  it "creates the directory and all its parent directories" do
89
- server.connection = double("connection")
90
148
  server.connection.should_receive(:mkdir).with("/").ordered
91
149
  server.connection.should_receive(:mkdir).with("/files").ordered
92
150
  server.connection.should_receive(:mkdir).with("/files/foo").ordered
@@ -95,7 +153,6 @@ describe Paperclip::Storage::Ftp::Server do
95
153
  end
96
154
 
97
155
  it "does not stop on Net::FTPPermError" do
98
- server.connection = double("connection")
99
156
  server.connection.should_receive(:mkdir).with("/").and_raise(Net::FTPPermError)
100
157
  server.connection.should_receive(:mkdir).with("/files")
101
158
  server.mkdir_p("/files")
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: paperclip-storage-ftp
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.rc3
5
- prerelease: 6
4
+ version: 1.0.0
5
+ prerelease:
6
6
  platform: ruby
7
7
  authors:
8
8
  - Sebastian Röbke
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-10-31 00:00:00.000000000 Z
12
+ date: 2012-11-01 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: paperclip
@@ -126,15 +126,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
126
126
  - - ! '>='
127
127
  - !ruby/object:Gem::Version
128
128
  version: '0'
129
- segments:
130
- - 0
131
- hash: -504637831743076511
132
129
  required_rubygems_version: !ruby/object:Gem::Requirement
133
130
  none: false
134
131
  requirements:
135
- - - ! '>'
132
+ - - ! '>='
136
133
  - !ruby/object:Gem::Version
137
- version: 1.3.1
134
+ version: '0'
138
135
  requirements: []
139
136
  rubyforge_project:
140
137
  rubygems_version: 1.8.24