paperclip-storage-ftp 1.0.0.rc3 → 1.0.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 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