backup_paradise 1.2.13
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of backup_paradise might be problematic. Click here for more details.
- checksums.yaml +7 -0
- data/README.md +231 -0
- data/backup_paradise.gemspec +51 -0
- data/bin/backup_paradise +7 -0
- data/doc/README.gen +214 -0
- data/doc/TODO.md +221 -0
- data/lib/backup_paradise.rb +5 -0
- data/lib/backup_paradise/advanced_backup/advanced_backup.rb +53 -0
- data/lib/backup_paradise/advanced_backup/audio.rb +124 -0
- data/lib/backup_paradise/advanced_backup/constants.rb +34 -0
- data/lib/backup_paradise/advanced_backup/data_directory.rb +50 -0
- data/lib/backup_paradise/advanced_backup/do_perform_the_backup_tasks.rb +95 -0
- data/lib/backup_paradise/advanced_backup/initialize.rb +38 -0
- data/lib/backup_paradise/advanced_backup/menu.rb +280 -0
- data/lib/backup_paradise/advanced_backup/misc.rb +836 -0
- data/lib/backup_paradise/advanced_backup/reset.rb +56 -0
- data/lib/backup_paradise/advanced_backup/run.rb +26 -0
- data/lib/backup_paradise/advanced_backup/system_directory.rb +35 -0
- data/lib/backup_paradise/base/base.rb +440 -0
- data/lib/backup_paradise/base/colours.rb +123 -0
- data/lib/backup_paradise/base/constants.rb +16 -0
- data/lib/backup_paradise/constants/constants.rb +192 -0
- data/lib/backup_paradise/gui/gtk2/backup.rb +345 -0
- data/lib/backup_paradise/gui/gtk3/backup.rb +383 -0
- data/lib/backup_paradise/project/project_base_directory.rb +22 -0
- data/lib/backup_paradise/requires/require_the_backup_paradise_project.rb +14 -0
- data/lib/backup_paradise/tab/tab.rb +84 -0
- data/lib/backup_paradise/toplevel_methods/cliner.rb +16 -0
- data/lib/backup_paradise/toplevel_methods/colours.rb +80 -0
- data/lib/backup_paradise/toplevel_methods/e.rb +16 -0
- data/lib/backup_paradise/toplevel_methods/help.rb +88 -0
- data/lib/backup_paradise/toplevel_methods/misc.rb +343 -0
- data/lib/backup_paradise/toplevel_methods/mountpoint.rb +80 -0
- data/lib/backup_paradise/toplevel_methods/opnn.rb +21 -0
- data/lib/backup_paradise/version/version.rb +19 -0
- data/lib/backup_paradise/yaml/config.yml +22 -0
- metadata +178 -0
@@ -0,0 +1,95 @@
|
|
1
|
+
#!/usr/bin/ruby -w
|
2
|
+
# Encoding: UTF-8
|
3
|
+
# frozen_string_literal: true
|
4
|
+
# =========================================================================== #
|
5
|
+
# === BackupParadise::AdvancedBackup
|
6
|
+
#
|
7
|
+
# This is the main class that will be used for making a backup, usually
|
8
|
+
# onto an external USB device, but optionally also to another (second)
|
9
|
+
# harddisc (HDD).
|
10
|
+
#
|
11
|
+
# Note that we will still store some information on the toplevel namespace
|
12
|
+
# where we will backup to.
|
13
|
+
#
|
14
|
+
# For a listing of specifict options have a look at the file "help.rb", or
|
15
|
+
# do "rbackup help" from the commandline.
|
16
|
+
#
|
17
|
+
# This class will backup a system, usually on an external USB device.
|
18
|
+
#
|
19
|
+
# Usage examples:
|
20
|
+
#
|
21
|
+
# BackupParadise::AdvancedBackup.new(ARGV)
|
22
|
+
#
|
23
|
+
# =========================================================================== #
|
24
|
+
# require 'backup_paradise/advanced_backup/do_perform_the_backup_tasks.rb'
|
25
|
+
# =========================================================================== #
|
26
|
+
module BackupParadise
|
27
|
+
|
28
|
+
class AdvancedBackup < ::BackupParadise::Base # === BackupParadise::AdvancedBackup
|
29
|
+
|
30
|
+
# ========================================================================= #
|
31
|
+
# === do_perform_the_backup_tasks (all tag)
|
32
|
+
#
|
33
|
+
# This method is the main powerhorse of this class. It connects all the
|
34
|
+
# various steps together, one after the other.
|
35
|
+
# ========================================================================= #
|
36
|
+
def do_perform_the_backup_tasks
|
37
|
+
determine_whether_the_target_harddisc_is_a_ntfs_system
|
38
|
+
determine_the_starting_time
|
39
|
+
create_file_keeping_track_of_when_the_last_backup_happened
|
40
|
+
show_welcome_message
|
41
|
+
rename_tab(:default, 'Backing up some data next.')
|
42
|
+
consider_removing_all_but_one_log_file
|
43
|
+
# ======================================================================= #
|
44
|
+
# The next method will rename entries such as
|
45
|
+
# "last_backup-13.10.2018-21:07:20/" to "backup-13.10.2018-21:07:20/".
|
46
|
+
# This is necessary so that we can only have one such directory
|
47
|
+
# name, after we are done with this method here.
|
48
|
+
# ======================================================================= #
|
49
|
+
consider_renaming_all_old_last_backup_directories
|
50
|
+
# ======================================================================= #
|
51
|
+
# We will next attempt to backup the directory at /AUTOGENERATED/.
|
52
|
+
# ======================================================================= #
|
53
|
+
try_to_backup_the_autogenerated_directory
|
54
|
+
try_to_backup_the_audio_directory
|
55
|
+
# ======================================================================= #
|
56
|
+
# We will also create a log file, to denote when we started to
|
57
|
+
# do this current backup-operation.
|
58
|
+
# ======================================================================= #
|
59
|
+
create_the_log_last_backup_file
|
60
|
+
create_the_directory_containing_the_last_backup
|
61
|
+
create_a_symlink_pointing_to_that_directory_that_was_just_created
|
62
|
+
cd @last_backup_directory
|
63
|
+
# ======================================================================= #
|
64
|
+
# Now we are in the last-backup directory - and we can back up
|
65
|
+
# the following three directories by default (usually "DATA/",
|
66
|
+
# "src/" and "studium/"; also books/ since as of February 2019
|
67
|
+
# and "songs/" since as of December 2019).
|
68
|
+
# ======================================================================= #
|
69
|
+
ARRAY_THE_FIVE_MAIN_ENTRIES.each {|this_directory|
|
70
|
+
if this_directory.include? '/'
|
71
|
+
full_path = this_directory.dup
|
72
|
+
else
|
73
|
+
full_path = "#{HOME_DIRECTORY_OF_THE_USER_X}#{this_directory}/"
|
74
|
+
end
|
75
|
+
rename_tab(:default, "Backing up #{this_directory}.")
|
76
|
+
backup_this_directory_if_it_exists(
|
77
|
+
full_path,
|
78
|
+
rds(@last_backup_directory+this_directory),
|
79
|
+
:do_continue,
|
80
|
+
:do_not_sync
|
81
|
+
)
|
82
|
+
}
|
83
|
+
popup_notification(:backup_complete) if show_popup_notification?
|
84
|
+
do_sync # Synchronize the USB devices here.
|
85
|
+
determine_end_time
|
86
|
+
report_time_difference
|
87
|
+
try_to_unmount_the_device
|
88
|
+
rename_tab(
|
89
|
+
use_this_program_to_rename_tabs?, 'Backup is complete!'
|
90
|
+
)
|
91
|
+
show_backup_complete_message
|
92
|
+
end; alias start_backup do_perform_the_backup_tasks # === start_backup
|
93
|
+
alias backup_everything do_perform_the_backup_tasks # === backup_everything
|
94
|
+
|
95
|
+
end; end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
#!/usr/bin/ruby -w
|
2
|
+
# Encoding: UTF-8
|
3
|
+
# frozen_string_literal: true
|
4
|
+
# =========================================================================== #
|
5
|
+
# require 'backup_paradise/advanced_backup/initialize.rb'
|
6
|
+
# =========================================================================== #
|
7
|
+
module BackupParadise
|
8
|
+
|
9
|
+
class AdvancedBackup < ::BackupParadise::Base # === BackupParadise::AdvancedBackup
|
10
|
+
|
11
|
+
# ========================================================================= #
|
12
|
+
# === initialize
|
13
|
+
#
|
14
|
+
# Invocation example:
|
15
|
+
#
|
16
|
+
# x = BackupParadise::AdvancedBackup.new(nil, :do_not_run_yet)
|
17
|
+
#
|
18
|
+
# ========================================================================= #
|
19
|
+
def initialize(
|
20
|
+
optional_arguments = ARGV,
|
21
|
+
run_already = true
|
22
|
+
)
|
23
|
+
register_sigint
|
24
|
+
reset
|
25
|
+
set_commandline_arguments(
|
26
|
+
optional_arguments
|
27
|
+
)
|
28
|
+
case run_already
|
29
|
+
# ======================================================================= #
|
30
|
+
# === :do_not_run_yet
|
31
|
+
# ======================================================================= #
|
32
|
+
when :do_not_run_yet
|
33
|
+
run_already = false
|
34
|
+
end
|
35
|
+
run if run_already
|
36
|
+
end
|
37
|
+
|
38
|
+
end; end
|
@@ -0,0 +1,280 @@
|
|
1
|
+
#!/usr/bin/ruby -w
|
2
|
+
# Encoding: UTF-8
|
3
|
+
# frozen_string_literal: true
|
4
|
+
# =========================================================================== #
|
5
|
+
# require 'backup_paradise/advanced_backup/menu.rb'
|
6
|
+
# =========================================================================== #
|
7
|
+
module BackupParadise
|
8
|
+
|
9
|
+
class AdvancedBackup < Base # === BackupParadise::AdvancedBackup
|
10
|
+
|
11
|
+
# ========================================================================= #
|
12
|
+
# === menu (menu tag)
|
13
|
+
# ========================================================================= #
|
14
|
+
def menu(
|
15
|
+
i = @commandline_arguments
|
16
|
+
)
|
17
|
+
if i.is_a? Array
|
18
|
+
@perform_backup = true if i.empty? # Have to set this as default in that case.
|
19
|
+
i.each {|entry| menu(entry) }
|
20
|
+
else
|
21
|
+
case i # case tag
|
22
|
+
# ===================================================================== #
|
23
|
+
# === rbackup --pwd
|
24
|
+
# ===================================================================== #
|
25
|
+
when /^-?-?pwd$/i
|
26
|
+
current_directory = (Dir.pwd+'/').squeeze('/')
|
27
|
+
set_target_mountpoint(current_directory)
|
28
|
+
@perform_backup = true
|
29
|
+
# ===================================================================== #
|
30
|
+
# === rbackup --usb1
|
31
|
+
# === rbackup --usb2
|
32
|
+
# ===================================================================== #
|
33
|
+
when /^-?-?usb(\d{1})$/i
|
34
|
+
set_target_mountpoint($1.to_s)
|
35
|
+
@perform_backup = true
|
36
|
+
# ===================================================================== #
|
37
|
+
# === Use a shorter name for the backup-directory
|
38
|
+
#
|
39
|
+
# This entry point has been created to allow simpler backup onto
|
40
|
+
# NTFS devices. I ran into a problem with a too-long, and special
|
41
|
+
# name for a directory.
|
42
|
+
#
|
43
|
+
# Usage example:
|
44
|
+
#
|
45
|
+
# rbackup --use-shorter-name
|
46
|
+
# rbackup tousb1 --use-shorter-name
|
47
|
+
#
|
48
|
+
# ===================================================================== #
|
49
|
+
when /^-?-?use(-| |_)?shorter(-| |_)?name$/i,
|
50
|
+
/^-?-?windows$/i,
|
51
|
+
/^-?-?sane-symlink$/i
|
52
|
+
do_use_simplified_directory
|
53
|
+
# ===================================================================== #
|
54
|
+
# === Backup all relevant entries to the chroot-directory
|
55
|
+
#
|
56
|
+
# This entry point is mostly used for my local Chroot directory. We
|
57
|
+
# will quickly backup the important files to that directory, which
|
58
|
+
# then allows us to cd into a better chroot-environment.
|
59
|
+
#
|
60
|
+
# Invocation example:
|
61
|
+
#
|
62
|
+
# rbackup --chroot
|
63
|
+
# rbackup --to-chroot
|
64
|
+
#
|
65
|
+
# ===================================================================== #
|
66
|
+
when /^-?-?chroot$/i,
|
67
|
+
/^-?-?to(-| |_)?chroot$/i,
|
68
|
+
/^-?-?into(-| |_)?chroot$/i
|
69
|
+
e
|
70
|
+
e "Setting the target to #{sdir('/Depot/Chroot/')} next."
|
71
|
+
e
|
72
|
+
set_target_device(:chroot) # Set to the above Chroot target.
|
73
|
+
set_main_target(
|
74
|
+
"#{main_target?.dup}#{home_dir_of_user_x?.dup}"
|
75
|
+
)
|
76
|
+
all_important_directories?.each {|this_directory|
|
77
|
+
new_target = main_target?+File.basename(this_directory)
|
78
|
+
backup_this_directory_if_it_exists(
|
79
|
+
this_directory,
|
80
|
+
new_target,
|
81
|
+
:do_not_continue
|
82
|
+
)
|
83
|
+
}
|
84
|
+
e 'All done!'
|
85
|
+
# ===================================================================== #
|
86
|
+
# === rbackup tousb1
|
87
|
+
# ===================================================================== #
|
88
|
+
when /^-?-?to(-| |_)?usb(\d{1,2})$/i # === $2
|
89
|
+
set_target_mountpoint($2.to_s)
|
90
|
+
@perform_backup = true
|
91
|
+
# ===================================================================== #
|
92
|
+
# === rbackup --audio-dir
|
93
|
+
#
|
94
|
+
# This entry point can be used to specifically backup the
|
95
|
+
# audio-directory - that is, the local directory that
|
96
|
+
# contains all songs.
|
97
|
+
#
|
98
|
+
# A more advanced invocation example is:
|
99
|
+
#
|
100
|
+
# rbackup --backup-to=/opt/ --audio-dir
|
101
|
+
#
|
102
|
+
# ===================================================================== #
|
103
|
+
when /^-?-?audio(-| |_)?dir$/i,
|
104
|
+
/^-?-?audio$/i,
|
105
|
+
/^-?-?aud$/i,
|
106
|
+
/^-?-?audi$/i,
|
107
|
+
/^-?-?aonly$/i,
|
108
|
+
/^-?-?audio(-| |_)?only$/i
|
109
|
+
backup_the_audio_directory
|
110
|
+
# ===================================================================== #
|
111
|
+
# === rbackup --use-this-as-target-for-backup=/opt/
|
112
|
+
# === rbackup --use-this-as-target=/opt/
|
113
|
+
# === rbackup --backup-to=/opt/
|
114
|
+
#
|
115
|
+
# This entry point allows the user to specify another target to
|
116
|
+
# be used from the commandline.
|
117
|
+
# ===================================================================== #
|
118
|
+
when /^-?-?backup(-| |_)?to=(.+)$/i,
|
119
|
+
/^-?-?use(-| |_)?this(-| |_)?as(-| |_)?target=(.+)$/i,
|
120
|
+
/^-?-?use(-| |_)?this(-| |_)?as(-| |_)?target(-| |_)?for(-| |_)?backup=(.+)$/i
|
121
|
+
_ = $2.to_s.dup
|
122
|
+
_ = $4.to_s.dup if $4
|
123
|
+
_ = $6.to_s.dup if $6
|
124
|
+
opnn; e 'The target device will be at '+sfancy(_)+'.'
|
125
|
+
set_target_device(_)
|
126
|
+
# ===================================================================== #
|
127
|
+
# === rbackup --show-file-size-of-popular_directories
|
128
|
+
# === rbackup --overview
|
129
|
+
# ===================================================================== #
|
130
|
+
when /^-?-?show(-| |_)?file(-| |_)?size(-| |_)?of(-| |_)?popular(-| |_)?directories$/i,
|
131
|
+
/^-?-?overview$/i
|
132
|
+
use_this_array = [
|
133
|
+
AUDIO_DIRECTORY,
|
134
|
+
PROGRAMS_DIRECTORY,
|
135
|
+
VIDEO_DIRECTORY
|
136
|
+
]+ARRAY_THE_THREE_MAIN_ENTRIES.map {|entry|
|
137
|
+
return_this_absolute_directory(entry+'_DIRECTORY')
|
138
|
+
}
|
139
|
+
use_this_array.each {|this_entry|
|
140
|
+
report_file_size_of(this_entry)
|
141
|
+
}
|
142
|
+
# ===================================================================== #
|
143
|
+
# === rbackup --studium-dir
|
144
|
+
# === rbackup --studium-directory
|
145
|
+
# === rbackup --studium
|
146
|
+
#
|
147
|
+
# This entry point allows the user to backup the /home/x/studium/
|
148
|
+
# directory, by making use of the constant STUDIUM_DIRECTORY.
|
149
|
+
# ===================================================================== #
|
150
|
+
when /^-?-?studium(-| |_)?dir$/i,
|
151
|
+
/^-?-?studium(-| |_)?directory$/i,
|
152
|
+
/^-?-?studium$/i
|
153
|
+
backup_this_directory_if_it_exists(
|
154
|
+
STUDIUM_DIRECTORY, :default, :do_not_continue
|
155
|
+
)
|
156
|
+
# ===================================================================== #
|
157
|
+
# === rbackup --source-dir
|
158
|
+
# === rbackup --source-directory
|
159
|
+
# === rbackup --source
|
160
|
+
# === rbackup --src-dir
|
161
|
+
# === rbackup --src
|
162
|
+
#
|
163
|
+
# This entry point allows the user to backup the /home/x/SRC/
|
164
|
+
# directory.
|
165
|
+
# ===================================================================== #
|
166
|
+
when /^-?-?source(-| |_)?dir$/i,
|
167
|
+
/^-?-?source(-| |_)?directory$/i,
|
168
|
+
/^-?-?source$/i,
|
169
|
+
/^-?-?src(-| |_)?dir$/i,
|
170
|
+
/^-?-?src$/i
|
171
|
+
backup_the_source_directory
|
172
|
+
# ===================================================================== #
|
173
|
+
# === rbackup --autogenerated
|
174
|
+
# ===================================================================== #
|
175
|
+
when 'autogen','agen','autog',
|
176
|
+
/^-?-?autogenerated$/
|
177
|
+
backup_the_autogenerated_directory
|
178
|
+
# ===================================================================== #
|
179
|
+
# === rbackup --video-dir
|
180
|
+
# ===================================================================== #
|
181
|
+
when /^-?-?video(-| |_)?dir$/i,
|
182
|
+
/^-?-?video(-| |_)?directory$/i,
|
183
|
+
/^-?-?video$/i
|
184
|
+
backup_the_video_directory
|
185
|
+
# ===================================================================== #
|
186
|
+
# === advanced_backup --gui
|
187
|
+
# ===================================================================== #
|
188
|
+
when /^-?-?gui$/i
|
189
|
+
do_not_run
|
190
|
+
start_gtk3_gui
|
191
|
+
# ===================================================================== #
|
192
|
+
# === rbackup --data-dir
|
193
|
+
# ===================================================================== #
|
194
|
+
when /^-?-?data(-| |_)?dir$/i,
|
195
|
+
/^-?-?data(-| |_)?directory$/i,
|
196
|
+
/^-?-?data$/i,
|
197
|
+
/^-?-?ONLY(-| |_)?DATA$/i,
|
198
|
+
/^-?-?DATA(-| |_)?ONLY$/i,
|
199
|
+
/^-?-?donly$/i
|
200
|
+
backup_the_data_directory
|
201
|
+
# ===================================================================== #
|
202
|
+
# === rbackup --system-dir
|
203
|
+
# ===================================================================== #
|
204
|
+
when /^-?-?system(-| |_)?dir$/i,
|
205
|
+
/^-?-?system(-| |_)?directory$/i,
|
206
|
+
/^-?-?system$/i
|
207
|
+
backup_the_system_directory
|
208
|
+
# ===================================================================== #
|
209
|
+
# === rbackup --programs-dir
|
210
|
+
# ===================================================================== #
|
211
|
+
when /^-?-?programs(-| |_)?dir$/i,
|
212
|
+
/^-?-?programs$/i
|
213
|
+
backup_the_programs_directory
|
214
|
+
# ===================================================================== #
|
215
|
+
# === rbackup --logfile
|
216
|
+
# ===================================================================== #
|
217
|
+
when /^-?-?logfile\??$/i
|
218
|
+
show_the_logfile
|
219
|
+
exit_program
|
220
|
+
# ===================================================================== #
|
221
|
+
# === advanced_backup default
|
222
|
+
# ===================================================================== #
|
223
|
+
when 'default' # Default entry point is for /Mount/USB1 aka :usb1.
|
224
|
+
set_target_mountpoint(:usb1)
|
225
|
+
@perform_backup = true
|
226
|
+
# ===================================================================== #
|
227
|
+
# === rbackup --mountpoints
|
228
|
+
# ===================================================================== #
|
229
|
+
when /mountpoints/
|
230
|
+
show_available_mountpoints
|
231
|
+
# ===================================================================== #
|
232
|
+
# === rbackup --help
|
233
|
+
#
|
234
|
+
# The user can use this entry point to obtain helpful information in
|
235
|
+
# how to use this class, on the commandline.
|
236
|
+
# ===================================================================== #
|
237
|
+
when /help/i,
|
238
|
+
/^-?-?show(-| |_)?help$/i,
|
239
|
+
'hel','he','h','?','*'
|
240
|
+
show_help
|
241
|
+
else
|
242
|
+
# =================================================================== #
|
243
|
+
# === Backup an existing directory
|
244
|
+
# =================================================================== #
|
245
|
+
if File.directory?(i)
|
246
|
+
i = File.absolute_path(i)
|
247
|
+
i << '/' unless i.end_with? '/'
|
248
|
+
backup_this_directory_if_it_exists(
|
249
|
+
i, :default, :do_not_continue
|
250
|
+
)
|
251
|
+
# =================================================================== #
|
252
|
+
# === Backup individual .h files quickly
|
253
|
+
#
|
254
|
+
# This is a hort circuit action here - we just backup an existing
|
255
|
+
# .h file quickly.
|
256
|
+
#
|
257
|
+
# Invocation example:
|
258
|
+
#
|
259
|
+
# rbackup /usr/include/xvid.h
|
260
|
+
#
|
261
|
+
# =================================================================== #
|
262
|
+
elsif File.exist?(i) and i.end_with?('.h')
|
263
|
+
base_directory = '/BACKUP/include/'
|
264
|
+
target = "#{base_directory}#{File.basename(i)}"
|
265
|
+
opnn; e "Backing up towards `#{sfile(target)}` (a mere copy operation)."
|
266
|
+
copy_file(i, target)
|
267
|
+
exit_program
|
268
|
+
else
|
269
|
+
if i and i.start_with?('--')
|
270
|
+
e 'Option '+i+' was not found. Exiting now.'
|
271
|
+
exit
|
272
|
+
else
|
273
|
+
@perform_backup = true
|
274
|
+
end
|
275
|
+
end
|
276
|
+
end
|
277
|
+
end
|
278
|
+
end
|
279
|
+
|
280
|
+
end; end
|
@@ -0,0 +1,836 @@
|
|
1
|
+
#!/usr/bin/ruby -w
|
2
|
+
# Encoding: UTF-8
|
3
|
+
# frozen_string_literal: true
|
4
|
+
# =========================================================================== #
|
5
|
+
# require 'backup_paradise/advanced_backup/misc.rb'
|
6
|
+
# =========================================================================== #
|
7
|
+
require 'backup_paradise/advanced_backup/constants.rb'
|
8
|
+
|
9
|
+
module BackupParadise
|
10
|
+
|
11
|
+
class AdvancedBackup < ::BackupParadise::Base
|
12
|
+
|
13
|
+
# ========================================================================= #
|
14
|
+
# === backup_the_books_directory (data tag)
|
15
|
+
#
|
16
|
+
# This method will backup the BOOKS directory, e. g. the one that is
|
17
|
+
# at "/home/x/books/" on my home system.
|
18
|
+
# ========================================================================= #
|
19
|
+
def backup_the_books_directory(
|
20
|
+
target_directory = BOOKS_DIRECTORY
|
21
|
+
)
|
22
|
+
if File.directory? target_directory
|
23
|
+
mountpoint_target = main_target?+File.basename(target_directory)
|
24
|
+
cliner
|
25
|
+
e "Now backing up the #{sdir(target_directory)} directory from "\
|
26
|
+
"#{sfancy(target_directory)} into "\
|
27
|
+
"#{sfile(mountpoint_target)}."
|
28
|
+
cliner
|
29
|
+
report_total_size_of(target_directory)
|
30
|
+
unless File.directory? mountpoint_target
|
31
|
+
create_directory(mountpoint_target, 0755)
|
32
|
+
end
|
33
|
+
backup_this_directory_if_it_exists(
|
34
|
+
target_directory, :default, :do_not_continue
|
35
|
+
)
|
36
|
+
rename_tab('.')
|
37
|
+
else
|
38
|
+
can_not_backup_this_directory_as_it_does_not_exist(target_directory)
|
39
|
+
end
|
40
|
+
end; alias backup_only_books_directory backup_the_books_directory # === backup_only_books_directory
|
41
|
+
alias backup_books_directory backup_the_books_directory # === backup_books_directory
|
42
|
+
|
43
|
+
# ========================================================================= #
|
44
|
+
# === return_default_target_directory_from_this_input
|
45
|
+
# ========================================================================= #
|
46
|
+
def return_default_target_directory_from_this_input(i)
|
47
|
+
rds(
|
48
|
+
main_target?+
|
49
|
+
File.basename(i)+
|
50
|
+
'/'
|
51
|
+
)
|
52
|
+
end
|
53
|
+
|
54
|
+
# ========================================================================= #
|
55
|
+
# === backup_this_directory_if_it_exists
|
56
|
+
#
|
57
|
+
# This method will handle the actual backup-job.
|
58
|
+
#
|
59
|
+
# Note that since as of December 2019, the method will treat all input
|
60
|
+
# as Array - I needed this because sometimes I have to backup only
|
61
|
+
# certain directories, but still want the whole script to run to
|
62
|
+
# completion.
|
63
|
+
#
|
64
|
+
# The second directory is the default target directory.
|
65
|
+
# ========================================================================= #
|
66
|
+
def backup_this_directory_if_it_exists(
|
67
|
+
i = :all_of_them,
|
68
|
+
target_dir = :default, # ← We will copy to this directory.
|
69
|
+
shall_we_continue = :do_continue,
|
70
|
+
shall_we_sync = true
|
71
|
+
)
|
72
|
+
case i
|
73
|
+
# ======================================================================= #
|
74
|
+
# === :default
|
75
|
+
# ======================================================================= #
|
76
|
+
when :default,
|
77
|
+
:all_of_them,
|
78
|
+
:all_important_directories
|
79
|
+
i = ARRAY_THE_FIVE_MAIN_ENTRIES
|
80
|
+
if main_target? == '/Depot/Chroot/'
|
81
|
+
target_dir = :default_without_additional_modification
|
82
|
+
# =================================================================== #
|
83
|
+
# In this case we will modify the target a little.
|
84
|
+
# =================================================================== #
|
85
|
+
set_main_target(
|
86
|
+
"#{main_target?.dup}#{home_dir_of_user_x?.dup}"
|
87
|
+
)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
i = [i].flatten.compact
|
91
|
+
i.each {|entry|
|
92
|
+
if File.directory? entry
|
93
|
+
entry = entry.dup if entry.frozen?
|
94
|
+
entry.delete!('-')
|
95
|
+
case target_dir
|
96
|
+
# =================================================================== #
|
97
|
+
# === :default
|
98
|
+
# =================================================================== #
|
99
|
+
when :default
|
100
|
+
target_dir = return_default_target_directory_from_this_input(entry)
|
101
|
+
# =================================================================== #
|
102
|
+
# === :default_without_additional_modification
|
103
|
+
# =================================================================== #
|
104
|
+
when :default_without_additional_modification
|
105
|
+
target_dir = entry.dup
|
106
|
+
end
|
107
|
+
target_dir = target_dir.dup if target_dir.frozen?
|
108
|
+
target_dir << '/' unless target_dir.end_with? '/'
|
109
|
+
# =================================================================== #
|
110
|
+
# === rbackup --VIDEO
|
111
|
+
# =================================================================== #
|
112
|
+
backup_this_directory(entry, target_dir, shall_we_sync)
|
113
|
+
opnn; e "The directory `#{sdir(entry.delete('*'))}` has "\
|
114
|
+
"been backed up"
|
115
|
+
opnn; e "into #{sdir(target_dir)}."
|
116
|
+
end
|
117
|
+
case shall_we_continue
|
118
|
+
# ===================================================================== #
|
119
|
+
# === :do_not_continue
|
120
|
+
# ===================================================================== #
|
121
|
+
when :do_not_continue,
|
122
|
+
:default
|
123
|
+
@perform_backup = false
|
124
|
+
# ===================================================================== #
|
125
|
+
# === :do_continue
|
126
|
+
# ===================================================================== #
|
127
|
+
when :do_continue
|
128
|
+
@perform_backup = true
|
129
|
+
end
|
130
|
+
}
|
131
|
+
end
|
132
|
+
|
133
|
+
# ========================================================================= #
|
134
|
+
# === set_commandline_arguments
|
135
|
+
# ========================================================================= #
|
136
|
+
def set_commandline_arguments(i)
|
137
|
+
@commandline_arguments = [i].flatten.compact
|
138
|
+
end
|
139
|
+
|
140
|
+
# ========================================================================= #
|
141
|
+
# === use_this_program_to_rename_tabs?
|
142
|
+
# ========================================================================= #
|
143
|
+
def use_this_program_to_rename_tabs?
|
144
|
+
BackupParadise.use_this_program_to_rename_tabs?
|
145
|
+
end
|
146
|
+
|
147
|
+
# ========================================================================= #
|
148
|
+
# === opnn
|
149
|
+
# ========================================================================= #
|
150
|
+
def opnn(i = NAMESPACE)
|
151
|
+
if i.is_a? String
|
152
|
+
i = { namespace: i }
|
153
|
+
end
|
154
|
+
super(i)
|
155
|
+
end
|
156
|
+
|
157
|
+
# ========================================================================= #
|
158
|
+
# === unmount
|
159
|
+
#
|
160
|
+
# Use this to unmount something. Right now, we unmount only the HDD.
|
161
|
+
# ========================================================================= #
|
162
|
+
def unmount(
|
163
|
+
what = :hdd
|
164
|
+
)
|
165
|
+
case what.to_sym
|
166
|
+
when :hdd
|
167
|
+
system "umount -l #{ENV['FIRST_HD']}"
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
# ========================================================================= #
|
172
|
+
# === return_all_log_files
|
173
|
+
# ========================================================================= #
|
174
|
+
def return_all_log_files(
|
175
|
+
from_where = main_target?
|
176
|
+
)
|
177
|
+
Dir["#{from_where}log_last_backup_*"].select {|entry|
|
178
|
+
File.file? entry # We only want files.
|
179
|
+
}
|
180
|
+
end
|
181
|
+
|
182
|
+
# ========================================================================= #
|
183
|
+
# === consider_creating_a_log_file
|
184
|
+
#
|
185
|
+
# This method will create a .log file.
|
186
|
+
#
|
187
|
+
# It accepts an argument, which should be an Integer or Float, denoting,
|
188
|
+
# in seconds, how long it took to make a backup.
|
189
|
+
# ========================================================================= #
|
190
|
+
def consider_creating_a_log_file(
|
191
|
+
n_seconds
|
192
|
+
)
|
193
|
+
if File.directory? '/Depot/Temp/'
|
194
|
+
n_minutes = (n_seconds.to_f / 60).round(1).to_s
|
195
|
+
what = "#{return_full_date}: Backing up the system took #{n_seconds} "\
|
196
|
+
"seconds (#{n_minutes} minutes).\n"
|
197
|
+
into = FILE_BACKUP_LOG
|
198
|
+
opnn; e "Storing the time it took to backup "\
|
199
|
+
"into the file `#{sfile(into)}`."
|
200
|
+
append_what_into(what, into)
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
# ========================================================================= #
|
205
|
+
# === determine_the_starting_time
|
206
|
+
# ========================================================================= #
|
207
|
+
def determine_the_starting_time
|
208
|
+
@array_store_times << Time.now
|
209
|
+
end; alias determine_starting_time determine_the_starting_time # === determine_starting_time
|
210
|
+
|
211
|
+
# ========================================================================= #
|
212
|
+
# === determine_end_time
|
213
|
+
# ========================================================================= #
|
214
|
+
def determine_end_time
|
215
|
+
@array_store_times << Time.now
|
216
|
+
end
|
217
|
+
|
218
|
+
# ========================================================================= #
|
219
|
+
# === show_popup_notification?
|
220
|
+
# ========================================================================= #
|
221
|
+
def show_popup_notification?
|
222
|
+
@show_popup_notification
|
223
|
+
end
|
224
|
+
|
225
|
+
# ========================================================================= #
|
226
|
+
# === do_show_popup
|
227
|
+
# ========================================================================= #
|
228
|
+
def do_show_popup
|
229
|
+
@show_popup_notification = true
|
230
|
+
end; alias show_popup do_show_popup # === show_popup
|
231
|
+
|
232
|
+
# ========================================================================= #
|
233
|
+
# === popup_notification
|
234
|
+
#
|
235
|
+
# Use this method to send a graphical popup to the user. Only invoke
|
236
|
+
# it when we set @show_popup_notification to true.
|
237
|
+
# ========================================================================= #
|
238
|
+
def popup_notification(
|
239
|
+
what = :backup_complete
|
240
|
+
)
|
241
|
+
case what
|
242
|
+
when :backup_complete
|
243
|
+
esystem 'xmessage -center Backup finished!'
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
# ========================================================================= #
|
248
|
+
# === esystem
|
249
|
+
# ========================================================================= #
|
250
|
+
def esystem(i)
|
251
|
+
e i
|
252
|
+
system i
|
253
|
+
end
|
254
|
+
|
255
|
+
# ========================================================================= #
|
256
|
+
# === create_file_keeping_track_of_when_the_last_backup_happened
|
257
|
+
#
|
258
|
+
# This method will store date-information into a file, when the last
|
259
|
+
# backup happened.
|
260
|
+
#
|
261
|
+
# It is normally found in a place such as:
|
262
|
+
#
|
263
|
+
# /home/x/DATA/LAST_BACKUP.md
|
264
|
+
#
|
265
|
+
# Since Dec 2012, we will also append the date to the name of said file.
|
266
|
+
# ========================================================================= #
|
267
|
+
def create_file_keeping_track_of_when_the_last_backup_happened
|
268
|
+
base_target = "#{data_directory?}LAST_BACKUP"
|
269
|
+
target = "#{base_target}_#{@date}.md" # Append the date here.
|
270
|
+
e N+'Storing '+sfile(@use_this_as_timestamp)+' into '+sfile(target)+' to note'
|
271
|
+
e 'down when we did our last backup.'
|
272
|
+
write_what_into(@use_this_as_timestamp, target)
|
273
|
+
# ======================================================================= #
|
274
|
+
# Next, obtain an array with potential similar names. We will have
|
275
|
+
# to delete stray entries so as to not clutter our original home
|
276
|
+
# directory there.
|
277
|
+
# ======================================================================= #
|
278
|
+
array_all_last_backup_files = Dir["#{base_target}*"]
|
279
|
+
if array_all_last_backup_files.size > 1
|
280
|
+
array_all_last_backup_files = array_all_last_backup_files.sort_by {|d|
|
281
|
+
d.split('.').reverse
|
282
|
+
} # Keep it sorted.
|
283
|
+
e N+'We found more than one entry in '+
|
284
|
+
sdir(File.dirname(base_target)+'/')+', thus removing'
|
285
|
+
e 'the extra-entries next.'
|
286
|
+
array_all_last_backup_files[0..-2].each {|my_file|
|
287
|
+
e "Removing `#{sfile(my_file)}` next."
|
288
|
+
remove(my_file)
|
289
|
+
}
|
290
|
+
end
|
291
|
+
end; alias store_when_was_the_last_backup create_file_keeping_track_of_when_the_last_backup_happened # === store_when_was_the_last_backup
|
292
|
+
|
293
|
+
# ========================================================================= #
|
294
|
+
# === try_to_unmount_the_device
|
295
|
+
#
|
296
|
+
# This method can be used to automatically unmount the target device
|
297
|
+
# again.
|
298
|
+
# ========================================================================= #
|
299
|
+
def try_to_unmount_the_device
|
300
|
+
this_is_the_mounted_device = backup_to_this_directory?
|
301
|
+
# ======================================================================= #
|
302
|
+
# Change directory to another directory where we can safely
|
303
|
+
# umount the directory.
|
304
|
+
# ======================================================================= #
|
305
|
+
if has_superuser_abilities?
|
306
|
+
if File.directory? '/Depot/j/'
|
307
|
+
cd '/Depot/j/'
|
308
|
+
elsif File.directory? '/tmp'
|
309
|
+
cd '/tmp'
|
310
|
+
elsif File.directory? '/home/Temp'
|
311
|
+
cd '/home/Temp'
|
312
|
+
else
|
313
|
+
cd '/'
|
314
|
+
end
|
315
|
+
opnn; e "Next unmounting the device at "\
|
316
|
+
"`#{sfancy(this_is_the_mounted_device)}`."
|
317
|
+
system "umount #{this_is_the_mounted_device}"
|
318
|
+
end
|
319
|
+
end
|
320
|
+
|
321
|
+
# ========================================================================= #
|
322
|
+
# === backup_src_directory (src tag)
|
323
|
+
#
|
324
|
+
# This method will backup the SRC/ directory, aka "/home/x/src/". It
|
325
|
+
# is evidently geared towards the system at my home setup.
|
326
|
+
#
|
327
|
+
# To invoke this method from the commandline, try:
|
328
|
+
#
|
329
|
+
# rbackup --src-dir
|
330
|
+
#
|
331
|
+
# ========================================================================= #
|
332
|
+
def backup_the_source_directory(
|
333
|
+
target_directory = SOURCE_DIRECTORY
|
334
|
+
)
|
335
|
+
if File.directory? target_directory
|
336
|
+
rename_tab(:default, 'Backing up the '+target_directory+' directory.')
|
337
|
+
cliner
|
338
|
+
e 'Now backing up the src/ directory from '+
|
339
|
+
sfancy(target_directory)+' into '+
|
340
|
+
sfile(main_target?+File.basename(target_directory))
|
341
|
+
cliner
|
342
|
+
report_total_size_of(target_directory)
|
343
|
+
backup_this_directory_if_it_exists(
|
344
|
+
target_directory, :default, :do_not_continue
|
345
|
+
)
|
346
|
+
else
|
347
|
+
can_not_backup_this_directory_as_it_does_not_exist(target_directory)
|
348
|
+
end
|
349
|
+
end
|
350
|
+
|
351
|
+
# ========================================================================= #
|
352
|
+
# === show_the_logfile
|
353
|
+
#
|
354
|
+
# To invoke this method from the commandline, try:
|
355
|
+
#
|
356
|
+
# advanced_backup --logfile?
|
357
|
+
#
|
358
|
+
# ========================================================================= #
|
359
|
+
def show_the_logfile
|
360
|
+
_ = FILE_BACKUP_LOG
|
361
|
+
if File.exist? _
|
362
|
+
opnn; e "Now reading the dataset from the file `#{sfile(_)}`:"
|
363
|
+
e
|
364
|
+
File.readlines(_).each {|line|
|
365
|
+
e orangered(" #{line.chomp}")
|
366
|
+
}
|
367
|
+
e
|
368
|
+
else
|
369
|
+
opnn; e no_file_exists_at(_)
|
370
|
+
end
|
371
|
+
end
|
372
|
+
|
373
|
+
# ========================================================================= #
|
374
|
+
# === return_this_absolute_directory
|
375
|
+
# ========================================================================= #
|
376
|
+
def return_this_absolute_directory(i)
|
377
|
+
i = case i
|
378
|
+
when 'DATA_DIRECTORY'
|
379
|
+
DATA_DIRECTORY
|
380
|
+
# ======================================================================= #
|
381
|
+
# === SRC_DIRECTORY
|
382
|
+
# ======================================================================= #
|
383
|
+
when 'SRC_DIRECTORY','SOURCE_DIRECTORY'
|
384
|
+
SOURCE_DIRECTORY
|
385
|
+
when 'STUDIUM_DIRECTORY'
|
386
|
+
STUDIUM_DIRECTORY
|
387
|
+
else
|
388
|
+
i
|
389
|
+
end
|
390
|
+
i
|
391
|
+
end
|
392
|
+
|
393
|
+
# ========================================================================= #
|
394
|
+
# === backup_the_programs_directory
|
395
|
+
#
|
396
|
+
# This method can be used to backup the /Programs directory.
|
397
|
+
# ========================================================================= #
|
398
|
+
def backup_the_programs_directory(
|
399
|
+
target_directory = PROGRAMS_DIRECTORY
|
400
|
+
)
|
401
|
+
if File.directory? target_directory
|
402
|
+
cliner
|
403
|
+
e 'Now backing up the Programs/ directory from '+
|
404
|
+
sfancy(target_directory)+' into '+
|
405
|
+
sfile(main_target?+File.basename(target_directory))
|
406
|
+
cliner
|
407
|
+
report_total_size_of(target_directory)
|
408
|
+
if target_hdd_does_not_have_enough_space_left?
|
409
|
+
opnn; e "We have to skip backing up #{sdir(target_directory)}"
|
410
|
+
opnn; e 'as it does not have enough space left (Threshold: '+
|
411
|
+
MINIMAL_FILESIZE+' bytes)'
|
412
|
+
else
|
413
|
+
backup_this_directory_if_it_exists(
|
414
|
+
target_directory, :default, :do_not_continue
|
415
|
+
)
|
416
|
+
end
|
417
|
+
else
|
418
|
+
can_not_backup_this_directory_as_it_does_not_exist(target_directory)
|
419
|
+
end
|
420
|
+
end
|
421
|
+
|
422
|
+
# ========================================================================= #
|
423
|
+
# === can_not_backup_this_directory_as_it_does_not_exist
|
424
|
+
# ========================================================================= #
|
425
|
+
def can_not_backup_this_directory_as_it_does_not_exist(i)
|
426
|
+
opnn; e "Can not backup the directory at #{sdir(i)}"
|
427
|
+
opnn; e 'as it does not exist.'
|
428
|
+
end
|
429
|
+
|
430
|
+
# ========================================================================= #
|
431
|
+
# === start_gtk3_gui
|
432
|
+
#
|
433
|
+
# To invoke this method, try:
|
434
|
+
#
|
435
|
+
# advanced_backup --gui
|
436
|
+
#
|
437
|
+
# ========================================================================= #
|
438
|
+
def start_gtk3_gui
|
439
|
+
require 'backup_paradise/gui/gtk3/backup.rb'
|
440
|
+
__BackupParadise::AdvancedBackup::GUI::Gtk::BackupWidget.new
|
441
|
+
end
|
442
|
+
|
443
|
+
# ========================================================================= #
|
444
|
+
# === backup_the_video_directory
|
445
|
+
# ========================================================================= #
|
446
|
+
def backup_the_video_directory(
|
447
|
+
target_directory = VIDEO_DIRECTORY
|
448
|
+
)
|
449
|
+
if File.directory? target_directory
|
450
|
+
cliner
|
451
|
+
e 'Now backing up the Video directory from '+
|
452
|
+
sfancy(target_directory)+' into '+
|
453
|
+
sfile(main_target?+File.basename(target_directory))
|
454
|
+
cliner
|
455
|
+
report_total_size_of(target_directory)
|
456
|
+
backup_this_directory_if_it_exists(
|
457
|
+
target_directory, :default, :do_not_continue
|
458
|
+
)
|
459
|
+
else
|
460
|
+
can_not_backup_this_directory_as_it_does_not_exist(target_directory)
|
461
|
+
end
|
462
|
+
end
|
463
|
+
|
464
|
+
# ========================================================================= #
|
465
|
+
# === try_to_backup_the_autogenerated_directory
|
466
|
+
# ========================================================================= #
|
467
|
+
def try_to_backup_the_autogenerated_directory(
|
468
|
+
i = AUTOGENERATED_DIRECTORY
|
469
|
+
)
|
470
|
+
if File.directory? i
|
471
|
+
_ = target_mountpoint?+File.basename(i)
|
472
|
+
_ = _.dup if _.frozen?
|
473
|
+
_ << '/' unless _.end_with? '/'
|
474
|
+
opnn; e 'Now trying to backup the AUTOGENERATED directory at `'+sdir(i)+'`.'
|
475
|
+
opnn; e "The target for this will be at `#{sdir(_)}`."
|
476
|
+
n_gigabytes = BackupParadise.size_in_gigabytes?(i).to_s
|
477
|
+
opnn; e 'This directory has a total of '+
|
478
|
+
sfancy(n_files_in?(i).to_s)+' entries '\
|
479
|
+
'(Total size: '+n_gigabytes+' GB).'
|
480
|
+
unless File.directory? _
|
481
|
+
verbose_create_a_directory_at_this_position(_)
|
482
|
+
end
|
483
|
+
rename_tab(:default, 'Backing up the AUTOGENERATED directory.')
|
484
|
+
unless i.end_with? '*'
|
485
|
+
i = i.dup if i.frozen?
|
486
|
+
i << '*'
|
487
|
+
end
|
488
|
+
copy_recursively(i, _)
|
489
|
+
opnn; e "Finished backing up the "\
|
490
|
+
"directory #{sdir(i.delete('*'))} into #{sdir(_)}."
|
491
|
+
else
|
492
|
+
can_not_backup_this_directory_as_it_does_not_exist(i)
|
493
|
+
end
|
494
|
+
end; alias backup_autogenerated_directory try_to_backup_the_autogenerated_directory # === backup_autogenerated_directory
|
495
|
+
alias backup_the_autogenerated_directory try_to_backup_the_autogenerated_directory # === backup_the_autogenerated_directory
|
496
|
+
|
497
|
+
# ========================================================================= #
|
498
|
+
# === consider_renaming_all_old_last_backup_directories
|
499
|
+
#
|
500
|
+
# This will rename all "last_directory*" directory entries to their
|
501
|
+
# corresponding equivalent without the leading 'last_' string.
|
502
|
+
# ========================================================================= #
|
503
|
+
def consider_renaming_all_old_last_backup_directories
|
504
|
+
# ======================================================================= #
|
505
|
+
# First grab all possible entries, and check that these are all existing
|
506
|
+
# directories. If there is at the least one entry we will continue to
|
507
|
+
# operate on it.
|
508
|
+
# ======================================================================= #
|
509
|
+
all_possible_entries = Dir["#{mount_target?}last_backup-*"].select {|entry|
|
510
|
+
File.directory?(entry)
|
511
|
+
}
|
512
|
+
if all_possible_entries.size > 0
|
513
|
+
# ===================================================================== #
|
514
|
+
# Batch-rename these directories in that case:
|
515
|
+
# ===================================================================== #
|
516
|
+
all_possible_entries.each {|this_directory|
|
517
|
+
new_name_of_the_new_target_directory = this_directory.sub(/^last_/,'')
|
518
|
+
opnn; e "Now renaming `#{sdir(this_directory)}` "\
|
519
|
+
"to `#{sdir(new_name_of_the_new_target_directory)}`."
|
520
|
+
rename(this_directory, new_name_of_the_new_target_directory)
|
521
|
+
}
|
522
|
+
end
|
523
|
+
end
|
524
|
+
|
525
|
+
# ========================================================================= #
|
526
|
+
# === report_time_difference
|
527
|
+
#
|
528
|
+
# This method will report to the user how long it took this class
|
529
|
+
# to backup the system.
|
530
|
+
# ========================================================================= #
|
531
|
+
def report_time_difference
|
532
|
+
if @array_store_times.size > 1
|
533
|
+
start_time = @array_store_times[-2]
|
534
|
+
end_time = @array_store_times.last
|
535
|
+
time_difference = end_time - start_time # This will result in a Float.
|
536
|
+
if time_difference.respond_to? :round
|
537
|
+
time_difference = time_difference.round(3)
|
538
|
+
end
|
539
|
+
n_minutes = (time_difference.to_f / 60.0).round(2).to_s
|
540
|
+
opnn; e "#{tomato('Time required')} for this backup-operation: "\
|
541
|
+
"#{sfancy(time_difference.to_s)}"\
|
542
|
+
" seconds (#{royalblue(n_minutes)} minutes)."
|
543
|
+
consider_creating_a_log_file(time_difference)
|
544
|
+
end
|
545
|
+
end
|
546
|
+
|
547
|
+
# ========================================================================= #
|
548
|
+
# === show_backup_complete_message
|
549
|
+
# ========================================================================= #
|
550
|
+
def show_backup_complete_message
|
551
|
+
e "#{cyan}Backup complete!#{rev}"
|
552
|
+
end
|
553
|
+
|
554
|
+
# ========================================================================= #
|
555
|
+
# === verbose_create_a_directory_at_this_position
|
556
|
+
#
|
557
|
+
# The first argument to this method should be the target directory,
|
558
|
+
# a path, that is where you wish to create that directory.
|
559
|
+
#
|
560
|
+
# The second argument to this method, which is optional, denotes the
|
561
|
+
# permission that is to be used.
|
562
|
+
# ========================================================================= #
|
563
|
+
def verbose_create_a_directory_at_this_position(
|
564
|
+
this_position, use_this_permission = 0754
|
565
|
+
)
|
566
|
+
e "Creating a directory at `#{sdir(this_position)}` next."
|
567
|
+
mkdir(this_position, use_this_permission)
|
568
|
+
end
|
569
|
+
|
570
|
+
# ========================================================================= #
|
571
|
+
# === commandline_arguments?
|
572
|
+
# ========================================================================= #
|
573
|
+
def commandline_arguments?
|
574
|
+
@commandline_arguments
|
575
|
+
end
|
576
|
+
|
577
|
+
# ========================================================================= #
|
578
|
+
# === show_available_mountpoints
|
579
|
+
#
|
580
|
+
# This helper-method can show the available mountpoints, at the least
|
581
|
+
# on a linux system.
|
582
|
+
#
|
583
|
+
# To invoke this, try:
|
584
|
+
#
|
585
|
+
# AdvancedBackup --mountpoints
|
586
|
+
#
|
587
|
+
# ========================================================================= #
|
588
|
+
def show_available_mountpoints
|
589
|
+
begin
|
590
|
+
require 'mountpoints'
|
591
|
+
rescue LoadError; end
|
592
|
+
if Mountpoints.is_any_mountpoint_available?
|
593
|
+
opnn; e 'The available (and mounted) USB devices are:'
|
594
|
+
e
|
595
|
+
Mountpoints[].each {|this_usb_device|
|
596
|
+
e " #{sfancy(this_usb_device)}"
|
597
|
+
}
|
598
|
+
e
|
599
|
+
else
|
600
|
+
opnn; e 'No external USB devices appear to be mounted.'
|
601
|
+
end
|
602
|
+
end
|
603
|
+
|
604
|
+
# ========================================================================= #
|
605
|
+
# === use_colours?
|
606
|
+
# ========================================================================= #
|
607
|
+
def use_colours?
|
608
|
+
BackupParadise.use_colours?
|
609
|
+
end
|
610
|
+
|
611
|
+
# ========================================================================= #
|
612
|
+
# === determine_the_target_mountpoint
|
613
|
+
#
|
614
|
+
# This method will determine the target base mountpoint that
|
615
|
+
# is to be used.
|
616
|
+
# ========================================================================= #
|
617
|
+
def determine_the_target_mountpoint(
|
618
|
+
i = '/Mount/USB1/'
|
619
|
+
)
|
620
|
+
BackupParadise.target_mountpoint = i
|
621
|
+
end
|
622
|
+
|
623
|
+
# ========================================================================= #
|
624
|
+
# === report_todays_date
|
625
|
+
# ========================================================================= #
|
626
|
+
def report_todays_date
|
627
|
+
e "Today is the #{sfancy(@date)}."
|
628
|
+
end
|
629
|
+
|
630
|
+
# ========================================================================= #
|
631
|
+
# === create_the_directory_containing_the_last_backup
|
632
|
+
# ========================================================================= #
|
633
|
+
def create_the_directory_containing_the_last_backup
|
634
|
+
target = main_target?+'backup-'+@use_this_as_timestamp
|
635
|
+
# ======================================================================= #
|
636
|
+
# Next, create the last_backup directory:
|
637
|
+
# ======================================================================= #
|
638
|
+
begin
|
639
|
+
mkdir(target, 0755)
|
640
|
+
rescue Errno::EINVAL
|
641
|
+
target.tr!(':','_')
|
642
|
+
mkdir(target, 0755)
|
643
|
+
end
|
644
|
+
@last_backup_directory = rds(target+'/')
|
645
|
+
opnn; e "Creating a directory at `#{sdir(@last_backup_directory)}`."
|
646
|
+
end
|
647
|
+
|
648
|
+
# ========================================================================= #
|
649
|
+
# === set_last_backup_directory
|
650
|
+
# ========================================================================= #
|
651
|
+
def set_last_backup_directory(i)
|
652
|
+
@last_backup_directory = i
|
653
|
+
end
|
654
|
+
|
655
|
+
# ========================================================================= #
|
656
|
+
# === consider_removing_all_but_one_log_file
|
657
|
+
# ========================================================================= #
|
658
|
+
def consider_removing_all_but_one_log_file
|
659
|
+
log_files = return_all_log_files
|
660
|
+
if log_files.size > 1
|
661
|
+
opnn; e 'More than one log file has been found. We will delete'
|
662
|
+
opnn; e 'all but one next.'
|
663
|
+
log_files.pop
|
664
|
+
delete_files(log_files, :be_verbose)
|
665
|
+
end
|
666
|
+
end
|
667
|
+
|
668
|
+
# ========================================================================= #
|
669
|
+
# === create_the_log_last_backup_file (log tag)
|
670
|
+
#
|
671
|
+
# We also have to remove all prior log files should they exist.
|
672
|
+
# ========================================================================= #
|
673
|
+
def create_the_log_last_backup_file
|
674
|
+
_ = return_all_log_files
|
675
|
+
unless _.empty?
|
676
|
+
# ===================================================================== #
|
677
|
+
# Remove all old log files next.
|
678
|
+
# ===================================================================== #
|
679
|
+
remove_these_files(_)
|
680
|
+
end
|
681
|
+
target = main_target?+'log_last_backup_'+@use_this_as_timestamp
|
682
|
+
what = dd_mm_yyyy
|
683
|
+
opnn; e "Keeping a backup file (a log) at `#{sfile(target)}`."
|
684
|
+
write_what_into(what, target)
|
685
|
+
end; alias create_log_file create_the_log_last_backup_file
|
686
|
+
|
687
|
+
# ========================================================================= #
|
688
|
+
# === create_a_symlink_pointing_to_that_directory_that_was_just_created
|
689
|
+
#
|
690
|
+
# This method will create a symlink to the last_backup/ directory.
|
691
|
+
#
|
692
|
+
# This is synonymous to the following ruby code:
|
693
|
+
#
|
694
|
+
# File.symlink('last_backup-13.08.2018-22:12:26/','last_backup')
|
695
|
+
#
|
696
|
+
# ========================================================================= #
|
697
|
+
def create_a_symlink_pointing_to_that_directory_that_was_just_created
|
698
|
+
cd_to_the_mounted_device
|
699
|
+
create_a_symlink_here = "#{backup_to_this_directory?}last_backup"
|
700
|
+
from_this_target = File.basename(@last_backup_directory)
|
701
|
+
from_this_target.chop! if from_this_target.end_with? '/'
|
702
|
+
# ========================================================================= #
|
703
|
+
# First, delete the old symlink if it exists. The method delete_symlink()
|
704
|
+
# will do that check for us.
|
705
|
+
# ========================================================================= #
|
706
|
+
delete_symlink(create_a_symlink_here)
|
707
|
+
# ========================================================================= #
|
708
|
+
# The next action can fail on e. g. vfat filesystems, with the error
|
709
|
+
# being Errno::EPERM. Hence we must rescue here.
|
710
|
+
# ========================================================================= #
|
711
|
+
begin
|
712
|
+
do_symlink(from_this_target, create_a_symlink_here)
|
713
|
+
if File.exist? create_a_symlink_here
|
714
|
+
points_towards = File.readlink(create_a_symlink_here)
|
715
|
+
opnn; e 'Next setting a symlink at `'+sfancy(create_a_symlink_here)+
|
716
|
+
'` pointing'
|
717
|
+
opnn; e "towards `#{sfile(points_towards)}`."
|
718
|
+
else
|
719
|
+
opnn; e no_file_exists_at(create_a_symlink_here)
|
720
|
+
end
|
721
|
+
rescue Errno::EPERM
|
722
|
+
end
|
723
|
+
end; alias create_symlink_to_last_backup_directory create_a_symlink_pointing_to_that_directory_that_was_just_created # === create_symlink_to_last_backup_directory
|
724
|
+
|
725
|
+
# ========================================================================= #
|
726
|
+
# === show_welcome_message
|
727
|
+
# ========================================================================= #
|
728
|
+
def show_welcome_message
|
729
|
+
cliner
|
730
|
+
e "Welcome to project #{lightcoral('BackupParadise')}!"
|
731
|
+
report_todays_date
|
732
|
+
cliner
|
733
|
+
e "Starting to backup into the target at `#{sdir(main_target?)}`."
|
734
|
+
cliner
|
735
|
+
end
|
736
|
+
|
737
|
+
# ========================================================================= #
|
738
|
+
# === backup_this_directory
|
739
|
+
#
|
740
|
+
# This method will quickly backup a given directory.
|
741
|
+
#
|
742
|
+
# The second argument will be the target-directory onto which
|
743
|
+
# we will copy our files.
|
744
|
+
# ========================================================================= #
|
745
|
+
def backup_this_directory(
|
746
|
+
i,
|
747
|
+
copy_to_this_target_directory = nil,
|
748
|
+
shall_we_sync = true
|
749
|
+
)
|
750
|
+
case shall_we_sync
|
751
|
+
when :do_not_sync
|
752
|
+
shall_we_sync = false
|
753
|
+
end
|
754
|
+
case copy_to_this_target_directory
|
755
|
+
when nil,
|
756
|
+
:default
|
757
|
+
copy_to_this_target_directory = return_default_target_directory_from_this_input(i)
|
758
|
+
end
|
759
|
+
unless File.directory? copy_to_this_target_directory
|
760
|
+
mkdir(copy_to_this_target_directory)
|
761
|
+
end
|
762
|
+
cd copy_to_this_target_directory
|
763
|
+
opnn; e 'Now copying '+sdir(i)+
|
764
|
+
' to '+sdir(copy_to_this_target_directory)+'.'
|
765
|
+
if File.directory?(i)
|
766
|
+
i << '*'
|
767
|
+
end
|
768
|
+
cpr(
|
769
|
+
i, copy_to_this_target_directory
|
770
|
+
)
|
771
|
+
do_sync if shall_we_sync
|
772
|
+
end
|
773
|
+
|
774
|
+
# ========================================================================= #
|
775
|
+
# === do_sync
|
776
|
+
#
|
777
|
+
# The do_sync() method, also aliased towards synchronize(), will sync
|
778
|
+
# the data onto USB items, by using the sync command.
|
779
|
+
# ========================================================================= #
|
780
|
+
def do_sync
|
781
|
+
opnn; e 'Starting to '+steelblue('sync data')+' ...'
|
782
|
+
system 'sync' # Be silent since May 2014.
|
783
|
+
opnn; e "> Syncing finished. (At: "\
|
784
|
+
"#{rosybrown(return_current_date_and_time.to_s)})"
|
785
|
+
end; alias synchronize do_sync # === synchronize
|
786
|
+
|
787
|
+
# ========================================================================= #
|
788
|
+
# === determine_whether_the_target_harddisc_is_a_ntfs_system
|
789
|
+
# ========================================================================= #
|
790
|
+
def determine_whether_the_target_harddisc_is_a_ntfs_system
|
791
|
+
if is_target_harddisc_a_ntfs_system?
|
792
|
+
do_use_simplified_directory
|
793
|
+
end
|
794
|
+
end
|
795
|
+
|
796
|
+
# ========================================================================= #
|
797
|
+
# === do_use_simplified_directory
|
798
|
+
# ========================================================================= #
|
799
|
+
def do_use_simplified_directory
|
800
|
+
set_last_backup_directory(
|
801
|
+
mount_point?+'last_backup'
|
802
|
+
)
|
803
|
+
end
|
804
|
+
|
805
|
+
# ========================================================================= #
|
806
|
+
# === is_target_harddisc_a_ntfs_system?
|
807
|
+
#
|
808
|
+
# This method will return a boolean - true or false.
|
809
|
+
#
|
810
|
+
# It will return true if the target harddisc is a NTFS system, and false
|
811
|
+
# otherwise.
|
812
|
+
# ========================================================================= #
|
813
|
+
def is_target_harddisc_a_ntfs_system?
|
814
|
+
return_value = false
|
815
|
+
_ = '/Mount'
|
816
|
+
if mount_target?.include? _
|
817
|
+
# ===================================================================== #
|
818
|
+
# Next, determine what is mounted.
|
819
|
+
# ===================================================================== #
|
820
|
+
these_may_be_mounted = `df -T -ah`.split(N).select {|line| line.include? _ }
|
821
|
+
if these_may_be_mounted and these_may_be_mounted.first and
|
822
|
+
these_may_be_mounted.first.include?('fuseblk') # This may mean a NTFS system.
|
823
|
+
return_value = true
|
824
|
+
end
|
825
|
+
end
|
826
|
+
return return_value
|
827
|
+
end
|
828
|
+
|
829
|
+
# ========================================================================= #
|
830
|
+
# === show_help
|
831
|
+
# ========================================================================= #
|
832
|
+
def show_help
|
833
|
+
BackupParadise.show_help
|
834
|
+
end; alias display_help show_help # === display_help
|
835
|
+
|
836
|
+
end; end
|