Class: Net::FTP::List::Unix
- Inherits:
-
Parser
- Object
- Parser
- Net::FTP::List::Unix
- Defined in:
- lib/net/ftp/list/unix.rb
Overview
Parse Unix like FTP LIST entries.
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
Constant Summary collapse
- REGEXP =
Stolen straight from the ASF’s commons Java FTP LIST parser library. svn.apache.org/repos/asf/commons/proper/net/trunk/src/java/org/apache/commons/net/ftp/
%r{ ([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.freeze
- ONE_YEAR =
(60 * 60 * 24 * 365)
Class Method Summary collapse
-
.parse(raw, timezone: :utc) ⇒ Object
Parse a Unix like FTP LIST entries.
Class Method Details
.parse(raw, timezone: :utc) ⇒ Object
Parse a Unix like FTP LIST entries.
29 30 31 32 33 34 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 |
# File 'lib/net/ftp/list/unix.rb', line 29 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? # Don't match on rumpus (which looks very similar to unix) 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. # If the parsed date, with today's year, could be in the future, then # the date must be for the previous year 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 = 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 type == :symlink basename.sub!(/\s+->(.+)$/, '') symlink_destination = Regexp.last_match(1).strip if Regexp.last_match(1) end emit_entry( raw, type: type, filesize: filesize, basename: basename, symlink_destination: symlink_destination, mtime: mtime, ) end |