ftp_paradise 1.4.5 → 1.5.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of ftp_paradise might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/README.md +152 -28
- data/bin/{iftp → ftp_paradise_shell} +1 -1
- data/doc/README.gen +97 -15
- data/doc/todo/{TODO_FOR_FTP_PARADISE_PROJECT.md → todo_for_the_ftp_paradise_project.md} +0 -0
- data/ftp_paradise.gemspec +30 -39
- data/lib/ftp_paradise/base/base.rb +375 -0
- data/lib/ftp_paradise/colours/colours.rb +27 -27
- data/lib/ftp_paradise/colours/use_colours.rb +6 -1
- data/lib/ftp_paradise/configuration/configuration.rb +7 -4
- data/lib/ftp_paradise/connection/README.md +0 -0
- data/lib/ftp_paradise/connection/connection.rb +2782 -15
- data/lib/ftp_paradise/constants/constants.rb +91 -5
- data/lib/ftp_paradise/entry/entry.rb +42 -5
- data/lib/ftp_paradise/{connection → gui/gtk3/ftp_client}/constants.rb +33 -21
- data/lib/ftp_paradise/gui/{shared_code/ftp_paradise/ftp_paradise_module.rb → gtk3/ftp_client/ftp_client.rb} +658 -170
- data/lib/ftp_paradise/gui/gtk3/ftp_client/misc.rb +27 -0
- data/lib/ftp_paradise/project/project.rb +11 -15
- data/lib/ftp_paradise/requires/require_class_connection.rb +7 -0
- data/lib/ftp_paradise/requires/require_net_ftp.rb +7 -0
- data/lib/ftp_paradise/requires/require_the_ftp_paradise_project.rb +4 -3
- data/lib/ftp_paradise/requires/require_the_ftp_paradise_project_with_the_GUI_bindings.rb +1 -1
- data/lib/ftp_paradise/requires/require_the_toplevel_methods.rb +1 -0
- data/lib/ftp_paradise/{interactive_ftp → shell}/menu.rb +554 -448
- data/lib/ftp_paradise/shell/shell.rb +2321 -0
- data/lib/ftp_paradise/toplevel_methods/connect.rb +3 -0
- data/lib/ftp_paradise/toplevel_methods/dataset.rb +111 -0
- data/lib/ftp_paradise/toplevel_methods/file_related_actions.rb +4 -3
- data/lib/ftp_paradise/toplevel_methods/ftp_object.rb +6 -5
- data/lib/ftp_paradise/toplevel_methods/login_name.rb +6 -4
- data/lib/ftp_paradise/toplevel_methods/misc.rb +19 -0
- data/lib/ftp_paradise/toplevel_methods/opn.rb +1 -1
- data/lib/ftp_paradise/toplevel_methods/password.rb +4 -2
- data/lib/ftp_paradise/toplevel_methods/port.rb +4 -1
- data/lib/ftp_paradise/toplevel_methods/remote_url.rb +11 -5
- data/lib/ftp_paradise/toplevel_methods/upload_and_download.rb +1 -0
- data/lib/ftp_paradise/version/version.rb +6 -1
- data/lib/ftp_paradise/www/web_interface.cgi +1 -1
- data/lib/ftp_paradise/yaml/automatically_connect_on_startup_of_the_interactive_ftp_shell.yml +0 -0
- data/lib/ftp_paradise/yaml/debug.yml +0 -0
- data/lib/ftp_paradise/yaml/open_in_default_editor.yml +0 -0
- data/lib/ftp_paradise/yaml/show_full_names.yml +0 -0
- data/lib/ftp_paradise/yaml/use_colours.yml +0 -0
- data/test/testing_minimal_pure_net_ftp_example_to_connect.rb +13 -3
- metadata +52 -126
- data/lib/ftp_paradise/base/cliner.rb +0 -23
- data/lib/ftp_paradise/base/colours.rb +0 -83
- data/lib/ftp_paradise/base/prototype.rb +0 -171
- data/lib/ftp_paradise/base/reset.rb +0 -29
- data/lib/ftp_paradise/connection/data.rb +0 -164
- data/lib/ftp_paradise/connection/debug.rb +0 -78
- data/lib/ftp_paradise/connection/directory_handling.rb +0 -271
- data/lib/ftp_paradise/connection/do_login.rb +0 -108
- data/lib/ftp_paradise/connection/download.rb +0 -86
- data/lib/ftp_paradise/connection/file_handling.rb +0 -174
- data/lib/ftp_paradise/connection/ftp_object.rb +0 -21
- data/lib/ftp_paradise/connection/initialize.rb +0 -88
- data/lib/ftp_paradise/connection/initialize_a_new_net_ftp_object_with_this_url.rb +0 -20
- data/lib/ftp_paradise/connection/is_connected.rb +0 -46
- data/lib/ftp_paradise/connection/misc.rb +0 -474
- data/lib/ftp_paradise/connection/notify.rb +0 -71
- data/lib/ftp_paradise/connection/password.rb +0 -47
- data/lib/ftp_paradise/connection/port.rb +0 -33
- data/lib/ftp_paradise/connection/remote_pwd.rb +0 -72
- data/lib/ftp_paradise/connection/remote_url.rb +0 -164
- data/lib/ftp_paradise/connection/remove.rb +0 -143
- data/lib/ftp_paradise/connection/reset.rb +0 -78
- data/lib/ftp_paradise/connection/run.rb +0 -18
- data/lib/ftp_paradise/connection/set_array_available_hosts.rb +0 -27
- data/lib/ftp_paradise/connection/set_input.rb +0 -18
- data/lib/ftp_paradise/connection/show.rb +0 -153
- data/lib/ftp_paradise/connection/sync_ftp_object_onto_the_main_namespace.rb +0 -24
- data/lib/ftp_paradise/connection/transfer_mode.rb +0 -163
- data/lib/ftp_paradise/connection/upload.rb +0 -253
- data/lib/ftp_paradise/connection/use_default_dataset.rb +0 -40
- data/lib/ftp_paradise/connection/username.rb +0 -42
- data/lib/ftp_paradise/constants/misc.rb +0 -57
- data/lib/ftp_paradise/constants/namespace.rb +0 -14
- data/lib/ftp_paradise/constants/newline.rb +0 -14
- data/lib/ftp_paradise/constants/roebe.rb +0 -31
- data/lib/ftp_paradise/constants/roebe_ftp_constants.rb +0 -233
- data/lib/ftp_paradise/gui/gtk2/ftp_paradise.rb +0 -34
- data/lib/ftp_paradise/gui/gtk3/ftp_paradise.rb +0 -34
- data/lib/ftp_paradise/interactive_ftp/constants.rb +0 -103
- data/lib/ftp_paradise/interactive_ftp/directory_handling.rb +0 -216
- data/lib/ftp_paradise/interactive_ftp/help.rb +0 -50
- data/lib/ftp_paradise/interactive_ftp/initialize.rb +0 -27
- data/lib/ftp_paradise/interactive_ftp/interactive_ftp.rb +0 -998
- data/lib/ftp_paradise/interactive_ftp/main_loop.rb +0 -51
- data/lib/ftp_paradise/interactive_ftp/misc.rb +0 -208
- data/lib/ftp_paradise/interactive_ftp/mode.rb +0 -124
- data/lib/ftp_paradise/interactive_ftp/readline.rb +0 -113
- data/lib/ftp_paradise/interactive_ftp/remove.rb +0 -97
- data/lib/ftp_paradise/interactive_ftp/reset.rb +0 -90
- data/lib/ftp_paradise/interactive_ftp/run.rb +0 -22
- data/lib/ftp_paradise/interactive_ftp/show.rb +0 -184
- data/lib/ftp_paradise/interactive_ftp/upload.rb +0 -90
- data/lib/ftp_paradise/interactive_ftp/user_input.rb +0 -53
- data/lib/ftp_paradise/toplevel_methods/can_connect_to_remote_site.rb +0 -28
- data/lib/ftp_paradise/toplevel_methods/clear_user_dataset.rb +0 -28
- data/lib/ftp_paradise/toplevel_methods/data.rb +0 -31
- data/lib/ftp_paradise/toplevel_methods/determine_user_dataset_from_this_hash.rb +0 -37
@@ -2,34 +2,2801 @@
|
|
2
2
|
# Encoding: UTF-8
|
3
3
|
# frozen_string_literal: true
|
4
4
|
# =========================================================================== #
|
5
|
+
# === FtpParadise::Connection
|
6
|
+
#
|
5
7
|
# This is the "connection class". It will have methods that can be use
|
6
|
-
# when
|
8
|
+
# when the user is connected to a remote site (via the FTP protocol).
|
7
9
|
#
|
8
10
|
# Rather than keeping FTP-related state within this class, such as remote
|
9
|
-
# URL and such, we will instead use FtpParadise module methods.
|
11
|
+
# URL and such, we will instead use FtpParadise toplevel-module methods.
|
12
|
+
# Or, at the least, we will tap into that dataset if it has been
|
13
|
+
# assigned by the user.
|
14
|
+
#
|
15
|
+
# Usage example:
|
16
|
+
#
|
17
|
+
# FtpParadise::Connection.new(ARGV)
|
18
|
+
#
|
10
19
|
# =========================================================================== #
|
11
20
|
# Possible errors and failures when we are trying to connect:
|
12
21
|
#
|
13
22
|
# Net::FTPPermError: 530 Please login with USER and PASS.
|
14
23
|
#
|
15
|
-
# Net::FTPConnectionError is raised if we are no longer connected
|
16
|
-
# the remote FTP site.
|
24
|
+
# Net::FTPConnectionError is raised if we are no longer connected
|
25
|
+
# to the remote FTP site.
|
17
26
|
#
|
18
27
|
# Errno::ETIMEDOUT is raised when a timeout event occurred.
|
28
|
+
#
|
19
29
|
# =========================================================================== #
|
20
30
|
# The official documentation for Ruby-FTP can be found here:
|
21
31
|
#
|
22
32
|
# https://ruby-doc.org/stdlib/libdoc/net/ftp/rdoc/Net/FTP.html
|
23
33
|
#
|
24
34
|
# =========================================================================== #
|
25
|
-
require 'ftp_paradise/connection/
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
require 'ftp_paradise/
|
32
|
-
|
33
|
-
|
34
|
-
require 'ftp_paradise/
|
35
|
-
require 'ftp_paradise/
|
35
|
+
# require 'ftp_paradise/connection/connection.rb'
|
36
|
+
# =========================================================================== #
|
37
|
+
module FtpParadise
|
38
|
+
|
39
|
+
class Connection # === FtpParadise::Connection
|
40
|
+
|
41
|
+
require 'ftp_paradise/base/base.rb'
|
42
|
+
include ::FtpParadise::Base
|
43
|
+
|
44
|
+
require 'ftp_paradise/requires/require_net_ftp.rb'
|
45
|
+
require 'ftp_paradise/requires/require_the_toplevel_methods.rb'
|
46
|
+
require 'ftp_paradise/entry/entry.rb'
|
47
|
+
require 'ftp_paradise/configuration/configuration.rb'
|
48
|
+
|
49
|
+
# ========================================================================= #
|
50
|
+
# === NAMESPACE
|
51
|
+
# ========================================================================= #
|
52
|
+
NAMESPACE = inspect
|
53
|
+
|
54
|
+
# ========================================================================= #
|
55
|
+
# === BE_VERBOSE
|
56
|
+
# ========================================================================= #
|
57
|
+
BE_VERBOSE = true
|
58
|
+
|
59
|
+
# ========================================================================= #
|
60
|
+
# === DEFAULT_TRANSFER_MODE
|
61
|
+
# ========================================================================= #
|
62
|
+
DEFAULT_TRANSFER_MODE = :ascii # Which transfer mode to use by default.
|
63
|
+
|
64
|
+
# ========================================================================= #
|
65
|
+
# === DEFAULT_PORT
|
66
|
+
# ========================================================================= #
|
67
|
+
DEFAULT_PORT = 21
|
68
|
+
|
69
|
+
# ========================================================================= #
|
70
|
+
# === DEFAULT_USER_NAME
|
71
|
+
#
|
72
|
+
# In the past this was set to a String (the user name); but since as
|
73
|
+
# of October 2018, it will default to nil, so that we really initialize
|
74
|
+
# the whole project to a nil-state (as the default). This thus allows
|
75
|
+
# us to determine whether this has been changed, aka initialized.
|
76
|
+
# ========================================================================= #
|
77
|
+
DEFAULT_USER_NAME = nil
|
78
|
+
|
79
|
+
# ========================================================================= #
|
80
|
+
# === RUN_ALREADY
|
81
|
+
# ========================================================================= #
|
82
|
+
RUN_ALREADY = true
|
83
|
+
|
84
|
+
# ========================================================================= #
|
85
|
+
# === initialize
|
86
|
+
#
|
87
|
+
# The first argument to this method should be the remote host's URL.
|
88
|
+
# ========================================================================= #
|
89
|
+
def initialize(
|
90
|
+
i = ARGV,
|
91
|
+
run_already = RUN_ALREADY
|
92
|
+
)
|
93
|
+
reset
|
94
|
+
# ======================================================================= #
|
95
|
+
# - If we pass in a Hash as the first argument, then we will use
|
96
|
+
# set_data(), otherwise we will set individually it all individually.
|
97
|
+
# ======================================================================= #
|
98
|
+
if i.is_a? Hash
|
99
|
+
set_data(i)
|
100
|
+
else
|
101
|
+
set_input(i)
|
102
|
+
end
|
103
|
+
case i
|
104
|
+
# ======================================================================= #
|
105
|
+
# === :dont_run_yet
|
106
|
+
# ======================================================================= #
|
107
|
+
when :dont_run_yet,
|
108
|
+
:do_not_run_yet
|
109
|
+
run_already = false
|
110
|
+
end
|
111
|
+
case run_already
|
112
|
+
# ======================================================================= #
|
113
|
+
# === :dont_run_yet
|
114
|
+
# ======================================================================= #
|
115
|
+
when :dont_run_yet
|
116
|
+
run_already = false
|
117
|
+
end
|
118
|
+
if run_already.is_a? Hash
|
119
|
+
_ = run_already
|
120
|
+
if _.has_key? :connect_to_this_host
|
121
|
+
set_this_host(
|
122
|
+
_.delete(:connect_to_this_host)
|
123
|
+
)
|
124
|
+
end
|
125
|
+
run_already = RUN_ALREADY # Restore to the default in this case.
|
126
|
+
end
|
127
|
+
# ======================================================================= #
|
128
|
+
# === Handle blocks given to this method next
|
129
|
+
# ======================================================================= #
|
130
|
+
if block_given?
|
131
|
+
yielded = yield
|
132
|
+
case yielded
|
133
|
+
# ===================================================================== #
|
134
|
+
# === :do_not_run_yet
|
135
|
+
# ===================================================================== #
|
136
|
+
when :do_not_run_yet
|
137
|
+
run_already = false
|
138
|
+
# ===================================================================== #
|
139
|
+
# The "default" dataset defaults to my personal FTP login dataset.
|
140
|
+
# ===================================================================== #
|
141
|
+
when :use_default_dataset,
|
142
|
+
:default_dataset,
|
143
|
+
:default
|
144
|
+
use_default_dataset
|
145
|
+
end
|
146
|
+
end
|
147
|
+
run if run_already
|
148
|
+
end
|
149
|
+
|
150
|
+
# ========================================================================= #
|
151
|
+
# === reset (reset tag)
|
152
|
+
# ========================================================================= #
|
153
|
+
def reset
|
154
|
+
super()
|
155
|
+
# ======================================================================= #
|
156
|
+
# === @namespace
|
157
|
+
# ======================================================================= #
|
158
|
+
@namespace = NAMESPACE
|
159
|
+
# ======================================================================= #
|
160
|
+
# === @ftp_object
|
161
|
+
# ======================================================================= #
|
162
|
+
@ftp_object = nil
|
163
|
+
# ======================================================================= #
|
164
|
+
# === @input
|
165
|
+
# ======================================================================= #
|
166
|
+
@input = nil
|
167
|
+
populate_internal_hash_with_default_values
|
168
|
+
# ======================================================================= #
|
169
|
+
# The next method-call must come after
|
170
|
+
# populate_internal_hash_with_default_values().
|
171
|
+
# ======================================================================= #
|
172
|
+
set_be_verbose if BE_VERBOSE
|
173
|
+
set_port
|
174
|
+
set_array_available_hosts
|
175
|
+
set_default_transfer_mode :be_quiet
|
176
|
+
set_username
|
177
|
+
end
|
178
|
+
|
179
|
+
# ========================================================================= #
|
180
|
+
# === binary=
|
181
|
+
# ========================================================================= #
|
182
|
+
def binary=(i = true)
|
183
|
+
@internal_hash[:transfer_mode] = :binary
|
184
|
+
ftp_object?.binary = i
|
185
|
+
end
|
186
|
+
|
187
|
+
# ========================================================================= #
|
188
|
+
# === binary_mode?
|
189
|
+
# ========================================================================= #
|
190
|
+
def binary_mode?
|
191
|
+
@internal_hash[:transfer_mode] == :binary
|
192
|
+
end
|
193
|
+
|
194
|
+
# ========================================================================= #
|
195
|
+
# === passive=
|
196
|
+
# ========================================================================= #
|
197
|
+
def passive=(i = true)
|
198
|
+
if ftp_object?
|
199
|
+
ftp_object?.passive = i
|
200
|
+
else
|
201
|
+
e 'In .passive=: No ftp-object has been instantiated yet.'
|
202
|
+
end
|
203
|
+
end; alias set_passive passive= # === set_passive
|
204
|
+
|
205
|
+
# ========================================================================= #
|
206
|
+
# === try_to_download_this_remote_file
|
207
|
+
# ========================================================================= #
|
208
|
+
def try_to_download_this_remote_file(
|
209
|
+
i, be_verbose = false, &block
|
210
|
+
)
|
211
|
+
if block_given?
|
212
|
+
yielded = yield
|
213
|
+
case yielded
|
214
|
+
when :be_verbose
|
215
|
+
be_verbose = true
|
216
|
+
end
|
217
|
+
end
|
218
|
+
e 'Trying to download `'+steelblue(i)+'` next.' if be_verbose
|
219
|
+
@ftp_object.getbinaryfile(i)
|
220
|
+
if be_verbose
|
221
|
+
e 'Download of '+steelblue(i)+' has finished! It is '\
|
222
|
+
'now at '+sfile(return_pwd+i)
|
223
|
+
end
|
224
|
+
end; alias getbinaryfile try_to_download_this_remote_file # === getbinaryfile
|
225
|
+
alias download_binary_file try_to_download_this_remote_file # === download_binary_file
|
226
|
+
|
227
|
+
# ========================================================================= #
|
228
|
+
# === list (raw tag)
|
229
|
+
#
|
230
|
+
# This method must yield the result of .list(), as Array.
|
231
|
+
# ========================================================================= #
|
232
|
+
def list(i = '*')
|
233
|
+
ftp_object?.list(i)
|
234
|
+
end; alias raw_list list # === raw_list
|
235
|
+
|
236
|
+
# ========================================================================= #
|
237
|
+
# === nlst?
|
238
|
+
#
|
239
|
+
# This method will return an array of filenames in the remote
|
240
|
+
# directory. This will yield less information than the "ls -l"
|
241
|
+
# variant, aka list().
|
242
|
+
#
|
243
|
+
# Documentation:
|
244
|
+
#
|
245
|
+
# https://ruby-doc.org/stdlib/libdoc/net/ftp/rdoc/Net/FTP.html#method-i-nlst
|
246
|
+
#
|
247
|
+
# ========================================================================= #
|
248
|
+
def nlst?
|
249
|
+
ftp_object?.nlst
|
250
|
+
end; alias nlst nlst? # === nlst
|
251
|
+
|
252
|
+
# ========================================================================= #
|
253
|
+
# === sendcmd
|
254
|
+
#
|
255
|
+
# Sends a command and returns the response of the server.
|
256
|
+
#
|
257
|
+
# This has to be rescued, because there are lots of different errors
|
258
|
+
# possible.
|
259
|
+
# ========================================================================= #
|
260
|
+
def sendcmd(i)
|
261
|
+
begin
|
262
|
+
ftp_object?.sendcmd(i)
|
263
|
+
rescue Exception => error
|
264
|
+
pp error
|
265
|
+
e '(This error may be due to the remote file not existing.)'
|
266
|
+
end
|
267
|
+
end
|
268
|
+
|
269
|
+
# ========================================================================= #
|
270
|
+
# === remove_file
|
271
|
+
#
|
272
|
+
# This method will delete a remote file.
|
273
|
+
#
|
274
|
+
# The API should remain fairly flexible.
|
275
|
+
#
|
276
|
+
# Example:
|
277
|
+
#
|
278
|
+
# ftp_connection?.remove_file(i.text?) { :be_verbose }
|
279
|
+
#
|
280
|
+
# ========================================================================= #
|
281
|
+
def remove_file(
|
282
|
+
i, be_verbose = false, &block
|
283
|
+
)
|
284
|
+
if block_given?
|
285
|
+
yielded = yield
|
286
|
+
case yielded
|
287
|
+
# ===================================================================== #
|
288
|
+
# === :be_verbose
|
289
|
+
# ===================================================================== #
|
290
|
+
when :be_verbose
|
291
|
+
be_verbose = true
|
292
|
+
end
|
293
|
+
end
|
294
|
+
e 'Deleting the remote file at '+steelblue(i)+' next:' if be_verbose
|
295
|
+
ftp_connection?.delete(i)
|
296
|
+
e 'Deleting the remote file at '+steelblue(i)+' has been completed.' if be_verbose
|
297
|
+
end; alias delete_file remove_file # === delete_file
|
298
|
+
alias delete remove_file # === delete
|
299
|
+
|
300
|
+
# ========================================================================= #
|
301
|
+
# === option
|
302
|
+
#
|
303
|
+
# This method will issue an OPTS command. The first argument should
|
304
|
+
# be the name of the option that is to be set. Additional arguments
|
305
|
+
# are treated as parameter to that command.
|
306
|
+
#
|
307
|
+
# Example:
|
308
|
+
#
|
309
|
+
# option('UTF8', 'ON') => 'OPTS UTF8 ON'
|
310
|
+
#
|
311
|
+
# ========================================================================= #
|
312
|
+
def option(i, optional_argument = nil)
|
313
|
+
ftp_connection?.option(i, optional_argument)
|
314
|
+
end
|
315
|
+
|
316
|
+
# ========================================================================= #
|
317
|
+
# === set_remote_url
|
318
|
+
#
|
319
|
+
# This method will do some sanitizing before it sets a proper and
|
320
|
+
# valid hostname. Remember to keep the 'default' entry at the
|
321
|
+
# current main FTP host you use.
|
322
|
+
# ========================================================================= #
|
323
|
+
def set_remote_url(
|
324
|
+
i = :default,
|
325
|
+
be_verbose = true
|
326
|
+
)
|
327
|
+
i = :default? if i.nil?
|
328
|
+
if i.is_a? Hash # Handle Hash as input here.
|
329
|
+
if i.has_key?(:to)
|
330
|
+
i = i[:to]
|
331
|
+
end
|
332
|
+
end
|
333
|
+
# ======================================================================= #
|
334
|
+
# The next block is mostly for my custom constants.
|
335
|
+
# You can simply pass in your own Hash.
|
336
|
+
# ======================================================================= #
|
337
|
+
case i # Do some sanitizing. This is a String here. (case tag)
|
338
|
+
# ======================================================================= #
|
339
|
+
# === bplaced (this is equivalent to shevy)
|
340
|
+
# ======================================================================= #
|
341
|
+
when /^-?-?bplaced$/i,
|
342
|
+
/^-?-?shevy$/i,
|
343
|
+
'default'
|
344
|
+
set_data(:bplaced)
|
345
|
+
i = BPLACED.first
|
346
|
+
# ======================================================================= #
|
347
|
+
# === ?
|
348
|
+
# ======================================================================= #
|
349
|
+
when '?'
|
350
|
+
feedback_login_hosts
|
351
|
+
# ======================================================================= #
|
352
|
+
# === uniwien_homepage
|
353
|
+
# ======================================================================= #
|
354
|
+
when /^uniwien_?homepage/
|
355
|
+
set_data(UNIWIEN_HOMEPAGE)
|
356
|
+
i = UNIWIEN_HOMEPAGE.first
|
357
|
+
# ======================================================================= #
|
358
|
+
# === unet
|
359
|
+
# ======================================================================= #
|
360
|
+
when 'unet','uni',
|
361
|
+
'uniftp'
|
362
|
+
set_data(UNIVIE)
|
363
|
+
i = UNIVIE.first
|
364
|
+
# ======================================================================= #
|
365
|
+
# === a1
|
366
|
+
# ======================================================================= #
|
367
|
+
when /^a1/
|
368
|
+
set_data(A1)
|
369
|
+
i = A1.first
|
370
|
+
# ======================================================================= #
|
371
|
+
# === byte
|
372
|
+
# ======================================================================= #
|
373
|
+
when /^byte/ # This also includese bytehost.
|
374
|
+
set_data(BYTEHOST)
|
375
|
+
i = BYTEHOST.first
|
376
|
+
# ======================================================================= #
|
377
|
+
# === zerofees
|
378
|
+
# ======================================================================= #
|
379
|
+
when 'ZEROFEES','zero','ZERO'
|
380
|
+
set_data(ZEROFEES)
|
381
|
+
i = ZEROFEES.first
|
382
|
+
# ======================================================================= #
|
383
|
+
# === ucoz
|
384
|
+
# ======================================================================= #
|
385
|
+
when 'ucoz','UCOZ',
|
386
|
+
'LAST',
|
387
|
+
/tanriel/i,
|
388
|
+
'last'
|
389
|
+
set_data(UCOZ)
|
390
|
+
i = UCOZ.first
|
391
|
+
end
|
392
|
+
case i.to_s
|
393
|
+
# ======================================================================= #
|
394
|
+
# === shevy
|
395
|
+
# ======================================================================= #
|
396
|
+
when 'shevy','5','default' # Current default entry.
|
397
|
+
i = SQUARE7.first
|
398
|
+
# ======================================================================= #
|
399
|
+
# === a1
|
400
|
+
# ======================================================================= #
|
401
|
+
when '1','a1'
|
402
|
+
i = A1.first
|
403
|
+
# ======================================================================= #
|
404
|
+
# === unet
|
405
|
+
# ======================================================================= #
|
406
|
+
when '2','unet','uni','uniftp'
|
407
|
+
i = UNIVIE.first
|
408
|
+
# ======================================================================= #
|
409
|
+
# === geas
|
410
|
+
# ======================================================================= #
|
411
|
+
when '3',
|
412
|
+
'geas'
|
413
|
+
i = GEAS.first
|
414
|
+
# ======================================================================= #
|
415
|
+
# === byte
|
416
|
+
# ======================================================================= #
|
417
|
+
when '4',
|
418
|
+
'byte'
|
419
|
+
i = BYTEHOST.first
|
420
|
+
end
|
421
|
+
i = i.to_s # Need a String here.
|
422
|
+
# ======================================================================= #
|
423
|
+
# === Provide more information to the user
|
424
|
+
# ======================================================================= #
|
425
|
+
if debug?
|
426
|
+
opnn; e "The remote URL was set to: #{sfancy(i)}"
|
427
|
+
end
|
428
|
+
if be_verbose
|
429
|
+
e "Setting url to #{sfancy(i)} now."
|
430
|
+
end
|
431
|
+
FtpParadise.set_remote_url(i)
|
432
|
+
# ======================================================================= #
|
433
|
+
# And we will always initialize a new ftp-object as well, whenever
|
434
|
+
# we call this method:
|
435
|
+
# ======================================================================= #
|
436
|
+
initialize_a_new_net_ftp_object_with_this_remote_url(i)
|
437
|
+
end; alias set_this_host set_remote_url # === set_this_host
|
438
|
+
alias set_host set_remote_url # === set_host
|
439
|
+
alias set_url set_remote_url # === set_url
|
440
|
+
alias host= set_remote_url # === host=
|
441
|
+
alias url= set_remote_url # === url=
|
442
|
+
alias set_remote_host set_remote_url # === set_remote_host
|
443
|
+
|
444
|
+
# ========================================================================= #
|
445
|
+
# === show_host_user_name_port_and_password
|
446
|
+
#
|
447
|
+
# Inform us about the basic settings.
|
448
|
+
# ========================================================================= #
|
449
|
+
def show_host_user_name_port_and_password(
|
450
|
+
do_use_spacer_around_the_output = true
|
451
|
+
)
|
452
|
+
ljust = 15
|
453
|
+
e if do_use_spacer_around_the_output
|
454
|
+
e ('Host: ' ).ljust(ljust)+sfancy(host?)
|
455
|
+
e ('User-Name: ').ljust(ljust)+sfancy(user_name?.to_s)
|
456
|
+
e ('Port: ' ).ljust(ljust)+sfancy(port?)
|
457
|
+
e ('Password: ' ).ljust(ljust)+sfancy(password?)
|
458
|
+
e if do_use_spacer_around_the_output
|
459
|
+
end
|
460
|
+
|
461
|
+
# ========================================================================= #
|
462
|
+
# === use_default_dataset
|
463
|
+
#
|
464
|
+
# This method will just take the default dataset for my FTP connections,
|
465
|
+
# hence the "File.exist?" check.
|
466
|
+
#
|
467
|
+
# Additionally we will initialize the default net-ftp object.
|
468
|
+
#
|
469
|
+
# Up to 20.07.2022 we also automatically tried to log in, but since
|
470
|
+
# that day we no longer do this.
|
471
|
+
# ========================================================================= #
|
472
|
+
def use_default_dataset(
|
473
|
+
i = :default # ← This is the default.
|
474
|
+
)
|
475
|
+
if File.exist? FILE_ROEBE_FTP
|
476
|
+
dataset = YAML.load_file(FILE_ROEBE_FTP)
|
477
|
+
# ===================================================================== #
|
478
|
+
# Set remote-url, username and password through the following method:
|
479
|
+
# ===================================================================== #
|
480
|
+
FtpParadise.determine_user_dataset_from_this_hash(dataset, i)
|
481
|
+
# do_login
|
482
|
+
end
|
483
|
+
end
|
484
|
+
|
485
|
+
# ========================================================================= #
|
486
|
+
# === show_full_names?
|
487
|
+
# ========================================================================= #
|
488
|
+
def show_full_names?
|
489
|
+
@internal_hash[:show_full_names]
|
490
|
+
end
|
491
|
+
|
492
|
+
# ========================================================================= #
|
493
|
+
# === show_remote_listing
|
494
|
+
#
|
495
|
+
# Use this method whenever you want to show the remote entries.
|
496
|
+
#
|
497
|
+
# As of June 2016, you can pass in your own dataset into this method
|
498
|
+
# as well. It must conform to the Array with the four entries, which
|
499
|
+
# is also returned via the method sanitized_remote_directory_content?.
|
500
|
+
# ========================================================================= #
|
501
|
+
def show_remote_listing(
|
502
|
+
dataset = sanitized_remote_directory_content?,
|
503
|
+
be_verbose = be_verbose?
|
504
|
+
)
|
505
|
+
n_rjust = 10
|
506
|
+
_ = dataset
|
507
|
+
if show_full_names?
|
508
|
+
_.map! {|entry|
|
509
|
+
filename = entry[0]
|
510
|
+
entry[0] = remote_pwd?+filename # This is the file size.
|
511
|
+
entry
|
512
|
+
}
|
513
|
+
end
|
514
|
+
_.each_with_index { |array, index|
|
515
|
+
if be_verbose # Display only when in verbose mode, which is the default.
|
516
|
+
file_or_directory = array[1]
|
517
|
+
name_of_the_file = array.first
|
518
|
+
# =================================================================== #
|
519
|
+
# Get a pointer to the filesize as well.
|
520
|
+
# =================================================================== #
|
521
|
+
filesize = array[2].to_s.rjust(n_rjust)
|
522
|
+
if file_or_directory == 'directory'
|
523
|
+
name_of_the_file << '/' unless name_of_the_file.end_with? '/'
|
524
|
+
end
|
525
|
+
# =================================================================== #
|
526
|
+
# === Put a proper padding to the index
|
527
|
+
# =================================================================== #
|
528
|
+
new_index = (index+1).to_s.rjust(_.size.to_s.size)
|
529
|
+
n_pad = 125
|
530
|
+
case file_or_directory
|
531
|
+
when 'directory' # Display for directories.
|
532
|
+
name_of_the_file = sdir(name_of_the_file)
|
533
|
+
e (padding?+sdir(new_index+') ')+name_of_the_file).ljust(n_pad)+' '+
|
534
|
+
filesize
|
535
|
+
else
|
536
|
+
e (padding?+sfancy(new_index+') ')+sfancy(name_of_the_file)).ljust(n_pad)+' '+
|
537
|
+
filesize
|
538
|
+
end
|
539
|
+
end
|
540
|
+
}
|
541
|
+
end; alias show_file_listing show_remote_listing # === show_file_listing
|
542
|
+
alias show_remote_file_listing show_remote_listing # === show_remote_file_listing
|
543
|
+
|
544
|
+
# ========================================================================= #
|
545
|
+
# === show_remote_directories
|
546
|
+
# ========================================================================= #
|
547
|
+
def show_remote_directories
|
548
|
+
show_remote_directory_listing :default, :show_only_directories
|
549
|
+
end
|
550
|
+
|
551
|
+
# ========================================================================= #
|
552
|
+
# === show_full_names=
|
553
|
+
# ========================================================================= #
|
554
|
+
def show_full_names=(i = true)
|
555
|
+
@internal_hash[:show_full_names] = i
|
556
|
+
end; alias show_full_names show_full_names= # === show_full_names
|
557
|
+
|
558
|
+
# ========================================================================= #
|
559
|
+
# === show_user_and_password
|
560
|
+
# ========================================================================= #
|
561
|
+
def show_user_and_password
|
562
|
+
ljust = 12
|
563
|
+
e
|
564
|
+
e ('User-Name: ').ljust(ljust)+sfancy(user_name?.to_s)
|
565
|
+
e ('Password: ' ).ljust(ljust)+sfancy(password?)
|
566
|
+
e
|
567
|
+
end; alias show_user_name_and_password show_user_and_password # === show_user_name_and_password
|
568
|
+
|
569
|
+
# ========================================================================= #
|
570
|
+
# === sync_ftp_object_onto_the_main_namespace
|
571
|
+
#
|
572
|
+
# Invoke this method only after having made sure that ftp_object?
|
573
|
+
# returns a non-nil object.
|
574
|
+
# ========================================================================= #
|
575
|
+
def sync_ftp_object_onto_the_main_namespace
|
576
|
+
::FtpParadise.ftp_object = self
|
577
|
+
end
|
578
|
+
|
579
|
+
# ========================================================================= #
|
580
|
+
# === upload_binary_file
|
581
|
+
#
|
582
|
+
# Use this method to upload a binary file to a remote host.
|
583
|
+
#
|
584
|
+
# The first argument `i` is the file that we wish to upload.
|
585
|
+
#
|
586
|
+
# The method will make use of the method .putbinaryfile().
|
587
|
+
#
|
588
|
+
# Documentation for that file can be found here:
|
589
|
+
#
|
590
|
+
# https://ruby-doc.org/stdlib/libdoc/net/ftp/rdoc/Net/FTP.html#method-i-putbinaryfile
|
591
|
+
#
|
592
|
+
# ========================================================================= #
|
593
|
+
def upload_binary_file(
|
594
|
+
i,
|
595
|
+
be_verbose = be_verbose?
|
596
|
+
)
|
597
|
+
be_verbose = false if be_verbose == :be_silent
|
598
|
+
if i.is_a? Array
|
599
|
+
i.each {|entry| upload_binary_file(entry, be_verbose) }
|
600
|
+
else
|
601
|
+
i = i.strip.delete(N) # Added Feb 2014.
|
602
|
+
if be_verbose
|
603
|
+
notify_the_user_about(i, __method__)
|
604
|
+
end
|
605
|
+
begin
|
606
|
+
# =================================================================== #
|
607
|
+
# Next we will delegate towards the @ftp_object:
|
608
|
+
# =================================================================== #
|
609
|
+
ftp_object?.putbinaryfile(i) # We will use the method .putbinaryfile()
|
610
|
+
@internal_hash[:uploaded_these_files] << i
|
611
|
+
if be_verbose
|
612
|
+
remote_path = rds(remote_path?+'/'+File.basename(i))
|
613
|
+
e 'Done uploading! The remote path is: '
|
614
|
+
e " #{simp(remote_path)}"
|
615
|
+
report_finished_uploading_of_this_file(i)
|
616
|
+
end
|
617
|
+
rescue Exception => error
|
618
|
+
e 'An error happened as we tried to use the method '+simp('upload_binary()')+'.'
|
619
|
+
e 'The method we used was: '+simp('ftp?.putbinaryfile(i)')
|
620
|
+
e 'We will feedback this error now (of class '+sfancy(error.class.to_s)+'):'
|
621
|
+
pp error
|
622
|
+
end
|
623
|
+
end
|
624
|
+
end; alias upload_binary upload_binary_file # === upload_binary
|
625
|
+
alias upload_this_binary_file upload_binary_file # === upload_this_binary_file()
|
626
|
+
|
627
|
+
# ========================================================================= #
|
628
|
+
# === upload_file
|
629
|
+
#
|
630
|
+
# This method will distinguish between a binary file or a text file,
|
631
|
+
# based on the transfer mode in use. The default is to work on a
|
632
|
+
# text file.
|
633
|
+
# ========================================================================= #
|
634
|
+
def upload_file(
|
635
|
+
i,
|
636
|
+
be_verbose = be_verbose?
|
637
|
+
)
|
638
|
+
if File.exist? i
|
639
|
+
case transfer_mode?
|
640
|
+
# ===================================================================== #
|
641
|
+
# === :ascii
|
642
|
+
# ===================================================================== #
|
643
|
+
when :ascii,
|
644
|
+
:text,
|
645
|
+
:default
|
646
|
+
upload_this_text_file(i, be_verbose)
|
647
|
+
# ===================================================================== #
|
648
|
+
# === :binary
|
649
|
+
# ===================================================================== #
|
650
|
+
when :binary
|
651
|
+
upload_this_binary_file(i, be_verbose)
|
652
|
+
end
|
653
|
+
update_raw_listing(:be_quiet)
|
654
|
+
else
|
655
|
+
opnn; e "No file called `#{sfile(i)}` appears to exist locally."
|
656
|
+
end
|
657
|
+
end; alias upload_this_file upload_file # === upload_this_file
|
658
|
+
|
659
|
+
# ========================================================================= #
|
660
|
+
# === set_array_available_hosts
|
661
|
+
#
|
662
|
+
# Use this method if you wish to define the available hosts. This is
|
663
|
+
# useful whenever you already have some pre-defined hosts that you wish
|
664
|
+
# to use.
|
665
|
+
# ========================================================================= #
|
666
|
+
def set_array_available_hosts(i = nil)
|
667
|
+
i = [i].flatten.compact
|
668
|
+
@internal_hash[:array_available_hosts] = i
|
669
|
+
end
|
670
|
+
|
671
|
+
# ========================================================================= #
|
672
|
+
# === set_input
|
673
|
+
# ========================================================================= #
|
674
|
+
def set_input(i)
|
675
|
+
if is_a? Symbol
|
676
|
+
i = '' # For now all Symbols are ignored here.
|
677
|
+
end
|
678
|
+
@input = i
|
679
|
+
end
|
680
|
+
|
681
|
+
# ========================================================================= #
|
682
|
+
# === set_username
|
683
|
+
#
|
684
|
+
# Set the username that you wish to use here. If the input is nil, a
|
685
|
+
# default name will be used instead.
|
686
|
+
# ========================================================================= #
|
687
|
+
def set_username(
|
688
|
+
i = DEFAULT_USER_NAME
|
689
|
+
)
|
690
|
+
i = i.first if i.is_a? Array
|
691
|
+
i = DEFAULT_USER_NAME if i.nil?
|
692
|
+
# ======================================================================= #
|
693
|
+
# The username will be stored on the toplevel-module.
|
694
|
+
# ======================================================================= #
|
695
|
+
FtpParadise.set_username(i)
|
696
|
+
end; alias set_user_name set_username # === set_user_name
|
697
|
+
alias login_name= set_username # === login_name?
|
698
|
+
alias set_name set_username # === set_name
|
699
|
+
alias set_user set_username # === set_user
|
700
|
+
alias set_login_name set_username # === set_login_name
|
701
|
+
alias user_name= set_username # === user_name?
|
702
|
+
|
703
|
+
# ========================================================================= #
|
704
|
+
# === username?
|
705
|
+
# ========================================================================= #
|
706
|
+
def username?
|
707
|
+
FtpParadise.username?.to_s
|
708
|
+
end; alias user_name? username? # === user_name?
|
709
|
+
|
710
|
+
# ========================================================================= #
|
711
|
+
# === download_remote_file (download tag)
|
712
|
+
#
|
713
|
+
# Use this method to download a remote file. If you are sure to have
|
714
|
+
# a binary file, the method download_binary_file() could be used
|
715
|
+
# instead.
|
716
|
+
#
|
717
|
+
# gettextfile(remotefile, localfile = File.basename(remotefile)) {|line| ...}
|
718
|
+
# ========================================================================= #
|
719
|
+
def download_remote_file(
|
720
|
+
i, be_verbose = be_verbose?
|
721
|
+
)
|
722
|
+
if i.is_a? Array # Handle arrays first.
|
723
|
+
i.each {|entry| download_remote_file(entry, be_verbose) }
|
724
|
+
else
|
725
|
+
if i =~ /^\d+$/ # if is a number
|
726
|
+
update_file_listing
|
727
|
+
i = return_remote_files[i.to_i - 1].first
|
728
|
+
end
|
729
|
+
if i == '*' # Here we want to download all files, as we passed in '*'.
|
730
|
+
i = []
|
731
|
+
update_file_listing
|
732
|
+
return_remote_files.each { |a,b| i << FtpParadise.rds(a) }
|
733
|
+
end
|
734
|
+
if be_verbose
|
735
|
+
notify_the_user_about(i, __method__)
|
736
|
+
end
|
737
|
+
set_file(i) # This assigns to @internal_hash[:file].
|
738
|
+
begin # We can use @file because we called set_file() before.
|
739
|
+
ftp_object?.gettextfile(file?)
|
740
|
+
basename = File.basename(file?)
|
741
|
+
e "Finished downloading `#{sandybrown(file?)}`"
|
742
|
+
e 'into `'+sdir(rds(Dir.pwd+'/'+basename))+'`.'
|
743
|
+
return file?
|
744
|
+
rescue Net::FTPPermError => error
|
745
|
+
pp error
|
746
|
+
e 'An exception occurred in the method '+sfancy('download()')+'.'
|
747
|
+
e 'The error was a '+sfancy('Permission Error')+', the input '\
|
748
|
+
'to the method was: `'+simp(i)+'`.'
|
749
|
+
e 'Is the file that you are trying to download really '\
|
750
|
+
'existing on the remote server?'
|
751
|
+
return false
|
752
|
+
end
|
753
|
+
end
|
754
|
+
end; alias download download_remote_file # === download
|
755
|
+
alias download_this_remote_file download_remote_file # === download_this_remote_file
|
756
|
+
alias download_this_file download_remote_file # === download_this_file
|
757
|
+
|
758
|
+
# ========================================================================= #
|
759
|
+
# === create_remote_file (touch tag)
|
760
|
+
#
|
761
|
+
# This "touches" a remote file.
|
762
|
+
# ========================================================================= #
|
763
|
+
def create_remote_file(
|
764
|
+
i,
|
765
|
+
be_verbose = be_verbose?
|
766
|
+
)
|
767
|
+
if i.is_a? Array
|
768
|
+
i.each {|entry| create_remote_file(entry, be_verbose) }
|
769
|
+
else
|
770
|
+
FileUtils.touch(i)
|
771
|
+
if be_verbose
|
772
|
+
notify_the_user_about(i, __method__)
|
773
|
+
end
|
774
|
+
upload_this_text_file(i, :be_quiet)
|
775
|
+
File.delete(i) if File.zero? i # And get rid of that file too.
|
776
|
+
end
|
777
|
+
end; alias touch create_remote_file # === touch
|
778
|
+
|
779
|
+
# ========================================================================= #
|
780
|
+
# === fancy_remote_listing
|
781
|
+
#
|
782
|
+
# This method will obtain the (remote) directory listing and then
|
783
|
+
# display it.
|
784
|
+
# ========================================================================= #
|
785
|
+
def fancy_remote_listing(
|
786
|
+
be_verbose = be_verbose?
|
787
|
+
)
|
788
|
+
update_file_listing
|
789
|
+
case be_verbose
|
790
|
+
when :be_silent,
|
791
|
+
:be_quiet
|
792
|
+
be_verbose = false
|
793
|
+
when :also_show_filesize
|
794
|
+
be_verbose = true
|
795
|
+
end
|
796
|
+
if be_verbose
|
797
|
+
e ('=' * 55)+' '+
|
798
|
+
FtpParadise.yellow('REMOTE FILES')+' '+('=' * 12)
|
799
|
+
if remote_directory_is_empty?
|
800
|
+
e "Remote `#{sdir(remote_path?)}` is empty."
|
801
|
+
e 'No files or directories can be found therein.'
|
802
|
+
else
|
803
|
+
e 'Remote content of `'+sdir(remote_path?)+'` is:'+N+N
|
804
|
+
e 'Index Filename '\
|
805
|
+
' Filesize'
|
806
|
+
show_remote_file_listing
|
807
|
+
end
|
808
|
+
cliner
|
809
|
+
end
|
810
|
+
return remote_directory_content
|
811
|
+
end
|
812
|
+
|
813
|
+
# ========================================================================= #
|
814
|
+
# === rename
|
815
|
+
#
|
816
|
+
# This method will attempt to rename a file on the remote server.
|
817
|
+
#
|
818
|
+
# Note that this is equivalent to moving a file, which is why the alias
|
819
|
+
# move_file can also be used. Any move-file actioni s simply a rename()
|
820
|
+
# action.
|
821
|
+
#
|
822
|
+
# The first argument passed to this method should be the name of an
|
823
|
+
# existing (remote) file. The second second argument should be the
|
824
|
+
# new name of that file, or its full (remote) path.
|
825
|
+
#
|
826
|
+
# Also note that it seems as if the FTP protocol requires the full
|
827
|
+
# target location, otherwise errors such as the following might
|
828
|
+
# happen:
|
829
|
+
#
|
830
|
+
# ftp.rb in `getresp': 451 Rename/move failure: Is a directory (Net::FTPTempError)
|
831
|
+
#
|
832
|
+
# The command used by .rename() command should be equivalent to this code:
|
833
|
+
#
|
834
|
+
# SITE mv oldpath newpath
|
835
|
+
#
|
836
|
+
# Documentation for the functionality can be found here:
|
837
|
+
#
|
838
|
+
# http://ruby-doc.org/stdlib/libdoc/net/ftp/rdoc/Net/FTP.html#method-i-rename
|
839
|
+
#
|
840
|
+
# ========================================================================= #
|
841
|
+
def rename(
|
842
|
+
from,
|
843
|
+
to,
|
844
|
+
be_verbose = be_verbose?
|
845
|
+
)
|
846
|
+
to = to.first if to.is_a? Array
|
847
|
+
if from.is_a? Array # Support batch-transfer.
|
848
|
+
from.each {|entry| rename(entry, to) }
|
849
|
+
else
|
850
|
+
from = rds(from)
|
851
|
+
to = rds(to)
|
852
|
+
begin
|
853
|
+
ftp_object?.rename(from, to)
|
854
|
+
if be_verbose
|
855
|
+
opnn; e "Renamed the remote entry `#{sfancy(from)}"\
|
856
|
+
"` to `#{sfancy(to)}`."
|
857
|
+
end
|
858
|
+
rescue Net::FTPTempError => error
|
859
|
+
e "An error (#{simp('Net::FTPTempError')}) occurred "\
|
860
|
+
"in the method #{simp('rename()')}:"
|
861
|
+
pp error
|
862
|
+
end
|
863
|
+
end
|
864
|
+
end; alias rename_file rename # === rename_file
|
865
|
+
alias move_file rename # === move_file
|
866
|
+
alias rename_remote_file rename # === rename_remote_file
|
867
|
+
|
868
|
+
# ========================================================================= #
|
869
|
+
# === update_remote_file_listing
|
870
|
+
# ========================================================================= #
|
871
|
+
def update_remote_file_listing(
|
872
|
+
be_verbose = be_verbose?
|
873
|
+
)
|
874
|
+
case be_verbose
|
875
|
+
when :be_quiet
|
876
|
+
be_verbose = false
|
877
|
+
end
|
878
|
+
if is_connected?
|
879
|
+
begin
|
880
|
+
# =================================================================== #
|
881
|
+
# Make use of a method that will skip a few entries, such as
|
882
|
+
# "." or "..".
|
883
|
+
# =================================================================== #
|
884
|
+
@internal_hash[:raw_entries] = return_slightly_sanitized_entries_ignoring_a_few
|
885
|
+
rescue Exception => error
|
886
|
+
opnn; e swarn('An error happened in the method '\
|
887
|
+
'update_remote_file_listing(), at '\
|
888
|
+
'line: '+__LINE__.to_s+'.')
|
889
|
+
pp error.class
|
890
|
+
pp error
|
891
|
+
end
|
892
|
+
else
|
893
|
+
if be_verbose
|
894
|
+
opnn; e 'Can not update the remote file listing '\
|
895
|
+
'because we are not connected.'
|
896
|
+
end
|
897
|
+
end
|
898
|
+
end; alias update_file_listing update_remote_file_listing # === update_file_listing
|
899
|
+
alias update_raw_listing update_remote_file_listing # === update_raw_listing
|
900
|
+
alias get_listing update_remote_file_listing # === get_listing
|
901
|
+
alias get_remote_listing update_remote_file_listing # === get_remote_listing
|
902
|
+
alias update update_remote_file_listing # === update
|
903
|
+
|
904
|
+
# ========================================================================= #
|
905
|
+
# === does_this_remote_file_exist?
|
906
|
+
# ========================================================================= #
|
907
|
+
def does_this_remote_file_exist?(i)
|
908
|
+
i = File.basename(i).strip
|
909
|
+
array = return_all_remote_files
|
910
|
+
if array.is_a?(Array) and
|
911
|
+
array.first.is_a?(String)
|
912
|
+
array.map! {|entry|
|
913
|
+
entry = FtpParadise::Entry.new(entry)
|
914
|
+
}
|
915
|
+
array.select! {|entry| entry.is_a_file? }
|
916
|
+
array.map! {|entry| entry.filename? }
|
917
|
+
end
|
918
|
+
return array.include?(i)
|
919
|
+
end
|
920
|
+
|
921
|
+
# ========================================================================= #
|
922
|
+
# === show_remote_directory_listing
|
923
|
+
#
|
924
|
+
# This will simply show the content of a remote directory.
|
925
|
+
#
|
926
|
+
# Invocation examples:
|
927
|
+
#
|
928
|
+
# show_remote_directory_listing
|
929
|
+
# show_remote_directory_listing :default, :show_only_directories
|
930
|
+
#
|
931
|
+
# ========================================================================= #
|
932
|
+
def show_remote_directory_listing(
|
933
|
+
i = list,
|
934
|
+
array_options = []
|
935
|
+
)
|
936
|
+
unless array_options.is_a? Array
|
937
|
+
array_options = [array_options]
|
938
|
+
end
|
939
|
+
case i
|
940
|
+
when :default
|
941
|
+
i = list
|
942
|
+
end
|
943
|
+
if i.is_a? Array
|
944
|
+
# ===================================================================== #
|
945
|
+
# Get rid of '.' and '..'.
|
946
|
+
# ===================================================================== #
|
947
|
+
i.reject! {|entry| entry.end_with?('..') or entry.end_with?('.') }
|
948
|
+
# ===================================================================== #
|
949
|
+
# First, turn them into entries.
|
950
|
+
# ===================================================================== #
|
951
|
+
i.map! {|entry| FtpParadise::Entry.new(entry) }
|
952
|
+
# ===================================================================== #
|
953
|
+
# Next, we can use different behaviours.
|
954
|
+
# ===================================================================== #
|
955
|
+
if array_options.include? :show_only_directories
|
956
|
+
i.select! {|entry| entry.is_a_directory? }
|
957
|
+
end
|
958
|
+
i.each {|entry| entry.show_the_line }
|
959
|
+
end
|
960
|
+
end; alias show_remote_files show_remote_directory_listing # === show_remote_files
|
961
|
+
|
962
|
+
# ========================================================================= #
|
963
|
+
# === upload (upload tag)
|
964
|
+
#
|
965
|
+
# This method can upload binary files, text files and whole directories.
|
966
|
+
# Based on that check, the method body will behave differently, and
|
967
|
+
# delegate to other methods such as upload_directory() or upload_file().
|
968
|
+
#
|
969
|
+
# A single file (as String) can be uploaded, or an Array of files. The
|
970
|
+
# upload activity will transfer the file or the files onto the remote host.
|
971
|
+
#
|
972
|
+
# The second argument specifies whether the method will be verbose and
|
973
|
+
# report back to the user, or whether the method will be quiet,
|
974
|
+
# defaulting to the return value of the method `be_verbose?`.
|
975
|
+
# ========================================================================= #
|
976
|
+
def upload(
|
977
|
+
i,
|
978
|
+
be_verbose = be_verbose?
|
979
|
+
)
|
980
|
+
be_verbose = false if be_verbose == :be_silent
|
981
|
+
if i.is_a? Array
|
982
|
+
i.each {|entry| upload(entry, be_verbose) }
|
983
|
+
else
|
984
|
+
if i == '*' # Here we want to upload all files.
|
985
|
+
i = get_all_local_files
|
986
|
+
upload(i, be_verbose)
|
987
|
+
else
|
988
|
+
# =================================================================== #
|
989
|
+
# === Handle upload of directories first
|
990
|
+
# =================================================================== #
|
991
|
+
if File.directory? i
|
992
|
+
upload_directory(i, be_verbose)
|
993
|
+
# =================================================================== #
|
994
|
+
# === Handle uploading of files next
|
995
|
+
# =================================================================== #
|
996
|
+
else
|
997
|
+
upload_file(i, be_verbose)
|
998
|
+
end
|
999
|
+
end
|
1000
|
+
end
|
1001
|
+
end
|
1002
|
+
|
1003
|
+
# ========================================================================= #
|
1004
|
+
# === uploaded_these_files?
|
1005
|
+
# ========================================================================= #
|
1006
|
+
def uploaded_these_files?
|
1007
|
+
@internal_hash[:uploaded_these_files]
|
1008
|
+
end
|
1009
|
+
|
1010
|
+
# ========================================================================= #
|
1011
|
+
# === list? (list tag)
|
1012
|
+
#
|
1013
|
+
# Returns an array of file information in the directory (the output
|
1014
|
+
# is like `ls -l`). If a block is given, it iterates through the
|
1015
|
+
# listing.
|
1016
|
+
# ========================================================================= #
|
1017
|
+
def list?(i = '*')
|
1018
|
+
# ======================================================================= #
|
1019
|
+
# We will also sanitize this a bit.
|
1020
|
+
# ======================================================================= #
|
1021
|
+
@internal_hash[:raw_entries] = return_slightly_sanitized_entries_ignoring_a_few
|
1022
|
+
return @internal_hash[:raw_entries] # And return the result here.
|
1023
|
+
end; alias ls list? # === ls
|
1024
|
+
alias populate_raw_entries list? # === populate_raw_entries
|
1025
|
+
|
1026
|
+
# ========================================================================= #
|
1027
|
+
# === list_content (list tag, ls tag)
|
1028
|
+
#
|
1029
|
+
# List available data.
|
1030
|
+
# ========================================================================= #
|
1031
|
+
def list_content
|
1032
|
+
report_current_remote_dir
|
1033
|
+
result = list?
|
1034
|
+
cliner { pp result }
|
1035
|
+
_ = result.first[0, 1]
|
1036
|
+
case _
|
1037
|
+
when 'd'
|
1038
|
+
e "Directory #{result.first}"
|
1039
|
+
# @array_directories
|
1040
|
+
when 'l'
|
1041
|
+
e "Link #{result.first}"
|
1042
|
+
else
|
1043
|
+
e "File #{result.first}"
|
1044
|
+
end
|
1045
|
+
end; alias do_list_content list_content # === list
|
1046
|
+
alias listing? list_content # === listing?
|
1047
|
+
|
1048
|
+
# ========================================================================= #
|
1049
|
+
# === file_listing_as_entries?
|
1050
|
+
# ========================================================================= #
|
1051
|
+
def file_listing_as_entries?
|
1052
|
+
_ = remote_file_listing?
|
1053
|
+
if _
|
1054
|
+
return _.map {|entry| FtpParadise::Entry.new(entry) }
|
1055
|
+
end
|
1056
|
+
return nil
|
1057
|
+
end
|
1058
|
+
|
1059
|
+
# ========================================================================= #
|
1060
|
+
# === closed?
|
1061
|
+
#
|
1062
|
+
# Returns true if the connection to our remote host is closed.
|
1063
|
+
# ========================================================================= #
|
1064
|
+
def closed?
|
1065
|
+
begin
|
1066
|
+
ftp_object?.closed? if ftp_object?
|
1067
|
+
rescue Net::FTPConnectionError
|
1068
|
+
true
|
1069
|
+
end
|
1070
|
+
end
|
1071
|
+
|
1072
|
+
# ========================================================================= #
|
1073
|
+
# === dataset?
|
1074
|
+
# ========================================================================= #
|
1075
|
+
def dataset?
|
1076
|
+
FtpParadise.data?
|
1077
|
+
end
|
1078
|
+
|
1079
|
+
# ========================================================================= #
|
1080
|
+
# === return_slightly_sanitized_entries_ignoring_a_few
|
1081
|
+
# ========================================================================= #
|
1082
|
+
def return_slightly_sanitized_entries_ignoring_a_few(
|
1083
|
+
i = '*'
|
1084
|
+
)
|
1085
|
+
ftp_object?.list(i).reject {|entry|
|
1086
|
+
entry.to_s.strip.empty? or entry.end_with?(' .') or entry.end_with?(' ..')
|
1087
|
+
}.map {|line|
|
1088
|
+
if line.end_with? ':' # <- Some remote FTP-hosts use ':' for a directory.
|
1089
|
+
line[-1,1] = '/'
|
1090
|
+
end
|
1091
|
+
line
|
1092
|
+
}
|
1093
|
+
end; alias list return_slightly_sanitized_entries_ignoring_a_few # === list
|
1094
|
+
|
1095
|
+
# ========================================================================= #
|
1096
|
+
# === populate_internal_hash_with_default_values
|
1097
|
+
# ========================================================================= #
|
1098
|
+
def populate_internal_hash_with_default_values
|
1099
|
+
# ======================================================================= #
|
1100
|
+
# === @internal_hash
|
1101
|
+
# ======================================================================= #
|
1102
|
+
@internal_hash = {}
|
1103
|
+
# ======================================================================= #
|
1104
|
+
# === :transfer_mode
|
1105
|
+
# ======================================================================= #
|
1106
|
+
@internal_hash[:transfer_mode] = :binary
|
1107
|
+
# ======================================================================= #
|
1108
|
+
# === :port
|
1109
|
+
#
|
1110
|
+
# The internal Hash keeps track of some configure-settings and slots
|
1111
|
+
# to be used that are of relevance to this class.
|
1112
|
+
# ======================================================================= #
|
1113
|
+
@internal_hash[:port] = nil # Has to be nil initially.
|
1114
|
+
# ======================================================================= #
|
1115
|
+
# === :be_verbose
|
1116
|
+
# ======================================================================= #
|
1117
|
+
@internal_hash[:be_verbose] = nil
|
1118
|
+
# ======================================================================= #
|
1119
|
+
# === :raw_entries
|
1120
|
+
# ======================================================================= #
|
1121
|
+
@internal_hash[:raw_entries] = nil
|
1122
|
+
@internal_hash[:file] = nil
|
1123
|
+
@internal_hash[:show_full_names] = false # Is false on startup.
|
1124
|
+
@internal_hash[:debug] = false
|
1125
|
+
# ======================================================================= #
|
1126
|
+
# === :array_available_hosts
|
1127
|
+
# ======================================================================= #
|
1128
|
+
@internal_hash[:array_available_hosts] = []
|
1129
|
+
# ======================================================================= #
|
1130
|
+
# === :padding
|
1131
|
+
# ======================================================================= #
|
1132
|
+
@internal_hash[:padding] = ' ' # This padding value is used for remote directory listing.
|
1133
|
+
# ======================================================================= #
|
1134
|
+
# The following Array keeps track over the files that were uploaded
|
1135
|
+
# successfully. This gives us the possibility to query this from other
|
1136
|
+
# classes.
|
1137
|
+
# ======================================================================= #
|
1138
|
+
@internal_hash[:uploaded_these_files] = []
|
1139
|
+
end
|
1140
|
+
|
1141
|
+
# ========================================================================= #
|
1142
|
+
# === is_a_directory?
|
1143
|
+
#
|
1144
|
+
# This method queries whether the given input is a (remote) directory.
|
1145
|
+
# For this to work, the given input must obviously exist as file or
|
1146
|
+
# directory.
|
1147
|
+
# ========================================================================= #
|
1148
|
+
def is_a_directory?(i)
|
1149
|
+
update_file_listing
|
1150
|
+
candidates = file_listing_as_entries?.select {|entry|
|
1151
|
+
entry.is_a_directory?
|
1152
|
+
}.map(&:last)
|
1153
|
+
candidates.include? i
|
1154
|
+
end; alias is_directory? is_a_directory? # === is_directory?
|
1155
|
+
alias is_a_directory? is_a_directory? # === is_a_directory?
|
1156
|
+
alias this_remote_directory_exists? is_a_directory? # === this_remote_directory_exists?
|
1157
|
+
alias is_dir? is_a_directory? # === is_dir?
|
1158
|
+
|
1159
|
+
# ========================================================================= #
|
1160
|
+
# === remote_directory_is_empty?
|
1161
|
+
#
|
1162
|
+
# This method will return a Boolean - true if the remote directory
|
1163
|
+
# is empty, and false otherwise.
|
1164
|
+
# ========================================================================= #
|
1165
|
+
def remote_directory_is_empty?
|
1166
|
+
_ = return_remote_directory_content
|
1167
|
+
_.reject! {|entry|
|
1168
|
+
(entry == '.') or (entry == '..')
|
1169
|
+
}
|
1170
|
+
_.empty?
|
1171
|
+
end
|
1172
|
+
|
1173
|
+
# ========================================================================= #
|
1174
|
+
# === create_this_remote_directory (mkdir tag)
|
1175
|
+
#
|
1176
|
+
# This method will attempt to create a remote directory.
|
1177
|
+
#
|
1178
|
+
# A Net::FTPPermError may result if the permission does not allow for
|
1179
|
+
# that action.
|
1180
|
+
# ========================================================================= #
|
1181
|
+
def create_this_remote_directory(
|
1182
|
+
i, be_verbose = be_verbose?
|
1183
|
+
)
|
1184
|
+
if i.is_a? Array
|
1185
|
+
i.each {|entry| create_this_remote_directory(entry, be_verbose) }
|
1186
|
+
else
|
1187
|
+
i = rds(i+'/')
|
1188
|
+
if be_verbose
|
1189
|
+
notify_the_user_about(i, __method__)
|
1190
|
+
if is_directory?(i)
|
1191
|
+
opnn; e swarn('Warning - the remote directory ')+
|
1192
|
+
sdir(i)+swarn(' already exists.')
|
1193
|
+
opnn; e swarn('We thus can not create a new directory.')
|
1194
|
+
end
|
1195
|
+
end
|
1196
|
+
begin
|
1197
|
+
ftp_object?.mkdir(i)
|
1198
|
+
rescue Net::FTPConnectionError
|
1199
|
+
opnn; e 'Not connected - is the network down/available?'
|
1200
|
+
rescue Net::FTPPermError
|
1201
|
+
opnn; e "Net::FTPPermError: Can not create the remote "\
|
1202
|
+
"directory `#{remote_path?}#{sdir(i)}`"
|
1203
|
+
opnn; e 'as it - or a file with the same name - already exists.'
|
1204
|
+
end
|
1205
|
+
end
|
1206
|
+
end; alias mkdir create_this_remote_directory # === mkdir
|
1207
|
+
alias rmkdir create_this_remote_directory # === rmkdir
|
1208
|
+
alias remote_mkdir create_this_remote_directory # === remote_mkdir
|
1209
|
+
alias create_directory create_this_remote_directory # === create_directory
|
1210
|
+
alias create_these_remote_directories create_this_remote_directory # === create_these_remote_directories
|
1211
|
+
alias remote_create_directory create_this_remote_directory # === remote_create_directory
|
1212
|
+
alias create_remote_directory create_this_remote_directory # === create_remote_directory
|
1213
|
+
|
1214
|
+
# ========================================================================= #
|
1215
|
+
# === sanitize_remote_directory_content
|
1216
|
+
#
|
1217
|
+
# The purpose of this method is to clean up the remote dataset.
|
1218
|
+
#
|
1219
|
+
# Keep in mind that the output comes in something like:
|
1220
|
+
#
|
1221
|
+
# "-rw-rw-rw- 1 web netscape 6820 May 30 2011 AppendToCookbook.rb"
|
1222
|
+
# "drwxrwxrwx 2 web netscape 8192 Oct 29 2007 CSS"
|
1223
|
+
# "-rw-rw-rw- 1 web netscape 10548 May 30 2011 Chained.rb"
|
1224
|
+
# "-rw-r--r-- 1 330 330 237904 Jun 9 14:24 11.03.2003_UniWien_Biologie_EinfuehrungInDieMikrobiologie.jpg",
|
1225
|
+
#
|
1226
|
+
# This should contain all the information that is needed.
|
1227
|
+
# ========================================================================= #
|
1228
|
+
def sanitize_remote_directory_content
|
1229
|
+
_ = []
|
1230
|
+
raw_entries?.each { |e|
|
1231
|
+
next if e.empty?
|
1232
|
+
entry = FtpParadise::Entry.new(e)
|
1233
|
+
filesize = entry.filesize?
|
1234
|
+
timestamp = entry.parsed_timestamp?
|
1235
|
+
# ===================================================================== #
|
1236
|
+
# === Exclude 3 entries next
|
1237
|
+
# ===================================================================== #
|
1238
|
+
next if e.include? 'total' or
|
1239
|
+
entry.name? == '.' or
|
1240
|
+
entry.name? == '..' # Batch next.
|
1241
|
+
# ===================================================================== #
|
1242
|
+
# === Build up the final Array
|
1243
|
+
#
|
1244
|
+
# Our Array will have four entries:
|
1245
|
+
#
|
1246
|
+
# (1) Filename
|
1247
|
+
# (2) File or Directory (String)
|
1248
|
+
# (3) Filesize
|
1249
|
+
# (4) Timestamp
|
1250
|
+
#
|
1251
|
+
# ===================================================================== #
|
1252
|
+
_ << [ rds(entry.filename?), entry.file_or_directory, filesize, timestamp ]
|
1253
|
+
}
|
1254
|
+
@internal_hash[:sanitized_remote_directory_content] = _ #.compact
|
1255
|
+
end
|
1256
|
+
|
1257
|
+
# ========================================================================= #
|
1258
|
+
# === sanitized_remote_directory_content?
|
1259
|
+
# ========================================================================= #
|
1260
|
+
def sanitized_remote_directory_content?
|
1261
|
+
update_remote_file_listing
|
1262
|
+
sanitize_remote_directory_content
|
1263
|
+
@internal_hash[:sanitized_remote_directory_content]
|
1264
|
+
end
|
1265
|
+
|
1266
|
+
# ========================================================================= #
|
1267
|
+
# === download_binary_file
|
1268
|
+
#
|
1269
|
+
# Use this method to download a binary file, by calling the method
|
1270
|
+
# getbinaryfile(). You can download as many files as you want to
|
1271
|
+
# through this method, but we expect this method to be a binary
|
1272
|
+
# file.
|
1273
|
+
#
|
1274
|
+
# Specific usage example:
|
1275
|
+
#
|
1276
|
+
# ftp?.download_binary_file('photos_2009-03-29.zip', 'ftp_photos/photos.zip')
|
1277
|
+
#
|
1278
|
+
# ========================================================================= #
|
1279
|
+
def download_binary_file(
|
1280
|
+
i,
|
1281
|
+
be_verbose = be_verbose?
|
1282
|
+
)
|
1283
|
+
if i.is_a? Array
|
1284
|
+
i.each {|entry| download_binary_file(entry) }
|
1285
|
+
else
|
1286
|
+
ftp?.getbinaryfile(i) # Delegate towards .getbinaryfile()
|
1287
|
+
if be_verbose
|
1288
|
+
e "Downloaded file #{sfile(i)}."
|
1289
|
+
end
|
1290
|
+
end
|
1291
|
+
end
|
1292
|
+
|
1293
|
+
# ========================================================================= #
|
1294
|
+
# === empty?
|
1295
|
+
# ========================================================================= #
|
1296
|
+
def empty?
|
1297
|
+
array_remote_files.empty?
|
1298
|
+
end
|
1299
|
+
|
1300
|
+
# ========================================================================= #
|
1301
|
+
# === find_matches_for
|
1302
|
+
#
|
1303
|
+
# This method will return an array of files and directories that match
|
1304
|
+
# to the provided input (which we will assume to be a query).
|
1305
|
+
# ========================================================================= #
|
1306
|
+
def find_matches_for(i)
|
1307
|
+
i = i.delete '*'
|
1308
|
+
update_file_listing
|
1309
|
+
_ = return_remote_directory_content.map(&:first)
|
1310
|
+
_ = _.grep(/#{i}/)
|
1311
|
+
return _
|
1312
|
+
end
|
1313
|
+
|
1314
|
+
# ========================================================================= #
|
1315
|
+
# === output_sorted_by_time
|
1316
|
+
#
|
1317
|
+
# This method will output the remote content in a time-sorted manner.
|
1318
|
+
# ========================================================================= #
|
1319
|
+
def output_sorted_by_time
|
1320
|
+
_ = sanitized_remote_directory_content?
|
1321
|
+
sorted_result = _.sort_by {|array|
|
1322
|
+
array.last
|
1323
|
+
}.reverse
|
1324
|
+
sorted_result.each_with_index {|array, index| index += 1
|
1325
|
+
file_or_directory = array[1]
|
1326
|
+
name_of_the_file = array.first
|
1327
|
+
if file_or_directory == 'directory'
|
1328
|
+
name_of_the_file << '/' unless name_of_the_file.end_with? '/'
|
1329
|
+
end
|
1330
|
+
index = simp( (index.to_s+') ').rjust(6))
|
1331
|
+
e index+sfancy(name_of_the_file)
|
1332
|
+
}
|
1333
|
+
end
|
1334
|
+
|
1335
|
+
# ========================================================================= #
|
1336
|
+
# === last_response
|
1337
|
+
#
|
1338
|
+
# The server's last response is available through this method here.
|
1339
|
+
# ========================================================================= #
|
1340
|
+
def last_response
|
1341
|
+
ftp_object?.last_response
|
1342
|
+
end; alias last_response? last_response # === last_response?
|
1343
|
+
alias last_server_response? last_response # === last_server_response?
|
1344
|
+
|
1345
|
+
# ========================================================================= #
|
1346
|
+
# === raw_entries?
|
1347
|
+
# ========================================================================= #
|
1348
|
+
def raw_entries?
|
1349
|
+
@internal_hash[:raw_entries]
|
1350
|
+
end; alias remote_file_listing? raw_entries? # === remote_file_listing?
|
1351
|
+
alias file_listing? raw_entries? # === file_listing?
|
1352
|
+
alias raw_listing? raw_entries? # === raw_listing?
|
1353
|
+
|
1354
|
+
# ========================================================================= #
|
1355
|
+
# === return_local_directories
|
1356
|
+
#
|
1357
|
+
# Return all local directories.
|
1358
|
+
# ========================================================================= #
|
1359
|
+
def return_local_directories
|
1360
|
+
Dir['*'].select {|entry| File.directory?(entry) }
|
1361
|
+
end
|
1362
|
+
|
1363
|
+
# ========================================================================= #
|
1364
|
+
# === modification_time_of?
|
1365
|
+
#
|
1366
|
+
# This method will give us the last modification time of a remote
|
1367
|
+
# file, by issuing the mdtm() command.
|
1368
|
+
#
|
1369
|
+
# The format returned will be in YYYMMDDhhmmss.
|
1370
|
+
#
|
1371
|
+
# If you require a parsed Time instance, you can use mtime()
|
1372
|
+
# on the ftp object.
|
1373
|
+
#
|
1374
|
+
# Symbols could also be used, such as "pp modification_time_of? :a".
|
1375
|
+
# ========================================================================= #
|
1376
|
+
def modification_time_of?(i)
|
1377
|
+
if i.is_a? Array
|
1378
|
+
i.each {|entry| modification_time_of(entry) } # <- Recursive call.
|
1379
|
+
else
|
1380
|
+
ftp_object?.mdtm(i.to_s)
|
1381
|
+
end
|
1382
|
+
end; alias mdtm modification_time_of? # === mdtm
|
1383
|
+
|
1384
|
+
# ========================================================================= #
|
1385
|
+
# === set_file
|
1386
|
+
#
|
1387
|
+
# Use only this to modify the @file variable.
|
1388
|
+
# ========================================================================= #
|
1389
|
+
def set_file(i = nil)
|
1390
|
+
@internal_hash[:file] = i
|
1391
|
+
end
|
1392
|
+
|
1393
|
+
# ========================================================================= #
|
1394
|
+
# === is_file?
|
1395
|
+
#
|
1396
|
+
# This method will check whether the input is a file or not.
|
1397
|
+
# It will call the method .is_directory?()
|
1398
|
+
# ========================================================================= #
|
1399
|
+
def is_file?(i)
|
1400
|
+
!is_a_directory?(i)
|
1401
|
+
end
|
1402
|
+
|
1403
|
+
# ========================================================================= #
|
1404
|
+
# === logged_in?
|
1405
|
+
# ========================================================================= #
|
1406
|
+
def logged_in?
|
1407
|
+
ftp_object?.instance_variable_get('@logged_in') and
|
1408
|
+
(ftp_object?.instance_variable_get('@logged_in') == true)
|
1409
|
+
end
|
1410
|
+
|
1411
|
+
# ========================================================================= #
|
1412
|
+
# === available_hosts?
|
1413
|
+
# ========================================================================= #
|
1414
|
+
def available_hosts?
|
1415
|
+
@internal_hash[:array_available_hosts]
|
1416
|
+
end; alias array_available_hosts available_hosts? # === array_available_hosts
|
1417
|
+
alias array_available_hosts? available_hosts? # === array_available_hosts?
|
1418
|
+
|
1419
|
+
# ========================================================================= #
|
1420
|
+
# === open_timeout?
|
1421
|
+
# ========================================================================= #
|
1422
|
+
def open_timeout?
|
1423
|
+
ftp_object?.open_timeout.to_s if ftp_object?.respond_to? :open_timeout
|
1424
|
+
end
|
1425
|
+
|
1426
|
+
# ========================================================================= #
|
1427
|
+
# === feedback_login_hosts
|
1428
|
+
#
|
1429
|
+
# Feedback all available login hosts, based on the information stored
|
1430
|
+
# in the Array @array_available_hosts.
|
1431
|
+
# ========================================================================= #
|
1432
|
+
def feedback_login_hosts
|
1433
|
+
opnn; e 'The followings hosts are easily available:'
|
1434
|
+
e
|
1435
|
+
available_hosts?.each { |host| e " - #{sfancy(host)}" }
|
1436
|
+
e
|
1437
|
+
end
|
1438
|
+
|
1439
|
+
# ========================================================================= #
|
1440
|
+
# === help?
|
1441
|
+
# ========================================================================= #
|
1442
|
+
def help?
|
1443
|
+
ftp_object?.help
|
1444
|
+
end; alias help help? # === help
|
1445
|
+
|
1446
|
+
# ========================================================================= #
|
1447
|
+
# === close (close tag)
|
1448
|
+
#
|
1449
|
+
# Close the connection here.
|
1450
|
+
#
|
1451
|
+
# Further operations will be impossible until a new connection
|
1452
|
+
# is opened up again, via connect().
|
1453
|
+
# ========================================================================= #
|
1454
|
+
def close
|
1455
|
+
ftp_object?.close
|
1456
|
+
end
|
1457
|
+
|
1458
|
+
# ========================================================================= #
|
1459
|
+
# === mlsd
|
1460
|
+
# ========================================================================= #
|
1461
|
+
def mlsd(i)
|
1462
|
+
ftp_object?.mlsd(i)
|
1463
|
+
end
|
1464
|
+
|
1465
|
+
# ========================================================================= #
|
1466
|
+
# === site
|
1467
|
+
# ========================================================================= #
|
1468
|
+
def site(i = nil)
|
1469
|
+
ftp_object?.site(i)
|
1470
|
+
end
|
1471
|
+
|
1472
|
+
# ========================================================================= #
|
1473
|
+
# === file?
|
1474
|
+
# ========================================================================= #
|
1475
|
+
def file?
|
1476
|
+
@internal_hash[:file]
|
1477
|
+
end
|
1478
|
+
|
1479
|
+
# ========================================================================= #
|
1480
|
+
# === system_command
|
1481
|
+
#
|
1482
|
+
# This will return system information from the remote host.
|
1483
|
+
#
|
1484
|
+
# Stuff like:
|
1485
|
+
# UNIX Type: L8
|
1486
|
+
# ========================================================================= #
|
1487
|
+
def system_command
|
1488
|
+
ftp_object?.system
|
1489
|
+
end; alias system system_command # === system
|
1490
|
+
|
1491
|
+
# ========================================================================= #
|
1492
|
+
# === report_host_port_user_name_and_password
|
1493
|
+
# ========================================================================= #
|
1494
|
+
def report_host_port_user_name_and_password
|
1495
|
+
ljust = 15
|
1496
|
+
e '- Now trying to log in to '+simp(host?)+
|
1497
|
+
' (Port: '+swarn(port?)+') using:'
|
1498
|
+
e ' '+('Login Name: ').ljust(ljust)+sfancy(user_name?)
|
1499
|
+
e ' '+('Password: ').ljust(ljust)+sfancy(password?)
|
1500
|
+
end
|
1501
|
+
|
1502
|
+
# ========================================================================= #
|
1503
|
+
# === opnn
|
1504
|
+
# ========================================================================= #
|
1505
|
+
def opnn
|
1506
|
+
super(NAMESPACE)
|
1507
|
+
end
|
1508
|
+
|
1509
|
+
# ========================================================================= #
|
1510
|
+
# === read_timeout=
|
1511
|
+
#
|
1512
|
+
# Setter-method for the #read_timeout attribute.
|
1513
|
+
# ========================================================================= #
|
1514
|
+
def read_timeout=(i)
|
1515
|
+
ftp_object?.read_timeout = i
|
1516
|
+
end
|
1517
|
+
|
1518
|
+
# ========================================================================= #
|
1519
|
+
# === size?
|
1520
|
+
#
|
1521
|
+
# This method will return the size of the given (remote) filename.
|
1522
|
+
# ========================================================================= #
|
1523
|
+
def size?(i)
|
1524
|
+
ftp_object?.size(i)
|
1525
|
+
end; alias size size? # === size
|
1526
|
+
|
1527
|
+
# ========================================================================= #
|
1528
|
+
# === padding?
|
1529
|
+
# ========================================================================= #
|
1530
|
+
def padding?
|
1531
|
+
@internal_hash[:padding]
|
1532
|
+
end
|
1533
|
+
|
1534
|
+
# ========================================================================= #
|
1535
|
+
# === be_verbose?
|
1536
|
+
# ========================================================================= #
|
1537
|
+
def be_verbose?
|
1538
|
+
@internal_hash[:be_verbose]
|
1539
|
+
end
|
1540
|
+
|
1541
|
+
# ========================================================================= #
|
1542
|
+
# === server_welcome_message?
|
1543
|
+
#
|
1544
|
+
# This method will return the remote server's welcome message.
|
1545
|
+
# ========================================================================= #
|
1546
|
+
def server_welcome_message?
|
1547
|
+
ftp_object?.welcome
|
1548
|
+
end; alias welcome? server_welcome_message? # === welcome?
|
1549
|
+
alias welcome server_welcome_message? # === welcome
|
1550
|
+
|
1551
|
+
# ========================================================================= #
|
1552
|
+
# === noop
|
1553
|
+
# ========================================================================= #
|
1554
|
+
def noop
|
1555
|
+
ftp_object?.noop
|
1556
|
+
end
|
1557
|
+
|
1558
|
+
# ========================================================================= #
|
1559
|
+
# === last_response_code?
|
1560
|
+
#
|
1561
|
+
# Return the server's last response code.
|
1562
|
+
# ========================================================================= #
|
1563
|
+
def last_response_code?
|
1564
|
+
ftp_object?.last_response_code
|
1565
|
+
end; alias last_response_code last_response_code? # === last_response_code
|
1566
|
+
|
1567
|
+
# ========================================================================= #
|
1568
|
+
# === []
|
1569
|
+
# ========================================================================= #
|
1570
|
+
def [](i)
|
1571
|
+
update_file_listing
|
1572
|
+
if i =~ /^\d+$/ # If is a number.
|
1573
|
+
i = remote_file_listing.size if i.to_i > remote_file_listing.size
|
1574
|
+
i = remote_file_listing[i.to_i - 1].first
|
1575
|
+
end
|
1576
|
+
return i
|
1577
|
+
end
|
1578
|
+
|
1579
|
+
# ========================================================================= #
|
1580
|
+
# === notify_the_user_about
|
1581
|
+
#
|
1582
|
+
# This method is a general "user notifier". It will notify the user
|
1583
|
+
# about doing certain actions within the FtpParadise project.
|
1584
|
+
# ========================================================================= #
|
1585
|
+
def notify_the_user_about(
|
1586
|
+
i, method
|
1587
|
+
)
|
1588
|
+
case method
|
1589
|
+
# ======================================================================= #
|
1590
|
+
# === :set_transfer_mode
|
1591
|
+
# ======================================================================= #
|
1592
|
+
when :set_transfer_mode
|
1593
|
+
opnn; e "Setting mode to #{orange(i.to_s)} now."
|
1594
|
+
# ======================================================================= #
|
1595
|
+
# === :remove_remote_files
|
1596
|
+
# ======================================================================= #
|
1597
|
+
when :remove_remote_files
|
1598
|
+
opnn; e "Deleting the remote file `#{sdir(i)}` now."
|
1599
|
+
# ======================================================================= #
|
1600
|
+
# === :upload_binary_file
|
1601
|
+
# ======================================================================= #
|
1602
|
+
when :upload_binary_file
|
1603
|
+
opnn; e 'Now trying to upload the binary file `'+sfile(i)+'`'
|
1604
|
+
opnn; e 'to the remote host `'+sfancy(remote_host?)+'`.'
|
1605
|
+
# ======================================================================= #
|
1606
|
+
# === :create_this_remote_directory
|
1607
|
+
# ======================================================================= #
|
1608
|
+
when :create_this_remote_directory
|
1609
|
+
opnn; e 'Creating the remote directory `'+sdir(i)+'` now.'
|
1610
|
+
# ======================================================================= #
|
1611
|
+
# === :remote_cd
|
1612
|
+
# ======================================================================= #
|
1613
|
+
when :remote_cd
|
1614
|
+
opnn; e 'Trying to remote-change directory into `'+sdir(i)+'`.'
|
1615
|
+
# ======================================================================= #
|
1616
|
+
# === :download_this_remote_file
|
1617
|
+
# ======================================================================= #
|
1618
|
+
when :download_this_remote_file
|
1619
|
+
opnn; e "Downloading the remote file `#{sdir(i)}` now."
|
1620
|
+
# ======================================================================= #
|
1621
|
+
# === :upload_this_text_file
|
1622
|
+
# ======================================================================= #
|
1623
|
+
when :upload_this_text_file
|
1624
|
+
opnn; e 'Uploading the local text file `'+sfile(i)+'` to '\
|
1625
|
+
'the remote host at `'+sfancy(remote_pwd?)+'`.'
|
1626
|
+
# ======================================================================= #
|
1627
|
+
# === :create_remote_file
|
1628
|
+
# ======================================================================= #
|
1629
|
+
when :create_remote_file
|
1630
|
+
opnn; e 'Creating the remote file `'+sdir(i)+'` now.'
|
1631
|
+
# ======================================================================= #
|
1632
|
+
# === :remove_remote_directory
|
1633
|
+
# ======================================================================= #
|
1634
|
+
when :remove_remote_directory
|
1635
|
+
opnn; e 'Removing the remote directory `'+sdir(i)+'` now.'
|
1636
|
+
end
|
1637
|
+
end
|
1638
|
+
|
1639
|
+
# ========================================================================= #
|
1640
|
+
# === report_finished_uploading_of_this_file
|
1641
|
+
#
|
1642
|
+
# Report that we have finished uploading a file.
|
1643
|
+
#
|
1644
|
+
# We should also denote the leading http part.
|
1645
|
+
# ========================================================================= #
|
1646
|
+
def report_finished_uploading_of_this_file(i)
|
1647
|
+
if is_connected?
|
1648
|
+
remote_path = "http://#{rds(remote_path?+File.basename(i))}"
|
1649
|
+
opnn; e "Done uploading `#{sfile(i)}` to `"\
|
1650
|
+
"#{sdir(remote_path)}`!"
|
1651
|
+
end
|
1652
|
+
end
|
1653
|
+
|
1654
|
+
# ========================================================================= #
|
1655
|
+
# === password?
|
1656
|
+
# ========================================================================= #
|
1657
|
+
def password?
|
1658
|
+
::FtpParadise.password?.to_s
|
1659
|
+
end; alias password password? # === password
|
1660
|
+
|
1661
|
+
# ========================================================================= #
|
1662
|
+
# === set_password
|
1663
|
+
#
|
1664
|
+
# Use only this method when attempting to modify the @password.
|
1665
|
+
#
|
1666
|
+
# This @ivar keeps track of the password we will use.
|
1667
|
+
# ========================================================================= #
|
1668
|
+
def set_password(
|
1669
|
+
i = :try_to_use_a_default_password
|
1670
|
+
)
|
1671
|
+
case i
|
1672
|
+
# === try_to_use_a_default_password
|
1673
|
+
when :try_to_use_a_default_password,
|
1674
|
+
:default
|
1675
|
+
_ = return_password_from_bplaced
|
1676
|
+
_.chop! if _.end_with? '_'
|
1677
|
+
i = _
|
1678
|
+
when :anonymous
|
1679
|
+
i = nil
|
1680
|
+
else
|
1681
|
+
i = i.to_s
|
1682
|
+
end
|
1683
|
+
::FtpParadise.set_password(i)
|
1684
|
+
i # Return the password here as well, so that we can use it for assignments.
|
1685
|
+
end; alias password= set_password # === password=
|
1686
|
+
|
1687
|
+
# ========================================================================= #
|
1688
|
+
# === return_password_from_bplaced
|
1689
|
+
# ========================================================================= #
|
1690
|
+
def return_password_from_bplaced
|
1691
|
+
dataset = YAML.load_file(FILE_ROEBE_FTP)['bplaced']
|
1692
|
+
return dataset['password']
|
1693
|
+
end
|
1694
|
+
|
1695
|
+
# ========================================================================= #
|
1696
|
+
# === set_port
|
1697
|
+
#
|
1698
|
+
# Use this method to set the port. The port will be stored on the
|
1699
|
+
# toplevel-"namespace".
|
1700
|
+
# ========================================================================= #
|
1701
|
+
def set_port(
|
1702
|
+
i = DEFAULT_PORT
|
1703
|
+
)
|
1704
|
+
FtpParadise.set_port(i)
|
1705
|
+
end
|
1706
|
+
|
1707
|
+
# ========================================================================= #
|
1708
|
+
# === port?
|
1709
|
+
# ========================================================================= #
|
1710
|
+
def port?
|
1711
|
+
FtpParadise.port?.to_s
|
1712
|
+
end; alias port port? # === port
|
1713
|
+
|
1714
|
+
require 'ftp_paradise/toplevel_methods/remote_url.rb'
|
1715
|
+
# ========================================================================= #
|
1716
|
+
# === remote_url?
|
1717
|
+
#
|
1718
|
+
# This method is guaranteed to return a String - except when an
|
1719
|
+
# error happens.
|
1720
|
+
# ========================================================================= #
|
1721
|
+
def remote_url?
|
1722
|
+
begin
|
1723
|
+
return FtpParadise.remote_url?.to_s
|
1724
|
+
rescue Interrupt
|
1725
|
+
exit # User interrupted, so we exit as requested.
|
1726
|
+
rescue Exception => error
|
1727
|
+
opnn; e 'We did encounter an error in the method '+
|
1728
|
+
simp(__method__.to_s)
|
1729
|
+
opnn; pp error
|
1730
|
+
return error.to_s # Return that exception.
|
1731
|
+
end
|
1732
|
+
end; alias remote_host? remote_url? # === remote_host?
|
1733
|
+
alias remote_url remote_url? # === remote_url
|
1734
|
+
alias url? remote_url? # === url?
|
1735
|
+
alias host? remote_url? # === host?
|
1736
|
+
alias host remote_url? # === host
|
1737
|
+
|
1738
|
+
# ========================================================================= #
|
1739
|
+
# === remove (remove tag)
|
1740
|
+
# ========================================================================= #
|
1741
|
+
def remove(i)
|
1742
|
+
if i.is_a? Array
|
1743
|
+
i.each {|entry| remove(entry) }
|
1744
|
+
else
|
1745
|
+
if is_a_directory?(i)
|
1746
|
+
remove_remote_directory(i)
|
1747
|
+
elsif is_a_file?(i)
|
1748
|
+
remove_remote_file(i, be_verbose?)
|
1749
|
+
end
|
1750
|
+
end
|
1751
|
+
end
|
1752
|
+
|
1753
|
+
# ========================================================================= #
|
1754
|
+
# === original_delete
|
1755
|
+
#
|
1756
|
+
# This method will remove the file, without doing any additional
|
1757
|
+
# checks.
|
1758
|
+
# ========================================================================= #
|
1759
|
+
def original_delete(i)
|
1760
|
+
ftp_object?.delete(i)
|
1761
|
+
end
|
1762
|
+
|
1763
|
+
# ========================================================================= #
|
1764
|
+
# === remove_remote_directory
|
1765
|
+
#
|
1766
|
+
# This method will remove a remote directory. For this to work, as
|
1767
|
+
# operation, the remote directory has to exist.
|
1768
|
+
#
|
1769
|
+
# This operation may fail e. g. when the remote directory is not empty.
|
1770
|
+
# This explains why we attempt to rescue some errors.
|
1771
|
+
# ========================================================================= #
|
1772
|
+
def remove_remote_directory(
|
1773
|
+
i,
|
1774
|
+
be_verbose = be_verbose?,
|
1775
|
+
force_remove = false
|
1776
|
+
)
|
1777
|
+
case force_remove
|
1778
|
+
when :force_remove
|
1779
|
+
force_remove = true
|
1780
|
+
when :do_not_force_remove
|
1781
|
+
force_remove = false
|
1782
|
+
end
|
1783
|
+
if i.is_a? Array
|
1784
|
+
i.each {|entry| remove_remote_directory(entry, be_verbose) }
|
1785
|
+
else
|
1786
|
+
if be_verbose
|
1787
|
+
notify_the_user_about(i, __method__)
|
1788
|
+
end
|
1789
|
+
if is_a_directory? i
|
1790
|
+
begin
|
1791
|
+
ftp_object?.rmdir(i)
|
1792
|
+
rescue Net::FTPPermError => error
|
1793
|
+
opnn; e swarn('We could not remove the remote directory at ')+
|
1794
|
+
sdir(i)+swarn(' as it is not empty.')
|
1795
|
+
pp error
|
1796
|
+
if force_remove
|
1797
|
+
opnn; e 'We will now try to enter into this directory'
|
1798
|
+
opnn; e 'and then remove all files of that directory.'
|
1799
|
+
rcd(this_dir)
|
1800
|
+
update_file_listing
|
1801
|
+
all_remote_files?.each {|file| remove(file) } # Now it should be removed.
|
1802
|
+
rcd('..') # Go back again.
|
1803
|
+
rmdir(i, be_verbose, :do_not_force_remove) # But we won't force again, to avoid recursive loops.
|
1804
|
+
opnn; e "The remote directory at #{sdir(i)} has been removed."
|
1805
|
+
end
|
1806
|
+
end
|
1807
|
+
else
|
1808
|
+
if be_verbose
|
1809
|
+
opnn; e "The given input #{sfancy(i)} is not a directory."
|
1810
|
+
end
|
1811
|
+
end
|
1812
|
+
end
|
1813
|
+
end; alias rmdir remove_remote_directory # === rmdir
|
1814
|
+
alias remove_these_remote_directories remove_remote_directory # === remove_these_remote_directories
|
1815
|
+
alias remove_directory remove_remote_directory # === remove_directory
|
1816
|
+
|
1817
|
+
# ========================================================================= #
|
1818
|
+
# === puttextfile
|
1819
|
+
#
|
1820
|
+
# This method will transfer a localfile to the remote server in
|
1821
|
+
# ASCII (text) mode. The result will be stored in "remotefile".
|
1822
|
+
#
|
1823
|
+
# If a callback or an associated block is supplied, calls it, passing
|
1824
|
+
# in the transmitted data one line at a time.
|
1825
|
+
# ========================================================================= #
|
1826
|
+
def puttextfile(
|
1827
|
+
local_file, remotefile = File.basename(local_file)
|
1828
|
+
)
|
1829
|
+
begin
|
1830
|
+
ftp_object?.puttextfile(local_file)
|
1831
|
+
@internal_hash[:uploaded_these_files] << local_file
|
1832
|
+
rescue Net::FTPPermError => error
|
1833
|
+
opnn; e swarn('Can not upload `')+sfile(local_file)+swarn('`.')
|
1834
|
+
opnn; e swarn('Reason provided to this method was:')
|
1835
|
+
opnn; e " → #{sfancy(error.to_s)}"
|
1836
|
+
rescue Exception => error
|
1837
|
+
opnn; e "An error happened in the method #{__method__}"
|
1838
|
+
pp error
|
1839
|
+
end
|
1840
|
+
end
|
1841
|
+
|
1842
|
+
# ========================================================================= #
|
1843
|
+
# === upload_this_text_file
|
1844
|
+
#
|
1845
|
+
# This method can be used to upload one or several text files.
|
1846
|
+
#
|
1847
|
+
# The first argument should be an Array or a String, denoting the
|
1848
|
+
# name/path of the local text file that you wish to upload.
|
1849
|
+
# ========================================================================= #
|
1850
|
+
def upload_this_text_file(
|
1851
|
+
i,
|
1852
|
+
be_verbose = be_verbose?
|
1853
|
+
)
|
1854
|
+
be_verbose = false if be_verbose == :be_silent
|
1855
|
+
if i.is_a? Array
|
1856
|
+
i.each {|entry| upload_this_text_file(entry, be_verbose) }
|
1857
|
+
else
|
1858
|
+
i = i.strip.delete(N) # Added in February 2014.
|
1859
|
+
case i
|
1860
|
+
when :default
|
1861
|
+
ENV['MISC'].to_s+'/SITEMAP.cgi' # <- Makes only sense for text-files anyway.
|
1862
|
+
end
|
1863
|
+
case be_verbose
|
1864
|
+
when :be_quiet
|
1865
|
+
be_verbose = false
|
1866
|
+
end
|
1867
|
+
if be_verbose
|
1868
|
+
notify_the_user_about(i, __method__)
|
1869
|
+
end
|
1870
|
+
puttextfile(i) # <- Delegate towards the method puttextfile().
|
1871
|
+
report_finished_uploading_of_this_file(i) if be_verbose
|
1872
|
+
end
|
1873
|
+
end
|
1874
|
+
|
1875
|
+
# ========================================================================= #
|
1876
|
+
# === upload_this_directory
|
1877
|
+
#
|
1878
|
+
# This method can be used to upload a local directory to a remote host.
|
1879
|
+
#
|
1880
|
+
# If the first input argument is an Array, then the method will call
|
1881
|
+
# itself recursively. This allows us to transfer several directories
|
1882
|
+
# in one go.
|
1883
|
+
#
|
1884
|
+
# If the input is a (local and existing) directory, then this method
|
1885
|
+
# will also have to create a remote directory, then chdir into it,
|
1886
|
+
# and then upload the content of that local directory to the remote
|
1887
|
+
# host.
|
1888
|
+
# ========================================================================= #
|
1889
|
+
def upload_this_directory(
|
1890
|
+
i,
|
1891
|
+
be_verbose = be_verbose?
|
1892
|
+
)
|
1893
|
+
if i.is_a? Array
|
1894
|
+
i.each {|entry| upload_this_directory(i, be_verbose) }
|
1895
|
+
else
|
1896
|
+
if File.directory? i
|
1897
|
+
unless this_remote_directory_exists?(i)
|
1898
|
+
remote_create_directory(i, be_verbose)
|
1899
|
+
end
|
1900
|
+
change_local_directory(i)
|
1901
|
+
change_remote_directory(i)
|
1902
|
+
report_remote_directory
|
1903
|
+
content = return_directory_content(i) # Last but not least, copy all files to that dir.
|
1904
|
+
content.each {|this_file| upload(this_file) }
|
1905
|
+
else
|
1906
|
+
opnn; e "The given input `#{sfancy(i)}` is not a directory."
|
1907
|
+
opnn; e 'This method can only upload directories.'
|
1908
|
+
end
|
1909
|
+
end
|
1910
|
+
end; alias upload_directory upload_this_directory # === upload_directory
|
1911
|
+
alias upload_these_directories upload_this_directory # === upload_these_directories
|
1912
|
+
|
1913
|
+
# ========================================================================= #
|
1914
|
+
# === set_transfer_mode
|
1915
|
+
#
|
1916
|
+
# This method will set to either one of two different possibles modes:
|
1917
|
+
#
|
1918
|
+
# (1) :ascii
|
1919
|
+
# (2) :binary
|
1920
|
+
# (3) :passive
|
1921
|
+
#
|
1922
|
+
# Note that :passive "mode" is ascii, with an additional invocation to
|
1923
|
+
# change the transfer mode to .passive.
|
1924
|
+
#
|
1925
|
+
# It will also change passive mode. The argument :default will default
|
1926
|
+
# to the more commonly used ASCII mode.
|
1927
|
+
#
|
1928
|
+
# When would you want to use ASCII mode?
|
1929
|
+
#
|
1930
|
+
# Use ascii mode for:
|
1931
|
+
#
|
1932
|
+
# txt, rtf, html, php
|
1933
|
+
#
|
1934
|
+
# Use binary mode for:
|
1935
|
+
#
|
1936
|
+
# images, videos and similar.
|
1937
|
+
#
|
1938
|
+
# ========================================================================= #
|
1939
|
+
def set_transfer_mode(
|
1940
|
+
i = DEFAULT_TRANSFER_MODE, # Will usually default to :ascii
|
1941
|
+
be_verbose = be_verbose?
|
1942
|
+
)
|
1943
|
+
case be_verbose
|
1944
|
+
when :be_verbose
|
1945
|
+
be_verbose = true
|
1946
|
+
when :be_quiet
|
1947
|
+
be_verbose = false
|
1948
|
+
end
|
1949
|
+
i = :ascii if i == :default
|
1950
|
+
case i
|
1951
|
+
# ======================================================================= #
|
1952
|
+
# === :ascii
|
1953
|
+
# ======================================================================= #
|
1954
|
+
when :ascii
|
1955
|
+
notify_the_user_about(i, __method__) if be_verbose
|
1956
|
+
@internal_hash[:transfer_mode] = :ascii
|
1957
|
+
ftp_object?.binary = false if ftp_object?
|
1958
|
+
# ======================================================================= #
|
1959
|
+
# === :binary
|
1960
|
+
# ======================================================================= #
|
1961
|
+
when :binary
|
1962
|
+
notify_the_user_about(i, __method__) if be_verbose
|
1963
|
+
@internal_hash[:transfer_mode] = :binary
|
1964
|
+
# ======================================================================= #
|
1965
|
+
# === :passive
|
1966
|
+
# ======================================================================= #
|
1967
|
+
when :passive,
|
1968
|
+
:pass
|
1969
|
+
notify_the_user_about(i, __method__) if be_verbose
|
1970
|
+
@internal_hash[:transfer_mode] = :ascii
|
1971
|
+
ftp_object?.passive = true if ftp_object?
|
1972
|
+
else
|
1973
|
+
opnn; e swarn('Not found the following mode: ')+
|
1974
|
+
sfancy(i.to_s)
|
1975
|
+
end
|
1976
|
+
end; alias mode_to_use= set_transfer_mode # === mode_to_use=
|
1977
|
+
alias set_mode set_transfer_mode # === set_mode
|
1978
|
+
|
1979
|
+
# ========================================================================= #
|
1980
|
+
# === report_transfer_mode_in_use
|
1981
|
+
# ========================================================================= #
|
1982
|
+
def report_transfer_mode_in_use
|
1983
|
+
e "Transfer mode: #{sfancy(transfer_mode?.to_s)}"
|
1984
|
+
end
|
1985
|
+
|
1986
|
+
# ========================================================================= #
|
1987
|
+
# === set_active
|
1988
|
+
# ========================================================================= #
|
1989
|
+
def set_active
|
1990
|
+
ftp_object?.passive = false
|
1991
|
+
end
|
1992
|
+
|
1993
|
+
# ========================================================================= #
|
1994
|
+
# === passive_transfer?
|
1995
|
+
# ========================================================================= #
|
1996
|
+
def passive_transfer?
|
1997
|
+
ftp_object?.passive
|
1998
|
+
end; alias passive? passive_transfer? # === passive?
|
1999
|
+
|
2000
|
+
# ========================================================================= #
|
2001
|
+
# === transfer_mode?
|
2002
|
+
#
|
2003
|
+
# This method will return the currently used transfer_mode. This mode
|
2004
|
+
# can be either :binary, or :ascii. By default it will be :binary.
|
2005
|
+
#
|
2006
|
+
# The transfer mode can be :binary or :text. :ascii is an alias to
|
2007
|
+
# :text.
|
2008
|
+
# ========================================================================= #
|
2009
|
+
def transfer_mode?
|
2010
|
+
@internal_hash[:transfer_mode]
|
2011
|
+
end; alias transfer_mode transfer_mode? # === transfer_mode
|
2012
|
+
alias mode? transfer_mode? # === mode?
|
2013
|
+
alias type transfer_mode? # === type
|
2014
|
+
alias type? transfer_mode? # === type?
|
2015
|
+
|
2016
|
+
# ========================================================================= #
|
2017
|
+
# === set_ascii
|
2018
|
+
#
|
2019
|
+
# Easier wrapper method.
|
2020
|
+
# ========================================================================= #
|
2021
|
+
def set_ascii
|
2022
|
+
set_transfer_mode :ascii
|
2023
|
+
end; alias set_ascii_mode set_ascii # === set_ascii_mode
|
2024
|
+
|
2025
|
+
# ========================================================================= #
|
2026
|
+
# === binary?
|
2027
|
+
#
|
2028
|
+
# When this is true, then then all FTP-transfers will be performed in
|
2029
|
+
# binary mode.
|
2030
|
+
#
|
2031
|
+
# Deaults to true.
|
2032
|
+
# ========================================================================= #
|
2033
|
+
def binary?
|
2034
|
+
ftp_object?.binary
|
2035
|
+
end; alias binary binary? # === binary
|
2036
|
+
|
2037
|
+
# ========================================================================= #
|
2038
|
+
# === set_binary_mode
|
2039
|
+
# ========================================================================= #
|
2040
|
+
def set_binary_mode
|
2041
|
+
set_transfer_mode :binary
|
2042
|
+
ftp_object?.binary = true
|
2043
|
+
end; alias set_binary set_binary_mode # === set_binary
|
2044
|
+
alias set_to_binary_mode set_binary_mode # === set_to_binary_mode
|
2045
|
+
|
2046
|
+
# ========================================================================= #
|
2047
|
+
# === set_passive_mode
|
2048
|
+
#
|
2049
|
+
# Use this when modifying the passive setting.
|
2050
|
+
# ========================================================================= #
|
2051
|
+
def set_passive_mode
|
2052
|
+
set_transfer_mode :ascii
|
2053
|
+
ftp_object?.passive = true if ftp_object?
|
2054
|
+
end; alias set_passive set_passive_mode # === set_passive
|
2055
|
+
|
2056
|
+
# ========================================================================= #
|
2057
|
+
# === set_default_transfer_mode
|
2058
|
+
# ========================================================================= #
|
2059
|
+
def set_default_transfer_mode(
|
2060
|
+
be_verbose = :be_quiet
|
2061
|
+
)
|
2062
|
+
set_transfer_mode(DEFAULT_TRANSFER_MODE, be_verbose)
|
2063
|
+
end
|
2064
|
+
|
2065
|
+
# ========================================================================= #
|
2066
|
+
# === set_debug
|
2067
|
+
# ========================================================================= #
|
2068
|
+
def set_debug(i = SHALL_WE_DEBUG)
|
2069
|
+
@internal_hash[:debug] = i
|
2070
|
+
end
|
2071
|
+
|
2072
|
+
# ========================================================================= #
|
2073
|
+
# === enable_debug_mode
|
2074
|
+
#
|
2075
|
+
# When the debug mode is set to true, then all traffic to and from
|
2076
|
+
# the server is written to $stdout. By default, this will NOT
|
2077
|
+
# be the case.
|
2078
|
+
# ========================================================================= #
|
2079
|
+
def enable_debug_mode
|
2080
|
+
ftp_object?.debug_mode = true
|
2081
|
+
end
|
2082
|
+
|
2083
|
+
# ========================================================================= #
|
2084
|
+
# === enable_debug
|
2085
|
+
#
|
2086
|
+
# Set the @debug variable to true, and also invoke enable_debug_mode().
|
2087
|
+
# ========================================================================= #
|
2088
|
+
def enable_debug
|
2089
|
+
enable_debug_mode
|
2090
|
+
set_debug(true)
|
2091
|
+
end
|
2092
|
+
|
2093
|
+
# ========================================================================= #
|
2094
|
+
# === debug?
|
2095
|
+
# ========================================================================= #
|
2096
|
+
def debug?
|
2097
|
+
@internal_hash[:debug]
|
2098
|
+
end
|
2099
|
+
|
2100
|
+
# ========================================================================= #
|
2101
|
+
# === disable_debug
|
2102
|
+
# ========================================================================= #
|
2103
|
+
def disable_debug
|
2104
|
+
ftp_object?.debug_mode = false
|
2105
|
+
@internal_hash[:debug] = false
|
2106
|
+
end
|
2107
|
+
|
2108
|
+
# ========================================================================= #
|
2109
|
+
# === debug (debug tag)
|
2110
|
+
#
|
2111
|
+
# This method can be used for some debugging output.
|
2112
|
+
# ========================================================================= #
|
2113
|
+
def debug(
|
2114
|
+
shall_we_debug = debug?
|
2115
|
+
)
|
2116
|
+
cliner {
|
2117
|
+
pp ftp?
|
2118
|
+
show_host_user_name_port_and_password
|
2119
|
+
update_file_listing
|
2120
|
+
if shall_we_debug
|
2121
|
+
opnn; e 'File Listing:'
|
2122
|
+
show_file_listing
|
2123
|
+
end
|
2124
|
+
if remote_file_listing?.empty?
|
2125
|
+
opnn; e 'No file could be found. The remote directory '\
|
2126
|
+
'is most likely empty.'
|
2127
|
+
end
|
2128
|
+
} if shall_we_debug
|
2129
|
+
end; alias feedback debug # === feedback
|
2130
|
+
alias report debug # === report
|
2131
|
+
|
2132
|
+
# ========================================================================= #
|
2133
|
+
# === remote_pwd
|
2134
|
+
# ========================================================================= #
|
2135
|
+
def remote_pwd
|
2136
|
+
ftp_object?.pwd
|
2137
|
+
end; alias rpwd remote_pwd # === rpwd
|
2138
|
+
alias getdir remote_pwd # === getdir
|
2139
|
+
|
2140
|
+
# ========================================================================= #
|
2141
|
+
# === return_remote_pwd
|
2142
|
+
#
|
2143
|
+
# This method will return the (remote) pwd, including the remote working
|
2144
|
+
# directory - including the subpath..
|
2145
|
+
#
|
2146
|
+
# This method will ensure that a trailing '/' will be returned here.
|
2147
|
+
#
|
2148
|
+
# The official documentation can be seen here:
|
2149
|
+
# https://ruby-doc.org/stdlib/libdoc/net/ftp/rdoc/Net/FTP.html#method-i-pwd
|
2150
|
+
# ========================================================================= #
|
2151
|
+
def return_remote_pwd
|
2152
|
+
begin
|
2153
|
+
if is_connected?
|
2154
|
+
remote_pwd = remote_url?.dup
|
2155
|
+
# ===================================================================== #
|
2156
|
+
# Need to safeguard, in the event that we are not connected to a
|
2157
|
+
# remote FTP server.
|
2158
|
+
# ===================================================================== #
|
2159
|
+
if ftp_object? and is_connected? and logged_in?
|
2160
|
+
remote_pwd << ftp_object?.pwd.to_s
|
2161
|
+
end
|
2162
|
+
remote_pwd << '/'
|
2163
|
+
return rds(remote_pwd)
|
2164
|
+
else
|
2165
|
+
opnn; e 'No FTP connection is open.'
|
2166
|
+
''
|
2167
|
+
end
|
2168
|
+
rescue Net::FTPReplyError
|
2169
|
+
opnn; e 'Error Net::FTPReplyError received. May be due to user interrupting.'
|
2170
|
+
opnn; e 'Exiting now at once either way.'
|
2171
|
+
exit
|
2172
|
+
rescue SystemExit, Interrupt
|
2173
|
+
opnn; e 'User requested to exit, thus exiting now.'
|
2174
|
+
exit
|
2175
|
+
end
|
2176
|
+
end; alias pwd? return_remote_pwd # === pwd?
|
2177
|
+
alias pwd return_remote_pwd # === pwd (pwd tag)
|
2178
|
+
alias getdir return_remote_pwd # === get_dir
|
2179
|
+
alias remote_pwd return_remote_pwd # === remote_pwd
|
2180
|
+
alias remote_pwd? return_remote_pwd # === remote_pwd?
|
2181
|
+
alias connected_to? return_remote_pwd # === connected_to?
|
2182
|
+
alias remote? return_remote_pwd # === remote?
|
2183
|
+
alias base_dir? return_remote_pwd # === base_dir?
|
2184
|
+
alias remote_directory? return_remote_pwd # === remote_directory?
|
2185
|
+
alias remote_dir? return_remote_pwd # === remote_dir?
|
2186
|
+
alias remote_path? return_remote_pwd # === remote_path?
|
2187
|
+
alias return_subdirectory return_remote_pwd # === return_subdirectory
|
2188
|
+
alias current_directory return_remote_pwd # === current_directory
|
2189
|
+
alias return_remote_dir return_remote_pwd # === return_remote_dir
|
2190
|
+
alias get_remote_dir return_remote_pwd # === get_remote_dir
|
2191
|
+
alias remote_host? return_remote_pwd # === remote_host?
|
2192
|
+
|
2193
|
+
# ========================================================================= #
|
2194
|
+
# === report_current_remote_dir
|
2195
|
+
#
|
2196
|
+
# Gives you the current dir.
|
2197
|
+
# ========================================================================= #
|
2198
|
+
def report_current_remote_dir(
|
2199
|
+
be_verbose = be_verbose?
|
2200
|
+
)
|
2201
|
+
begin
|
2202
|
+
if be_verbose
|
2203
|
+
opnn; e 'The remote directory is:'
|
2204
|
+
e " #{sdir(return_remote_pwd)}"
|
2205
|
+
end
|
2206
|
+
rescue Exception => error
|
2207
|
+
opnn; e error.class
|
2208
|
+
opnn; e error
|
2209
|
+
end
|
2210
|
+
end; alias report_remote_directory report_current_remote_dir # === report_remote_directory
|
2211
|
+
alias dir? report_current_remote_dir # === dir?
|
2212
|
+
alias report_remote_pwd report_current_remote_dir # === report_remote_pwd
|
2213
|
+
|
2214
|
+
# ========================================================================= #
|
2215
|
+
# === remote_chdir (cd tag, chdir tag)
|
2216
|
+
#
|
2217
|
+
# This method allows us to cd to another remote directory, on the
|
2218
|
+
# remote FTP server (our main connection).
|
2219
|
+
#
|
2220
|
+
# The method must be able to check whether we are connected to the
|
2221
|
+
# remote host.
|
2222
|
+
# ========================================================================= #
|
2223
|
+
def remote_chdir(
|
2224
|
+
i,
|
2225
|
+
be_verbose = be_verbose?,
|
2226
|
+
&block
|
2227
|
+
)
|
2228
|
+
if block_given?
|
2229
|
+
case yield
|
2230
|
+
# ===================================================================== #
|
2231
|
+
# === :be_verbose
|
2232
|
+
# ===================================================================== #
|
2233
|
+
when :be_verbose
|
2234
|
+
be_verbose = true
|
2235
|
+
end
|
2236
|
+
end
|
2237
|
+
i = i.dup if i.frozen?
|
2238
|
+
# ======================================================================= #
|
2239
|
+
# Sanitize odd entries ending with ':'
|
2240
|
+
# ======================================================================= #
|
2241
|
+
i[-1,1] = '/' if i.end_with? ':'
|
2242
|
+
i = rds("#{i}/") # <- Always ensure that a '/' is the last character.
|
2243
|
+
if be_verbose
|
2244
|
+
notify_the_user_about(i, __method__)
|
2245
|
+
end
|
2246
|
+
if is_connected?
|
2247
|
+
# ===================================================================== #
|
2248
|
+
# If we cd to a non-existing target, the exception Net::FTPPermError
|
2249
|
+
# will be raised.
|
2250
|
+
# ===================================================================== #
|
2251
|
+
begin
|
2252
|
+
ftp_object?.chdir(i)
|
2253
|
+
update_remote_file_listing
|
2254
|
+
# ===================================================================== #
|
2255
|
+
# The user may have insufficient permissions:
|
2256
|
+
# ===================================================================== #
|
2257
|
+
rescue Net::FTPPermError => error
|
2258
|
+
pp error
|
2259
|
+
rescue Net::ReadTimeout => error
|
2260
|
+
opnn; e 'An error was encountered in the method '\
|
2261
|
+
'remote_chdir().'
|
2262
|
+
opnn; e 'The error-class was Net::ReadTimeout.'
|
2263
|
+
e
|
2264
|
+
opnn; e 'The specific error will be displayed next.'
|
2265
|
+
e
|
2266
|
+
pp error
|
2267
|
+
end
|
2268
|
+
else
|
2269
|
+
opnn; e 'We are not connected to a remote host right now.'
|
2270
|
+
opnn; e 'Thus we can not change the directory.'
|
2271
|
+
end
|
2272
|
+
report_current_remote_dir if be_verbose # right now mandatory
|
2273
|
+
end; alias rcd remote_chdir # === rcd
|
2274
|
+
alias remote_cd remote_chdir # === remote_cd
|
2275
|
+
alias chdir remote_chdir # === chdir
|
2276
|
+
alias cd remote_chdir # === cd
|
2277
|
+
alias chdir remote_chdir # === chdir
|
2278
|
+
alias rcd remote_chdir # === rcd
|
2279
|
+
alias change_directory remote_chdir # === change_directory
|
2280
|
+
alias change_remote_directory remote_chdir # === change_remote_directory
|
2281
|
+
alias cd_into_this_remote_directory remote_chdir # === cd_into_this_remote_directory
|
2282
|
+
alias remote_change_directory remote_chdir # === remote_change_directory
|
2283
|
+
|
2284
|
+
# ========================================================================= #
|
2285
|
+
# === return_remote_directories
|
2286
|
+
#
|
2287
|
+
# Give us a list of (remote) directories - only directories, not
|
2288
|
+
# files.
|
2289
|
+
#
|
2290
|
+
# An Array will be returned as a result.
|
2291
|
+
# ========================================================================= #
|
2292
|
+
def return_remote_directories
|
2293
|
+
_ = []
|
2294
|
+
update_file_listing # Populate the file listing anew, so we will always get proper results back.
|
2295
|
+
raw_listing?.each {|entry|
|
2296
|
+
entry = FtpParadise::Entry.new(entry)
|
2297
|
+
_ << rds(entry.return_name) if entry.is_a_directory?
|
2298
|
+
}
|
2299
|
+
# ======================================================================= #
|
2300
|
+
# Directories must end with '/'. Ensure this to be the case next.
|
2301
|
+
# ======================================================================= #
|
2302
|
+
_.map! {|entry|
|
2303
|
+
entry << '/' unless entry.end_with? '/'
|
2304
|
+
entry
|
2305
|
+
}
|
2306
|
+
return _
|
2307
|
+
end; alias directories? return_remote_directories # === directories?
|
2308
|
+
alias return_directories return_remote_directories # === return_directories
|
2309
|
+
|
2310
|
+
# ========================================================================= #
|
2311
|
+
# === return_remote_directory_content
|
2312
|
+
#
|
2313
|
+
# This method will return ALL remote entries, no matter if file or
|
2314
|
+
# directory.
|
2315
|
+
# ========================================================================= #
|
2316
|
+
def return_remote_directory_content
|
2317
|
+
raw_entries = raw_entries?
|
2318
|
+
if raw_entries.nil?
|
2319
|
+
populate_raw_entries
|
2320
|
+
raw_entries = raw_entries?
|
2321
|
+
end
|
2322
|
+
if raw_entries
|
2323
|
+
_ = raw_entries.reject {|line|
|
2324
|
+
line.empty?
|
2325
|
+
}.map {|entry|
|
2326
|
+
FtpParadise::Entry.new(entry).name?
|
2327
|
+
}
|
2328
|
+
end
|
2329
|
+
return _
|
2330
|
+
end; alias array_file_listing? return_remote_directory_content # === array_file_listing?
|
2331
|
+
alias array_file_listing return_remote_directory_content # === array_file_listing
|
2332
|
+
alias remote_directory_content return_remote_directory_content # === remote_directory_content
|
2333
|
+
alias list? return_remote_directory_content # === list?
|
2334
|
+
|
2335
|
+
# ========================================================================= #
|
2336
|
+
# === quit (quit tag)
|
2337
|
+
#
|
2338
|
+
# Use this method to quit (and disconnect) from the FTP Connection
|
2339
|
+
# again.
|
2340
|
+
# ========================================================================= #
|
2341
|
+
def quit
|
2342
|
+
begin
|
2343
|
+
if is_connected?
|
2344
|
+
if ftp_object?
|
2345
|
+
FtpParadise.clear_user_dataset
|
2346
|
+
ftp_object?.quit
|
2347
|
+
end
|
2348
|
+
end
|
2349
|
+
rescue Exception => error
|
2350
|
+
opnn; e "An error happened in the method #{sfancy(__method__)}()"
|
2351
|
+
pp error
|
2352
|
+
end
|
2353
|
+
end
|
2354
|
+
|
2355
|
+
# ========================================================================= #
|
2356
|
+
# === FtpParadise::Connection[]
|
2357
|
+
# ========================================================================= #
|
2358
|
+
def self.[](i = '')
|
2359
|
+
new(i)
|
2360
|
+
end
|
2361
|
+
|
2362
|
+
# ========================================================================= #
|
2363
|
+
# === chdir (cd tag, chdir tag)
|
2364
|
+
# ========================================================================= #
|
2365
|
+
def chdir(i)
|
2366
|
+
@ftp_object.chdir(i)
|
2367
|
+
end; alias cd chdir # === cd
|
2368
|
+
alias remote_cd chdir # === remote_cd
|
2369
|
+
|
2370
|
+
# ========================================================================= #
|
2371
|
+
# === pwd
|
2372
|
+
#
|
2373
|
+
# Returns the current remote directory.
|
2374
|
+
# ========================================================================= #
|
2375
|
+
def pwd
|
2376
|
+
"#{@ftp_object.pwd}/".squeeze('/')
|
2377
|
+
end; alias getdir pwd # === getdir
|
2378
|
+
alias remote_directory? pwd # === remote_directory?
|
2379
|
+
|
2380
|
+
# ========================================================================= #
|
2381
|
+
# === ftp_connection?
|
2382
|
+
# ========================================================================= #
|
2383
|
+
def ftp_connection?
|
2384
|
+
@ftp_object
|
2385
|
+
end; alias ftp_object? ftp_connection? # === ftp_object?
|
2386
|
+
alias net_ftp? ftp_connection? # === net_ftp?
|
2387
|
+
alias ftp? ftp_connection? # === ftp?
|
2388
|
+
alias ftp ftp_connection? # === ftp?
|
2389
|
+
alias ftp_object ftp_connection? # === ftp_object
|
2390
|
+
|
2391
|
+
# ========================================================================= #
|
2392
|
+
# === do_login
|
2393
|
+
#
|
2394
|
+
# This method is responsible for the login-action.
|
2395
|
+
#
|
2396
|
+
# The method signature for the net-ftp class' .login() is:
|
2397
|
+
#
|
2398
|
+
# login(user = "anonymous", passwd = nil, acct = nil)
|
2399
|
+
#
|
2400
|
+
# This method here accepts a Hash as first argument.
|
2401
|
+
#
|
2402
|
+
# For official information about .login(), see here:
|
2403
|
+
#
|
2404
|
+
# https://ruby-doc.org/stdlib/libdoc/net/ftp/rdoc/Net/FTP.html#method-i-login
|
2405
|
+
#
|
2406
|
+
# ========================================================================= #
|
2407
|
+
def do_login(
|
2408
|
+
to_this_url = nil, # The remote URL.
|
2409
|
+
use_this_as_username = username?, # The login-name.
|
2410
|
+
use_this_as_password = password?, # The password for that user.
|
2411
|
+
be_verbose = be_verbose?
|
2412
|
+
)
|
2413
|
+
if to_this_url.nil?
|
2414
|
+
to_this_url = FtpParadise.remote_url?
|
2415
|
+
elsif to_this_url.is_a? Hash
|
2416
|
+
end
|
2417
|
+
# ======================================================================= #
|
2418
|
+
# Rescue nil-passwords here.
|
2419
|
+
# ======================================================================= #
|
2420
|
+
if use_this_as_password.to_s.empty?
|
2421
|
+
use_this_as_password = set_password(:try_to_use_a_default_password)
|
2422
|
+
end
|
2423
|
+
if be_verbose
|
2424
|
+
# ===================================================================== #
|
2425
|
+
# Display some info to the user here.
|
2426
|
+
# ===================================================================== #
|
2427
|
+
e; cliner
|
2428
|
+
opnn; e "Using the URL #{royalblue(to_this_url)} (remote FTP host)."
|
2429
|
+
e
|
2430
|
+
e " Username: #{slateblue(use_this_as_username)}"
|
2431
|
+
e " Password: #{slateblue(use_this_as_password)}"
|
2432
|
+
e
|
2433
|
+
report_transfer_mode_in_use
|
2434
|
+
e
|
2435
|
+
cliner
|
2436
|
+
end
|
2437
|
+
if ftp_object?.nil? and !to_this_url.nil?
|
2438
|
+
initialize_a_new_net_ftp_object_with_this_url(to_this_url)
|
2439
|
+
end
|
2440
|
+
use_this_as_username = use_this_as_username.to_s
|
2441
|
+
# ======================================================================= #
|
2442
|
+
# The following code must be rescued because the login() method
|
2443
|
+
# may fail in various ways.
|
2444
|
+
# ======================================================================= #
|
2445
|
+
begin
|
2446
|
+
ftp_object?.login(
|
2447
|
+
use_this_as_username,
|
2448
|
+
use_this_as_password
|
2449
|
+
)
|
2450
|
+
# =================================================================== #
|
2451
|
+
# Next, assign towards the toplevel reference to the ftp-connection.
|
2452
|
+
# =================================================================== #
|
2453
|
+
sync_ftp_object_onto_the_main_namespace if ftp_object?
|
2454
|
+
if be_verbose and is_connected?
|
2455
|
+
e
|
2456
|
+
cliner {
|
2457
|
+
e "- #{sfancy('Successfully')} logged into "\
|
2458
|
+
"the remote FTP host at `#{simp(to_this_url)}`"
|
2459
|
+
}
|
2460
|
+
end
|
2461
|
+
rescue Net::FTPPermError => error
|
2462
|
+
opnn; e "We could not connect and login to `#{sfancy(to_this_url)}`."
|
2463
|
+
opnn; e 'It may be that you lack the proper permissions.'
|
2464
|
+
opnn; e 'This may happen because the user/password combination was'
|
2465
|
+
opnn; e 'incorrect. User and password combination will be shown next:'
|
2466
|
+
show_user_and_password
|
2467
|
+
opnn; e "Feedbacking that error next, of class #{error.class.to_s}:"
|
2468
|
+
opnn; e orange(error.to_s)
|
2469
|
+
rescue Net::FTPConnectionError => error
|
2470
|
+
opnn; e 'We do not seem to be connected. An error happened.'
|
2471
|
+
pp error
|
2472
|
+
pp error.class
|
2473
|
+
end
|
2474
|
+
end; alias do_connect do_login # === do_connect
|
2475
|
+
alias connect_to do_login # === connect_to
|
2476
|
+
alias connect do_login # === connect
|
2477
|
+
alias login do_login # === login
|
2478
|
+
alias login_to do_login # === login_to
|
2479
|
+
alias reconnect do_login # === reconnect
|
2480
|
+
|
2481
|
+
# ========================================================================= #
|
2482
|
+
# === remove_remote_file
|
2483
|
+
#
|
2484
|
+
# Remove a (remote) file, via the delete() method of the FTP protocol.
|
2485
|
+
#
|
2486
|
+
# Note that this method will only delete files.
|
2487
|
+
#
|
2488
|
+
# The official documentation for the Ruby-FTP delete() method can be
|
2489
|
+
# found here:
|
2490
|
+
#
|
2491
|
+
# https://www.ruby-doc.org/stdlib/libdoc/net/ftp/rdoc/Net/FTP.html#method-i-delete
|
2492
|
+
#
|
2493
|
+
# ========================================================================= #
|
2494
|
+
def remove_remote_file(
|
2495
|
+
i,
|
2496
|
+
be_verbose = be_verbose?
|
2497
|
+
)
|
2498
|
+
case be_verbose
|
2499
|
+
when :be_verbose
|
2500
|
+
be_verbose = true
|
2501
|
+
end
|
2502
|
+
if i.is_a? Array
|
2503
|
+
i.each {|entry| remove_remote_file(entry, be_verbose) }
|
2504
|
+
else
|
2505
|
+
if does_this_remote_file_exist?(File.basename(i))
|
2506
|
+
i = File.basename(i)
|
2507
|
+
if i =~ /^\d+$/ # if is a number
|
2508
|
+
update_file_listing
|
2509
|
+
_ = return_remote_file_listing[i.to_i - 1].first
|
2510
|
+
_ = File.basename(_)
|
2511
|
+
e "Performing a substitution of #{sfancy(i)}"\
|
2512
|
+
" to #{simp(_)}."
|
2513
|
+
i = _
|
2514
|
+
end
|
2515
|
+
if be_verbose
|
2516
|
+
notify_the_user_about(i, __method__)
|
2517
|
+
end
|
2518
|
+
ftp_object?.delete(i)
|
2519
|
+
update_file_listing
|
2520
|
+
return i # Also return the file that was deleted.
|
2521
|
+
else
|
2522
|
+
opnn; e "No remote file called `#{sfile(i)}` was "\
|
2523
|
+
"found at `#{sfancy(remote_pwd)}`."
|
2524
|
+
end
|
2525
|
+
end
|
2526
|
+
end; alias remote_remove remove_remote_file # === remote_remove
|
2527
|
+
alias remote_remove_files remove_remote_file # === remote_remove_files
|
2528
|
+
alias remote_remove_file remove_remote_file # === remote_remove_files
|
2529
|
+
alias delete remove_remote_file # === delete
|
2530
|
+
alias remove_file remove_remote_file # === remove_file
|
2531
|
+
alias rm_file remove_remote_file # === rm_file
|
2532
|
+
alias rmfile remove_remote_file # === rmfile
|
2533
|
+
alias delete_this_remote_file remove_remote_file # === delete_this_remote_file
|
2534
|
+
|
2535
|
+
# ========================================================================= #
|
2536
|
+
# === return_all_remote_files
|
2537
|
+
#
|
2538
|
+
# This method will return an Array with all remote files.
|
2539
|
+
# ========================================================================= #
|
2540
|
+
def return_all_remote_files
|
2541
|
+
results = []
|
2542
|
+
if file_listing?
|
2543
|
+
results = file_listing?.select {|entry|
|
2544
|
+
if entry.is_a?(String) and !entry.empty?
|
2545
|
+
entry = FtpParadise::Entry.new(entry)
|
2546
|
+
end
|
2547
|
+
entry.is_a_file?
|
2548
|
+
}
|
2549
|
+
end
|
2550
|
+
return results
|
2551
|
+
end; alias remote_file_listing? return_all_remote_files # === remote_file_listing?
|
2552
|
+
alias all_remote_files? return_all_remote_files # === all_remote_files?
|
2553
|
+
alias array_remote_files return_all_remote_files # === array_remote_files
|
2554
|
+
alias return_remote_files return_all_remote_files # === return_remote_files
|
2555
|
+
alias return_remote_file_listing return_all_remote_files # === return_remote_file_listing
|
2556
|
+
alias remote_files? return_all_remote_files # === remote_files
|
2557
|
+
alias files? return_all_remote_files # === files?
|
2558
|
+
|
2559
|
+
# ========================================================================= #
|
2560
|
+
# === open?
|
2561
|
+
#
|
2562
|
+
# This method can also be used to determine whether we are still
|
2563
|
+
# connected to the remote site.
|
2564
|
+
#
|
2565
|
+
# This method will return true if the connection is open.
|
2566
|
+
#
|
2567
|
+
# If you want to determine whether you are still connected to the
|
2568
|
+
# remote host, you can alias use the alias are_we_connected? - it
|
2569
|
+
# may read nicer.
|
2570
|
+
# ========================================================================= #
|
2571
|
+
def open?
|
2572
|
+
!closed?
|
2573
|
+
end; alias are_we_connected? open? # === are_we_connected?
|
2574
|
+
alias is_connected? open? # === is_connected?
|
2575
|
+
alias is_connected open? # === is_connected
|
2576
|
+
alias connected? open? # === connected?
|
2577
|
+
alias did_we_connect? open? # === did_we_connect?
|
2578
|
+
|
2579
|
+
# ========================================================================= #
|
2580
|
+
# === status?
|
2581
|
+
#
|
2582
|
+
# Report the status here. This is equivalent to the STAT command.
|
2583
|
+
# ========================================================================= #
|
2584
|
+
def status?
|
2585
|
+
ftp_object?.status.to_s
|
2586
|
+
end; alias status status? # === status
|
2587
|
+
alias remote_status? status? # === remote_status?
|
2588
|
+
|
2589
|
+
# ========================================================================= #
|
2590
|
+
# === initialize_a_new_net_ftp_object_with_this_remote_url
|
2591
|
+
#
|
2592
|
+
# This method is the only one allowed to create a new Net::FTP instance.
|
2593
|
+
# ========================================================================= #
|
2594
|
+
def initialize_a_new_net_ftp_object_with_this_remote_url(i)
|
2595
|
+
@ftp_object = Net::FTP.new(i) # ftp = Net::FTP.new(YAML.load_file(ENV['FTP_YAML_FILE'])['freehosting']['url'])
|
2596
|
+
end; alias initialize_a_new_net_ftp_object initialize_a_new_net_ftp_object_with_this_remote_url # === initialize_a_new_net_ftp_object
|
2597
|
+
alias initialize_a_new_net_ftp_object_with_this_url initialize_a_new_net_ftp_object_with_this_remote_url # === initialize_a_new_net_ftp_object_with_this_url
|
2598
|
+
|
2599
|
+
# ========================================================================= #
|
2600
|
+
# === connect_via_this_dataset
|
2601
|
+
# ========================================================================= #
|
2602
|
+
def connect_via_this_dataset(hash)
|
2603
|
+
set_data(hash)
|
2604
|
+
if ::FtpParadise.remote_host?.nil? and hash.has_key?(:remote_url)
|
2605
|
+
::FtpParadise.set_remote_host(hash[:remote_url])
|
2606
|
+
end
|
2607
|
+
do_login(FtpParadise.remote_url?)
|
2608
|
+
end
|
2609
|
+
|
2610
|
+
# ========================================================================= #
|
2611
|
+
# === set_data (all in one, set_data tag)
|
2612
|
+
#
|
2613
|
+
# This method sets:
|
2614
|
+
#
|
2615
|
+
# - host
|
2616
|
+
# - user name
|
2617
|
+
# - port and
|
2618
|
+
# - password
|
2619
|
+
#
|
2620
|
+
# This method is thus a nifty little convenience method. You can pass
|
2621
|
+
# a hash to it too, which is the recommended way to use this method.
|
2622
|
+
#
|
2623
|
+
# You can also use an Array (with 4 elements), in which case we will
|
2624
|
+
# process it one after the other. The reason for this procedure is
|
2625
|
+
# because we can also use yaml files that way, that also use the
|
2626
|
+
# exact order of elements.
|
2627
|
+
#
|
2628
|
+
# If you add a new entry to the case menu below, also add this to
|
2629
|
+
# ARRAY_AVAILABLE_HOSTS, please. That Array can be found in the
|
2630
|
+
# file 'constants/roebe_ftp_constants.rb'.
|
2631
|
+
# ========================================================================= #
|
2632
|
+
def set_data(
|
2633
|
+
i = 'default'
|
2634
|
+
) # set the default here.
|
2635
|
+
if debug?
|
2636
|
+
opnn; e 'We will debug next, as the @debug variable was set to true.'
|
2637
|
+
pp i
|
2638
|
+
end
|
2639
|
+
# ======================================================================= #
|
2640
|
+
# === Handle Hash as input first
|
2641
|
+
# ======================================================================= #
|
2642
|
+
if i.is_a? Hash # Hash is treated differently.
|
2643
|
+
|
2644
|
+
# ===================================================================== #
|
2645
|
+
# === :host
|
2646
|
+
# ===================================================================== #
|
2647
|
+
if i.has_key? :host
|
2648
|
+
set_host i.fetch(:host)
|
2649
|
+
# ===================================================================== #
|
2650
|
+
# === :remote_host
|
2651
|
+
# ===================================================================== #
|
2652
|
+
elsif i.has_key? :remote_host
|
2653
|
+
set_host i.fetch(:remote_host)
|
2654
|
+
elsif i.has_key? :to # :to is an alias to :host.
|
2655
|
+
set_host i.fetch(:to)
|
2656
|
+
elsif i.has_key? :remote_url
|
2657
|
+
set_host i.fetch(:remote_url)
|
2658
|
+
end
|
2659
|
+
|
2660
|
+
# ===================================================================== #
|
2661
|
+
# === :user_name
|
2662
|
+
# ===================================================================== #
|
2663
|
+
if i.has_key? :user_name
|
2664
|
+
set_user_name i.fetch(:user_name)
|
2665
|
+
elsif i.has_key? :login_name
|
2666
|
+
set_user_name i.fetch(:login_name)
|
2667
|
+
end
|
2668
|
+
|
2669
|
+
# ===================================================================== #
|
2670
|
+
# === :password
|
2671
|
+
# ===================================================================== #
|
2672
|
+
if i.has_key? :password
|
2673
|
+
set_password i.fetch(:password)
|
2674
|
+
# ===================================================================== #
|
2675
|
+
# === :login_password
|
2676
|
+
# ===================================================================== #
|
2677
|
+
elsif i.has_key? :login_password
|
2678
|
+
set_password i.fetch(:login_password)
|
2679
|
+
end
|
2680
|
+
|
2681
|
+
# ===================================================================== #
|
2682
|
+
# === :port
|
2683
|
+
# ===================================================================== #
|
2684
|
+
if i.has_key? :port
|
2685
|
+
set_port i.fetch(:port)
|
2686
|
+
end
|
2687
|
+
# ======================================================================= #
|
2688
|
+
# === Handle Array as input next
|
2689
|
+
# ======================================================================= #
|
2690
|
+
elsif i.is_a? Array # Example-Array: ["ftp.byethost33.com", "b33_14144659", "1aaaaaa", 21]
|
2691
|
+
set_host i.first
|
2692
|
+
set_user_name i[1]
|
2693
|
+
set_password i[2]
|
2694
|
+
set_port i[3]
|
2695
|
+
# ======================================================================= #
|
2696
|
+
# === Else, use simple toggle commands, such as 1,2,3,4,5 and so forth.
|
2697
|
+
# ======================================================================= #
|
2698
|
+
else # In the following case menu you can toggle your FTP.
|
2699
|
+
case i.to_s # Work on strings only. Assumes shortcuts as well.
|
2700
|
+
# ===================================================================== #
|
2701
|
+
# === bplaced
|
2702
|
+
# ===================================================================== #
|
2703
|
+
when '1',
|
2704
|
+
'bplaced',
|
2705
|
+
/shevy/i,
|
2706
|
+
'default',
|
2707
|
+
'top' # Current default.
|
2708
|
+
dataset = YAML.load_file(FILE_ROEBE_FTP)['bplaced']
|
2709
|
+
set_host dataset['host']
|
2710
|
+
set_user_name dataset['user_name']
|
2711
|
+
set_password dataset['password']
|
2712
|
+
set_port dataset['port']
|
2713
|
+
# ===================================================================== #
|
2714
|
+
# === shevy
|
2715
|
+
#
|
2716
|
+
# This defaults to my home system.
|
2717
|
+
# ===================================================================== #
|
2718
|
+
when '2',
|
2719
|
+
'square',
|
2720
|
+
'square7',
|
2721
|
+
'podserver'
|
2722
|
+
_ = FILE_ROEBE_FTP
|
2723
|
+
if File.exist? _
|
2724
|
+
data = YAML.load_file(_)['bplaced']
|
2725
|
+
set_host data['url']
|
2726
|
+
set_user_name data['user_name']
|
2727
|
+
this_password = data['password']
|
2728
|
+
this_password.chop! if this_password.end_with? '_'
|
2729
|
+
set_password this_password
|
2730
|
+
set_port data['port']
|
2731
|
+
end
|
2732
|
+
# ===================================================================== #
|
2733
|
+
# === a1
|
2734
|
+
# ===================================================================== #
|
2735
|
+
when '3',
|
2736
|
+
'a1',
|
2737
|
+
'a1_ftp' # A1 FTP host. No longer in use but still kept.
|
2738
|
+
set_host A1.first
|
2739
|
+
set_user_name A1[1]
|
2740
|
+
set_password A1[2]
|
2741
|
+
set_port A1[3]
|
2742
|
+
# ===================================================================== #
|
2743
|
+
# === zymix
|
2744
|
+
# ===================================================================== #
|
2745
|
+
when '4',
|
2746
|
+
'zymix',
|
2747
|
+
'standard'
|
2748
|
+
set_host ZYMIX.first
|
2749
|
+
set_user_name ZYMIX[1]
|
2750
|
+
set_password ZYMIX[2]
|
2751
|
+
set_port ZYMIX[3]
|
2752
|
+
# ===================================================================== #
|
2753
|
+
# === uniwien
|
2754
|
+
# ===================================================================== #
|
2755
|
+
when '5',
|
2756
|
+
'univie',
|
2757
|
+
'uniwien' # Uni Wien FTP Account.
|
2758
|
+
set_host UNIVIE.first
|
2759
|
+
set_user_name UNIVIE[1]
|
2760
|
+
set_password UNIVIE[2]
|
2761
|
+
set_port UNIVIE[3]
|
2762
|
+
# ===================================================================== #
|
2763
|
+
# === byte
|
2764
|
+
# ===================================================================== #
|
2765
|
+
when '6',
|
2766
|
+
'byte',
|
2767
|
+
'bytehost'
|
2768
|
+
dataset = YAML.load_file(FILE_ROEBE_FTP)['bytehost']
|
2769
|
+
set_host dataset['host']
|
2770
|
+
set_user_name dataset['user_name']
|
2771
|
+
set_password dataset['password']
|
2772
|
+
set_port dataset['port']
|
2773
|
+
else
|
2774
|
+
set_data(:default) # Go back to default again if not found.
|
2775
|
+
end
|
2776
|
+
end
|
2777
|
+
end
|
2778
|
+
|
2779
|
+
# ========================================================================= #
|
2780
|
+
# === upload_this_local_file
|
2781
|
+
# ========================================================================= #
|
2782
|
+
def upload_this_local_file(i)
|
2783
|
+
i = i.join if i.is_a? Array
|
2784
|
+
ftp_connection?.putbinaryfile(i)
|
2785
|
+
end; alias putbinaryfile upload_this_local_file # === putbinaryfile
|
2786
|
+
|
2787
|
+
# ========================================================================= #
|
2788
|
+
# === run (run tag)
|
2789
|
+
# ========================================================================= #
|
2790
|
+
def run
|
2791
|
+
do_connect
|
2792
|
+
end
|
2793
|
+
|
2794
|
+
end; end
|
2795
|
+
|
2796
|
+
if __FILE__ == $PROGRAM_NAME
|
2797
|
+
if FtpParadise.is_on_roebe?
|
2798
|
+
FtpParadise::Connection.new(ARGV) { :use_default_dataset }
|
2799
|
+
else
|
2800
|
+
FtpParadise::Connection.new(ARGV)
|
2801
|
+
end
|
2802
|
+
end # connection.rb
|