paperclip-storage-ftp 1.2.1 → 1.2.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7ac0615dacb3edb9fd6ed435afa757d631e96946
4
- data.tar.gz: 78db92783d426bb615b9beef8133d2e717d69740
3
+ metadata.gz: 8ca9a1238f7b7f38cac421a942ccd513b637bd10
4
+ data.tar.gz: d48282fb301803804f7ae63f25eac3cb8f3f7555
5
5
  SHA512:
6
- metadata.gz: f42bcf600a6cddde9324da644dfbed5de0d4af895318041cd357772bd48a59a15c38537579037701e8fecbccc5578474efd19130c6842875f08fac4757644461
7
- data.tar.gz: ac45ef8e943368a069369c5c56d7645c740f1124d28b72e768205692653fda754bb323584baa5047fbfd1174fb0cffafcc9fe531193ba29cf5018a96734225bd
6
+ metadata.gz: 17a256d870d927dece3b64d96f00c9db3d2a020a7a399494d566d4c99300edd7ef9dae2feab33c4b697236fcf111efeb2a12ed867e837400ebc3ad751a37d8ca
7
+ data.tar.gz: 8f7fe427c147d1268b2d533be54c58a68c31b86bca1bbd3525d57ecdff0fed9b6ea43fc56211d896c9a6645224a837b26ec7dd6b5ab8d080e14165e959ebb7cf
data/.gitignore CHANGED
@@ -2,6 +2,7 @@
2
2
  *.rbc
3
3
  .bundle
4
4
  .config
5
+ .coveralls.yml
5
6
  .yardoc
6
7
  Gemfile.lock
7
8
  gemfiles/Gemfile.*.lock
data/.travis.yml CHANGED
@@ -1,8 +1,7 @@
1
1
  language: ruby
2
2
  rvm:
3
3
  - 1.9.3
4
- - 2.0.0
5
- - 2.1.0
4
+ - 2.1
6
5
  - jruby-19mode
7
6
  - rbx
8
7
  gemfile:
data/Gemfile CHANGED
@@ -6,6 +6,8 @@ gemspec
6
6
  group :test do
7
7
  gem "sqlite3", :platforms => :ruby
8
8
  gem "activerecord-jdbcsqlite3-adapter", "1.3.0.beta2", :platforms => :jruby
9
+
10
+ gem "coveralls", :require => false
9
11
  end
10
12
 
11
13
  platforms :rbx do
data/README.md CHANGED
@@ -3,9 +3,11 @@
3
3
  Allow [Paperclip](https://github.com/thoughtbot/paperclip) attachments
4
4
  to be stored on FTP servers.
5
5
 
6
- ## Build status
6
+ ## Status
7
7
 
8
8
  [![Build Status](https://secure.travis-ci.org/xing/paperclip-storage-ftp.png)](http://travis-ci.org/xing/paperclip-storage-ftp)
9
+ [![Coverage Status](https://coveralls.io/repos/xing/paperclip-storage-ftp/badge.png?branch=master)](https://coveralls.io/r/xing/paperclip-storage-ftp?branch=master)
10
+ [![Gem Version](https://badge.fury.io/rb/paperclip-storage-ftp.png)](http://badge.fury.io/rb/paperclip-storage-ftp)
9
11
 
10
12
  ## Installation
11
13
 
@@ -66,11 +68,14 @@ class User < ActiveRecord::Base
66
68
  ],
67
69
 
68
70
  # Optional socket connect timeout (in seconds).
69
- # This only limits the connection phase, once connected this option is of no more use.
71
+ # This only limits the connection phase, once connected
72
+ # this option is of no more use.
70
73
  :ftp_connect_timeout => 5, # optional, nil by default (OS default timeout)
71
74
 
72
- # If set to true and the connection to a particular server cannot be established,
73
- # the connection error will be ignored and the files will not be uploaded to that server.
75
+ # Optional flag to skip dead servers.
76
+ # If set to true and the connection to a particular server cannot be
77
+ # established, the connection error will be ignored and the files will
78
+ # not be uploaded to that server.
74
79
  # If set to false and the connection to a particular server cannot be established,
75
80
  # a SystemCallError will be raised (Errno::ETIMEDOUT, Errno::ENETUNREACH, etc.).
76
81
  :ftp_ignore_failing_connections => true # optional, false by default
@@ -79,6 +84,10 @@ end
79
84
 
80
85
  ## Changelog
81
86
 
87
+ ### 1.2.2
88
+
89
+ * Remove empty parent directories after image deletion [#21](https://github.com/xing/paperclip-storage-ftp/pull/21)
90
+
82
91
  ### 1.2.1
83
92
 
84
93
  * Raise `Paperclip::Storage::Ftp::NoServerAvailable` error when using `:ftp_ignore_failing_connections => true` but all servers are down
@@ -9,6 +9,8 @@ group :test do
9
9
 
10
10
  gem "sqlite3", :platforms => :ruby
11
11
  gem "activerecord-jdbcsqlite3-adapter", :platforms => :jruby
12
+
13
+ gem "coveralls", :require => false
12
14
  end
13
15
 
14
16
  platforms :rbx do
@@ -7,6 +7,8 @@ gem "paperclip", "~>3.0"
7
7
  group :test do
8
8
  gem "sqlite3", :platforms => :ruby
9
9
  gem "activerecord-jdbcsqlite3-adapter", :platforms => :jruby
10
+
11
+ gem "coveralls", :require => false
10
12
  end
11
13
 
12
14
  platforms :rbx do
@@ -7,6 +7,8 @@ gem "paperclip", "~>4.0"
7
7
  group :test do
8
8
  gem "sqlite3", :platforms => :ruby
9
9
  gem "activerecord-jdbcsqlite3-adapter", :platforms => :jruby
10
+
11
+ gem "coveralls", :require => false
10
12
  end
11
13
 
12
14
  platforms :rbx do
@@ -59,6 +59,9 @@ module Paperclip
59
59
  @queued_for_delete.each do |path|
60
60
  log("deleting ftp://#{server.user}@#{server.host}:#{path}")
61
61
  server.delete_file(path)
62
+
63
+ log("deleting empty parent directories ftp://#{server.user}@#{server.host}:#{path}")
64
+ server.rmdir_p(File.dirname(path))
62
65
  end
63
66
  end
64
67
  end.each(&:join)
@@ -68,6 +68,15 @@ module Paperclip
68
68
  connection.delete(remote_file_path)
69
69
  end
70
70
 
71
+ def rmdir_p(dir_path)
72
+ while(true)
73
+ connection.rmdir(dir_path)
74
+ dir_path = File.dirname(dir_path)
75
+ end
76
+ rescue Net::FTPTempError, Net::FTPPermError
77
+ # Stop trying to remove parent directories
78
+ end
79
+
71
80
  def mkdir_p(dirname)
72
81
  pathname = Pathname.new(dirname)
73
82
  pathname.descend do |p|
@@ -12,7 +12,7 @@ Gem::Specification.new do |gem|
12
12
  gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
13
13
  gem.name = "paperclip-storage-ftp"
14
14
  gem.require_paths = ["lib"]
15
- gem.version = "1.2.1"
15
+ gem.version = "1.2.2"
16
16
 
17
17
  gem.add_dependency("paperclip")
18
18
 
@@ -1,5 +1,6 @@
1
1
  require "spec_helper"
2
2
  require "timeout"
3
+ require "fileutils"
3
4
 
4
5
  describe "paperclip-storage-ftp", :integration => true do
5
6
 
@@ -23,16 +24,18 @@ describe "paperclip-storage-ftp", :integration => true do
23
24
  let(:uploaded_file_server2_medium) { FtpServer::USER2_PATH + "/medium/avatar.jpg" }
24
25
  let(:uploaded_file_server2_thumb) { FtpServer::USER2_PATH + "/thumb/avatar.jpg" }
25
26
 
27
+ let(:uploaded_file_server1_other) { FtpServer::USER1_PATH + "/original/foo.txt" }
28
+
26
29
  it "stores the attachment on the ftp servers" do
27
30
  user.avatar = file
28
31
  user.save!
29
32
 
30
- File.exists?(uploaded_file_server1).should be_true
31
- File.exists?(uploaded_file_server1_medium).should be_true
32
- File.exists?(uploaded_file_server1_thumb).should be_true
33
- File.exists?(uploaded_file_server2).should be_true
34
- File.exists?(uploaded_file_server2_medium).should be_true
35
- File.exists?(uploaded_file_server2_thumb).should be_true
33
+ File.exists?(uploaded_file_server1).should be true
34
+ File.exists?(uploaded_file_server1_medium).should be true
35
+ File.exists?(uploaded_file_server1_thumb).should be true
36
+ File.exists?(uploaded_file_server2).should be true
37
+ File.exists?(uploaded_file_server2_medium).should be true
38
+ File.exists?(uploaded_file_server2_thumb).should be true
36
39
 
37
40
  file.size.should == File.size(uploaded_file_server1)
38
41
  file.size.should == File.size(uploaded_file_server2)
@@ -44,12 +47,34 @@ describe "paperclip-storage-ftp", :integration => true do
44
47
 
45
48
  user.destroy
46
49
 
47
- File.exists?(uploaded_file_server1).should be_false
48
- File.exists?(uploaded_file_server1_medium).should be_false
49
- File.exists?(uploaded_file_server1_thumb).should be_false
50
- File.exists?(uploaded_file_server2).should be_false
51
- File.exists?(uploaded_file_server2_medium).should be_false
52
- File.exists?(uploaded_file_server2_thumb).should be_false
50
+ File.exists?(uploaded_file_server1).should be false
51
+ File.exists?(uploaded_file_server1_medium).should be false
52
+ File.exists?(uploaded_file_server1_thumb).should be false
53
+
54
+ File.exists?(uploaded_file_server2).should be false
55
+ File.exists?(uploaded_file_server2_medium).should be false
56
+ File.exists?(uploaded_file_server2_thumb).should be false
57
+ end
58
+
59
+ it "removes empty parent directories after image deletion" do
60
+ user.avatar = file
61
+ user.save!
62
+
63
+ user.destroy
64
+
65
+ Dir.exists?(File.dirname(uploaded_file_server1)).should be false
66
+ Dir.exists?(File.dirname(uploaded_file_server2)).should be false
67
+ end
68
+
69
+ it "does not remove parent directories which are not empty" do
70
+ user.avatar = file
71
+ user.save!
72
+
73
+ FileUtils.touch(uploaded_file_server1_other)
74
+
75
+ user.destroy
76
+
77
+ File.exists?(uploaded_file_server1_other).should be true
53
78
  end
54
79
 
55
80
  it "survives temporarily closed ftp connections" do
@@ -64,8 +89,8 @@ describe "paperclip-storage-ftp", :integration => true do
64
89
  user.avatar = file
65
90
  user.save!
66
91
 
67
- File.exists?(uploaded_file_server1).should be_true
68
- File.exists?(uploaded_file_server2).should be_true
92
+ File.exists?(uploaded_file_server1).should be true
93
+ File.exists?(uploaded_file_server2).should be true
69
94
  end
70
95
 
71
96
  it "allows ignoring failed connections" do
@@ -73,12 +98,12 @@ describe "paperclip-storage-ftp", :integration => true do
73
98
  user.avatar = file
74
99
  expect{ user.save! }.to_not raise_error
75
100
 
76
- File.exists?(uploaded_file_server1).should be_true
77
- File.exists?(uploaded_file_server1_medium).should be_true
78
- File.exists?(uploaded_file_server1_thumb).should be_true
79
- File.exists?(uploaded_file_server2).should be_false
80
- File.exists?(uploaded_file_server2_medium).should be_false
81
- File.exists?(uploaded_file_server2_thumb).should be_false
101
+ File.exists?(uploaded_file_server1).should be true
102
+ File.exists?(uploaded_file_server1_medium).should be true
103
+ File.exists?(uploaded_file_server1_thumb).should be true
104
+ File.exists?(uploaded_file_server2).should be false
105
+ File.exists?(uploaded_file_server2_medium).should be false
106
+ File.exists?(uploaded_file_server2_thumb).should be false
82
107
  end
83
108
 
84
109
  it "raises a SystemCallError when not ignoring failed connections" do
@@ -30,22 +30,22 @@ describe Paperclip::Storage::Ftp::Server do
30
30
 
31
31
  it "returns true if the file exists on the server" do
32
32
  server.connection.should_receive(:nlst).with("/files/original").and_return(["foo.jpg"])
33
- server.file_exists?("/files/original/foo.jpg").should be_true
33
+ server.file_exists?("/files/original/foo.jpg").should be true
34
34
  end
35
35
 
36
36
  it "recognizes complete file paths correctly" do
37
37
  server.connection.should_receive(:nlst).with("/files/original").and_return(["/files/original/foo.jpg"])
38
- server.file_exists?("/files/original/foo.jpg").should be_true
38
+ server.file_exists?("/files/original/foo.jpg").should be true
39
39
  end
40
40
 
41
41
  it "returns false if the file does not exist on the server" do
42
42
  server.connection.should_receive(:nlst).with("/files/original").and_return([])
43
- server.file_exists?("/files/original/foo.jpg").should be_false
43
+ server.file_exists?("/files/original/foo.jpg").should be false
44
44
  end
45
45
 
46
46
  it "returns false if the ftp server responds with a FTPTempError" do
47
47
  server.connection.should_receive(:nlst).with("/files/original").and_raise(Net::FTPTempError)
48
- server.file_exists?("/files/original/foo.jpg").should be_false
48
+ server.file_exists?("/files/original/foo.jpg").should be false
49
49
  end
50
50
  end
51
51
 
@@ -83,6 +83,20 @@ describe Paperclip::Storage::Ftp::Server do
83
83
  end
84
84
  end
85
85
 
86
+ context "#rmdir_p" do
87
+ before do
88
+ server.stub(:connection).and_return(double("connection"))
89
+ end
90
+
91
+ it "deletes the directory and all parent directories" do
92
+ server.connection.should_receive(:rmdir).with("/files/foo/bar")
93
+ server.connection.should_receive(:rmdir).with("/files/foo")
94
+ server.connection.should_receive(:rmdir).with("/files"){ raise Net::FTPPermError }
95
+ server.connection.should_not_receive(:rmdir).with("/")
96
+ server.rmdir_p("/files/foo/bar")
97
+ end
98
+ end
99
+
86
100
  context "#establish_connection" do
87
101
  it "creates the ftp connection for the given server" do
88
102
  ftp = double("ftp")
@@ -34,13 +34,13 @@ describe Paperclip::Storage::Ftp do
34
34
  context "#exists?" do
35
35
  it "returns false if original_filename not set" do
36
36
  attachment.stub(:original_filename).and_return(nil)
37
- attachment.exists?.should be_false
37
+ attachment.exists?.should be false
38
38
  end
39
39
 
40
40
  it "returns true if the file exists on the primary server" do
41
41
  first_server.should_receive(:file_exists?).with("/files/original/foo.jpg").and_return(true)
42
42
  attachment.should_receive(:with_primary_ftp_server).and_yield(first_server)
43
- attachment.exists?.should be_true
43
+ attachment.exists?.should be true
44
44
  end
45
45
 
46
46
  it "accepts an optional style_name parameter to build the correct file path" do
@@ -112,9 +112,13 @@ describe Paperclip::Storage::Ftp do
112
112
  ])
113
113
 
114
114
  first_server.should_receive(:delete_file).with("/files/original/foo.jpg")
115
+ first_server.should_receive(:rmdir_p).with("/files/original")
115
116
  first_server.should_receive(:delete_file).with("/files/thumb/foo.jpg")
117
+ first_server.should_receive(:rmdir_p).with("/files/thumb")
116
118
  second_server.should_receive(:delete_file).with("/files/original/foo.jpg")
119
+ second_server.should_receive(:rmdir_p).with("/files/original")
117
120
  second_server.should_receive(:delete_file).with("/files/thumb/foo.jpg")
121
+ second_server.should_receive(:rmdir_p).with("/files/thumb")
118
122
 
119
123
  attachment.should_receive(:with_ftp_servers).and_yield([first_server, second_server])
120
124
 
data/spec/spec_helper.rb CHANGED
@@ -1,6 +1,21 @@
1
+ require "simplecov"
2
+ require "coveralls"
3
+
4
+ SimpleCov.formatter = Coveralls::SimpleCov::Formatter
5
+ SimpleCov.start do
6
+ add_filter "spec"
7
+ end
8
+
1
9
  RSpec.configure do |config|
2
- config.treat_symbols_as_metadata_keys_with_true_values = true
3
10
  config.run_all_when_everything_filtered = true
11
+
12
+ config.expect_with :rspec do |c|
13
+ c.syntax = [:expect, :should]
14
+ end
15
+
16
+ config.mock_with :rspec do |c|
17
+ c.syntax = [:expect, :should]
18
+ end
4
19
  end
5
20
 
6
21
  require "paperclip/storage/ftp"
@@ -40,29 +40,27 @@ class UserBase < ActiveRecord::Base
40
40
  }
41
41
  end
42
42
 
43
- # must be called after has_attached_file
44
- def self.setup_validation
43
+ def self.setup_avatar_attachment(options = avatar_options)
44
+ has_attached_file :avatar, options
45
45
  validates_attachment_content_type :avatar, :content_type => /\Aimage\/.*\Z/
46
46
  end
47
47
  end
48
48
 
49
49
  class User < UserBase
50
- has_attached_file :avatar, avatar_options
51
- setup_validation
50
+ setup_avatar_attachment
52
51
  end
53
52
 
54
53
  class UserWithConnectTimeout < UserBase
55
54
  TIMEOUT = 0.1
56
55
 
57
- has_attached_file :avatar, avatar_options.merge(
56
+ setup_avatar_attachment(avatar_options.merge(
58
57
  :ftp_servers => [
59
58
  {
60
59
  :host => "127.0.0.2" # should raise Errno::ETIMEDOUT
61
60
  }
62
61
  ],
63
62
  :ftp_connect_timeout => TIMEOUT
64
- )
65
- setup_validation
63
+ ))
66
64
  end
67
65
 
68
66
  class UserWithInvalidPort < UserBase
@@ -87,15 +85,13 @@ class UserWithInvalidPort < UserBase
87
85
  end
88
86
 
89
87
  class UserIgnoringFailingConnection < UserWithInvalidPort
90
- has_attached_file :avatar, avatar_options.merge(
88
+ setup_avatar_attachment(avatar_options.merge(
91
89
  :ftp_ignore_failing_connections => true
92
- )
93
- setup_validation
90
+ ))
94
91
  end
95
92
 
96
93
  class UserNotIgnoringFailingConnection < UserWithInvalidPort
97
- has_attached_file :avatar, avatar_options.merge(
94
+ setup_avatar_attachment(avatar_options.merge(
98
95
  :ftp_ignore_failing_connections => false
99
- )
100
- setup_validation
96
+ ))
101
97
  end
data/test-all.sh CHANGED
@@ -14,7 +14,7 @@ else
14
14
  printf "ERROR: An RVM installation was not found.\n"
15
15
  fi
16
16
 
17
- for ruby in '1.9.3' '2.0.0' '2.1.0' 'jruby --1.9' 'rbx'
17
+ for ruby in '1.9.3' '2.1' 'jruby --1.9' 'rbx'
18
18
  do
19
19
  rvm try_install $ruby
20
20
  rvm use $ruby
metadata CHANGED
@@ -1,85 +1,85 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: paperclip-storage-ftp
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.1
4
+ version: 1.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sebastian Röbke
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-02-10 00:00:00.000000000 Z
11
+ date: 2014-10-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- version_requirements: !ruby/object:Gem::Requirement
15
- requirements:
16
- - - '>='
17
- - !ruby/object:Gem::Version
18
- version: '0'
19
- prerelease: false
20
14
  name: paperclip
21
15
  requirement: !ruby/object:Gem::Requirement
22
16
  requirements:
23
- - - '>='
17
+ - - ">="
24
18
  - !ruby/object:Gem::Version
25
19
  version: '0'
26
20
  type: :runtime
27
- - !ruby/object:Gem::Dependency
21
+ prerelease: false
28
22
  version_requirements: !ruby/object:Gem::Requirement
29
23
  requirements:
30
- - - '>='
24
+ - - ">="
31
25
  - !ruby/object:Gem::Version
32
26
  version: '0'
33
- prerelease: false
27
+ - !ruby/object:Gem::Dependency
34
28
  name: rspec
35
29
  requirement: !ruby/object:Gem::Requirement
36
30
  requirements:
37
- - - '>='
31
+ - - ">="
38
32
  - !ruby/object:Gem::Version
39
33
  version: '0'
40
34
  type: :development
41
- - !ruby/object:Gem::Dependency
35
+ prerelease: false
42
36
  version_requirements: !ruby/object:Gem::Requirement
43
37
  requirements:
44
- - - '>='
38
+ - - ">="
45
39
  - !ruby/object:Gem::Version
46
40
  version: '0'
47
- prerelease: false
41
+ - !ruby/object:Gem::Dependency
48
42
  name: rake
49
43
  requirement: !ruby/object:Gem::Requirement
50
44
  requirements:
51
- - - '>='
45
+ - - ">="
52
46
  - !ruby/object:Gem::Version
53
47
  version: '0'
54
48
  type: :development
55
- - !ruby/object:Gem::Dependency
49
+ prerelease: false
56
50
  version_requirements: !ruby/object:Gem::Requirement
57
51
  requirements:
58
- - - '>='
52
+ - - ">="
59
53
  - !ruby/object:Gem::Version
60
- version: 1.1.0
61
- prerelease: false
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
62
56
  name: daemon_controller
63
57
  requirement: !ruby/object:Gem::Requirement
64
58
  requirements:
65
- - - '>='
59
+ - - ">="
66
60
  - !ruby/object:Gem::Version
67
61
  version: 1.1.0
68
62
  type: :development
69
- - !ruby/object:Gem::Dependency
63
+ prerelease: false
70
64
  version_requirements: !ruby/object:Gem::Requirement
71
65
  requirements:
72
- - - '>='
66
+ - - ">="
73
67
  - !ruby/object:Gem::Version
74
- version: '0'
75
- prerelease: false
68
+ version: 1.1.0
69
+ - !ruby/object:Gem::Dependency
76
70
  name: activerecord
77
71
  requirement: !ruby/object:Gem::Requirement
78
72
  requirements:
79
- - - '>='
73
+ - - ">="
80
74
  - !ruby/object:Gem::Version
81
75
  version: '0'
82
76
  type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
83
  description: Allow Paperclip attachments to be stored on FTP servers
84
84
  email:
85
85
  - sebastian.roebke@xing.com
@@ -87,8 +87,8 @@ executables: []
87
87
  extensions: []
88
88
  extra_rdoc_files: []
89
89
  files:
90
- - .gitignore
91
- - .travis.yml
90
+ - ".gitignore"
91
+ - ".travis.yml"
92
92
  - Gemfile
93
93
  - LICENSE
94
94
  - README.md
@@ -147,17 +147,17 @@ require_paths:
147
147
  - lib
148
148
  required_ruby_version: !ruby/object:Gem::Requirement
149
149
  requirements:
150
- - - '>='
150
+ - - ">="
151
151
  - !ruby/object:Gem::Version
152
152
  version: '0'
153
153
  required_rubygems_version: !ruby/object:Gem::Requirement
154
154
  requirements:
155
- - - '>='
155
+ - - ">="
156
156
  - !ruby/object:Gem::Version
157
157
  version: '0'
158
158
  requirements: []
159
159
  rubyforge_project:
160
- rubygems_version: 2.2.1
160
+ rubygems_version: 2.2.2
161
161
  signing_key:
162
162
  specification_version: 4
163
163
  summary: Allow Paperclip attachments to be stored on FTP servers