backup_paradise 1.2.13
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 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
|