Skip to content

Commit

Permalink
Refactoring a bit, adding ListInfo class for formatting list info
Browse files Browse the repository at this point in the history
  • Loading branch information
petebrowne committed Jul 23, 2010
1 parent ad432ab commit 7cedd7d
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 87 deletions.
5 changes: 3 additions & 2 deletions lib/mock_ftp.rb
Expand Up @@ -2,8 +2,9 @@
require 'mock_ftp/core_ext/string'

module MockFTP
autoload :File, 'mock_ftp/file'
autoload :Folder, 'mock_ftp/folder'
autoload :File, 'mock_ftp/file'
autoload :Folder, 'mock_ftp/folder'
autoload :ListInfo, 'mock_ftp/list_info'

module Net
autoload :FTP, 'mock_ftp/net_ftp'
Expand Down
7 changes: 5 additions & 2 deletions lib/mock_ftp/folder.rb
Expand Up @@ -2,8 +2,11 @@ module MockFTP
class Folder
class << self
def root(root_path, &block)
@structure = nil
self.new(root_path, &block)
begin
new(root_path, &block)
ensure
@structure = nil
end
end

def structure
Expand Down
45 changes: 45 additions & 0 deletions lib/mock_ftp/list_info.rb
@@ -0,0 +1,45 @@
module MockFTP
class ListInfo

def initialize(file, user = 'anonymous')
@file = file
@user = user
end

def to_s
if @file.folder?
folders_count = @file.list.select(&:folder?).count + 2
[
'drwxr-xr-x',
folders_count.to_s.rjust(3),
@user, @user,
' 4096',
formatted_date,
@file.basename
].join(' ')
else
[
'-rw-r--r-- 1',
@user, @user,
@file.size.to_s.rjust(8),
formatted_date,
@file.basename
].join(' ')
end
end

protected

def formatted_date
date = @file.mtime.utc
date_parts = [ date.strftime('%b') ]
date_parts << date.day.to_s.rjust(2)
date_parts << if date.year == Time.now.year
date.strftime('%H:%M').gsub(/^0/, '')
else
date.year.to_s
end.rjust(5)
date_parts.join(' ')
end
end
end
109 changes: 26 additions & 83 deletions lib/mock_ftp/net_ftp.rb
Expand Up @@ -20,7 +20,7 @@ def open(host, user = nil, passwd = nil, acct = nil)
def initialize(host = nil, user = nil, passwd = nil, acct = nil)
@current_path = ''
@closed = false
@host = host
@host = host || 'www.example.com'
@user = user || 'anonymous'
end

Expand All @@ -32,12 +32,10 @@ def abort
def chdir(path)
raise_if_closed
full_path = follow_path(path)
file = MockFTP::Folder.find(full_path)
raise_ftp_error("550 #{path}: No such file or directory") if file.nil?

if folder = find(full_path)
@current_path = full_path
else
raise ::Net::FTPPermError.new("550 #{path}: No such file or directory")
end
@current_path = full_path
end

def close
Expand All @@ -55,18 +53,14 @@ def connect(host, port = nil)

def list(path = '')
raise_if_closed
full_path = follow_path(path)
file = find(path, "450 #{path}: No such file or directory")

if file = find(full_path)
if file.folder?
file.list.collect do |f|
list_details_for(f)
end
else
[ list_details_for(file) ]
if file.folder?
file.list.collect do |f|
MockFTP::ListInfo.new(f, @user).to_s
end
else
raise ::Net::FTPPermError.new("450 #{path}: No such file or directory")
[ MockFTP::ListInfo.new(file, @user).to_s ]
end
end
alias_method :ls, :list
Expand All @@ -84,29 +78,18 @@ def mdtm(path)

def mtime(path, local = false)
raise_if_closed
full_path = follow_path(path)
file = find(path)
raise_ftp_error("550 #{path}: not a plain file.") unless file.file?

if file = find(full_path)
if file.file?
local ? file.mtime : file.mtime.utc
else
raise ::Net::FTPPermError.new("550 #{path}: not a plain file.")
end
else
raise ::Net::FTPPermError.new("550 #{path}: No such file or directory")
end
local ? file.mtime : file.mtime.utc
end

def nlst(path = '')
raise_if_closed
full_path = follow_path(path)
folder = find(path, '550 Directory not found')

if folder = find(full_path)
folder.list.collect do |f|
path.empty? ? f.basename : (path / f.basename)
end
else
raise ::Net::FTPPermError.new('550 Directory not found')
folder.list.collect do |f|
path.empty? ? f.basename : (path / f.basename)
end
end

Expand All @@ -130,23 +113,20 @@ def quit

def size(path)
raise_if_closed
full_path = follow_path(path)
file = find(path)
raise_ftp_error("550 #{path}: not a regular file") unless file.file?

if file = find(full_path)
if file.file?
file.content.size
else
raise ::Net::FTPPermError.new("550 #{path}: not a regular file")
end
else
raise ::Net::FTPPermError.new("550 #{path}: No such file or directory")
end
file.size
end

protected

def find(path)
MockFTP::Folder.find(path)
def find(path, error_message = "550 #{path}: No such file or directory")
if file = MockFTP::Folder.find(follow_path(path))
file
else
raise_ftp_error(error_message)
end
end

def follow_path(path)
Expand All @@ -162,49 +142,12 @@ def follow_path(path)
end
end

def format_date(date)
formatted_date = [ date.strftime('%b') ]
formatted_date << right_align_text(date.day.to_s, 2)
formatted_date << if date.year == Time.now.year
date.strftime('%H:%M').gsub(/^0/, ' ')
else
" #{date.year}"
end
formatted_date.join(' ')
end

def list_details_for(file)
if file.folder?
folders_count = file.list.select(&:folder?).count + 2
[
'drwxr-xr-x',
right_align_text(folders_count.to_s, 3),
@user, @user,
' 4096',
format_date(file.mtime.utc),
file.basename
].join(' ')
else
[
'-rw-r--r-- 1',
@user, @user,
right_align_text(file.size.to_s, 8),
format_date(file.mtime.utc),
file.basename
].join(' ')
end
def raise_ftp_error(error_message)
raise ::Net::FTPPermError.new(error_message)
end

def raise_if_closed
raise IOError.new('closed stream') if closed?
end

def right_align_text(content, spaces)
if content.length >= spaces
content
else
' ' * (spaces - content.length) + content
end
end
end
end

0 comments on commit 7cedd7d

Please sign in to comment.