forked from stateless-systems/net-ftp-list
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'master' of github.com:stateless-systems/net-ftp-list
Conflicts: lib/net/ftp/list/microsoft.rb lib/net/ftp/list/netware.rb lib/net/ftp/list/parser.rb lib/net/ftp/list/unix.rb test/test_net_ftp_list_microsoft.rb test/test_net_ftp_list_unix.rb
- Loading branch information
Showing
18 changed files
with
436 additions
and
321 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
--- | ||
:major: 2 | ||
:major: 3 | ||
:minor: 1 | ||
:patch: 0 | ||
:patch: 1 | ||
:build: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,43 +1,35 @@ | ||
require 'net/ftp' | ||
require 'net/ftp/list/parser' | ||
|
||
# The order here is important for the time being. Corse grained parsers should appear before specializations because | ||
# the whole thing is searched in reverse order. | ||
require 'net/ftp/list/unix' | ||
require 'net/ftp/list/microsoft' | ||
require 'net/ftp/list/netware' | ||
module Net::FTP::List | ||
require 'net/ftp/list/parser' | ||
require 'net/ftp/list/entry' | ||
|
||
module Net #:nodoc: | ||
class FTP #:nodoc: | ||
# Parser classes should be listed top to bottom, the most specific | ||
# (and rare!) server variations coming last | ||
require 'net/ftp/list/unix' | ||
require 'net/ftp/list/microsoft' | ||
require 'net/ftp/list/netware' | ||
require 'net/ftp/list/rumpus' | ||
require 'net/ftp/list/unknown' | ||
|
||
# Parse FTP LIST responses. | ||
# | ||
# == Creation | ||
# | ||
# require 'net/ftp' # Not really required but I like to list dependencies sometimes. | ||
# require 'net/ftp/list' | ||
# | ||
# ftp = Net::FTP.open('somehost.com', 'user', 'pass') | ||
# ftp.list('/some/path') do |e| | ||
# entry = Net::FTP::List.parse(e) | ||
# | ||
# # Ignore everything that's not a file (so symlinks, directories and devices etc.) | ||
# next unless entry.file? | ||
# | ||
# # If entry isn't a kind_of Net::FTP::List::Unknown then there is a bug in Net::FTP::List if this isn't the | ||
# # same name as ftp.nlist('/some/path') would have returned. | ||
# puts entry.basename | ||
# end | ||
# | ||
# == Exceptions | ||
# | ||
# None at this time. At worst you'll end up with an Net::FTP::List::Unknown instance which won't have any extra | ||
# useful information. Methods like <tt>dir?</tt>, <tt>file?</tt> and <tt>symlink?</tt> will all return +false+. | ||
module List | ||
def self.parse(*args) | ||
Parser.parse(*args) | ||
end | ||
def self.raise_on_failed_server_detection=(new_flag) | ||
Thread.current[:net_ftp_list_raise_on_failed_server_detection] = !!new_flag | ||
end | ||
|
||
def self.raise_on_failed_server_detection | ||
Thread.current[:net_ftp_list_raise_on_failed_server_detection] | ||
end | ||
|
||
# Parse a line from FTP LIST responsesa and return a Net::FTP::List::Entry | ||
def self.parse(*args) | ||
Parser.with_each_parser do | p | | ||
entry = p.parse(*args) | ||
return entry if entry | ||
end | ||
end | ||
|
||
# Gets raised with raise_on_failed_server_detection set | ||
class ParseError < RuntimeError | ||
end | ||
end | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
# Represents an entry of the FTP list. Gets returned when you parse a list. | ||
class Net::FTP::List::Entry | ||
|
||
ALLOWED_ATTRIBUTES = [:raw, :basename, :dir, :file, :symlink, :mtime, :filesize, :device, :server_type] #:nodoc: | ||
|
||
# Create a new entry object. The additional argument is the list of metadata keys | ||
# that can be used on the object. By default just takes and set the raw list entry. | ||
# Net::FTP::List.parse(raw_list_string) # => Net::FTP::List::Parser instance. | ||
def initialize(raw_ls_line, optional_attributes = {}) #:nodoc: | ||
@raw = raw_ls_line | ||
optional_attributes.each_pair do |key, value| | ||
raise ArgumentError, "#{key} is not supported" unless ALLOWED_ATTRIBUTES.include?(key) | ||
instance_variable_set("@#{key}", value) | ||
end | ||
end | ||
|
||
# The raw list entry string. | ||
def raw | ||
@raw ||= '' | ||
end | ||
alias_method :to_s, :raw | ||
|
||
# The items basename (filename). | ||
def basename | ||
@basename ||= '' | ||
end | ||
|
||
# Looks like a directory, try CWD. | ||
def dir? | ||
!!(@dir ||= false) | ||
end | ||
|
||
# Looks like a file, try RETR. | ||
def file? | ||
!!(@file ||= false) | ||
end | ||
|
||
# Looks like a symbolic link. | ||
def symlink? | ||
!!(@symlink ||= false) | ||
end | ||
|
||
# Looks like a device. | ||
def device? | ||
!!(@device ||= false) | ||
end | ||
|
||
# Returns the modification time of the file/directory or the current time if unknown | ||
def mtime | ||
@mtime || Time.now | ||
end | ||
|
||
# Returns the filesize of the entry or 0 for directorties | ||
def filesize | ||
@filesize || 0 | ||
end | ||
|
||
# Returns the detected server type if this entry | ||
def server_type | ||
@server_type || "Unknown" | ||
end | ||
|
||
def unknown? | ||
@dir.nil? && @file.nil? && @symlink.nil? && @device.nil? | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,54 +1,38 @@ | ||
require 'net/ftp/list/parser' | ||
require 'date' | ||
|
||
module Net | ||
class FTP | ||
module List | ||
|
||
# Parse Microsoft(NT) like FTP LIST entries. | ||
# | ||
# == MATCHES | ||
# | ||
# 06-25-07 01:08PM <DIR> etc | ||
# 11-27-07 08:45PM 23437 README.TXT | ||
# | ||
# == SYNOPSIS | ||
# | ||
# entry = Net::FTP::List::Microsoft.new('06-25-07 01:08PM <DIR> etc') | ||
# entry.dir? # => true | ||
# entry.basename # => 'etc' | ||
class Microsoft < 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! | ||
^\s* | ||
([0-9\-:\/]{5,})\s+([0-9\-:]{3,}(?:[aApP][mM])?)\s+ | ||
(?:(<DIR>)|([0-9]+))\s+ | ||
(\S.*) | ||
\s*$ | ||
!x | ||
|
||
# Parse a Microsoft(NT) like FTP LIST entries. | ||
def initialize(raw) | ||
super(raw) | ||
match = REGEXP.match(raw.strip) or raise ParserError | ||
|
||
@mtime = DateTime.strptime("#{match[1]} #{match[2]}", "%m-%d-%y %I:%M%p") | ||
|
||
if match[3] == '<DIR>' | ||
@dir = true | ||
else | ||
@filesize = match[4].to_i | ||
@file = true | ||
end | ||
|
||
# TODO: Permissions, users, groups, date/time. | ||
|
||
@basename = match[5] | ||
end | ||
end | ||
|
||
end | ||
# Parse Microsoft(NT) like FTP LIST entries. | ||
# | ||
# == MATCHES | ||
# | ||
# 06-25-07 01:08PM <DIR> etc | ||
# 11-27-07 08:45PM 23437 README.TXT | ||
class Net::FTP::List::Microsoft < 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! | ||
^\s* | ||
([0-9\-:\/]{5,})\s+([0-9\-:]{3,}(?:[aApP][mM])?)\s+ | ||
(?:(<DIR>)|([0-9]+))\s+ | ||
(\S.*) | ||
\s*$ | ||
!x | ||
|
||
# Parse a Microsoft(NT) like FTP LIST entries. | ||
def self.parse(raw) | ||
match = REGEXP.match(raw.strip) or return false | ||
|
||
mtime = DateTime.strptime("#{match[1]} #{match[2]}", "%m-%d-%y %H:%M%p") | ||
is_dir = match[3] == '<DIR>' | ||
filesize = is_dir ? 0 : match[4].to_i | ||
|
||
emit_entry( | ||
raw, | ||
:dir => is_dir, | ||
:file => !is_dir, | ||
:filesize => filesize, | ||
:basename => match[5], | ||
:mtime => mtime | ||
) | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,54 +1,35 @@ | ||
require 'net/ftp/list/parser' | ||
require 'time' | ||
|
||
module Net | ||
class FTP | ||
module List | ||
|
||
# Parse Netware like FTP LIST entries. | ||
# | ||
# == MATCHES | ||
# | ||
# d [RWCEAFMS] dpearce 512 Jun 27 23:46 public.www | ||
# | ||
# == SYNOPSIS | ||
# | ||
# entry = Net::FTP::List::Netware.new('d [RWCEAFMS] dpearce 512 Jun 27 23:46 public.www') | ||
# entry.dir? # => true | ||
# entry.basename # => 'public.www' | ||
class Netware < 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!^ | ||
(d|-){1}\s+ | ||
\[(.*?)\]\s+ | ||
(\S+)\s+(\d+)\s+ | ||
(\S+\s+\S+\s+((\d+:\d+)|(\d{4}))) | ||
\s+(.*) | ||
$!x | ||
|
||
# Parse a Netware like FTP LIST entries. | ||
def initialize(raw) | ||
super(raw) | ||
match = REGEXP.match(raw.strip) or raise ParserError | ||
|
||
@mtime = Time.parse(match[5]) | ||
@filesize = match[4].to_i | ||
|
||
if match[1] == 'd' | ||
@dir = true | ||
else | ||
@file = true | ||
end | ||
|
||
# TODO: Permissions, users, groups, date/time. | ||
|
||
@basename = match[9] | ||
end | ||
end | ||
|
||
end | ||
# Parse Netware like FTP LIST entries. | ||
# | ||
# == MATCHES | ||
# | ||
# d [RWCEAFMS] dpearce 512 Jun 27 23:46 public.www | ||
class Net::FTP::List::Netware < 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!^ | ||
(d|-){1}\s+ | ||
\[(.*?)\]\s+ | ||
(\S+)\s+(\d+)\s+ | ||
(\S+\s+\S+\s+((\d+:\d+)|(\d{4}))) | ||
\s+(.*) | ||
$!x | ||
|
||
# Parse a Netware like FTP LIST entries. | ||
def self.parse(raw) | ||
match = REGEXP.match(raw.strip) or return false | ||
|
||
is_dir = match[1] == 'd' | ||
|
||
emit_entry( | ||
raw, | ||
:mtime => Time.parse(match[5]), | ||
:filesize => match[4].to_i, | ||
:dir => is_dir, | ||
:file => !is_dir, | ||
:basename => match[9] | ||
) | ||
end | ||
end |
Oops, something went wrong.