lib/net/ftp/list/unix.rb in net-ftp-list-3.2.11 vs lib/net/ftp/list/unix.rb in net-ftp-list-3.3.0

- old
+ new

@@ -6,85 +6,78 @@ # == MATCHES # # drwxr-xr-x 4 steve group 4096 Dec 10 20:23 etc # -rw-r--r-- 1 root other 531 Jan 29 03:26 README.txt class Net::FTP::List::Unix < Net::FTP::List::Parser - # Stolen straight from the ASF's commons Java FTP LIST parser library. # http://svn.apache.org/repos/asf/commons/proper/net/trunk/src/java/org/apache/commons/net/ftp/ REGEXP = %r{ - ([pbcdlfmpSs-]) + ([pbcdlfmSs-]) (((r|-)(w|-)([xsStTL-]))((r|-)(w|-)([xsStTL-]))((r|-)(w|-)([xsStTL-])))\+?\s+ (?:(\d+)\s+)? (\S+)?\s+ (?:(\S+(?:\s\S+)*)\s+)? (?:\d+,\s+)? (\d+)\s+ ((?:\d+[-/]\d+[-/]\d+)|(?:\S+\s+\S+))\s+ (\d+(?::\d+)?)\s+ (\S*)(\s*.*) - }x + }x.freeze ONE_YEAR = (60 * 60 * 24 * 365) # Parse a Unix like FTP LIST entries. - def self.parse(raw) + def self.parse(raw, timezone: :utc) match = REGEXP.match(raw.strip) or return false + type = case match[1] + when /d/ then :dir + when /l/ then :symlink + when /[f-]/ then :file + when /[psbc]/ then :device + end + return false if type.nil? - dir, symlink, file, device = false, false, false, false - case match[1] - when /d/ then dir = true - when /l/ then symlink = true - when /[f-]/ then file = true - when /[psbc]/ then device = true - end - return false unless dir or symlink or file or device - # Don't match on rumpus (which looks very similar to unix) - return false if match[17].nil? and ((match[15].nil? and match[16].to_s == 'folder') or match[15].to_s == '0') + return false if match[17].nil? && ((match[15].nil? && (match[16].to_s == 'folder')) || (match[15].to_s == '0')) # TODO: Permissions, users, groups, date/time. filesize = match[18].to_i - mtime_month_and_day = match[19] mtime_time_or_year = match[20] # Unix mtimes specify a 4 digit year unless the data is within the past 180 - # days or so. Future dates always specify a 4 digit year. + # days or so. Future dates always specify a 4 digit year. # If the parsed date, with today's year, could be in the future, then # the date must be for the previous year - mtime_string = if mtime_time_or_year.match(/^[0-9]{1,2}:[0-9]{2}$/) - if Time.parse("#{mtime_month_and_day} #{Time.now.year}") > Time.now - "#{mtime_month_and_day} #{mtime_time_or_year} #{Time.now.year - 1}" - else - "#{mtime_month_and_day} #{mtime_time_or_year} #{Time.now.year}" - end - elsif mtime_time_or_year.match(/^[0-9]{4}$/) - "#{mtime_month_and_day} #{mtime_time_or_year}" - end + mtime_string = case mtime_time_or_year + when /^[0-9]{1,2}:[0-9]{2}$/ + if parse_time("#{mtime_month_and_day} #{Time.now.year}", timezone: timezone) > Time.now + "#{mtime_month_and_day} #{mtime_time_or_year} #{Time.now.year - 1}" + else + "#{mtime_month_and_day} #{mtime_time_or_year} #{Time.now.year}" + end + when /^[0-9]{4}$/ + "#{mtime_month_and_day} #{mtime_time_or_year}" + end - mtime = Time.parse(mtime_string) - + mtime = parse_time(mtime_string, timezone: timezone) basename = match[21].strip # filenames with spaces will end up in the last match basename += match[22] unless match[22].nil? # strip the symlink stuff we don't care about - if symlink - basename.sub!(/\s+\->(.+)$/, '') - symlink_destination = $1.strip if $1 + if type == :symlink + basename.sub!(/\s+->(.+)$/, '') + symlink_destination = Regexp.last_match(1).strip if Regexp.last_match(1) end emit_entry( raw, - :dir => dir, - :file => file, - :device => device, - :symlink => symlink, - :filesize => filesize, - :basename => basename, - :symlink_destination => symlink_destination, - :mtime => mtime + type: type, + filesize: filesize, + basename: basename, + symlink_destination: symlink_destination, + mtime: mtime, ) end end