olek-paperclipftp 0.1.0.5 → 0.1.0.6

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.
Files changed (3) hide show
  1. data/VERSION +1 -1
  2. data/lib/paperclipftp.rb +61 -30
  3. metadata +4 -4
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.0.5
1
+ 0.1.0.6
data/lib/paperclipftp.rb CHANGED
@@ -1,48 +1,60 @@
1
1
  module Paperclip
2
2
  module Storage
3
3
  module Ftp
4
+ class FtpTimeout < Timeout::Error; end
5
+
4
6
  def self.extended base
5
7
  require 'net/ftp'
6
8
  base.instance_eval do
7
9
  @ftp_credentials = parse_credentials(@options[:ftp_credentials])
8
10
  @passive_mode = !!@options[:ftp_passive_mode]
9
11
  @debug_mode = !!@options[:ftp_debug_mode]
12
+ @timeout = @options[:timeout] || 3600
10
13
  end
11
14
  end
12
15
 
13
16
  def ftp
14
17
  if @ftp.nil? || @ftp.closed?
15
- @ftp = Net::FTP.new(@ftp_credentials[:host], @ftp_credentials[:username], @ftp_credentials[:password])
16
- @ftp.passive = @passive_mode
17
- @ftp.debug_mode = @debug_mode
18
+ Timeout::timeout(@timeout, FtpTimeout) do
19
+ @ftp = Net::FTP.new(@ftp_credentials[:host], @ftp_credentials[:username], @ftp_credentials[:password])
20
+ @ftp.debug_mode = @debug_mode
21
+ @ftp.passive = @passive_mode
22
+ end
18
23
  end
19
24
  @ftp
20
25
  end
21
26
 
22
27
  def exists?(style = default_style)
23
- file_size(path(style)) > 0
28
+ Timeout::timeout(@timeout, FtpTimeout) do
29
+ file_size(ftp_path(style)) > 0
30
+ end
24
31
  end
25
32
 
26
33
  def to_file style = default_style
27
34
  return @queued_for_write[style] if @queued_for_write[style]
28
- file = Tempfile.new(path(style))
29
- ftp.getbinaryfile(path(style), file.path)
30
- file.rewind
31
- return file
35
+ Timeout::timeout(@timeout, FtpTimeout) do
36
+ file = Tempfile.new(ftp_path(style))
37
+ ftp.getbinaryfile(ftp_path(style), file.path)
38
+ file.rewind
39
+ return file
40
+ end
32
41
  end
33
42
 
34
43
  alias_method :to_io, :to_file
35
44
 
36
45
  def flush_writes
37
46
  @queued_for_write.each do |style, file|
38
- local_file_size = file.size
39
- file.close
40
- remote_path = path(style)
41
- ensure_parent_folder_for(remote_path)
42
- log("uploading #{remote_path}")
43
- ftp.putbinaryfile(file.path, remote_path)
44
- remote_file_size = file_size(remote_path)
45
- raise Net::FTPError.new "Uploaded #{remote_file_size} bytes instead of #{local_file_size} bytes" unless remote_file_size == local_file_size
47
+ Timeout::timeout(@timeout, FtpTimeout) do
48
+ file.close
49
+ # avoiding those weird occasional 0 file sizes by not using instance method file.size
50
+ local_file_size = File.size(file.path)
51
+ remote_path = ftp_path(style)
52
+ ensure_parent_folder_for(remote_path)
53
+ log("uploading #{remote_path}")
54
+ ftp.putbinaryfile(file.path, remote_path)
55
+ remote_file_size = file_size(remote_path)
56
+ raise Net::FTPError.new "Uploaded #{remote_file_size} bytes instead of #{local_file_size} bytes" unless remote_file_size == local_file_size
57
+ end
46
58
  end
47
59
  @queued_for_write = {}
48
60
  rescue Net::FTPReplyError => e
@@ -55,10 +67,12 @@ module Paperclip
55
67
 
56
68
  def flush_deletes
57
69
  @queued_for_delete.each do |path|
58
- begin
59
- log("deleting #{path}")
60
- ftp.delete(path)
61
- rescue Net::FTPPermError, Net::FTPReplyError
70
+ Timeout::timeout(@timeout, FtpTimeout) do
71
+ begin
72
+ log("deleting #{path}")
73
+ ftp.delete('/' + path)
74
+ rescue Net::FTPPermError, Net::FTPReplyError
75
+ end
62
76
  end
63
77
  end
64
78
  @queued_for_delete = []
@@ -70,23 +84,40 @@ module Paperclip
70
84
  ftp.close
71
85
  end
72
86
 
87
+ private
88
+
73
89
  def ensure_parent_folder_for(remote_path)
74
90
  dir_path = File.dirname(remote_path)
75
- ftp.chdir("/")
76
- dir_path.split(File::SEPARATOR).each do |rdir|
77
- rdir = rdir.strip
78
- unless rdir.blank?
79
- list = ftp.ls.collect { |f| f.split.last }
80
- unless list.include?(rdir)
81
- ftp.mkdir(rdir)
91
+ already_exists =
92
+ begin
93
+ ftp.chdir(dir_path)
94
+ true
95
+ rescue Net::FTPPermError
96
+ false
97
+ end
98
+ unless already_exists
99
+ ftp.chdir("/")
100
+ dir_path.split(File::SEPARATOR).each do |rdir|
101
+ next if rdir.blank?
102
+ first_time = true
103
+ begin
104
+ ftp.chdir(rdir)
105
+ rescue Net::FTPPermError => e
106
+ if first_time
107
+ ftp.mkdir(rdir)
108
+ first_time = false
109
+ retry
110
+ else
111
+ raise e
112
+ end
82
113
  end
83
- ftp.chdir(rdir)
84
114
  end
85
115
  end
86
- ftp.chdir("/")
87
116
  end
88
117
 
89
- private
118
+ def ftp_path(style)
119
+ '/' + path(style)
120
+ end
90
121
 
91
122
  def file_size(remote_path)
92
123
  ftp.size(remote_path)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: olek-paperclipftp
3
3
  version: !ruby/object:Gem::Version
4
- hash: 77
4
+ hash: 75
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 1
9
9
  - 0
10
- - 5
11
- version: 0.1.0.5
10
+ - 6
11
+ version: 0.1.0.6
12
12
  platform: ruby
13
13
  authors:
14
14
  - Damian Caruso
@@ -16,7 +16,7 @@ autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
18
 
19
- date: 2011-05-05 00:00:00 -04:00
19
+ date: 2011-05-09 00:00:00 -04:00
20
20
  default_executable:
21
21
  dependencies:
22
22
  - !ruby/object:Gem::Dependency