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