Class: FtpSync
- Inherits:
-
Object
- Object
- FtpSync
- Defined in:
- lib/ftp_sync.rb
Overview
A Ruby library for recursively downloading and uploading directories to/from ftp servers. Also supports uploading and downloading a list of files relative to the local/remote roots. You can specify a timestamp to only download files newer than that timestamp, or only download files newer than their local copy.
Instance Attribute Summary collapse
-
#passive ⇒ Object
Returns the value of attribute passive.
-
#password ⇒ Object
Returns the value of attribute password.
-
#server ⇒ Object
Returns the value of attribute server.
-
#user ⇒ Object
Returns the value of attribute user.
-
#verbose ⇒ Object
Returns the value of attribute verbose.
Instance Method Summary collapse
-
#initialize(server, user, password, options = {}) ⇒ FtpSync
constructor
Creates a new instance for accessing a ftp server requires
server
,user
, andpassword
options * :ignore - Accepts an instance of class which has an ignore? method, taking a path and returns true or false, for whether to ignore the file or not. -
#pull_dir(localpath, remotepath, options = {}, &block) ⇒ Object
Recursively pull down files :since => true - only pull down files newer than their local counterpart, or with a different filesize :since => Time.now - only pull down files newer than the supplied timestamp, or with a different filesize :delete => Remove local files which don’t exist on the FTP server If a block is supplied then it will be called to remove a local file.
-
#pull_files(localpath, remotepath, filelist) ⇒ Object
Pull a supplied list of files from the remote ftp path into the local path.
-
#push_dir(localpath, remotepath) ⇒ Object
Recursively push a local directory of files onto an FTP server.
-
#push_files(localpath, remotepath, filelist) ⇒ Object
Push a supplied list of files from the local path into the remote ftp path.
-
#remove_files(basepath, filelist) ⇒ Object
Remove listed files from the FTP server.
-
#should_ignore?(path) ⇒ Boolean
Chains off to the (if supplied) Ignore class, ie GitIgnores.new.ignore?(‘path/to/my/file’).
Constructor Details
#initialize(server, user, password, options = {}) ⇒ FtpSync
Creates a new instance for accessing a ftp server requires server
, user
, and password
options
-
:ignore - Accepts an instance of class which has an ignore? method, taking a path and returns true or false, for whether to ignore the file or not.
-
:verbose - Whether should be verbose
18 19 20 21 22 23 24 25 26 27 |
# File 'lib/ftp_sync.rb', line 18 def initialize(server, user, password, = {}) @server = server @user = user @password = password @connection = nil @ignore = [:ignore] @recursion_level = 0 @verbose = [:verbose] || false @passive = [:passive] || false end |
Instance Attribute Details
#passive ⇒ Object
Returns the value of attribute passive.
12 13 14 |
# File 'lib/ftp_sync.rb', line 12 def passive @passive end |
#password ⇒ Object
Returns the value of attribute password.
12 13 14 |
# File 'lib/ftp_sync.rb', line 12 def password @password end |
#server ⇒ Object
Returns the value of attribute server.
12 13 14 |
# File 'lib/ftp_sync.rb', line 12 def server @server end |
#user ⇒ Object
Returns the value of attribute user.
12 13 14 |
# File 'lib/ftp_sync.rb', line 12 def user @user end |
#verbose ⇒ Object
Returns the value of attribute verbose.
12 13 14 |
# File 'lib/ftp_sync.rb', line 12 def verbose @verbose end |
Instance Method Details
#pull_dir(localpath, remotepath, options = {}, &block) ⇒ Object
Recursively pull down files :since => true - only pull down files newer than their local counterpart, or with a different filesize :since => Time.now - only pull down files newer than the supplied timestamp, or with a different filesize :delete => Remove local files which don’t exist on the FTP server If a block is supplied then it will be called to remove a local file
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/ftp_sync.rb', line 35 def pull_dir(localpath, remotepath, = {}, &block) connect! unless @connection @recursion_level += 1 todelete = Dir.glob(File.join(localpath, '*')) tocopy = [] recurse = [] # To trigger error if path doesnt exist since list will # just return and empty array @connection.chdir(remotepath) @connection.list(remotepath) do |e| entry = Net::FTP::List.parse(e) paths = [ File.join(localpath, entry.basename), "#{remotepath}/#{entry.basename}".gsub(/\/+/, '/') ] if entry.dir? recurse << paths elsif entry.file? if [:since] == :src tocopy << paths unless File.exist?(paths[0]) and entry.mtime < File.mtime(paths[0]) and entry.filesize == File.size(paths[0]) elsif [:since].is_a?(Time) tocopy << paths unless entry.mtime < [:since] and File.exist?(paths[0]) and entry.filesize == File.size(paths[0]) else tocopy << paths end end todelete.delete paths[0] end tocopy.each do |paths| localfile, remotefile = paths unless should_ignore?(localfile) begin @connection.get(remotefile, localfile) log "Pulled file #{remotefile}" rescue Net::FTPPermError log "ERROR READING #{remotefile}" raise Net::FTPPermError unless [:skip_errors] end end end recurse.each do |paths| localdir, remotedir = paths Dir.mkdir(localdir) unless File.exist?(localdir) pull_dir(localdir, remotedir, , &block) end if [:delete] todelete.each do |p| block_given? ? yield(p) : FileUtils.rm_rf(p) log "Removed path #{p}" end end @recursion_level -= 1 close! if @recursion_level == 0 rescue Net::FTPPermError close! raise Net::FTPPermError end |
#pull_files(localpath, remotepath, filelist) ⇒ Object
Pull a supplied list of files from the remote ftp path into the local path
122 123 124 125 126 127 128 129 130 131 |
# File 'lib/ftp_sync.rb', line 122 def pull_files(localpath, remotepath, filelist) connect! filelist.each do |f| localdir = File.join(localpath, File.dirname(f)) FileUtils.mkdir_p localdir unless File.exist?(localdir) @connection.get "#{remotepath}/#{f}", File.join(localpath, f) log "Pulled file #{remotepath}/#{f}" end close! end |
#push_dir(localpath, remotepath) ⇒ Object
Recursively push a local directory of files onto an FTP server
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
# File 'lib/ftp_sync.rb', line 101 def push_dir(localpath, remotepath) connect! Dir.glob(File.join(localpath, '**', '*')) do |f| f.gsub!("#{localpath}/", '') local = File.join localpath, f remote = "#{remotepath}/#{f}".gsub(/\/+/, '/') if File.directory?(local) @connection.mkdir remote rescue Net::FTPPermError log "Created Remote Directory #{local}" elsif File.file?(local) @connection.put local, remote log "Pushed file #{remote}" end end close! end |
#push_files(localpath, remotepath, filelist) ⇒ Object
Push a supplied list of files from the local path into the remote ftp path
134 135 136 137 138 139 140 141 142 143 144 145 |
# File 'lib/ftp_sync.rb', line 134 def push_files(localpath, remotepath, filelist) connect! remote_paths = filelist.map {|f| File.dirname(f) }.uniq.reject{|p| p == '.' } create_remote_paths(remotepath, remote_paths) filelist.each do |f| @connection.put File.join(localpath, f), "#{remotepath}/#{f}" log "Pushed file #{remotepath}/#{f}" end close! end |
#remove_files(basepath, filelist) ⇒ Object
Remove listed files from the FTP server
148 149 150 151 152 153 154 155 156 157 158 159 160 161 |
# File 'lib/ftp_sync.rb', line 148 def remove_files(basepath, filelist) connect! filelist.each do |f| begin @connection.delete "#{basepath}/#{f}".gsub(/\/+/, '/') log "Removed file #{basepath}/#{f}" rescue Net::FTPPermError => e raise e unless /^550/ =~ e. end end close! end |
#should_ignore?(path) ⇒ Boolean
Chains off to the (if supplied) Ignore class, ie GitIgnores.new.ignore?(‘path/to/my/file’)
164 165 166 |
# File 'lib/ftp_sync.rb', line 164 def should_ignore?(path) @ignore && @ignore.ignore?(path) end |