xftp 0.3.3 → 0.4.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +33 -1
- data/lib/xftp/operations/ftp/glob.rb +5 -0
- data/lib/xftp/session/base.rb +6 -0
- data/lib/xftp/session/ftp.rb +41 -7
- data/lib/xftp/session/sftp.rb +51 -8
- data/lib/xftp/version.rb +2 -2
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 519e2c6a592998d81cfcff39a0b07896de6d107a
|
4
|
+
data.tar.gz: 7c964302e0290616bb71e32fa2da427804c0a839
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 21e2e2c9f5d002ea1cbb48bafb28fb08f1e6645ba5eac6d1131dcf1093b8b1f1458cbc0ea077c951cdf6ac4267e38fdd9728f0f46b33a4432504900a91cf3b4a
|
7
|
+
data.tar.gz: 06b5984a465cefa1e955550d5dfc0859d5f995fa7ce3294c7f7985e66c2e4cf9afcbc3cd4a31e86d9047c335f28952932bf10598386182f7acfa8c31f2703249
|
data/README.md
CHANGED
@@ -17,8 +17,9 @@ or
|
|
17
17
|
$ gem install xftp
|
18
18
|
```
|
19
19
|
|
20
|
-
## Usage
|
20
|
+
## Usage examples
|
21
21
|
|
22
|
+
Basic example:
|
22
23
|
```ruby
|
23
24
|
XFTP.start('ftps://hostname', credentials: { login: 'login', password: 'pass' }) do |x|
|
24
25
|
x.chdir 'remote-src-path'
|
@@ -32,6 +33,37 @@ XFTP.start('ftps://hostname', credentials: { login: 'login', password: 'pass' })
|
|
32
33
|
end
|
33
34
|
```
|
34
35
|
|
36
|
+
Connection as anonymous with emtpy password, checking remote dir existence, globbing and getting `StringIO`'s:
|
37
|
+
```ruby
|
38
|
+
XFTP.start('ftp://hostname') do |x|
|
39
|
+
x.mkdir 'some-dir' unless x.exist? 'some-dir'
|
40
|
+
x.glob '*.csv' do |filename|
|
41
|
+
io = x.get filename
|
42
|
+
end
|
43
|
+
end
|
44
|
+
```
|
45
|
+
|
46
|
+
Example using `each_io`:
|
47
|
+
```ruby
|
48
|
+
XFTP.start('ftps://hostname', credentials: { login: 'login', password: 'password' }) do |x|
|
49
|
+
x.chdir 'some-dir'
|
50
|
+
x.each_io do |filename, io|
|
51
|
+
# do smth with it
|
52
|
+
end
|
53
|
+
end
|
54
|
+
```
|
55
|
+
|
56
|
+
Wihout block argument (ntoe that you should rely on you local execution context objects):
|
57
|
+
```ruby
|
58
|
+
XFTP.start('ftps://hostname', credentials: credentials)
|
59
|
+
chdir 'blahblah'
|
60
|
+
each_file do |filename|
|
61
|
+
download filename, to: File.join('local-dir', filename)
|
62
|
+
move filename, to: File.join('remote-archive-path', filename)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
```
|
66
|
+
|
35
67
|
## Development
|
36
68
|
|
37
69
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `bin/console` for an interactive prompt that will allow you to experiment.
|
@@ -7,6 +7,8 @@ module XFTP
|
|
7
7
|
# @note It isn't tested on Windows OS and chances are that it won't work,
|
8
8
|
# that's why it is implemented as a separate "command"
|
9
9
|
class Glob
|
10
|
+
NO_SUCH_FILE_OR_DIRECTORY_CODE = 450
|
11
|
+
|
10
12
|
def initialize(ftp)
|
11
13
|
@ftp = ftp
|
12
14
|
end
|
@@ -17,6 +19,9 @@ module XFTP
|
|
17
19
|
# @param [Proc] callback
|
18
20
|
def call(pattern, &callback)
|
19
21
|
@ftp.nlst(pattern).each { |filename| callback.call(filename) }
|
22
|
+
rescue Net::FTPTempError => err
|
23
|
+
code = err.to_s[0, 3].try(:to_i)
|
24
|
+
raise err unless code == NO_SUCH_FILE_OR_DIRECTORY_CODE
|
20
25
|
end
|
21
26
|
end
|
22
27
|
end
|
data/lib/xftp/session/base.rb
CHANGED
data/lib/xftp/session/ftp.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
require 'active_support/core_ext/hash/deep_merge'
|
2
|
-
require 'forwardable'
|
3
2
|
require 'net/ftp'
|
4
3
|
|
5
4
|
require 'xftp/session/base'
|
@@ -10,12 +9,6 @@ module XFTP
|
|
10
9
|
# FTP session adapter
|
11
10
|
# @api private
|
12
11
|
class FTP < Base
|
13
|
-
extend Forwardable
|
14
|
-
|
15
|
-
# Delegate methods which have the same method signature
|
16
|
-
# directly to Net::FTP session
|
17
|
-
def_delegators :@ftp, :chdir, :mkdir, :rmdir
|
18
|
-
|
19
12
|
# Creates an FTP session adapter instance
|
20
13
|
# @param [URI] uri the remote uri
|
21
14
|
# @param [Hash] settings the adapter connection settings
|
@@ -30,14 +23,40 @@ module XFTP
|
|
30
23
|
options.each { |key, val| @ftp.public_send("#{key}=", val) }
|
31
24
|
end
|
32
25
|
|
26
|
+
# Changes the current (remote) working directory
|
27
|
+
# @param [String] path the relative (remote) path
|
28
|
+
def chdir(path)
|
29
|
+
ensure_relative_path! :chdir, path
|
30
|
+
@ftp.chdir path
|
31
|
+
end
|
32
|
+
|
33
|
+
# Creates a remote directory
|
34
|
+
# @param [String] dirname the name of new directory
|
35
|
+
# relative to the current (remote) working directory
|
36
|
+
def mkdir(dirname)
|
37
|
+
ensure_relative_path! :mkdir, dirname
|
38
|
+
@ftp.mkdir dirname
|
39
|
+
end
|
40
|
+
|
41
|
+
# Removes the remote directory
|
42
|
+
# @param [String] dirname the name of directory to be removed
|
43
|
+
def rmdir(dirname)
|
44
|
+
ensure_relative_path! :rmdir, dirname
|
45
|
+
@ftp.rmdir dirname
|
46
|
+
end
|
47
|
+
|
33
48
|
# @return [Boolean] `true` if the argument refers to a directory on the remote host
|
34
49
|
def exists?(dirname)
|
35
50
|
entries.include? dirname
|
36
51
|
end
|
37
52
|
|
53
|
+
# HACK: It looks ridiculous, but its the only way to find out
|
54
|
+
# if the given remote path is a file or directory
|
55
|
+
|
38
56
|
# @return [Boolean] `true` if the argument refers to
|
39
57
|
# a directory on the remote host
|
40
58
|
def directory?(path)
|
59
|
+
ensure_relative_path! :directory?, path
|
41
60
|
chdir path
|
42
61
|
chdir '..'
|
43
62
|
true
|
@@ -65,6 +84,21 @@ module XFTP
|
|
65
84
|
files.each { |filename| yield filename }
|
66
85
|
end
|
67
86
|
|
87
|
+
# Calls the block once for each entry in the current directory
|
88
|
+
# on the remote server and yields a filename and `StringIO` object to the block
|
89
|
+
def each_io
|
90
|
+
each_file do |filename|
|
91
|
+
io = get filename
|
92
|
+
yield filename, io
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
# Downloads file into IO object
|
97
|
+
# @return [StringIO] the remote file data
|
98
|
+
def get(filename)
|
99
|
+
@ftp.getbinaryfile(filename, nil)
|
100
|
+
end
|
101
|
+
|
68
102
|
# @see XFTP::Operations::FTP::Glob
|
69
103
|
def glob(pattern, &callback)
|
70
104
|
Operations::FTP::Glob.new(@ftp).call(pattern, &callback)
|
data/lib/xftp/session/sftp.rb
CHANGED
@@ -8,6 +8,31 @@ module XFTP
|
|
8
8
|
# SFTP session adapter
|
9
9
|
# @api private
|
10
10
|
class SFTP < Base
|
11
|
+
# Helper class for progress monitoring
|
12
|
+
class ProgressHandler
|
13
|
+
include Helpers::Logging
|
14
|
+
|
15
|
+
def on_open(_downloader, file)
|
16
|
+
log "starting download: #{file.remote} -> #{file.local} (#{file.size} bytes)"
|
17
|
+
end
|
18
|
+
|
19
|
+
def on_get(_downloader, file, offset, data)
|
20
|
+
log "writing #{data.length} bytes to #{file.local} starting at #{offset}"
|
21
|
+
end
|
22
|
+
|
23
|
+
def on_close(_downloader, file)
|
24
|
+
log "finished with #{file.remote}"
|
25
|
+
end
|
26
|
+
|
27
|
+
def on_mkdir(_downloader, path)
|
28
|
+
log "creating directory #{path}"
|
29
|
+
end
|
30
|
+
|
31
|
+
def on_finish(_downloader)
|
32
|
+
log 'done'
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
11
36
|
# Default flags for rename operation
|
12
37
|
RENAME_OPERATION_FLAGS = 0x0004
|
13
38
|
# Default flags for glob operation
|
@@ -26,6 +51,7 @@ module XFTP
|
|
26
51
|
# Changes the current (remote) working directory
|
27
52
|
# @param [String] path the relative (remote) path
|
28
53
|
def chdir(path)
|
54
|
+
ensure_relative_path! :chdir, path
|
29
55
|
@path += path
|
30
56
|
end
|
31
57
|
|
@@ -35,9 +61,17 @@ module XFTP
|
|
35
61
|
# @param [Hash] attrs the attributes of new directory
|
36
62
|
# supported by the the version of SFTP protocol in use
|
37
63
|
def mkdir(dirname, attrs = {})
|
64
|
+
ensure_relative_path! :mkdir, path
|
38
65
|
@sftp.mkdir!(remote_path(dirname), attrs)
|
39
66
|
end
|
40
67
|
|
68
|
+
# Removes the remote directory
|
69
|
+
# @param [String] dirname the name of directory to be removed
|
70
|
+
def rmdir(dirname)
|
71
|
+
ensure_relative_path! :rmdir, path
|
72
|
+
@sftp.rmdir! remote_path(dirname)
|
73
|
+
end
|
74
|
+
|
41
75
|
# @return [Boolean] `true` if the file exists
|
42
76
|
# in a current working directory on the remote host
|
43
77
|
def exists?(filename)
|
@@ -47,6 +81,7 @@ module XFTP
|
|
47
81
|
# @return [Boolean] `true` if the argument refers to
|
48
82
|
# a directory on the remote host
|
49
83
|
def directory?(path)
|
84
|
+
ensure_relative_path! :directory?, path
|
50
85
|
@sftp.file.directory? remote_path(path)
|
51
86
|
end
|
52
87
|
|
@@ -56,12 +91,6 @@ module XFTP
|
|
56
91
|
!directory?(path)
|
57
92
|
end
|
58
93
|
|
59
|
-
# Removes the remote directory
|
60
|
-
# @param [String] dirname the name of directory to be removed
|
61
|
-
def rmdir(dirname)
|
62
|
-
@sftp.rmdir! remote_path(dirname)
|
63
|
-
end
|
64
|
-
|
65
94
|
# Renames (moves) a file on the server
|
66
95
|
# @param [String] from the path to move from
|
67
96
|
# @param [String] to the path to move to
|
@@ -79,6 +108,21 @@ module XFTP
|
|
79
108
|
end
|
80
109
|
end
|
81
110
|
|
111
|
+
# Calls the block once for each entry in the current directory
|
112
|
+
# on the remote server and (asynchronously) yields a filename and `StringIO` object to the block
|
113
|
+
def each_io
|
114
|
+
each_file do |filename|
|
115
|
+
io = get filename
|
116
|
+
yield filename, io
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
# Downloads file into IO object
|
121
|
+
# @return [StringIO] the remote file data
|
122
|
+
def get(filename)
|
123
|
+
@sftp.download!(remote_path(filename), nil, progress: ProgressHandler)
|
124
|
+
end
|
125
|
+
|
82
126
|
# For more info (see Dir#glob), it's almost of the same nature
|
83
127
|
# @param [String] pattern the search pattern relative
|
84
128
|
# the the current working directory
|
@@ -105,8 +149,7 @@ module XFTP
|
|
105
149
|
entries.reject { |filename| directory? filename }
|
106
150
|
end
|
107
151
|
|
108
|
-
# @return [Array<String>] an array of entries (including directories)
|
109
|
-
# in the remote directory
|
152
|
+
# @return [Array<String>] an array of entries (including directories) in the remote directory
|
110
153
|
def entries
|
111
154
|
@sftp.dir.entries(@path.to_s).map(&:name)
|
112
155
|
end
|
data/lib/xftp/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: xftp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Vasiliy Yorkin
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-04-
|
11
|
+
date: 2015-04-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -239,6 +239,6 @@ rubyforge_project:
|
|
239
239
|
rubygems_version: 2.2.2
|
240
240
|
signing_key:
|
241
241
|
specification_version: 4
|
242
|
-
summary: xftp-0.
|
242
|
+
summary: xftp-0.4.1
|
243
243
|
test_files: []
|
244
244
|
has_rdoc:
|