ftp_paradise 1.3.8
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 +7 -0
- data/README.md +309 -0
- data/bin/create_remote_directory +9 -0
- data/bin/ftp_get +17 -0
- data/bin/ftp_upload +42 -0
- data/bin/ftp_upload_binary +18 -0
- data/bin/iftp +7 -0
- data/bin/remote_remove +28 -0
- data/doc/README.gen +292 -0
- data/doc/TODO_FOR_FTP_PARADISE_PROJECT.md +79 -0
- data/ftp_paradise.gemspec +114 -0
- data/lib/ftp_paradise.rb +5 -0
- data/lib/ftp_paradise/base/cliner.rb +21 -0
- data/lib/ftp_paradise/base/colours.rb +83 -0
- data/lib/ftp_paradise/base/prototype.rb +169 -0
- data/lib/ftp_paradise/base/reset.rb +29 -0
- data/lib/ftp_paradise/colours/colours.rb +141 -0
- data/lib/ftp_paradise/colours/use_colours.rb +74 -0
- data/lib/ftp_paradise/configuration/configuration.rb +49 -0
- data/lib/ftp_paradise/connection/README.md +1 -0
- data/lib/ftp_paradise/connection/connection.rb +35 -0
- data/lib/ftp_paradise/connection/constants.rb +46 -0
- data/lib/ftp_paradise/connection/data.rb +148 -0
- data/lib/ftp_paradise/connection/debug.rb +80 -0
- data/lib/ftp_paradise/connection/directory_handling.rb +271 -0
- data/lib/ftp_paradise/connection/do_login.rb +108 -0
- data/lib/ftp_paradise/connection/download.rb +86 -0
- data/lib/ftp_paradise/connection/file_handling.rb +172 -0
- data/lib/ftp_paradise/connection/ftp_object.rb +21 -0
- data/lib/ftp_paradise/connection/initialize.rb +86 -0
- data/lib/ftp_paradise/connection/initialize_a_new_net_ftp_object_with_this_url.rb +20 -0
- data/lib/ftp_paradise/connection/is_connected.rb +46 -0
- data/lib/ftp_paradise/connection/misc.rb +472 -0
- data/lib/ftp_paradise/connection/notify.rb +71 -0
- data/lib/ftp_paradise/connection/password.rb +47 -0
- data/lib/ftp_paradise/connection/port.rb +33 -0
- data/lib/ftp_paradise/connection/remote_pwd.rb +72 -0
- data/lib/ftp_paradise/connection/remote_url.rb +163 -0
- data/lib/ftp_paradise/connection/remove.rb +143 -0
- data/lib/ftp_paradise/connection/reset.rb +75 -0
- data/lib/ftp_paradise/connection/run.rb +18 -0
- data/lib/ftp_paradise/connection/set_array_available_hosts.rb +27 -0
- data/lib/ftp_paradise/connection/set_input.rb +18 -0
- data/lib/ftp_paradise/connection/show.rb +153 -0
- data/lib/ftp_paradise/connection/sync_ftp_object_onto_the_main_namespace.rb +24 -0
- data/lib/ftp_paradise/connection/transfer_mode.rb +162 -0
- data/lib/ftp_paradise/connection/upload.rb +253 -0
- data/lib/ftp_paradise/connection/use_default_dataset.rb +41 -0
- data/lib/ftp_paradise/connection/username.rb +42 -0
- data/lib/ftp_paradise/constants/constants.rb +19 -0
- data/lib/ftp_paradise/constants/misc.rb +57 -0
- data/lib/ftp_paradise/constants/namespace.rb +14 -0
- data/lib/ftp_paradise/constants/newline.rb +14 -0
- data/lib/ftp_paradise/constants/roebe.rb +27 -0
- data/lib/ftp_paradise/constants/roebe_ftp_constants.rb +219 -0
- data/lib/ftp_paradise/entry/entry.rb +293 -0
- data/lib/ftp_paradise/gui/gtk/constants.rb +58 -0
- data/lib/ftp_paradise/gui/gtk/ftp_bindings.rb +1149 -0
- data/lib/ftp_paradise/interactive_ftp/constants.rb +103 -0
- data/lib/ftp_paradise/interactive_ftp/directory_handling.rb +215 -0
- data/lib/ftp_paradise/interactive_ftp/help.rb +50 -0
- data/lib/ftp_paradise/interactive_ftp/initialize.rb +27 -0
- data/lib/ftp_paradise/interactive_ftp/interactive_ftp.rb +995 -0
- data/lib/ftp_paradise/interactive_ftp/main_loop.rb +50 -0
- data/lib/ftp_paradise/interactive_ftp/menu.rb +788 -0
- data/lib/ftp_paradise/interactive_ftp/misc.rb +208 -0
- data/lib/ftp_paradise/interactive_ftp/mode.rb +124 -0
- data/lib/ftp_paradise/interactive_ftp/readline.rb +115 -0
- data/lib/ftp_paradise/interactive_ftp/remove.rb +97 -0
- data/lib/ftp_paradise/interactive_ftp/reset.rb +90 -0
- data/lib/ftp_paradise/interactive_ftp/run.rb +22 -0
- data/lib/ftp_paradise/interactive_ftp/show.rb +184 -0
- data/lib/ftp_paradise/interactive_ftp/upload.rb +90 -0
- data/lib/ftp_paradise/interactive_ftp/user_input.rb +53 -0
- data/lib/ftp_paradise/project/project.rb +62 -0
- data/lib/ftp_paradise/requires/common_basic_requires.rb +13 -0
- data/lib/ftp_paradise/requires/common_external_requires.rb +9 -0
- data/lib/ftp_paradise/requires/require_the_constants.rb +7 -0
- data/lib/ftp_paradise/requires/require_the_ftp_paradise_project.rb +18 -0
- data/lib/ftp_paradise/requires/require_the_ftp_paradise_project_with_the_GUI_bindings.rb +10 -0
- data/lib/ftp_paradise/requires/require_the_toplevel_methods.rb +24 -0
- data/lib/ftp_paradise/toplevel_methods/can_connect_to_remote_site.rb +29 -0
- data/lib/ftp_paradise/toplevel_methods/clear_user_dataset.rb +28 -0
- data/lib/ftp_paradise/toplevel_methods/connect.rb +49 -0
- data/lib/ftp_paradise/toplevel_methods/create_file.rb +18 -0
- data/lib/ftp_paradise/toplevel_methods/data.rb +31 -0
- data/lib/ftp_paradise/toplevel_methods/delete.rb +23 -0
- data/lib/ftp_paradise/toplevel_methods/determine_user_dataset_from_this_hash.rb +37 -0
- data/lib/ftp_paradise/toplevel_methods/e.rb +16 -0
- data/lib/ftp_paradise/toplevel_methods/ftp_object.rb +270 -0
- data/lib/ftp_paradise/toplevel_methods/get_files.rb +24 -0
- data/lib/ftp_paradise/toplevel_methods/is_directory.rb +33 -0
- data/lib/ftp_paradise/toplevel_methods/is_on_roebe.rb +20 -0
- data/lib/ftp_paradise/toplevel_methods/login_name.rb +49 -0
- data/lib/ftp_paradise/toplevel_methods/opn.rb +24 -0
- data/lib/ftp_paradise/toplevel_methods/password.rb +48 -0
- data/lib/ftp_paradise/toplevel_methods/port.rb +41 -0
- data/lib/ftp_paradise/toplevel_methods/rds.rb +18 -0
- data/lib/ftp_paradise/toplevel_methods/remote_url.rb +57 -0
- data/lib/ftp_paradise/toplevel_methods/time.rb +45 -0
- data/lib/ftp_paradise/toplevel_methods/upload.rb +29 -0
- data/lib/ftp_paradise/toplevel_methods/upload_this_binary_file.rb +58 -0
- data/lib/ftp_paradise/version/version.rb +19 -0
- data/lib/ftp_paradise/www/public/css/style.css +3 -0
- data/lib/ftp_paradise/www/sinatra_web_interface.rb +242 -0
- data/lib/ftp_paradise/www/views/index.slim +3 -0
- data/lib/ftp_paradise/www/views/layout.slim +11 -0
- data/lib/ftp_paradise/www/web_interface.cgi +35 -0
- data/lib/ftp_paradise/yaml/automatically_connect_on_startup_of_the_interactive_ftp_shell.yml +1 -0
- data/lib/ftp_paradise/yaml/debug.yml +1 -0
- data/lib/ftp_paradise/yaml/open_in_default_editor.yml +1 -0
- data/lib/ftp_paradise/yaml/show_full_names.yml +1 -0
- data/lib/ftp_paradise/yaml/use_colours.yml +1 -0
- data/test/testing_ftp_paradise.rb +94 -0
- data/test/testing_minimal_pure_net_ftp_example_to_connect.rb +28 -0
- data/test/testing_the_ftp_connection_component.rb +70 -0
- data/test/testing_upload_a_local_directory.rb +10 -0
- metadata +315 -0
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
#!/usr/bin/ruby -w
|
|
2
|
+
# Encoding: UTF-8
|
|
3
|
+
# frozen_string_literal: true
|
|
4
|
+
# =========================================================================== #
|
|
5
|
+
begin
|
|
6
|
+
require 'gtk_paradise'
|
|
7
|
+
rescue LoadError; end
|
|
8
|
+
|
|
9
|
+
module FtpParadise # === FtpParadise
|
|
10
|
+
|
|
11
|
+
module Gtk # === FtpParadise::Gtk
|
|
12
|
+
|
|
13
|
+
class Ftp < ::Gtk::Frame
|
|
14
|
+
|
|
15
|
+
begin
|
|
16
|
+
require 'cyberweb/web_images/web_images.rb'
|
|
17
|
+
rescue LoadError; end
|
|
18
|
+
|
|
19
|
+
# ========================================================================= #
|
|
20
|
+
# === SHALL_WE_DEBUG
|
|
21
|
+
# ========================================================================= #
|
|
22
|
+
SHALL_WE_DEBUG = false
|
|
23
|
+
|
|
24
|
+
# ========================================================================= #
|
|
25
|
+
# === MY_TEMP
|
|
26
|
+
# ========================================================================= #
|
|
27
|
+
if ENV['MY_TEMP']
|
|
28
|
+
MY_TEMP = ENV['MY_TEMP'].to_s+'/'
|
|
29
|
+
else
|
|
30
|
+
MY_TEMP = '/tmp/'
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# ========================================================================= #
|
|
34
|
+
# === USE_THIS_HOST
|
|
35
|
+
# ========================================================================= #
|
|
36
|
+
USE_THIS_HOST = 'square'
|
|
37
|
+
|
|
38
|
+
# ========================================================================= #
|
|
39
|
+
# === MAIN_BG_COLOUR
|
|
40
|
+
# ========================================================================= #
|
|
41
|
+
MAIN_BG_COLOUR = ::Gtk::Colours::BEIGE
|
|
42
|
+
|
|
43
|
+
# ========================================================================= #
|
|
44
|
+
# === MAIN_BG_COLOUR_PRELIGHT
|
|
45
|
+
# ========================================================================= #
|
|
46
|
+
MAIN_BG_COLOUR_PRELIGHT = ::Gtk::Colours::BLANCHEDALMOND
|
|
47
|
+
# ========================================================================= #
|
|
48
|
+
# === COLOUR_OF_BORDER
|
|
49
|
+
# ========================================================================= #
|
|
50
|
+
COLOUR_OF_BORDER = 'darkgreen' # DARKBLUE
|
|
51
|
+
USE_THIS_FONT = 'Sans 16' # Size tag.
|
|
52
|
+
TITLE = 'FTP Client'
|
|
53
|
+
IMG = ENV['IMG'].to_s+'/'
|
|
54
|
+
STOCK_ITEMS = IMG+'GUI/GTK/STOCK_ITEMS/'
|
|
55
|
+
DOWNLOAD_ICON = IMG+WebImages[:download2]
|
|
56
|
+
UPLOAD_ICON = IMG+WebImages[:upload2]
|
|
57
|
+
|
|
58
|
+
end; end; end
|
|
@@ -0,0 +1,1149 @@
|
|
|
1
|
+
#!/usr/bin/ruby -w
|
|
2
|
+
# Encoding: UTF-8
|
|
3
|
+
# frozen-string-literal: true
|
|
4
|
+
# =========================================================================== #
|
|
5
|
+
# === FtpParadise::Gtk::Ftp
|
|
6
|
+
#
|
|
7
|
+
# The Purpose of this class is to provide GTK-FTP Client.
|
|
8
|
+
#
|
|
9
|
+
# Usage examples:
|
|
10
|
+
#
|
|
11
|
+
# FtpParadise::Gtk::Ftp.new
|
|
12
|
+
#
|
|
13
|
+
# =========================================================================== #
|
|
14
|
+
# require 'ftp_paradise/gui/ftp_bindings.rb'
|
|
15
|
+
# =========================================================================== #
|
|
16
|
+
require 'ftp_paradise/requires/common_basic_requires.rb'
|
|
17
|
+
require 'ftp_paradise/requires/common_external_requires.rb'
|
|
18
|
+
require 'ftp_paradise/ftp_connection/connection.rb'
|
|
19
|
+
require 'ftp_paradise/constants/file_constants.rb'
|
|
20
|
+
require 'ftp_paradise/gui/gtk/constants.rb'
|
|
21
|
+
require 'gtk_paradise'
|
|
22
|
+
|
|
23
|
+
module FtpParadise # === FtpParadise
|
|
24
|
+
|
|
25
|
+
module Gtk # === FtpParadise::Gtk
|
|
26
|
+
|
|
27
|
+
class Ftp < ::Gtk::Frame # === FtpParadise::Gtk::Ftp.new
|
|
28
|
+
|
|
29
|
+
include ::Gtk::BaseModule
|
|
30
|
+
|
|
31
|
+
module WidthHeight
|
|
32
|
+
|
|
33
|
+
# ======================================================================= #
|
|
34
|
+
# === FTP_MAIN_ICON
|
|
35
|
+
# ======================================================================= #
|
|
36
|
+
FTP_MAIN_ICON = HOME_DIRECTOY_OF_USER_X+'DATA/IMG/PC/FTP/FTP.png'
|
|
37
|
+
|
|
38
|
+
# ======================================================================= #
|
|
39
|
+
# WIDTH and HEIGHT settings.
|
|
40
|
+
# ======================================================================= #
|
|
41
|
+
|
|
42
|
+
# ======================================================================= #
|
|
43
|
+
# === HEIGHT
|
|
44
|
+
# ======================================================================= #
|
|
45
|
+
HEIGHT = 680 # WidthHeight::HEIGHT
|
|
46
|
+
|
|
47
|
+
# ======================================================================= #
|
|
48
|
+
# === WIDTH
|
|
49
|
+
# ======================================================================= #
|
|
50
|
+
WIDTH = 740 # WidthHeight::WIDTH
|
|
51
|
+
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
include ::Gtk
|
|
55
|
+
include ::Gtk::Colours
|
|
56
|
+
include Colours # We require the Colours module here. Always.
|
|
57
|
+
include FtpParadise
|
|
58
|
+
include WidthHeight
|
|
59
|
+
|
|
60
|
+
# ========================================================================= #
|
|
61
|
+
# === initialize
|
|
62
|
+
# ========================================================================= #
|
|
63
|
+
def initialize(
|
|
64
|
+
run_already = true
|
|
65
|
+
)
|
|
66
|
+
super(TITLE)
|
|
67
|
+
set_font
|
|
68
|
+
set_background
|
|
69
|
+
run if run_already
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# ========================================================================= #
|
|
73
|
+
# === initialize_ftp_object (ftp tag, initialize tag)
|
|
74
|
+
#
|
|
75
|
+
# This method is called from within reset() method.
|
|
76
|
+
# ========================================================================= #
|
|
77
|
+
def initialize_ftp_object
|
|
78
|
+
@_ = FtpParadise::Connection.new(:dont_run_yet) # Our main ftp client.
|
|
79
|
+
@_.be_verbose = false # for now, let's be verbose.
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# ========================================================================= #
|
|
83
|
+
# === set_background
|
|
84
|
+
#
|
|
85
|
+
# This method actually sets the colour of the border.
|
|
86
|
+
# ========================================================================= #
|
|
87
|
+
def set_background
|
|
88
|
+
self.modify_bg(STATE_NORMAL,
|
|
89
|
+
validate_gtk_colour(COLOUR_OF_BORDER)
|
|
90
|
+
)
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# ========================================================================= #
|
|
94
|
+
# === set_font
|
|
95
|
+
# ========================================================================= #
|
|
96
|
+
def set_font(
|
|
97
|
+
i = USE_THIS_FONT
|
|
98
|
+
)
|
|
99
|
+
set_font_in_use_for_this_application(i)
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# ========================================================================= #
|
|
103
|
+
# === create_renderer
|
|
104
|
+
# ========================================================================= #
|
|
105
|
+
def create_renderer
|
|
106
|
+
@cell_renderer_text = gtk_cell_renderer_text
|
|
107
|
+
@cell_renderer_text.set_property('background', 'lavender')
|
|
108
|
+
@cell_renderer_text.set_property('foreground', 'black')
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
# ========================================================================= #
|
|
112
|
+
# === add_status_message
|
|
113
|
+
#
|
|
114
|
+
# Use this to append to the Statusbar.
|
|
115
|
+
# ========================================================================= #
|
|
116
|
+
def add_status_message(i)
|
|
117
|
+
@status_bar.push @status_bar_context_id, i
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
# ========================================================================= #
|
|
121
|
+
# === create_gtk_liststore
|
|
122
|
+
#
|
|
123
|
+
# Uses Gtk::ListStore. These lists contain the local and
|
|
124
|
+
# remote files.
|
|
125
|
+
# ========================================================================= #
|
|
126
|
+
def create_gtk_liststore
|
|
127
|
+
@list_store_local_files = ::Gtk::ListStore[
|
|
128
|
+
String, ::GdkPixbuf::Pixbuf
|
|
129
|
+
]
|
|
130
|
+
@list_store_remote_files = ::Gtk::ListStore[
|
|
131
|
+
String, ::GdkPixbuf::Pixbuf
|
|
132
|
+
]
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
# ========================================================================= #
|
|
136
|
+
# === create_accel_groups
|
|
137
|
+
# ========================================================================= #
|
|
138
|
+
def create_accel_groups
|
|
139
|
+
@accel_group = gtk_accel_group
|
|
140
|
+
self.add_accel_group(@accel_group)
|
|
141
|
+
@accel_group.connect( Gdk::Keyval::GDK_Q,
|
|
142
|
+
Gdk::Window::CONTROL_MASK, ACCEL_VISIBLE) {
|
|
143
|
+
e 'Global quit key issued. Quitting.'
|
|
144
|
+
efancy 'Bye!'
|
|
145
|
+
Gtk.main_quit
|
|
146
|
+
}
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
# ========================================================================= #
|
|
150
|
+
# === update_local_files
|
|
151
|
+
# ========================================================================= #
|
|
152
|
+
def update_local_files(
|
|
153
|
+
be_verbose = false
|
|
154
|
+
)
|
|
155
|
+
@list_store_local_files.clear
|
|
156
|
+
@tree_view_local_files.remove_column(
|
|
157
|
+
@tree_view_column_local_files
|
|
158
|
+
)
|
|
159
|
+
@tree_view_column_local_files = TreeViewColumn.new('Local Files',
|
|
160
|
+
@cell_renderer_text, {:text => 0})
|
|
161
|
+
update_array_with_local_files
|
|
162
|
+
fill_up_iter_for_local_files
|
|
163
|
+
@tree_view_local_files.append_column(@tree_view_column_local_files)
|
|
164
|
+
colour_to_use = 'darkblue'
|
|
165
|
+
_ = "<markup><span weight=\"bold\" foreground=\""+colour_to_use+"\">LocalDir: #{return_current_directory}</span></markup>"
|
|
166
|
+
@label_local_dir.set_markup(_, true)
|
|
167
|
+
if be_verbose
|
|
168
|
+
e 'Reporting in '+sdir(Dir.pwd)+':'
|
|
169
|
+
pp @array_file_listing_local
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
# ========================================================================= #
|
|
174
|
+
# === return_current_directory
|
|
175
|
+
# ========================================================================= #
|
|
176
|
+
def return_current_directory
|
|
177
|
+
return rds(Dir.pwd+'/')
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
# ========================================================================= #
|
|
181
|
+
# === update_everything (update tag)
|
|
182
|
+
# ========================================================================= #
|
|
183
|
+
def update_everything
|
|
184
|
+
e ' => Updating content of remote and local files now.'
|
|
185
|
+
update_local_files(false)
|
|
186
|
+
update_remote_files
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
# ========================================================================= #
|
|
190
|
+
# === check_for_file_uploading
|
|
191
|
+
#
|
|
192
|
+
# Also checks if there is a directory but it wont change dir.
|
|
193
|
+
# ========================================================================= #
|
|
194
|
+
def check_for_file_uploading(i = '..')
|
|
195
|
+
if i.is_a? String
|
|
196
|
+
opn; e "Now uploading the file `#{sfile(i)}` to `#{simp(host?)}`."
|
|
197
|
+
if File.directory? i
|
|
198
|
+
e sdir(i)+' is a dir - dont wanna upload it. Instead, '+
|
|
199
|
+
'we will enter it now.'
|
|
200
|
+
cd i
|
|
201
|
+
update_local_files(false)
|
|
202
|
+
elsif File.symlink? i
|
|
203
|
+
# pass thru
|
|
204
|
+
e i+' is a symlink - dont wanna upload'
|
|
205
|
+
else # If we assume a file here, then we upload the file.
|
|
206
|
+
output_coloured_line ' => Uploading file:'
|
|
207
|
+
e sfile(i)+' is a file, so we upload it:'
|
|
208
|
+
@_.upload(i)
|
|
209
|
+
update_everything
|
|
210
|
+
end
|
|
211
|
+
else
|
|
212
|
+
opn; e 'The input is not a string. Instead, it is of '+
|
|
213
|
+
'class '+simp(i.class.to_s)+'.'
|
|
214
|
+
end
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
# ========================================================================= #
|
|
218
|
+
# === set_current_dir
|
|
219
|
+
#
|
|
220
|
+
# Use only this method to modify the @current_dir.
|
|
221
|
+
# ========================================================================= #
|
|
222
|
+
def set_current_dir(i = Dir.pwd+'/')
|
|
223
|
+
i << '/' unless i.end_with? '/'
|
|
224
|
+
@current_dir = i # tracks the current dir
|
|
225
|
+
end; alias set_local_dir set_current_dir # === set_local_dir
|
|
226
|
+
|
|
227
|
+
# ========================================================================= #
|
|
228
|
+
# === update_array_with_local_files
|
|
229
|
+
#
|
|
230
|
+
# Here we update the local file listing.
|
|
231
|
+
# ========================================================================= #
|
|
232
|
+
def update_array_with_local_files
|
|
233
|
+
_ = Dir['*'].sort
|
|
234
|
+
_.unshift '..' # Add .. to beginning of the Array.
|
|
235
|
+
# Since 10.12.2011 we use only the basename.
|
|
236
|
+
_.map! {|entry| File.basename(entry) }
|
|
237
|
+
@array_file_listing_local = _
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
# ========================================================================= #
|
|
241
|
+
# === set_login_name
|
|
242
|
+
# ========================================================================= #
|
|
243
|
+
def set_login_name(i = '')
|
|
244
|
+
@login_name = i
|
|
245
|
+
update_login_name # Sync it here.
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
# ========================================================================= #
|
|
249
|
+
# === set_password
|
|
250
|
+
# ========================================================================= #
|
|
251
|
+
def set_password(i = '1aaaaaa')
|
|
252
|
+
@password = i
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
# ========================================================================= #
|
|
256
|
+
# === reset
|
|
257
|
+
# ========================================================================= #
|
|
258
|
+
def reset
|
|
259
|
+
@label_remote_dir = nil
|
|
260
|
+
@colour_for_label = 'darkblue'
|
|
261
|
+
set_remote_dir(nil)
|
|
262
|
+
# ======================================================================= #
|
|
263
|
+
# Use the available hosts next.
|
|
264
|
+
# ======================================================================= #
|
|
265
|
+
if FtpParadise.const_defined? :RoebeFtpConstants
|
|
266
|
+
@array_possible_hosts = FtpParadise::RoebeFtpConstants.possible_hosts?
|
|
267
|
+
@array_possible_hosts.reject! {|entry| entry.include? 'geas' }
|
|
268
|
+
end
|
|
269
|
+
@entry_user_name = nil
|
|
270
|
+
@debug = SHALL_WE_DEBUG
|
|
271
|
+
set_password
|
|
272
|
+
initialize_ftp_object
|
|
273
|
+
set_host # wrapper
|
|
274
|
+
if Dir.pwd.include? '/Users/x'
|
|
275
|
+
cd MY_TEMP if MY_TEMP
|
|
276
|
+
end
|
|
277
|
+
@button_ftp_target = ''
|
|
278
|
+
@array_file_listing_local = []
|
|
279
|
+
@array_file_listing_remote = []
|
|
280
|
+
# ======================================================================= #
|
|
281
|
+
# We also must keep an updated list of allowed hosts.
|
|
282
|
+
# ======================================================================= #
|
|
283
|
+
if Object.const_defined? :RoebeFtpConstants
|
|
284
|
+
@_.set_data 'square' # MY_FTP['geas']['url'] # prepend to the array.
|
|
285
|
+
end
|
|
286
|
+
@v_box = VBox.new
|
|
287
|
+
@h_box_ftp_entry = HBox.new
|
|
288
|
+
@h_box_ftp_entry.border_width = 5
|
|
289
|
+
update_array_with_local_files
|
|
290
|
+
set_login_name '0fe_14741968'
|
|
291
|
+
end
|
|
292
|
+
|
|
293
|
+
# ========================================================================= #
|
|
294
|
+
# === create_statusbar
|
|
295
|
+
#
|
|
296
|
+
# Create the Statusbar.
|
|
297
|
+
# ========================================================================= #
|
|
298
|
+
def create_statusbar
|
|
299
|
+
@status_bar = gtk_statusbar
|
|
300
|
+
@status_bar.has_resize_grip = true
|
|
301
|
+
@status_bar_context_id = @status_bar.get_context_id('Gtk Ftp Client')
|
|
302
|
+
end
|
|
303
|
+
|
|
304
|
+
# ========================================================================= #
|
|
305
|
+
# === create_hboxes
|
|
306
|
+
#
|
|
307
|
+
# The buttons must exist before calling this method.
|
|
308
|
+
# ========================================================================= #
|
|
309
|
+
def create_hboxes
|
|
310
|
+
@hbox_for_buttons = gtk_hbox
|
|
311
|
+
@hbox_for_buttons.pack_start(
|
|
312
|
+
@button_debug, true, true, 5)
|
|
313
|
+
@hbox_for_buttons.pack_start(
|
|
314
|
+
@button_update_listing, true, true, 5)
|
|
315
|
+
@hbox_for_dirs = gtk_hbox
|
|
316
|
+
@hbox_for_dirs.pack_start(
|
|
317
|
+
@label_local_dir = ::Gtk.modify_bold_label(
|
|
318
|
+
'LocalDir: '+@current_dir, 'darkblue'), true, false, 1)
|
|
319
|
+
@hbox_for_dirs.pack_start(
|
|
320
|
+
@label_remote_dir = gtk_label, true, false,1
|
|
321
|
+
)
|
|
322
|
+
set_remote_dir
|
|
323
|
+
@hbox_for_arrows = gtk_hbox # Add both buttons to the hbox for arrows.
|
|
324
|
+
@hbox_for_arrows.add(@button_upload)
|
|
325
|
+
@hbox_for_arrows.add(@button_download)
|
|
326
|
+
end
|
|
327
|
+
|
|
328
|
+
# ========================================================================= #
|
|
329
|
+
# === create_boxes
|
|
330
|
+
#
|
|
331
|
+
# Used for?
|
|
332
|
+
# When we call this method, @scrolled_window_local_files must already
|
|
333
|
+
# exist.
|
|
334
|
+
# ========================================================================= #
|
|
335
|
+
def create_boxes
|
|
336
|
+
@h_box_file_listing = HBox.new(true, 0)
|
|
337
|
+
@h_box_file_listing.add(@scrolled_window_local_files)
|
|
338
|
+
@h_box_file_listing.add(@scrolled_window_remote_files)
|
|
339
|
+
end
|
|
340
|
+
|
|
341
|
+
# ========================================================================= #
|
|
342
|
+
# === create_status_icon
|
|
343
|
+
# ========================================================================= #
|
|
344
|
+
def create_status_icon
|
|
345
|
+
@status_icon = StatusIcon.new
|
|
346
|
+
@status_icon.pixbuf = Gdk::Pixbuf.new(FTP_MAIN_ICON)
|
|
347
|
+
@status_icon.tooltip = 'StatusIcon'
|
|
348
|
+
end
|
|
349
|
+
|
|
350
|
+
# ========================================================================= #
|
|
351
|
+
# === delete_remote_file
|
|
352
|
+
#
|
|
353
|
+
# Wrapper to delete a remote file.
|
|
354
|
+
# ========================================================================= #
|
|
355
|
+
def delete_remote_file
|
|
356
|
+
ewarn 'Deleting this remote file:'
|
|
357
|
+
efancy selection?(:right)
|
|
358
|
+
@_.remove_file( selection?(:right) )
|
|
359
|
+
update_everything
|
|
360
|
+
end
|
|
361
|
+
|
|
362
|
+
# ========================================================================= #
|
|
363
|
+
# === enable_dragging
|
|
364
|
+
#
|
|
365
|
+
# Enables dragging for local and remote files.
|
|
366
|
+
# ========================================================================= #
|
|
367
|
+
def enable_dragging
|
|
368
|
+
[
|
|
369
|
+
@tree_view_local_files, @tree_view_remote_files
|
|
370
|
+
].each { |tree_view|
|
|
371
|
+
tree_view.enable_model_drag_source(Gdk::Window::BUTTON1_MASK,
|
|
372
|
+
[ ['GTK_TREE_MODEL_ROW', 0, 0] ],
|
|
373
|
+
Gdk::DragContext::ACTION_COPY|Gdk::DragContext::ACTION_MOVE)
|
|
374
|
+
tree_view.enable_model_drag_dest(
|
|
375
|
+
[ ['GTK_TREE_MODEL_ROW', 0, 0] ],
|
|
376
|
+
Gdk::DragContext::ACTION_COPY|Gdk::DragContext::ACTION_MOVE)
|
|
377
|
+
}
|
|
378
|
+
end
|
|
379
|
+
|
|
380
|
+
# ========================================================================= #
|
|
381
|
+
# === hook_up_tree_view_clicks
|
|
382
|
+
#
|
|
383
|
+
# Connect our tree views with mouse clicks.
|
|
384
|
+
# ========================================================================= #
|
|
385
|
+
def hook_up_tree_view_clicks
|
|
386
|
+
@tree_view_local_files.signal_connect(:button_release_event) { |widget, event|
|
|
387
|
+
ewarn selection?(:left)
|
|
388
|
+
check_for_file_uploading(selection?(:left))
|
|
389
|
+
}
|
|
390
|
+
# Nun die remote files.
|
|
391
|
+
@tree_view_remote_files.signal_connect(:button_release_event) { |widget, event|
|
|
392
|
+
selected = selection?(:right).to_s
|
|
393
|
+
e 'The selected file is: `'+sfancy(selected)+'`'
|
|
394
|
+
e 'Is '+selected+' a directory? '+@_.is_directory?(selected).to_s
|
|
395
|
+
e swarn('-> TODO (FIXME): if it is a file, download, if it is a directory, enter directory.')
|
|
396
|
+
if @_.is_a_directory?(selected) # If it is a directory, change into it.
|
|
397
|
+
change_remote_directory(selected)
|
|
398
|
+
else
|
|
399
|
+
set_remote_dir
|
|
400
|
+
download_files(selected)
|
|
401
|
+
end
|
|
402
|
+
}
|
|
403
|
+
end
|
|
404
|
+
|
|
405
|
+
# ========================================================================= #
|
|
406
|
+
# === fill_up_iter_for_local_files
|
|
407
|
+
#
|
|
408
|
+
# Now iterate through our file listing.
|
|
409
|
+
# ========================================================================= #
|
|
410
|
+
def fill_up_iter_for_local_files
|
|
411
|
+
_ = '/Users/x/DATA/IMG/STD/UHR.png'
|
|
412
|
+
@array_file_listing_local.each { |file|
|
|
413
|
+
next if file == '..' && (Dir.pwd == '/')
|
|
414
|
+
file << '/' if File.directory?(file) # append if is directory.
|
|
415
|
+
iter = @list_store_local_files.append
|
|
416
|
+
iter.set_value(0, file)
|
|
417
|
+
if File.exist? _
|
|
418
|
+
iter.set_value(1, GdkPixbuf::Pixbuf.new(_)) # Uhr Icon.
|
|
419
|
+
else
|
|
420
|
+
ewarn 'File at '+sfile(_)+' does not exist.'
|
|
421
|
+
end
|
|
422
|
+
}
|
|
423
|
+
end
|
|
424
|
+
|
|
425
|
+
# ========================================================================= #
|
|
426
|
+
# === change_remote_directory
|
|
427
|
+
# ========================================================================= #
|
|
428
|
+
def change_remote_directory(i)
|
|
429
|
+
@_.change_remote_directory(i)
|
|
430
|
+
update_remote_files
|
|
431
|
+
end
|
|
432
|
+
|
|
433
|
+
# ========================================================================= #
|
|
434
|
+
# === change_dir_and_report
|
|
435
|
+
#
|
|
436
|
+
# Use this method if you want to change the local directory. It will also
|
|
437
|
+
# assign to a new @current_dir, via the method set_current_dir()
|
|
438
|
+
# ========================================================================= #
|
|
439
|
+
def change_dir_and_report(input = '..')
|
|
440
|
+
Dir.chdir(input)
|
|
441
|
+
e 'Current directory: '+sdir(Dir.pwd)
|
|
442
|
+
set_current_dir
|
|
443
|
+
end; alias cd change_dir_and_report # === cd
|
|
444
|
+
|
|
445
|
+
# ========================================================================= #
|
|
446
|
+
# === create_main_table
|
|
447
|
+
#
|
|
448
|
+
# @main_table tag.
|
|
449
|
+
# ========================================================================= #
|
|
450
|
+
def create_main_table
|
|
451
|
+
n_rows = 10
|
|
452
|
+
@main_table = Table.new(n_rows, 2, true)
|
|
453
|
+
@main_table.set_column_spacings(2)
|
|
454
|
+
@main_table.set_row_spacings(2)
|
|
455
|
+
fill_main_table
|
|
456
|
+
end
|
|
457
|
+
|
|
458
|
+
# ========================================================================= #
|
|
459
|
+
# === create_gtk_buttons (buttons tag)
|
|
460
|
+
#
|
|
461
|
+
# This method will create all the different buttons.
|
|
462
|
+
# ========================================================================= #
|
|
463
|
+
def create_gtk_buttons
|
|
464
|
+
create_debug_button
|
|
465
|
+
create_update_button
|
|
466
|
+
# ======================================================================= #
|
|
467
|
+
# This button is a ComboBox which has all of our default FTP hosts.
|
|
468
|
+
# ======================================================================= #
|
|
469
|
+
@button_ftp_site = ComboBoxEntry.new(true) # True for text-only.
|
|
470
|
+
# The remote-file removal button.
|
|
471
|
+
@button_delete_remote_file = gtk_button('_DeleteRemoteFile')
|
|
472
|
+
@button_delete_remote_file.signal_connect(:clicked) {
|
|
473
|
+
delete_remote_file
|
|
474
|
+
}
|
|
475
|
+
@button_ftp_site.modify_bg( ::Gtk::StateType::NORMAL, GREY)
|
|
476
|
+
@button_ftp_site.modify_bg( ::Gtk::StateType::PRELIGHT, GREY)
|
|
477
|
+
@button_ftp_site.modify_bg( ::Gtk::StateType::ACTIVE, GREY)
|
|
478
|
+
|
|
479
|
+
name_tip = 'Use this when you wish to remove a remote file.'
|
|
480
|
+
::Gtk::Tooltips.new.set_tip(
|
|
481
|
+
@button_delete_remote_file, name_tip, nil
|
|
482
|
+
)
|
|
483
|
+
# ======================================================================= #
|
|
484
|
+
# The Drop down combo box. Dropdown combo box. (Dropdown tag)
|
|
485
|
+
# ======================================================================= #
|
|
486
|
+
@array_possible_hosts.each {|val|
|
|
487
|
+
@button_ftp_site.append_text(val)
|
|
488
|
+
}
|
|
489
|
+
# ======================================================================= #
|
|
490
|
+
# Assign to the last entry.
|
|
491
|
+
# ======================================================================= #
|
|
492
|
+
set_host(default_host?)
|
|
493
|
+
@button_ftp_site.active = @array_possible_hosts.size - 1
|
|
494
|
+
# ======================================================================= #
|
|
495
|
+
# The connect-button on the right side will be created next.
|
|
496
|
+
# ======================================================================= #
|
|
497
|
+
create_connect_button
|
|
498
|
+
# ======================================================================= #
|
|
499
|
+
# === Upload Button (left tag)
|
|
500
|
+
#
|
|
501
|
+
# The upload button with the right arrow.
|
|
502
|
+
# ======================================================================= #
|
|
503
|
+
@button_upload = gtk_button
|
|
504
|
+
_ = STOCK_ITEMS+'stock_right_arrow_24.png'
|
|
505
|
+
left = Image.new(_)
|
|
506
|
+
@button_upload.signal_connect(:clicked) {
|
|
507
|
+
output_coloured_line('Uploading file(s)')
|
|
508
|
+
check_for_file_uploading
|
|
509
|
+
}
|
|
510
|
+
hbox = gtk_hbox
|
|
511
|
+
hbox.add gtk_image(UPLOAD_ICON)
|
|
512
|
+
hbox.add left
|
|
513
|
+
@button_upload.add(hbox)
|
|
514
|
+
name_tip = 'Upload the selected files/directories.'
|
|
515
|
+
::Gtk::Tooltips.new.set_tip(@button_upload, name_tip, nil)
|
|
516
|
+
# ======================================================================= #
|
|
517
|
+
# === Download Button
|
|
518
|
+
#
|
|
519
|
+
# The download button with the left arrow.
|
|
520
|
+
# ======================================================================= #
|
|
521
|
+
@button_download = gtk_button
|
|
522
|
+
right = Image.new(STOCK_ITEMS+'stock_left_arrow_24.png')
|
|
523
|
+
@button_download.signal_connect(:clicked) {
|
|
524
|
+
output_coloured_line('Download file(s)')
|
|
525
|
+
download_files
|
|
526
|
+
}
|
|
527
|
+
hbox = gtk_hbox
|
|
528
|
+
hbox.add right
|
|
529
|
+
hbox.add gtk_image(DOWNLOAD_ICON)
|
|
530
|
+
@button_download.add(hbox)
|
|
531
|
+
name_tip = 'Download the selected (remote) files/directories.'
|
|
532
|
+
::Gtk::Tooltips.new.set_tip(@button_download, name_tip, nil)
|
|
533
|
+
# ======================================================================= #
|
|
534
|
+
# Lets spice it up, and use some colours for our buttons.
|
|
535
|
+
# ======================================================================= #
|
|
536
|
+
[
|
|
537
|
+
@button_ftp_site,
|
|
538
|
+
@button_connect,
|
|
539
|
+
@button_debug,
|
|
540
|
+
@button_update_listing,
|
|
541
|
+
@button_delete_remote_file,
|
|
542
|
+
@button_download
|
|
543
|
+
].each { |a_button|
|
|
544
|
+
a_button.modify_bg( StateType::ACTIVE, CORAL )
|
|
545
|
+
a_button.modify_bg( StateType::NORMAL, CORNFLOWERBLUE )
|
|
546
|
+
a_button.modify_bg( StateType::PRELIGHT, DARKVIOLET )
|
|
547
|
+
}
|
|
548
|
+
# ======================================================================= #
|
|
549
|
+
# Here come buttons which shouldnt highlight that awfully.
|
|
550
|
+
# ======================================================================= #
|
|
551
|
+
[
|
|
552
|
+
@button_upload, @button_download
|
|
553
|
+
].each { |a_button|
|
|
554
|
+
a_button.modify_bg( StateType::ACTIVE, MAIN_BG_COLOUR )
|
|
555
|
+
a_button.modify_bg( StateType::NORMAL, MAIN_BG_COLOUR )
|
|
556
|
+
a_button.modify_bg( StateType::PRELIGHT, MAIN_BG_COLOUR_PRELIGHT)
|
|
557
|
+
a_button.set_border_width(14)
|
|
558
|
+
}
|
|
559
|
+
end
|
|
560
|
+
|
|
561
|
+
# ========================================================================= #
|
|
562
|
+
# === fill_up_iter_for_remote_files
|
|
563
|
+
# ========================================================================= #
|
|
564
|
+
def fill_up_iter_for_remote_files
|
|
565
|
+
if @debug
|
|
566
|
+
cliner { pp @array_file_listing_remote }
|
|
567
|
+
end
|
|
568
|
+
@array_file_listing_remote.each {|file|
|
|
569
|
+
if @debug
|
|
570
|
+
opn; e "THE REMOTE FILE WAS: `#{file}`"
|
|
571
|
+
end
|
|
572
|
+
# file = file + '/' if File.directory?(file)
|
|
573
|
+
iter = @list_store_remote_files.append
|
|
574
|
+
begin
|
|
575
|
+
_ = file.first
|
|
576
|
+
if file[1] == 'directory'
|
|
577
|
+
_ << '/' unless _.end_with? '/'
|
|
578
|
+
end
|
|
579
|
+
iter.set_value(0, _)
|
|
580
|
+
rescue Exception => error
|
|
581
|
+
opn; e 'An exception happened at line: '+__LINE__.to_s
|
|
582
|
+
cliner {pp file}
|
|
583
|
+
pp error
|
|
584
|
+
end
|
|
585
|
+
}
|
|
586
|
+
end
|
|
587
|
+
|
|
588
|
+
# ========================================================================= #
|
|
589
|
+
# === create_debug_button (debug tag, debug button)
|
|
590
|
+
# ========================================================================= #
|
|
591
|
+
def create_debug_button
|
|
592
|
+
@button_debug = gtk_button('_Debug') # The debug-button.
|
|
593
|
+
@button_debug.signal_connect(:clicked) {
|
|
594
|
+
e 'Debugging FTP Client.'
|
|
595
|
+
efancy ' '+@entry_search.text
|
|
596
|
+
output_coloured_line(@button_ftp_site.active_text)
|
|
597
|
+
pp @_.array_file_listing
|
|
598
|
+
e
|
|
599
|
+
e 'The current directory is: '+sdir(@current_dir.to_s)
|
|
600
|
+
e
|
|
601
|
+
ecomment ('The password is: ').ljust(20)+password?, token: ':'
|
|
602
|
+
ecomment 'The login name is: '+@login_name, token: ':'
|
|
603
|
+
}
|
|
604
|
+
end
|
|
605
|
+
|
|
606
|
+
# ========================================================================= #
|
|
607
|
+
# === password?
|
|
608
|
+
# ========================================================================= #
|
|
609
|
+
def password?
|
|
610
|
+
@_.password?
|
|
611
|
+
end
|
|
612
|
+
|
|
613
|
+
# ========================================================================= #
|
|
614
|
+
# === do_ftp_login
|
|
615
|
+
#
|
|
616
|
+
# Wrapper towards the FTP Connection. Call from within initialize().
|
|
617
|
+
# ========================================================================= #
|
|
618
|
+
def do_ftp_login
|
|
619
|
+
@_.set_ascii
|
|
620
|
+
@_.set_passive
|
|
621
|
+
@_.do_connect
|
|
622
|
+
end
|
|
623
|
+
|
|
624
|
+
# ========================================================================= #
|
|
625
|
+
# === download_files
|
|
626
|
+
#
|
|
627
|
+
# Use this to download one or several files.
|
|
628
|
+
# ========================================================================= #
|
|
629
|
+
def download_files(i)
|
|
630
|
+
if i.is_a? Array
|
|
631
|
+
i.each {|entry| download_files(entry) }
|
|
632
|
+
else
|
|
633
|
+
e 'We will now try to download '+sfile(i)+'.'
|
|
634
|
+
@_.download_remote_file(i)
|
|
635
|
+
end
|
|
636
|
+
end
|
|
637
|
+
|
|
638
|
+
# ========================================================================= #
|
|
639
|
+
# === create_entries
|
|
640
|
+
# ========================================================================= #
|
|
641
|
+
def create_entries
|
|
642
|
+
create_search_entry
|
|
643
|
+
create_user_name_entry
|
|
644
|
+
end
|
|
645
|
+
|
|
646
|
+
# ========================================================================= #
|
|
647
|
+
# === create_search_entry
|
|
648
|
+
# ========================================================================= #
|
|
649
|
+
def create_search_entry
|
|
650
|
+
# The search entry box at bottom (ganz unten...)
|
|
651
|
+
@entry_search = gtk_entry
|
|
652
|
+
@entry_search.signal_connect(:key_press_event) { |w,event|
|
|
653
|
+
e Gdk::Keyval.to_name(event.keyval)
|
|
654
|
+
}
|
|
655
|
+
@entry_search.set_text('Input file filter here:')
|
|
656
|
+
@entry_search.set_focus(true)
|
|
657
|
+
@entry_search.signal_connect(:button_press_event) { |widget, event|
|
|
658
|
+
@entry_search.set_focus(true)
|
|
659
|
+
@entry_search.select_region(0, -1)
|
|
660
|
+
}
|
|
661
|
+
end
|
|
662
|
+
|
|
663
|
+
# ========================================================================= #
|
|
664
|
+
# === user_name?
|
|
665
|
+
# ========================================================================= #
|
|
666
|
+
def user_name?
|
|
667
|
+
@entry_user_name.text
|
|
668
|
+
end
|
|
669
|
+
|
|
670
|
+
# ========================================================================= #
|
|
671
|
+
# === update_login_name
|
|
672
|
+
# ========================================================================= #
|
|
673
|
+
def update_login_name
|
|
674
|
+
if @entry_user_name
|
|
675
|
+
@entry_user_name.text = @login_name
|
|
676
|
+
end
|
|
677
|
+
end
|
|
678
|
+
|
|
679
|
+
# ========================================================================= #
|
|
680
|
+
# === show_startup_message
|
|
681
|
+
# ========================================================================= #
|
|
682
|
+
def show_startup_message
|
|
683
|
+
cliner {
|
|
684
|
+
e ' => Starting GTK2 FTP Client '\
|
|
685
|
+
'(Height: '+sfancy(height?.to_s)+', '\
|
|
686
|
+
'Width: '+sfancy(width?.to_s)+')'
|
|
687
|
+
}
|
|
688
|
+
end
|
|
689
|
+
|
|
690
|
+
# ========================================================================= #
|
|
691
|
+
# === height?
|
|
692
|
+
# ========================================================================= #
|
|
693
|
+
def height?
|
|
694
|
+
WidthHeight::HEIGHT
|
|
695
|
+
end
|
|
696
|
+
|
|
697
|
+
# ========================================================================= #
|
|
698
|
+
# === width?
|
|
699
|
+
# ========================================================================= #
|
|
700
|
+
def width?
|
|
701
|
+
WidthHeight::WIDTH
|
|
702
|
+
end
|
|
703
|
+
|
|
704
|
+
# ========================================================================= #
|
|
705
|
+
# === sanitize_file_listing
|
|
706
|
+
#
|
|
707
|
+
# Sanitizes file listing of the remote computer.
|
|
708
|
+
# ========================================================================= #
|
|
709
|
+
def sanitize_file_listing
|
|
710
|
+
unless @_.array_file_listing.nil?
|
|
711
|
+
@array_file_listing_remote = @_.array_file_listing
|
|
712
|
+
update_array_with_remote_files
|
|
713
|
+
end
|
|
714
|
+
end; alias update_remote_file_listing sanitize_file_listing # === update_remote_file_listing
|
|
715
|
+
|
|
716
|
+
# ========================================================================= #
|
|
717
|
+
# === update_array_with_remote_files
|
|
718
|
+
# ========================================================================= #
|
|
719
|
+
def update_array_with_remote_files
|
|
720
|
+
output_coloured_line ' > Updating array for remote files'
|
|
721
|
+
if @_.is_connected?
|
|
722
|
+
@_.get_listing
|
|
723
|
+
@_.report_current_remote_dir
|
|
724
|
+
end
|
|
725
|
+
@array_file_listing_remote = @_.array_file_listing
|
|
726
|
+
@array_file_listing_remote.unshift(
|
|
727
|
+
['../','directory', '0']
|
|
728
|
+
) # Add '..' to beginning of the Array.
|
|
729
|
+
if debug?
|
|
730
|
+
opn; e 'Debugging @array_file_listing_remote next:'
|
|
731
|
+
pp @array_file_listing_remote
|
|
732
|
+
end
|
|
733
|
+
end
|
|
734
|
+
|
|
735
|
+
# ========================================================================= #
|
|
736
|
+
# === debug?
|
|
737
|
+
# ========================================================================= #
|
|
738
|
+
def debug?
|
|
739
|
+
@debug
|
|
740
|
+
end
|
|
741
|
+
|
|
742
|
+
# ========================================================================= #
|
|
743
|
+
# === create_update_button (update button tag)
|
|
744
|
+
#
|
|
745
|
+
# This is the update button.
|
|
746
|
+
# ========================================================================= #
|
|
747
|
+
def create_update_button
|
|
748
|
+
# ======================================================================= #
|
|
749
|
+
# The Update button comes next.
|
|
750
|
+
# ======================================================================= #
|
|
751
|
+
@button_update_listing = Button.new('_Update')
|
|
752
|
+
@button_update_listing.signal_connect(:clicked) {
|
|
753
|
+
output_coloured_line('Updating remote file listing')
|
|
754
|
+
update_remote_files
|
|
755
|
+
}
|
|
756
|
+
name_tip = 'Use this when you wish to update the remote file listing.'
|
|
757
|
+
::Gtk::Tooltips.new.set_tip(@button_update_listing, name_tip, nil)
|
|
758
|
+
end
|
|
759
|
+
|
|
760
|
+
# ========================================================================= #
|
|
761
|
+
# === create_connect_button (connect tag)
|
|
762
|
+
# ========================================================================= #
|
|
763
|
+
def create_connect_button
|
|
764
|
+
@button_connect = Button.new(Stock::CONNECT)
|
|
765
|
+
name_tip = 'Connect to the remote site by clicking this button.'
|
|
766
|
+
::Gtk::Tooltips.new.set_tip(@button_connect, name_tip, nil)
|
|
767
|
+
@button_connect.signal_connect(:clicked) {
|
|
768
|
+
set_host(@button_ftp_site.active_text)
|
|
769
|
+
@_.set_password(@password)
|
|
770
|
+
@_.set_login_name(user_name?) # This is the user name.
|
|
771
|
+
cliner {
|
|
772
|
+
e 'Connecting to:'+sfancy(' '+host?)
|
|
773
|
+
}
|
|
774
|
+
@_.show_host_user_name_port_and_password
|
|
775
|
+
begin
|
|
776
|
+
connect_to_remote_host # Use this wrapper to login.
|
|
777
|
+
update_remote_file_listing
|
|
778
|
+
update_remote_files # This is for the GUI component.
|
|
779
|
+
rescue SocketError => error
|
|
780
|
+
e 'A small Error (SocketError) occurred:'
|
|
781
|
+
e error
|
|
782
|
+
end
|
|
783
|
+
}
|
|
784
|
+
end
|
|
785
|
+
|
|
786
|
+
# ========================================================================= #
|
|
787
|
+
# === host?
|
|
788
|
+
# ========================================================================= #
|
|
789
|
+
def host?
|
|
790
|
+
@host
|
|
791
|
+
end
|
|
792
|
+
|
|
793
|
+
# ========================================================================= #
|
|
794
|
+
# === set_host
|
|
795
|
+
# ========================================================================= #
|
|
796
|
+
def set_host(i = default_host?)
|
|
797
|
+
@host = i
|
|
798
|
+
@_.set_host(i) if @_
|
|
799
|
+
end
|
|
800
|
+
|
|
801
|
+
# ========================================================================= #
|
|
802
|
+
# === default_host?
|
|
803
|
+
# ========================================================================= #
|
|
804
|
+
def default_host?
|
|
805
|
+
@array_possible_hosts[-1]
|
|
806
|
+
end
|
|
807
|
+
|
|
808
|
+
# ========================================================================= #
|
|
809
|
+
# === connect_to_remote_host
|
|
810
|
+
#
|
|
811
|
+
# Use this method when connecting to the remote host.
|
|
812
|
+
# ========================================================================= #
|
|
813
|
+
def connect_to_remote_host(this_host = host?)
|
|
814
|
+
this_host = this_host.to_s
|
|
815
|
+
@_.connect_to this_host, :be_verbose
|
|
816
|
+
add_status_message 'Connecting to '+this_host.to_s+' now.'
|
|
817
|
+
try_to_sync_label_remote_dir
|
|
818
|
+
end
|
|
819
|
+
|
|
820
|
+
# ========================================================================= #
|
|
821
|
+
# === create_scrolled_windows
|
|
822
|
+
#
|
|
823
|
+
# We use two scrolled windows - the left side has our local files and
|
|
824
|
+
# the right side holds our remote files.
|
|
825
|
+
# ========================================================================= #
|
|
826
|
+
def create_scrolled_windows
|
|
827
|
+
@scrolled_window_local_files = ScrolledWindow.new
|
|
828
|
+
@scrolled_window_local_files.set_window_placement(CORNER_BOTTOM_RIGHT)
|
|
829
|
+
@scrolled_window_local_files.set_policy(POLICY_AUTOMATIC, POLICY_ALWAYS)
|
|
830
|
+
@scrolled_window_local_files.add(@tree_view_local_files)
|
|
831
|
+
@scrolled_window_remote_files = ScrolledWindow.new
|
|
832
|
+
@scrolled_window_remote_files.set_policy(POLICY_AUTOMATIC, POLICY_ALWAYS)
|
|
833
|
+
@scrolled_window_remote_files.add(@tree_view_remote_files)
|
|
834
|
+
@scrolled_window_local_files.set_window_placement(CORNER_TOP_LEFT)
|
|
835
|
+
end
|
|
836
|
+
|
|
837
|
+
# ========================================================================= #
|
|
838
|
+
# === create_gtk_treeview
|
|
839
|
+
#
|
|
840
|
+
# We must attach the ListStore to our tree view.
|
|
841
|
+
#
|
|
842
|
+
# Local files is to the left, remote files is to the right.
|
|
843
|
+
# ========================================================================= #
|
|
844
|
+
def create_gtk_treeview
|
|
845
|
+
@tree_view_local_files = TreeView.new(@list_store_local_files)
|
|
846
|
+
@tree_view_local_files.modify_bg(STATE_NORMAL, DARKBLUE)
|
|
847
|
+
@tree_view_column_local_files = TreeViewColumn.new('Local Files',
|
|
848
|
+
@cell_renderer_text, {:text => 0})
|
|
849
|
+
@tree_view_local_files.append_column(@tree_view_column_local_files)
|
|
850
|
+
@tree_view_local_files.selection.mode = SELECTION_SINGLE
|
|
851
|
+
# ======================================================================= #
|
|
852
|
+
# Now work on the remote files. They are on the right side of
|
|
853
|
+
# the main widget.
|
|
854
|
+
# ======================================================================= #
|
|
855
|
+
@tree_view_remote_files = TreeView.new(@list_store_remote_files)
|
|
856
|
+
@tree_view_remote_files.modify_bg(STATE_NORMAL, DARKBLUE)
|
|
857
|
+
@tree_view_column_remote_files = TreeViewColumn.new('Remote Files',
|
|
858
|
+
@cell_renderer_text, {:text => 0})
|
|
859
|
+
@tree_view_remote_files.append_column(@tree_view_column_remote_files)
|
|
860
|
+
@tree_view_remote_files.selection.mode = SELECTION_SINGLE
|
|
861
|
+
enable_dragging
|
|
862
|
+
hook_up_tree_view_clicks
|
|
863
|
+
fill_up_iter_for_local_files
|
|
864
|
+
fill_up_iter_for_remote_files
|
|
865
|
+
# create scrolled window before continuing
|
|
866
|
+
end
|
|
867
|
+
|
|
868
|
+
# ========================================================================= #
|
|
869
|
+
# === update_remote_files (upd tag. UP TAG.)
|
|
870
|
+
#
|
|
871
|
+
# Use this method to update the remove files.
|
|
872
|
+
# ========================================================================= #
|
|
873
|
+
def update_remote_files
|
|
874
|
+
@list_store_remote_files.clear
|
|
875
|
+
@tree_view_remote_files.remove_column(@tree_view_column_remote_files)
|
|
876
|
+
@tree_view_column_remote_files = TreeViewColumn.new(
|
|
877
|
+
'Remote Files', @cell_renderer_text, {:text => 0})
|
|
878
|
+
update_array_with_remote_files
|
|
879
|
+
fill_up_iter_for_remote_files
|
|
880
|
+
@tree_view_remote_files.append_column(
|
|
881
|
+
@tree_view_column_remote_files
|
|
882
|
+
)
|
|
883
|
+
end
|
|
884
|
+
|
|
885
|
+
# ========================================================================= #
|
|
886
|
+
# === output_coloured_line
|
|
887
|
+
#
|
|
888
|
+
# Makes a nicely coloured line.
|
|
889
|
+
# ========================================================================= #
|
|
890
|
+
def output_coloured_line(
|
|
891
|
+
input, optional_colour = 'yelb'
|
|
892
|
+
)
|
|
893
|
+
cliner {
|
|
894
|
+
e sfancy(input)
|
|
895
|
+
}
|
|
896
|
+
end
|
|
897
|
+
|
|
898
|
+
# ========================================================================= #
|
|
899
|
+
# === fill_main_table
|
|
900
|
+
#
|
|
901
|
+
# Fill our table with the various smaller widgets.
|
|
902
|
+
# ========================================================================= #
|
|
903
|
+
def fill_main_table
|
|
904
|
+
@main_table.attach_defaults(@h_box_ftp_entry, 0,2,0,1)
|
|
905
|
+
# ======================================================================= #
|
|
906
|
+
# The following hbox has 4 buttons.
|
|
907
|
+
# ======================================================================= #
|
|
908
|
+
@main_table.attach_defaults(@hbox_for_buttons, 0,2,1,2)
|
|
909
|
+
# ======================================================================= #
|
|
910
|
+
# Next an entry and the delete button.
|
|
911
|
+
# ======================================================================= #
|
|
912
|
+
_ = ::Gtk::HBox.new
|
|
913
|
+
host_label = ::Gtk::Label.new('Login Name:')
|
|
914
|
+
host_label.set_markup(
|
|
915
|
+
%Q[<markup><span weight="bold">Login Name:</span></markup>], true
|
|
916
|
+
)
|
|
917
|
+
name_tip = 'The login name you will use should come here.'
|
|
918
|
+
::Gtk::Tooltips.new.set_tip(host_label, name_tip, nil)
|
|
919
|
+
_.pack_start(host_label,true,true, 1)
|
|
920
|
+
_.pack_start(@entry_user_name,true,true, 1)
|
|
921
|
+
@main_table.attach_defaults(_, 0,1,2,3)
|
|
922
|
+
@main_table.attach_defaults(@button_delete_remote_file,1,2,2,3)
|
|
923
|
+
@main_table.attach_defaults(@hbox_for_arrows, 0,2,3,4)
|
|
924
|
+
@main_table.attach_defaults(@hbox_for_dirs, 0,2,4,5)
|
|
925
|
+
@main_table.attach_defaults(@h_box_file_listing,0,2,5,8)
|
|
926
|
+
# @main_table.attach_defaults(@entry_search, 0,2,8,9)
|
|
927
|
+
@main_table.attach(@entry_search, 0,2,8,9,
|
|
928
|
+
::Gtk::EXPAND|::Gtk::FILL,::Gtk::EXPAND|::Gtk::FILL,2,2)
|
|
929
|
+
end
|
|
930
|
+
|
|
931
|
+
# ========================================================================= #
|
|
932
|
+
# === create_user_name_entry
|
|
933
|
+
#
|
|
934
|
+
# This is the user-name.
|
|
935
|
+
# ========================================================================= #
|
|
936
|
+
def create_user_name_entry
|
|
937
|
+
@entry_user_name = ::Gtk::Entry.new
|
|
938
|
+
@entry_user_name.set_max_length(70)
|
|
939
|
+
@entry_user_name.text = return_default_user_name_based_on_selected_host
|
|
940
|
+
# ======================================================================= #
|
|
941
|
+
# When the user clicks on it, we select the whole thing.
|
|
942
|
+
# ======================================================================= #
|
|
943
|
+
@entry_user_name.signal_connect(:button_press_event) {|widget, event|
|
|
944
|
+
@entry_user_name.set_focus(true)
|
|
945
|
+
@entry_user_name.select_region(0, -1)
|
|
946
|
+
}
|
|
947
|
+
end
|
|
948
|
+
|
|
949
|
+
# ========================================================================= #
|
|
950
|
+
# === return_default_user_name_based_on_selected_host
|
|
951
|
+
# ========================================================================= #
|
|
952
|
+
def return_default_user_name_based_on_selected_host
|
|
953
|
+
selected_host = host?
|
|
954
|
+
selected_host = FtpParadise::RoebeFtpConstants.return_user_name_based_on_given_host(selected_host)
|
|
955
|
+
return selected_host
|
|
956
|
+
end
|
|
957
|
+
|
|
958
|
+
# ========================================================================= #
|
|
959
|
+
# === try_to_sync_label_remote_dir
|
|
960
|
+
# ========================================================================= #
|
|
961
|
+
def try_to_sync_label_remote_dir
|
|
962
|
+
if @label_remote_dir
|
|
963
|
+
set_remote_dir { :do_not_sync }
|
|
964
|
+
colour_to_use = @colour_for_label
|
|
965
|
+
@label_remote_dir.set_markup(
|
|
966
|
+
%Q[<markup><span weight="bold" foreground="#{colour_to_use}">
|
|
967
|
+
RemoteDir: #{remote_dir?}
|
|
968
|
+
</span></markup>], true)
|
|
969
|
+
end
|
|
970
|
+
end
|
|
971
|
+
|
|
972
|
+
# ========================================================================= #
|
|
973
|
+
# === remote_dir?
|
|
974
|
+
# ========================================================================= #
|
|
975
|
+
def remote_dir?
|
|
976
|
+
@remote_dir
|
|
977
|
+
end
|
|
978
|
+
|
|
979
|
+
# ========================================================================= #
|
|
980
|
+
# === set_remote_dir
|
|
981
|
+
#
|
|
982
|
+
# Use this to set the path of the remote dir in the label.
|
|
983
|
+
#
|
|
984
|
+
# If we have the String 'not connected' then we will not append a '/'
|
|
985
|
+
# character.
|
|
986
|
+
# ========================================================================= #
|
|
987
|
+
def set_remote_dir(i = @_.remote_directory?)
|
|
988
|
+
i = i.to_s
|
|
989
|
+
unless i.include? 'not connected'
|
|
990
|
+
i << '/' unless i.end_with? '/'
|
|
991
|
+
end
|
|
992
|
+
@remote_dir = i
|
|
993
|
+
# Try to sync the label next, unless a block was given.
|
|
994
|
+
if block_given?
|
|
995
|
+
try_to_sync_label_remote_dir unless yield == :do_not_sync
|
|
996
|
+
else
|
|
997
|
+
try_to_sync_label_remote_dir
|
|
998
|
+
end
|
|
999
|
+
end
|
|
1000
|
+
|
|
1001
|
+
# ========================================================================= #
|
|
1002
|
+
# === set_title_for_frame
|
|
1003
|
+
#
|
|
1004
|
+
# Set the title for the Gtk::Frame via markup. This is the top-left
|
|
1005
|
+
# title.
|
|
1006
|
+
# ========================================================================= #
|
|
1007
|
+
def set_title_for_frame
|
|
1008
|
+
colour_to_use = 'darkblue'
|
|
1009
|
+
_ = '<markup><span weight="bold" style="italic" size="x-large" foreground="'+colour_to_use+'"> FTP Client </span></markup>'
|
|
1010
|
+
self.label_widget.set_markup(_)
|
|
1011
|
+
end
|
|
1012
|
+
|
|
1013
|
+
# ========================================================================= #
|
|
1014
|
+
# === create_gtk_skeleton (skeleton tag)
|
|
1015
|
+
# ========================================================================= #
|
|
1016
|
+
def create_gtk_skeleton
|
|
1017
|
+
colour_to_use = '#3456a5'
|
|
1018
|
+
set_title_for_frame
|
|
1019
|
+
# @v_box.pack_start(HSeparator.new, false, true, 0)
|
|
1020
|
+
create_renderer
|
|
1021
|
+
create_gtk_liststore
|
|
1022
|
+
create_gtk_treeview
|
|
1023
|
+
create_entries
|
|
1024
|
+
create_scrolled_windows # Must come after treeview initialization.
|
|
1025
|
+
create_boxes
|
|
1026
|
+
create_statusbar
|
|
1027
|
+
create_gtk_buttons # This must be called before we can call create_hboxes()
|
|
1028
|
+
create_hboxes
|
|
1029
|
+
create_main_table
|
|
1030
|
+
_ = ::Gtk::HBox.new
|
|
1031
|
+
# ======================================================================= #
|
|
1032
|
+
# Add the host label next:
|
|
1033
|
+
# ======================================================================= #
|
|
1034
|
+
name_tip = 'The (remote) host we will connect to. This should be '+
|
|
1035
|
+
'a valid ftp site.'
|
|
1036
|
+
host_label = ::Gtk::Label.new('Host:')
|
|
1037
|
+
host_label.set_markup(
|
|
1038
|
+
%Q[<markup><span weight="bold">Host:</span></markup>], true
|
|
1039
|
+
)
|
|
1040
|
+
::Gtk::Tooltips.new.set_tip(host_label, name_tip, nil)
|
|
1041
|
+
# Now comes the host label, and then the button ftp site.
|
|
1042
|
+
_.pack_start(host_label,true,true, 1)
|
|
1043
|
+
_.pack_start(@button_ftp_site,true,true, 1)
|
|
1044
|
+
@h_box_ftp_entry.add(_)
|
|
1045
|
+
@h_box_ftp_entry.add(@button_connect) # Add the connect-button here.
|
|
1046
|
+
# ======================================================================= #
|
|
1047
|
+
# Now connect things.
|
|
1048
|
+
# ======================================================================= #
|
|
1049
|
+
_ = VBox.new
|
|
1050
|
+
@label_title = Label.new.set_markup(%Q[<span weight="bold" size="x-large" foreground="#{colour_to_use}">
|
|
1051
|
+
#{TITLE}</span>], false)
|
|
1052
|
+
_.pack_start(@label_title, false, true, 1) # false for shrinking.
|
|
1053
|
+
_.pack_start(@main_table, true, true, 1)
|
|
1054
|
+
_.pack_start(@status_bar, true, true, 1)
|
|
1055
|
+
self.add _
|
|
1056
|
+
self.signal_connect(:delete_event) { main_quit }
|
|
1057
|
+
show_all
|
|
1058
|
+
sanitize_file_listing
|
|
1059
|
+
update_everything # also populate the remote file listing, to the right.
|
|
1060
|
+
end
|
|
1061
|
+
|
|
1062
|
+
# ========================================================================= #
|
|
1063
|
+
# === selection?
|
|
1064
|
+
#
|
|
1065
|
+
# gives you what was selected.
|
|
1066
|
+
#
|
|
1067
|
+
# Alternative way would be:
|
|
1068
|
+
# name = @tree_view_local_files.selection.selected[0]
|
|
1069
|
+
# ========================================================================= #
|
|
1070
|
+
def selection?(which_side = :left)
|
|
1071
|
+
case which_side
|
|
1072
|
+
when :left
|
|
1073
|
+
@tree_view_local_files.selection.selected_each { |model, path, iter|
|
|
1074
|
+
iter.first
|
|
1075
|
+
}
|
|
1076
|
+
when :right
|
|
1077
|
+
@tree_view_remote_files.selection.selected_each { |model, path, iter|
|
|
1078
|
+
iter.first
|
|
1079
|
+
}
|
|
1080
|
+
end
|
|
1081
|
+
end
|
|
1082
|
+
|
|
1083
|
+
# ========================================================================= #
|
|
1084
|
+
# === FtpParadise::Gtk::Ftp.run
|
|
1085
|
+
# ========================================================================= #
|
|
1086
|
+
def self.run
|
|
1087
|
+
_ = self.new
|
|
1088
|
+
# ======================================================================= #
|
|
1089
|
+
# Next, proper our Gtk::Runner class for display.
|
|
1090
|
+
# ======================================================================= #
|
|
1091
|
+
r = ::Gtk.run('60%', '95%')
|
|
1092
|
+
r.icon = FTP_MAIN_ICON
|
|
1093
|
+
r.title = 'FTP Client'
|
|
1094
|
+
r.padding = 8
|
|
1095
|
+
r.add(_)
|
|
1096
|
+
r.set_window_position(::Gtk::Window::POS_NONE)
|
|
1097
|
+
r.add_shortcut(1, 'focus(:left)', :alt)
|
|
1098
|
+
r.run
|
|
1099
|
+
end
|
|
1100
|
+
|
|
1101
|
+
# ========================================================================= #
|
|
1102
|
+
# === run
|
|
1103
|
+
# ========================================================================= #
|
|
1104
|
+
def run
|
|
1105
|
+
reset
|
|
1106
|
+
show_startup_message
|
|
1107
|
+
set_current_dir # Do this after the startup message.
|
|
1108
|
+
create_gtk_skeleton
|
|
1109
|
+
end
|
|
1110
|
+
|
|
1111
|
+
end if defined? ::Gtk # Safeguard if the user does not have Gtk installed.
|
|
1112
|
+
|
|
1113
|
+
end
|
|
1114
|
+
|
|
1115
|
+
# =========================================================================== #
|
|
1116
|
+
# === FtpParadise.do_start_gui
|
|
1117
|
+
#
|
|
1118
|
+
# This will output what will be done, then start the GUI bindings.
|
|
1119
|
+
#
|
|
1120
|
+
# This method can be invoked via:
|
|
1121
|
+
# ftpparadise --gui
|
|
1122
|
+
# =========================================================================== #
|
|
1123
|
+
def self.do_start_gui
|
|
1124
|
+
opnn; puts 'We will next start the GUI.'
|
|
1125
|
+
FtpParadise.start_gtk
|
|
1126
|
+
end
|
|
1127
|
+
|
|
1128
|
+
# =========================================================================== #
|
|
1129
|
+
# === FtpParadise.start_gtk
|
|
1130
|
+
# =========================================================================== #
|
|
1131
|
+
def self.start_gtk
|
|
1132
|
+
FtpParadise::Gtk::Ftp.run
|
|
1133
|
+
end
|
|
1134
|
+
|
|
1135
|
+
# =========================================================================== #
|
|
1136
|
+
# === FtpParadise.gtk_widget
|
|
1137
|
+
#
|
|
1138
|
+
# This method will return a useable GTK widget that can be embedded into
|
|
1139
|
+
# other applications.
|
|
1140
|
+
# =========================================================================== #
|
|
1141
|
+
def self.gtk_widget
|
|
1142
|
+
FtpParadise::Gtk::Ftp
|
|
1143
|
+
end
|
|
1144
|
+
|
|
1145
|
+
end
|
|
1146
|
+
|
|
1147
|
+
if __FILE__ == $PROGRAM_NAME
|
|
1148
|
+
FtpParadise.start_gtk
|
|
1149
|
+
end # gtkftp
|