1# = Tools for FTP uploading. 2# 3# This file is still under development and is not released for general 4# use. 5 6require 'date' 7require 'net/ftp' 8require 'rake/file_list' 9 10module Rake # :nodoc: 11 12 #################################################################### 13 # <b>Note:</b> <em> Not released for general use.</em> 14 class FtpFile 15 attr_reader :name, :size, :owner, :group, :time 16 17 def self.date 18 @date_class ||= Date 19 end 20 21 def self.time 22 @time_class ||= Time 23 end 24 25 def initialize(path, entry) 26 @path = path 27 @mode, _, @owner, @group, size, d1, d2, d3, @name = entry.split(' ') 28 @size = size.to_i 29 @time = determine_time(d1, d2, d3) 30 end 31 32 def path 33 File.join(@path, @name) 34 end 35 36 def directory? 37 @mode[0] == ?d 38 end 39 40 def mode 41 parse_mode(@mode) 42 end 43 44 def symlink? 45 @mode[0] == ?l 46 end 47 48 private # -------------------------------------------------------- 49 50 def parse_mode(m) 51 result = 0 52 (1..9).each do |i| 53 result = 2*result + ((m[i]==?-) ? 0 : 1) 54 end 55 result 56 end 57 58 def determine_time(d1, d2, d3) 59 now = self.class.time.now 60 if /:/ =~ d3 61 result = Time.parse("#{d1} #{d2} #{now.year} #{d3}") 62 if result > now 63 result = Time.parse("#{d1} #{d2} #{now.year-1} #{d3}") 64 end 65 else 66 result = Time.parse("#{d1} #{d2} #{d3}") 67 end 68 result 69# elements = ParseDate.parsedate("#{d1} #{d2} #{d3}") 70# if elements[0].nil? 71# today = self.class.date.today 72# if elements[1] > today.month 73# elements[0] = today.year - 1 74# else 75# elements[0] = today.year 76# end 77# end 78# elements = elements.collect { |el| el.nil? ? 0 : el } 79# Time.mktime(*elements[0,7]) 80 end 81 end 82 83 #################################################################### 84 # Manage the uploading of files to an FTP account. 85 class FtpUploader 86 87 # Log uploads to standard output when true. 88 attr_accessor :verbose 89 90 class << FtpUploader 91 # Create an uploader and pass it to the given block as +up+. 92 # When the block is complete, close the uploader. 93 def connect(path, host, account, password) 94 up = self.new(path, host, account, password) 95 begin 96 yield(up) 97 ensure 98 up.close 99 end 100 end 101 end 102 103 # Create an FTP uploader targeting the directory +path+ on +host+ 104 # using the given account and password. +path+ will be the root 105 # path of the uploader. 106 def initialize(path, host, account, password) 107 @created = Hash.new 108 @path = path 109 @ftp = Net::FTP.new(host, account, password) 110 makedirs(@path) 111 @ftp.chdir(@path) 112 end 113 114 # Create the directory +path+ in the uploader root path. 115 def makedirs(path) 116 route = [] 117 File.split(path).each do |dir| 118 route << dir 119 current_dir = File.join(route) 120 if @created[current_dir].nil? 121 @created[current_dir] = true 122 $stderr.puts "Creating Directory #{current_dir}" if @verbose 123 @ftp.mkdir(current_dir) rescue nil 124 end 125 end 126 end 127 128 # Upload all files matching +wildcard+ to the uploader's root 129 # path. 130 def upload_files(wildcard) 131 FileList.glob(wildcard).each do |fn| 132 upload(fn) 133 end 134 end 135 136 # Close the uploader. 137 def close 138 @ftp.close 139 end 140 141 private # -------------------------------------------------------- 142 143 # Upload a single file to the uploader's root path. 144 def upload(file) 145 $stderr.puts "Uploading #{file}" if @verbose 146 dir = File.dirname(file) 147 makedirs(dir) 148 @ftp.putbinaryfile(file, file) unless File.directory?(file) 149 end 150 end 151end 152