net-ftp-list 0.3 → 0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/README.txt +1 -7
- data/Rakefile +1 -1
- data/lib/net/ftp/list.rb +22 -27
- data/lib/net/ftp/list/parser.rb +22 -32
- data/lib/net/ftp/list/unix.rb +4 -4
- data/test/test_net_ftp_list.rb +3 -3
- metadata +2 -2
data/README.txt
CHANGED
@@ -21,20 +21,14 @@ See the RFC for more guff on LIST and NLST: http://www.ietf.org/rfc/rfc0959.txt
|
|
21
21
|
* The factory and abstract base class for parsers are one and the same. OO geeks will cry.
|
22
22
|
* More OS's and server types. Only servers that return Unix like LIST responses will work at the moment.
|
23
23
|
* Calling <tt>if entry.file? or entry.dir?</tt> is hard work when you really mean <tt>unless entry.unknown?</tt>
|
24
|
-
* I'm not sure about overwriting Net::FTP's +list+, +ls+ and +dir+. It's a base lib after all and people will be
|
25
|
-
expecting String. Perhaps I'd be better to <tt>class Parser < String</tt> for the abstract parser.
|
26
|
-
* The block handling for +list+, +ls+ and +dir+ has a nasty +map+ that's essentially building up an unused Array.
|
27
24
|
|
28
25
|
== SYNOPSIS
|
29
26
|
|
30
|
-
By requiring Net::FTP::List instances are created by calling any of Net::FTP's <tt>list</tt>, <tt>ls</tt> or
|
31
|
-
<tt>dir</tt> metods. The <tt>to_s</tt> method still returns the raw line so for the most part this should be
|
32
|
-
transparent.
|
33
|
-
|
34
27
|
require 'net/ftp' # Not really required but I like to list dependencies sometimes.
|
35
28
|
require 'net/ftp/list'
|
36
29
|
|
37
30
|
ftp = Net::FTP.open('somehost.com', 'user', 'pass')
|
31
|
+
ftp.extend Net::FTP::List # Tweak list, ls and dir to returned parsed content.
|
38
32
|
ftp.list('/some/path') do |entry|
|
39
33
|
# Ignore everything that's not a file (so symlinks, directories and devices etc.)
|
40
34
|
next unless entry.file?
|
data/Rakefile
CHANGED
data/lib/net/ftp/list.rb
CHANGED
@@ -8,30 +8,18 @@ require 'net/ftp/list/unix'
|
|
8
8
|
module Net #:nodoc:
|
9
9
|
class FTP #:nodoc:
|
10
10
|
|
11
|
-
alias_method :raw_list, :list
|
12
|
-
def list(*args, &block)
|
13
|
-
# TODO: Map in void context when you pass a block.
|
14
|
-
raw_list(*args).map do |raw|
|
15
|
-
entry = Net::FTP::List.parse(raw)
|
16
|
-
block ? yield(entry) : entry
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
11
|
# Parse FTP LIST responses.
|
21
12
|
#
|
22
|
-
#
|
23
|
-
#
|
13
|
+
# Mixin the +Net::FTP::List+ module and subsequent calls to the Net::FTP +list+, +ls+ or +dir+ methods will be
|
14
|
+
# parsed by the LIST parser as best it can.
|
24
15
|
#
|
25
16
|
# == Creation
|
26
17
|
#
|
27
|
-
# By requiring Net::FTP::List instances are created by calling any of Net::FTP's +list+, +ls+ or
|
28
|
-
# +dir+ metods. The +to_s+ method still returns the raw line so for the most part this should be
|
29
|
-
# transparent.
|
30
|
-
#
|
31
18
|
# require 'net/ftp' # Not really required but I like to list dependencies sometimes.
|
32
19
|
# require 'net/ftp/list'
|
33
20
|
#
|
34
21
|
# ftp = Net::FTP.open('somehost.com', 'user', 'pass')
|
22
|
+
# ftp.extend Net::FTP::List
|
35
23
|
# ftp.list('/some/path') do |entry|
|
36
24
|
# # Ignore everything that's not a file (so symlinks, directories and devices etc.)
|
37
25
|
# next unless entry.file?
|
@@ -46,22 +34,29 @@ module Net #:nodoc:
|
|
46
34
|
# None at this time. At worst you'll end up with an Net::FTP::List::Unknown instance which won't have any extra
|
47
35
|
# useful information. Methods like <tt>dir?</tt>, <tt>file?</tt> and <tt>symlink?</tt> will all return +false+.
|
48
36
|
module List
|
49
|
-
class << self
|
50
37
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
38
|
+
def self.extended(klass) #:nodoc:
|
39
|
+
class << klass
|
40
|
+
|
41
|
+
alias_method :raw_list, :list
|
42
|
+
def list(*args, &block)
|
43
|
+
if block
|
44
|
+
raw_list(*args) do |raw|
|
45
|
+
Net::FTP::List::Parser.parse(raw)
|
46
|
+
yield raw
|
47
|
+
end
|
48
|
+
else
|
49
|
+
raw_list(*args).map do |raw|
|
50
|
+
Net::FTP::List::Parser.parse(raw)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
62
54
|
|
55
|
+
end
|
63
56
|
end
|
57
|
+
|
64
58
|
end
|
65
59
|
|
66
60
|
end
|
67
61
|
end
|
62
|
+
|
data/lib/net/ftp/list/parser.rb
CHANGED
@@ -21,55 +21,54 @@ module Net
|
|
21
21
|
class Parser
|
22
22
|
@@parsers = []
|
23
23
|
|
24
|
+
# Parse a raw FTP LIST line.
|
25
|
+
#
|
26
|
+
# By default just takes and set the raw list entry.
|
27
|
+
#
|
28
|
+
# Net::FTP::List.parse(raw_list_string) # => Net::FTP::List::Parser instance.
|
29
|
+
def initialize(raw)
|
30
|
+
@raw = raw
|
31
|
+
end
|
32
|
+
|
24
33
|
# The raw list entry string.
|
25
|
-
|
34
|
+
def raw
|
35
|
+
@raw
|
36
|
+
end
|
37
|
+
alias_method :to_s, :raw
|
26
38
|
|
27
39
|
# The items basename (filename).
|
28
|
-
|
40
|
+
def basename
|
41
|
+
@basename
|
42
|
+
end
|
29
43
|
|
30
44
|
# Looks like a directory, try CWD.
|
31
45
|
def dir?
|
32
|
-
|
46
|
+
!!@dir
|
33
47
|
end
|
34
48
|
|
35
49
|
# Looks like a file, try RETR.
|
36
50
|
def file?
|
37
|
-
|
51
|
+
!!@file
|
38
52
|
end
|
39
53
|
|
40
54
|
# Looks like a symbolic link.
|
41
55
|
def symlink?
|
42
|
-
|
56
|
+
!!@symlink
|
43
57
|
end
|
44
58
|
|
45
|
-
# Parse a raw FTP LIST line.
|
46
|
-
#
|
47
|
-
# By default just takes and set the raw list entry.
|
48
|
-
#
|
49
|
-
# Net::FTP::List.parse(raw_list_string) # => Net::FTP::List::Parser instance.
|
50
|
-
def initialize(raw)
|
51
|
-
self.raw = raw
|
52
|
-
end
|
53
|
-
|
54
|
-
# Stringify.
|
55
|
-
def to_s
|
56
|
-
raw
|
57
|
-
end
|
58
|
-
alias_method :raw, :to_s
|
59
|
-
|
60
59
|
class << self
|
61
|
-
|
62
60
|
# Acts as a factory.
|
63
61
|
#
|
64
62
|
# TODO: Having a class be both factory and abstract implementation seems a little nutty to me. If it ends up
|
65
63
|
# too confusing or gives anyone the shits I'll move it.
|
66
|
-
def inherited(klass)
|
64
|
+
def inherited(klass) #:nodoc:
|
67
65
|
@@parsers << klass
|
68
66
|
end
|
69
67
|
|
70
68
|
# Factory method.
|
71
69
|
#
|
72
|
-
# Attempt to find and parse a list item
|
70
|
+
# Attempt to find a parser and parse a list item. At worst the item will return an Net::FTP::List::Unknown
|
71
|
+
# instance. This may change in the future so that only parsable entries are kept.
|
73
72
|
def parse(raw)
|
74
73
|
@@parsers.reverse.each do |parser|
|
75
74
|
begin
|
@@ -81,15 +80,6 @@ module Net
|
|
81
80
|
end
|
82
81
|
end
|
83
82
|
|
84
|
-
protected
|
85
|
-
# Protected boolean.
|
86
|
-
attr_accessor :file, :dir, :symlink
|
87
|
-
|
88
|
-
# Protected raw list entry string.
|
89
|
-
attr_writer :raw
|
90
|
-
|
91
|
-
# Protected item basename (filename).
|
92
|
-
attr_writer :basename
|
93
83
|
end
|
94
84
|
|
95
85
|
# Unknown parser.
|
data/lib/net/ftp/list/unix.rb
CHANGED
@@ -38,16 +38,16 @@ module Net
|
|
38
38
|
match = REGEXP.match(raw.strip) or raise ParserError
|
39
39
|
|
40
40
|
case match[1]
|
41
|
-
when /d/ then
|
42
|
-
when /l/ then
|
43
|
-
when /[f-]/ then
|
41
|
+
when /d/ then @dir = true
|
42
|
+
when /l/ then @symlink = true
|
43
|
+
when /[f-]/ then @file = true
|
44
44
|
when /[bc]/ then # Do nothing with devices for now.
|
45
45
|
else ParserError 'Unknown LIST entry type.'
|
46
46
|
end
|
47
47
|
|
48
48
|
# TODO: Permissions, users, groups, date/time.
|
49
49
|
|
50
|
-
|
50
|
+
@basename = match[21].match(/^(.+)(?:\s+\->.+)?$/)[0].strip
|
51
51
|
end
|
52
52
|
end
|
53
53
|
|
data/test/test_net_ftp_list.rb
CHANGED
@@ -4,8 +4,8 @@ require 'net/ftp/list'
|
|
4
4
|
class TestNetFTPList < Test::Unit::TestCase
|
5
5
|
|
6
6
|
def setup
|
7
|
-
@dir = Net::FTP::List.
|
8
|
-
@file = Net::FTP::List.
|
7
|
+
@dir = Net::FTP::List::Parser.parse('drwxr-xr-x 4 user group 4096 Dec 10 20:23 etc')
|
8
|
+
@file = Net::FTP::List::Parser.parse('-rw-r--r-- 1 root other 531 Jan 29 03:26 README')
|
9
9
|
end
|
10
10
|
|
11
11
|
def test_parse_new
|
@@ -14,7 +14,7 @@ class TestNetFTPList < Test::Unit::TestCase
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def test_rubbish_lines
|
17
|
-
assert_instance_of Net::FTP::List::Unknown, Net::FTP::List.
|
17
|
+
assert_instance_of Net::FTP::List::Unknown, Net::FTP::List::Parser.parse("++ bah! ++")
|
18
18
|
end
|
19
19
|
|
20
20
|
def test_ruby_unix_like_dir
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.4
|
|
3
3
|
specification_version: 1
|
4
4
|
name: net-ftp-list
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: "0.
|
7
|
-
date: 2008-01-
|
6
|
+
version: "0.4"
|
7
|
+
date: 2008-01-16 00:00:00 +11:00
|
8
8
|
summary: Parse FTP LIST command output.
|
9
9
|
require_paths:
|
10
10
|
- lib
|