extracter 1.2.32 → 1.3.6
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.
- checksums.yaml +4 -4
- data/README.md +116 -87
- data/bin/extract +2 -2
- data/doc/README.gen +117 -88
- data/extracter.gemspec +12 -32
- data/lib/extracter/base/base.rb +354 -43
- data/lib/extracter/class/extracter.rb +722 -559
- data/lib/extracter/constants/constants.rb +38 -39
- data/lib/extracter/requires/require_the_extracter_project.rb +1 -1
- data/lib/extracter/requires/require_the_toplevel_methods.rb +7 -0
- data/lib/extracter/toplevel_methods/toplevel_methods.rb +99 -0
- data/lib/extracter/version/version.rb +2 -2
- data/lib/extracter.rb +0 -0
- data/test/testing_are_we_on_windows.rb +10 -0
- data/test/testing_class_extracter.rb +3 -2
- data/test/testing_class_method_extract_what_to.rb +4 -1
- metadata +31 -35
- data/bin/extract_it +0 -13
- data/lib/extracter/class/extract_this_archive.rb +0 -289
- data/lib/extracter/extract_it/extract_it.rb +0 -241
- data/lib/extracter/toplevel_methods/is_this_a_valid_archive.rb +0 -41
- data/lib/extracter/toplevel_methods/misc.rb +0 -34
@@ -4,14 +4,21 @@
|
|
4
4
|
# =========================================================================== #
|
5
5
|
# === Extracter::Extracter
|
6
6
|
#
|
7
|
-
# The primary purpose of this class is to abstract
|
8
|
-
# to a target location.
|
9
|
-
#
|
7
|
+
# The primary purpose of this class is to abstract-away the extraction-step
|
8
|
+
# of source archives to a target location.
|
9
|
+
#
|
10
|
+
# The user should simply just pass the argument of the file that has
|
11
|
+
# to be extracted to this class, and the class will handle the rest.
|
10
12
|
#
|
11
13
|
# The class can be used to "extract" audio files as well, by calling the
|
12
14
|
# module ExtractAudio, which is part of MultimediaParadise. You can try
|
13
15
|
# this - just pass a .mp4 file as first argument to this class. Make sure
|
14
|
-
# to have installed
|
16
|
+
# to have installed the multimedia gem before, via:
|
17
|
+
#
|
18
|
+
# gem install multimedia_paradise
|
19
|
+
#
|
20
|
+
# If no input was provided to this class, but a .zip file exists in
|
21
|
+
# the current working directory, then that .zip file will be used.
|
15
22
|
#
|
16
23
|
# Usage examples:
|
17
24
|
#
|
@@ -28,11 +35,7 @@ module Extracter
|
|
28
35
|
|
29
36
|
class Extracter < ::Extracter::Base # === Extracter::Extracter
|
30
37
|
|
31
|
-
require 'fileutils'
|
32
|
-
require 'extracter/toplevel_methods/is_this_a_valid_archive.rb'
|
33
|
-
require 'extracter/toplevel_methods/misc.rb'
|
34
38
|
require 'extracter/version/version.rb'
|
35
|
-
require 'extracter/class/extract_this_archive.rb'
|
36
39
|
|
37
40
|
begin
|
38
41
|
require 'opn'
|
@@ -81,8 +84,8 @@ class Extracter < ::Extracter::Base # === Extracter::Extracter
|
|
81
84
|
commandline_arguments
|
82
85
|
)
|
83
86
|
if debug? # Some debug-information in this case.
|
84
|
-
|
85
|
-
|
87
|
+
opne "The first argument what is: `#{commandline_arguments}`"
|
88
|
+
opne "The second argument where_to is: `#{extract_to}`"
|
86
89
|
end
|
87
90
|
case run_already
|
88
91
|
# ======================================================================= #
|
@@ -129,25 +132,20 @@ class Extracter < ::Extracter::Base # === Extracter::Extracter
|
|
129
132
|
def reset
|
130
133
|
super()
|
131
134
|
# ======================================================================= #
|
132
|
-
# === :
|
133
|
-
#
|
134
|
-
|
135
|
-
#
|
136
|
-
# === :colour_to_use_for_directories
|
137
|
-
# ======================================================================= #
|
138
|
-
@internal_hash[:colour_to_use_for_directories] = 'cyan'
|
139
|
-
# ======================================================================= #
|
140
|
-
# === :use_opn
|
135
|
+
# === :namespace
|
136
|
+
#
|
137
|
+
# Specify the main namespace to be used. This setting can be modified
|
138
|
+
# at "runtime".
|
141
139
|
# ======================================================================= #
|
142
|
-
@internal_hash[:
|
140
|
+
@internal_hash[:namespace] = NAMESPACE
|
143
141
|
# ======================================================================= #
|
144
|
-
# === :
|
142
|
+
# === :array_work_on_these_files
|
145
143
|
# ======================================================================= #
|
146
|
-
@internal_hash[:
|
144
|
+
@internal_hash[:array_work_on_these_files] = []
|
147
145
|
# ======================================================================= #
|
148
|
-
# === :
|
146
|
+
# === :try_to_use_colours
|
149
147
|
# ======================================================================= #
|
150
|
-
@internal_hash[:
|
148
|
+
@internal_hash[:try_to_use_colours] = true
|
151
149
|
# ======================================================================= #
|
152
150
|
# === :append_this_to_the_commandline
|
153
151
|
#
|
@@ -156,16 +154,9 @@ class Extracter < ::Extracter::Base # === Extracter::Extracter
|
|
156
154
|
# ======================================================================= #
|
157
155
|
@internal_hash[:append_this_to_the_commandline] = ''.dup
|
158
156
|
# ======================================================================= #
|
159
|
-
# === :
|
160
|
-
#
|
161
|
-
# Specify the main namespace to be used. This setting can be modified
|
162
|
-
# at "runtime".
|
163
|
-
# ======================================================================= #
|
164
|
-
@internal_hash[:namespace] = NAMESPACE
|
165
|
-
# ======================================================================= #
|
166
|
-
# === :be_verbose
|
157
|
+
# === :show_the_full_name_of_the_archive
|
167
158
|
# ======================================================================= #
|
168
|
-
@internal_hash[:
|
159
|
+
@internal_hash[:show_the_full_name_of_the_archive] = false
|
169
160
|
# ======================================================================= #
|
170
161
|
# === :show_the_name
|
171
162
|
#
|
@@ -195,181 +186,93 @@ class Extracter < ::Extracter::Base # === Extracter::Extracter
|
|
195
186
|
end
|
196
187
|
|
197
188
|
# ========================================================================= #
|
198
|
-
# ===
|
199
|
-
#
|
200
|
-
# Tells us whether to use opn() or not.
|
201
|
-
# ========================================================================= #
|
202
|
-
def do_not_show_name
|
203
|
-
@internal_hash[:show_the_name] = false
|
204
|
-
end
|
205
|
-
|
206
|
-
# ========================================================================= #
|
207
|
-
# === show_the_name?
|
208
|
-
# ========================================================================= #
|
209
|
-
def show_the_name?
|
210
|
-
@internal_hash[:show_the_name]
|
211
|
-
end
|
212
|
-
|
213
|
-
# ========================================================================= #
|
214
|
-
# === check_whether_rar_is_available
|
215
|
-
#
|
216
|
-
# We try to find out whether unrar is available.
|
217
|
-
# ========================================================================= #
|
218
|
-
def check_whether_rar_is_available
|
219
|
-
is_available = false
|
220
|
-
ENV['PATH'].split(':').each {|entry|
|
221
|
-
is_available = true if File.exist? "#{entry}/unrar"
|
222
|
-
}
|
223
|
-
unless is_available
|
224
|
-
copn; e 'Sorry, unrar is not available. Please install it first.'
|
225
|
-
end
|
226
|
-
end
|
227
|
-
|
228
|
-
# ========================================================================= #
|
229
|
-
# === debug?
|
230
|
-
# ========================================================================= #
|
231
|
-
def debug?
|
232
|
-
@internal_hash[:debug]
|
233
|
-
end
|
234
|
-
|
235
|
-
# ========================================================================= #
|
236
|
-
# === run_already?
|
237
|
-
# ========================================================================= #
|
238
|
-
def run_already?
|
239
|
-
@internal_hash[:run_already]
|
240
|
-
end
|
241
|
-
|
242
|
-
# ========================================================================= #
|
243
|
-
# === enable_debug
|
244
|
-
# ========================================================================= #
|
245
|
-
def enable_debug
|
246
|
-
@internal_hash[:debug] = true
|
247
|
-
end
|
248
|
-
|
249
|
-
# ========================================================================= #
|
250
|
-
# === return_pwd
|
251
|
-
# ========================================================================= #
|
252
|
-
def return_pwd
|
253
|
-
"#{Dir.pwd}/".squeeze('/')
|
254
|
-
end
|
255
|
-
|
256
|
-
# ========================================================================= #
|
257
|
-
# === set_use_opn
|
258
|
-
# ========================================================================= #
|
259
|
-
def set_use_opn(i = true)
|
260
|
-
@internal_hash[:use_opn] = i
|
261
|
-
end
|
262
|
-
|
263
|
-
# ========================================================================= #
|
264
|
-
# === use_opn?
|
265
|
-
# ========================================================================= #
|
266
|
-
def use_opn?
|
267
|
-
@internal_hash[:use_opn]
|
268
|
-
end
|
269
|
-
|
270
|
-
# ========================================================================= #
|
271
|
-
# === set_commandline_arguments
|
272
|
-
# ========================================================================= #
|
273
|
-
def set_commandline_arguments(i = '')
|
274
|
-
i = [i].flatten.compact
|
275
|
-
@commandline_arguments = i
|
276
|
-
end
|
277
|
-
|
278
|
-
# ========================================================================= #
|
279
|
-
# === commandline_arguments?
|
280
|
-
# ========================================================================= #
|
281
|
-
def commandline_arguments?
|
282
|
-
@commandline_arguments
|
283
|
-
end
|
284
|
-
|
285
|
-
# ========================================================================= #
|
286
|
-
# === first_argument?
|
287
|
-
# ========================================================================= #
|
288
|
-
def first_argument?
|
289
|
-
@commandline_arguments.first
|
290
|
-
end; alias first? first_argument? # === first?
|
291
|
-
|
292
|
-
# ========================================================================= #
|
293
|
-
# === padded_extract_to?
|
294
|
-
# ========================================================================= #
|
295
|
-
def padded_extract_to?
|
296
|
-
" -C #{extract_to?} "
|
297
|
-
end
|
298
|
-
|
299
|
-
# ========================================================================= #
|
300
|
-
# === set_colour_for_directories
|
301
|
-
#
|
302
|
-
# Set the colour for directories to use.
|
189
|
+
# === notify_the_user_that_no_input_was_given_but_this_file_was_found
|
303
190
|
# ========================================================================= #
|
304
|
-
def
|
305
|
-
|
191
|
+
def notify_the_user_that_no_input_was_given_but_this_file_was_found(
|
192
|
+
this_file
|
193
|
+
)
|
194
|
+
opne "No input was given to #{sfancy(NAMESPACE)} but a "\
|
195
|
+
".zip file was"
|
196
|
+
opne 'found in this directory ('+sdir(return_pwd)+rev+
|
197
|
+
'): '+sfancy(this_file)
|
198
|
+
opne 'We will use this zip file.'
|
306
199
|
end
|
307
200
|
|
308
201
|
# ========================================================================= #
|
309
|
-
# ===
|
310
|
-
#
|
311
|
-
# Note that this method is guaranteed to return a String.
|
312
|
-
# ========================================================================= #
|
313
|
-
def extract_to?
|
314
|
-
@internal_hash[:extract_to].to_s
|
315
|
-
end; alias source_package_location extract_to? # === source_package
|
316
|
-
alias extract_to_this_location? extract_to? # === extract_to_this_location?
|
317
|
-
alias extracted_to? extract_to? # === extracted_to?
|
318
|
-
alias extracted_path? extract_to? # === extracted_path?
|
319
|
-
|
320
|
-
# ========================================================================= #
|
321
|
-
# === opnn
|
322
|
-
#
|
323
|
-
# This variant will also check whether we should show the name or not.
|
202
|
+
# === work_on_the_given_input
|
324
203
|
# ========================================================================= #
|
325
|
-
def
|
326
|
-
|
204
|
+
def work_on_the_given_input(
|
205
|
+
array = @internal_hash[:array_work_on_these_files],
|
206
|
+
extract_to = extract_to?
|
327
207
|
)
|
328
|
-
|
329
|
-
|
208
|
+
pp array if debug?
|
209
|
+
case extract_to
|
210
|
+
# ======================================================================= #
|
211
|
+
# === :default
|
212
|
+
# ======================================================================= #
|
213
|
+
when :default,
|
214
|
+
nil
|
215
|
+
extract_to = extract_to?
|
330
216
|
end
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
217
|
+
# ======================================================================= #
|
218
|
+
# If the user supplied a directory then a random entry will be grabbed
|
219
|
+
# from said directory.
|
220
|
+
# ======================================================================= #
|
221
|
+
if array.is_a?(String) and File.directory?(array)
|
222
|
+
array = Dir[rds("#{array}/")+'*'].sample
|
223
|
+
end
|
224
|
+
if array.empty?
|
225
|
+
opne 'No archive (input) was provided. Please provide the file'
|
226
|
+
opne 'that is to be extracted.'
|
227
|
+
else
|
228
|
+
array.each {|this_file|
|
229
|
+
# =================================================================== #
|
230
|
+
# The next if-clause is for my home setup, for pseudo Symbols:
|
231
|
+
# =================================================================== #
|
232
|
+
if this_file.is_a?(String) and this_file.start_with?(':')
|
233
|
+
_ = '/home/x/src/'
|
234
|
+
if File.directory?(_+this_file.delete(':'))
|
235
|
+
target = _+this_file.delete(':')+'/*'
|
236
|
+
possible_files = Dir[target].select {|entry|
|
237
|
+
File.file?(entry)
|
238
|
+
}
|
239
|
+
unless possible_files.empty?
|
240
|
+
this_file = possible_files.first
|
241
|
+
end
|
242
|
+
end
|
243
|
+
end
|
244
|
+
# =================================================================== #
|
245
|
+
# Create the directory if it does not yet exist.
|
246
|
+
# =================================================================== #
|
247
|
+
create_directory(extract_to) unless File.directory?(extract_to)
|
248
|
+
# =================================================================== #
|
249
|
+
# Handle the case when the user did input a number.
|
250
|
+
# =================================================================== #
|
251
|
+
begin
|
252
|
+
if this_file =~ /^\d$/
|
253
|
+
this_file = Dir['*'][( this_file.to_i - 1 )] unless File.exist?(this_file)
|
254
|
+
end
|
255
|
+
rescue ArgumentError => error
|
256
|
+
opne 'An error occurred for '+sfancy(this_file)+':'
|
257
|
+
pp error
|
258
|
+
end
|
259
|
+
# =================================================================== #
|
260
|
+
# If the user supplied a directory then a random entry will be
|
261
|
+
# grabbed from said directory.
|
262
|
+
#
|
263
|
+
# Usage example:
|
264
|
+
#
|
265
|
+
# rubyextracter /home/x/src/htop/
|
266
|
+
#
|
267
|
+
# =================================================================== #
|
268
|
+
if File.directory? this_file
|
269
|
+
this_file = Dir[rds("#{this_file}/")+'*'].sample
|
270
|
+
end
|
271
|
+
extract_this_archive(this_file, extract_to)
|
272
|
+
report_to_the_user(this_file, extract_to)
|
273
|
+
}
|
274
|
+
end
|
275
|
+
end; alias extract_input work_on_the_given_input # === extract_input
|
373
276
|
|
374
277
|
# ========================================================================= #
|
375
278
|
# === pad (pad tag)
|
@@ -380,7 +283,8 @@ class Extracter < ::Extracter::Base # === Extracter::Extracter
|
|
380
283
|
# padding.
|
381
284
|
# ========================================================================= #
|
382
285
|
def pad(
|
383
|
-
i,
|
286
|
+
i,
|
287
|
+
with_this_character = "'"
|
384
288
|
)
|
385
289
|
if i.include?('(') or i.include?(')')
|
386
290
|
i.tr!('(','\(')
|
@@ -394,215 +298,16 @@ class Extracter < ::Extracter::Base # === Extracter::Extracter
|
|
394
298
|
end
|
395
299
|
|
396
300
|
# ========================================================================= #
|
397
|
-
# ===
|
398
|
-
# ========================================================================= #
|
399
|
-
def namespace?
|
400
|
-
@internal_hash[:namespace]
|
401
|
-
end
|
402
|
-
|
403
|
-
# ========================================================================= #
|
404
|
-
# === set_be_verbose
|
301
|
+
# === set_extract_to
|
405
302
|
#
|
406
|
-
# This
|
407
|
-
#
|
408
|
-
# ========================================================================= #
|
409
|
-
def set_be_verbose(i = false)
|
410
|
-
@internal_hash[:be_verbose] = i
|
411
|
-
end; alias set_verbosity set_be_verbose # === set_verbosity
|
412
|
-
|
413
|
-
# ========================================================================= #
|
414
|
-
# === be_verbose?
|
303
|
+
# This is the method that should be used to determine into which
|
304
|
+
# directory this class will extract archives into.
|
415
305
|
#
|
416
|
-
#
|
417
|
-
#
|
418
|
-
def be_verbose?
|
419
|
-
@internal_hash[:be_verbose]
|
420
|
-
end
|
421
|
-
|
422
|
-
# ========================================================================= #
|
423
|
-
# === register_sigint
|
424
|
-
# ========================================================================= #
|
425
|
-
def register_sigint
|
426
|
-
Signal.trap('SIGINT') {
|
427
|
-
e sfancy('Requesting a graceful exit from ')+
|
428
|
-
colour_to_use_for_directories?+
|
429
|
-
'class Extracter'+
|
430
|
-
sfancy('. Exiting now.')
|
431
|
-
exit
|
432
|
-
}
|
433
|
-
end
|
434
|
-
|
435
|
-
# ========================================================================= #
|
436
|
-
# === colour_to_use_for_directories?
|
437
|
-
# ========================================================================= #
|
438
|
-
def colour_to_use_for_directories?
|
439
|
-
if use_colours?
|
440
|
-
return @internal_hash[:colour_to_use_for_directories]
|
441
|
-
else
|
442
|
-
return ''
|
443
|
-
end
|
444
|
-
end
|
445
|
-
|
446
|
-
# ========================================================================= #
|
447
|
-
# === do_show_the_full_name_of_the_archive
|
448
|
-
# ========================================================================= #
|
449
|
-
def do_show_the_full_name_of_the_archive
|
450
|
-
@internal_hash[:show_the_full_name_of_the_archive] = true
|
451
|
-
end
|
452
|
-
|
453
|
-
# ========================================================================= #
|
454
|
-
# === prefix_namespace_with
|
455
|
-
# ========================================================================= #
|
456
|
-
def prefix_namespace_with(i)
|
457
|
-
@internal_hash[:namespace] = "#{i}#{@internal_hash[:namespace].dup}"
|
458
|
-
update_the_main_hash # Also update the opn-hash here.
|
459
|
-
end
|
460
|
-
|
461
|
-
# ========================================================================= #
|
462
|
-
# === pad_opn_with_n_tokens
|
463
|
-
# ========================================================================= #
|
464
|
-
def pad_opn_with_n_tokens(n_tokens = nil)
|
465
|
-
if n_tokens
|
466
|
-
determine_default_opn_hash # Update this, just in case.
|
467
|
-
main_hash?.update(padding: n_tokens)
|
468
|
-
end
|
469
|
-
end; alias set_pad_opn_with_n_tokens pad_opn_with_n_tokens # === set_pad_opn_with_n_tokens
|
470
|
-
|
306
|
+
# Note that this target can be modified from the commandline, if
|
307
|
+
# the user wants to do so.
|
471
308
|
# ========================================================================= #
|
472
|
-
|
473
|
-
|
474
|
-
def prepare_the_hash_for_opn(
|
475
|
-
use_this_hash = {
|
476
|
-
namespace: namespace?,
|
477
|
-
use_colours: use_colours?
|
478
|
-
}
|
479
|
-
)
|
480
|
-
# ======================================================================= #
|
481
|
-
# === :use_this_opn_hash
|
482
|
-
# ======================================================================= #
|
483
|
-
@internal_hash[:use_this_opn_hash] = use_this_hash
|
484
|
-
return @internal_hash[:use_this_opn_hash]
|
485
|
-
end; alias update_the_opn_hash prepare_the_hash_for_opn # === update_the_opn_hash
|
486
|
-
alias determine_default_opn_hash prepare_the_hash_for_opn # === determine_default_opn_hash
|
487
|
-
alias determine_the_default_opn_hash prepare_the_hash_for_opn # === determine_the_default_opn_hash
|
488
|
-
alias update_the_main_hash prepare_the_hash_for_opn # === update_the_main_hash
|
489
|
-
|
490
|
-
# ========================================================================= #
|
491
|
-
# === show_only_the_short_name_of_the_archive?
|
492
|
-
# ========================================================================= #
|
493
|
-
def show_only_the_short_name_of_the_archive?
|
494
|
-
@internal_hash[:show_only_the_short_name_of_the_archive]
|
495
|
-
end
|
496
|
-
|
497
|
-
# ========================================================================= #
|
498
|
-
# === set_run_simulation
|
499
|
-
# ========================================================================= #
|
500
|
-
def set_run_simulation(i = false) # false is the default here.
|
501
|
-
@internal_hash[:run_simulation] = i
|
502
|
-
end
|
503
|
-
|
504
|
-
# ========================================================================= #
|
505
|
-
# === run_simulation=
|
506
|
-
# ========================================================================= #
|
507
|
-
def run_simulation=(i)
|
508
|
-
@internal_hash[:run_simulation] = i
|
509
|
-
end
|
510
|
-
|
511
|
-
# ========================================================================= #
|
512
|
-
# === run_simulation?
|
513
|
-
# ========================================================================= #
|
514
|
-
def run_simulation?
|
515
|
-
@internal_hash[:run_simulation]
|
516
|
-
end
|
517
|
-
|
518
|
-
# ========================================================================= #
|
519
|
-
# === strip_components
|
520
|
-
#
|
521
|
-
# The first argument to this method will determine how far "down" tar
|
522
|
-
# will strip the components.
|
523
|
-
# ========================================================================= #
|
524
|
-
def strip_components(
|
525
|
-
by_n = 1
|
526
|
-
)
|
527
|
-
@internal_hash[:append_this_to_the_commandline] <<
|
528
|
-
" --strip-components=#{by_n}"
|
529
|
-
end
|
530
|
-
|
531
|
-
# ========================================================================= #
|
532
|
-
# === do_show_name
|
533
|
-
#
|
534
|
-
# If this method is called then the class here will show the name of
|
535
|
-
# the file on the commandline, via opn().
|
536
|
-
# ========================================================================= #
|
537
|
-
def do_show_name
|
538
|
-
@internal_hash[:show_the_name] = true
|
539
|
-
end
|
540
|
-
|
541
|
-
# ========================================================================= #
|
542
|
-
# === enable_colours
|
543
|
-
# ========================================================================= #
|
544
|
-
def enable_colours
|
545
|
-
set_use_colours(true)
|
546
|
-
@internal_hash[:colour_to_use_for_directories] = cyan?
|
547
|
-
end
|
548
|
-
|
549
|
-
# ========================================================================= #
|
550
|
-
# === disable_colours
|
551
|
-
#
|
552
|
-
# Use this method if you want to disable colour-support of this class.
|
553
|
-
# ========================================================================= #
|
554
|
-
def disable_colours
|
555
|
-
set_use_colours(false)
|
556
|
-
@internal_hash[:colour_to_use_for_directories] = ''.dup
|
557
|
-
end
|
558
|
-
|
559
|
-
# ========================================================================= #
|
560
|
-
# === set_use_colours
|
561
|
-
# ========================================================================= #
|
562
|
-
def set_use_colours(i)
|
563
|
-
# ======================================================================= #
|
564
|
-
# We must also sync this towards our main Hash, for opn(). The next
|
565
|
-
# line of code achieves precisely that.
|
566
|
-
# ======================================================================= #
|
567
|
-
main_hash?.update(use_colours: i)
|
568
|
-
@internal_hash[:try_to_use_colours] = i
|
569
|
-
end
|
570
|
-
|
571
|
-
# ========================================================================= #
|
572
|
-
# === try_to_use_colours?
|
573
|
-
# ========================================================================= #
|
574
|
-
def try_to_use_colours?
|
575
|
-
@internal_hash[:try_to_use_colours]
|
576
|
-
end
|
577
|
-
|
578
|
-
# ========================================================================= #
|
579
|
-
# === remove_file_extension
|
580
|
-
# ========================================================================= #
|
581
|
-
def remove_file_extension(i)
|
582
|
-
_ = File.basename(i)
|
583
|
-
return ::Extracter.remove_archive_type(_)
|
584
|
-
end; alias remove_extension remove_file_extension # === remove_extensions
|
585
|
-
alias remove_ext remove_file_extension # === remove_ext
|
586
|
-
|
587
|
-
# ========================================================================= #
|
588
|
-
# === rds
|
589
|
-
# ========================================================================= #
|
590
|
-
def rds(i)
|
591
|
-
return i.squeeze('/') if i.respond_to? :squeeze
|
592
|
-
return i
|
593
|
-
end
|
594
|
-
|
595
|
-
# ========================================================================= #
|
596
|
-
# === set_extract_to
|
597
|
-
#
|
598
|
-
# This is the method that should be used to determine into which
|
599
|
-
# directory this class will extract archives into.
|
600
|
-
#
|
601
|
-
# Note that this target can be modified from the commandline, if
|
602
|
-
# the user wants to do so.
|
603
|
-
# ========================================================================= #
|
604
|
-
def set_extract_to(
|
605
|
-
i = :temp_dir
|
309
|
+
def set_extract_to(
|
310
|
+
i = :temp_dir
|
606
311
|
)
|
607
312
|
if i.is_a?(Hash) and i.empty?
|
608
313
|
i = :temp_dir
|
@@ -714,133 +419,83 @@ class Extracter < ::Extracter::Base # === Extracter::Extracter
|
|
714
419
|
alias extract_to set_extract_to # === extract_to
|
715
420
|
|
716
421
|
# ========================================================================= #
|
717
|
-
# ===
|
422
|
+
# === run_simulation=
|
718
423
|
# ========================================================================= #
|
719
|
-
def
|
720
|
-
|
721
|
-
'than extracting a .tar.gz tarball'
|
722
|
-
opnn; e 'archive. This class will first create a helper '\
|
723
|
-
'directory; then mount the .iso there,'
|
724
|
-
opnn; e 'then copy the content to the main directory.'
|
725
|
-
helper_directory = File.dirname(i)+
|
726
|
-
'/READ_ONLY_DIRECTORY_'+
|
727
|
-
File.basename(
|
728
|
-
i.delete_suffix(File.extname(i))
|
729
|
-
)+
|
730
|
-
'/'
|
731
|
-
mkdir(helper_directory) unless File.directory? helper_directory
|
732
|
-
esystem 'mount -o loop '+i+' '+helper_directory
|
733
|
-
e 'The helper directory in use is '\
|
734
|
-
'`'+sdir(File.absolute_path(helper_directory))+'`.'
|
735
|
-
main_directory = File.dirname(i)+
|
736
|
-
'/'+
|
737
|
-
File.basename(
|
738
|
-
i.delete_suffix(File.extname(i))
|
739
|
-
)+
|
740
|
-
'/'
|
741
|
-
e 'Next creating the main directory at `'+sdir(main_directory)+'`.'
|
742
|
-
mkdir(main_directory) unless File.directory? main_directory
|
743
|
-
e 'Next copying the content of the helper directory recursively '
|
744
|
-
e 'from `'+sdir(helper_directory)+'`'
|
745
|
-
e 'onto `'+sdir(
|
746
|
-
main_directory+File.basename(helper_directory)+'/'
|
747
|
-
)+'`.'
|
748
|
-
cpr(
|
749
|
-
helper_directory,
|
750
|
-
main_directory+File.basename(helper_directory)+'/'
|
751
|
-
)
|
752
|
-
a = main_directory+File.basename(helper_directory)+'/'
|
753
|
-
e 'Relocating the files next from:'
|
754
|
-
e
|
755
|
-
e " #{sdir(a)}"
|
756
|
-
e
|
757
|
-
Dir[a+'*'].each {|entry|
|
758
|
-
mv(
|
759
|
-
entry,
|
760
|
-
main_directory
|
761
|
-
)
|
762
|
-
}
|
763
|
-
# ======================================================================= #
|
764
|
-
# And remove the directory:
|
765
|
-
# ======================================================================= #
|
766
|
-
remove_this_directory(a)
|
767
|
-
e 'The content of the extracted (or rather, mounted) archive is:'
|
768
|
-
e
|
769
|
-
pp Dir["#{main_directory}*"]
|
770
|
-
e
|
424
|
+
def run_simulation=(i)
|
425
|
+
@internal_hash[:run_simulation] = i
|
771
426
|
end
|
772
427
|
|
773
428
|
# ========================================================================= #
|
774
|
-
# ===
|
429
|
+
# === run_simulation?
|
775
430
|
# ========================================================================= #
|
776
|
-
def
|
777
|
-
|
778
|
-
|
779
|
-
|
431
|
+
def run_simulation?
|
432
|
+
@internal_hash[:run_simulation]
|
433
|
+
end
|
434
|
+
# ========================================================================= #
|
435
|
+
# === consider_verbosity_for
|
436
|
+
# ========================================================================= #
|
437
|
+
def consider_verbosity_for(i)
|
438
|
+
i = i.dup
|
439
|
+
unless be_verbose?
|
440
|
+
case i
|
441
|
+
# "tar -xvf" must become "tar -xvf" here.
|
442
|
+
when COMMAND_TO_EXTRACT_TAR_XZ_FILES
|
443
|
+
i.delete!('v')
|
444
|
+
end
|
445
|
+
end
|
446
|
+
return i
|
447
|
+
end
|
448
|
+
|
449
|
+
# ========================================================================= #
|
450
|
+
# === try_to_glob_on
|
451
|
+
# ========================================================================= #
|
452
|
+
def try_to_glob_on(i)
|
453
|
+
result = Dir["#{i}*"]
|
780
454
|
# ======================================================================= #
|
781
|
-
#
|
782
|
-
# from said directory.
|
455
|
+
# Next, sort this result to put archives on the beginning of the Array.
|
783
456
|
# ======================================================================= #
|
784
|
-
|
785
|
-
|
786
|
-
|
787
|
-
|
788
|
-
|
789
|
-
|
790
|
-
|
791
|
-
|
792
|
-
|
793
|
-
opnn; e 'that is to be extracted.'
|
794
|
-
else
|
795
|
-
array.each {|this_file|
|
796
|
-
# =================================================================== #
|
797
|
-
# Create the directory if it does not yet exist.
|
798
|
-
# =================================================================== #
|
799
|
-
create_directory(extract_to) unless File.directory?(extract_to)
|
800
|
-
# =================================================================== #
|
801
|
-
# Handle the case when the user did input a number.
|
802
|
-
# =================================================================== #
|
803
|
-
begin
|
804
|
-
if this_file =~ /^\d$/
|
805
|
-
this_file = Dir['*'][( this_file.to_i - 1 )] unless File.exist?(this_file)
|
806
|
-
end
|
807
|
-
rescue ArgumentError => error
|
808
|
-
e 'Error for '+sfancy(this_file)+':'
|
809
|
-
pp error
|
810
|
-
end
|
811
|
-
# =================================================================== #
|
812
|
-
# If the user supplied a directory then a random entry will be
|
813
|
-
# grabbed from said directory.
|
814
|
-
#
|
815
|
-
# Usage example:
|
816
|
-
#
|
817
|
-
# rubyextracter /home/x/src/htop/
|
818
|
-
#
|
819
|
-
# =================================================================== #
|
820
|
-
if File.directory? this_file
|
821
|
-
this_file = Dir[rds("#{this_file}/")+'*'].sample
|
822
|
-
end
|
823
|
-
extract_this_archive(this_file, extract_to)
|
824
|
-
report_to_the_user(this_file, extract_to)
|
825
|
-
}
|
457
|
+
result = result.partition {|entry| is_archive?(entry) }
|
458
|
+
result.flatten!
|
459
|
+
unless result.empty?
|
460
|
+
# ===================================================================== #
|
461
|
+
# Ok, we grab the first entry next.
|
462
|
+
# ===================================================================== #
|
463
|
+
i = result.first
|
464
|
+
opne "#{rev}No result could be found for the given input, "\
|
465
|
+
"thus using #{sfancy(i)} #{rev}instead."
|
826
466
|
end
|
467
|
+
return i
|
468
|
+
end
|
469
|
+
|
470
|
+
# ========================================================================= #
|
471
|
+
# === strip_components
|
472
|
+
#
|
473
|
+
# The first argument to this method will determine how far "down" tar
|
474
|
+
# will strip the components.
|
475
|
+
# ========================================================================= #
|
476
|
+
def strip_components(
|
477
|
+
by_n = 1
|
478
|
+
)
|
479
|
+
@internal_hash[:append_this_to_the_commandline] <<
|
480
|
+
" --strip-components=#{by_n}"
|
827
481
|
end
|
828
482
|
|
829
483
|
# ========================================================================= #
|
830
|
-
# ===
|
484
|
+
# === do_show_name
|
831
485
|
#
|
832
|
-
#
|
486
|
+
# If this method is called then the class here will show the name of
|
487
|
+
# the file on the commandline, via opn().
|
833
488
|
# ========================================================================= #
|
834
|
-
def
|
835
|
-
|
836
|
-
end
|
489
|
+
def do_show_name
|
490
|
+
@internal_hash[:show_the_name] = true
|
491
|
+
end
|
837
492
|
|
838
493
|
# ========================================================================= #
|
839
494
|
# === notify_the_user_that_this_extension_has_not_been_registered_yet
|
840
495
|
# ========================================================================= #
|
841
496
|
def notify_the_user_that_this_extension_has_not_been_registered_yet(i)
|
842
|
-
|
843
|
-
|
497
|
+
opne "The archive at `#{i}` is #{tomato('not')}"
|
498
|
+
opne "registered as a permissive extension."
|
844
499
|
fail_message_not_registered(i)
|
845
500
|
end
|
846
501
|
|
@@ -850,20 +505,8 @@ class Extracter < ::Extracter::Base # === Extracter::Extracter
|
|
850
505
|
# Output a fail message when the archive format is not registered.
|
851
506
|
# ========================================================================= #
|
852
507
|
def fail_message_not_registered(i)
|
853
|
-
|
854
|
-
|
855
|
-
end
|
856
|
-
|
857
|
-
# ========================================================================= #
|
858
|
-
# === try_to_extract_this_img_file
|
859
|
-
# ========================================================================= #
|
860
|
-
def try_to_extract_this_img_file(i)
|
861
|
-
opnn; e 'Handling a squashfs .img file format next:'
|
862
|
-
name_without_extension = i.delete_suffix(File.extname(i))
|
863
|
-
mkdir(name_without_extension) unless File.directory? name_without_extension
|
864
|
-
esystem "mount -o loop -t squashfs #{i} #{name_without_extension}"
|
865
|
-
e 'The content of the extracted (or rather, mounted) archive is:'
|
866
|
-
pp Dir["#{name_without_extension}*"]
|
508
|
+
opne "#{rev}Can not extract `#{sfancy(i)}#{rev}` - it is "\
|
509
|
+
"not registered."
|
867
510
|
end
|
868
511
|
|
869
512
|
# ========================================================================= #
|
@@ -872,12 +515,17 @@ class Extracter < ::Extracter::Base # === Extracter::Extracter
|
|
872
515
|
def menu(
|
873
516
|
i = commandline_arguments?
|
874
517
|
)
|
518
|
+
if debug?
|
519
|
+
opne 'The input given to this method was: `'+sfile(i)+'`'
|
520
|
+
end
|
875
521
|
if i.is_a? Array
|
876
522
|
i.each {|entry| menu(entry) }
|
877
523
|
else
|
878
524
|
case i
|
879
525
|
# ===================================================================== #
|
880
|
-
# === --help
|
526
|
+
# === extracter --help
|
527
|
+
#
|
528
|
+
# Entry point for showing help.
|
881
529
|
# ===================================================================== #
|
882
530
|
when /^-?-?help$/i
|
883
531
|
show_help
|
@@ -890,7 +538,8 @@ class Extracter < ::Extracter::Base # === Extracter::Extracter
|
|
890
538
|
# === esystem (system tag, esystem tag)
|
891
539
|
# ========================================================================= #
|
892
540
|
def esystem(
|
893
|
-
i,
|
541
|
+
i,
|
542
|
+
try_to_use_colours = try_to_use_colours?
|
894
543
|
)
|
895
544
|
i = i.dup if i.frozen?
|
896
545
|
# ======================================================================= #
|
@@ -907,9 +556,9 @@ class Extracter < ::Extracter::Base # === Extracter::Extracter
|
|
907
556
|
end
|
908
557
|
end
|
909
558
|
if run_simulation?
|
910
|
-
|
911
|
-
|
912
|
-
|
559
|
+
opne 'As we are running in simulation mode, the following command '
|
560
|
+
opne 'is the one that we would have been used if we were to not run '
|
561
|
+
opne 'in simulation mode:'
|
913
562
|
if be_verbose?
|
914
563
|
if try_to_use_colours
|
915
564
|
e steelblue(i)
|
@@ -959,35 +608,545 @@ class Extracter < ::Extracter::Base # === Extracter::Extracter
|
|
959
608
|
)
|
960
609
|
if be_verbose?
|
961
610
|
target = extract_to+
|
962
|
-
remove_file_extension(
|
963
|
-
File.basename(i)
|
964
|
-
)+
|
611
|
+
remove_file_extension(File.basename(i))+
|
965
612
|
'/'
|
966
|
-
|
967
|
-
|
613
|
+
opne "#{rev}Finished extracting to `"\
|
614
|
+
"#{sdir(target)}#{rev}`." # This is an Array.
|
968
615
|
end
|
969
616
|
end
|
970
617
|
|
971
618
|
# ========================================================================= #
|
972
|
-
# ===
|
619
|
+
# === try_to_extract_this_iso_file
|
973
620
|
# ========================================================================= #
|
974
|
-
def
|
975
|
-
|
621
|
+
def try_to_extract_this_iso_file(i)
|
622
|
+
opne 'Extracting an .iso file is a bit more complicated '\
|
623
|
+
'than extracting a .tar.gz tarball'
|
624
|
+
opne 'archive. This class will first create a helper '\
|
625
|
+
'directory; then mount the .iso there,'
|
626
|
+
opne 'then copy the content to the main directory.'
|
627
|
+
helper_directory = File.dirname(i)+
|
628
|
+
'/READ_ONLY_DIRECTORY_'+
|
629
|
+
File.basename(
|
630
|
+
i.delete_suffix(File.extname(i))
|
631
|
+
)+
|
632
|
+
'/'
|
633
|
+
mkdir(helper_directory) unless File.directory? helper_directory
|
634
|
+
esystem 'mount -o loop '+i+' '+helper_directory
|
635
|
+
opne 'The helper directory in use is '\
|
636
|
+
'`'+sdir(File.absolute_path(helper_directory))+'`.'
|
637
|
+
main_directory = File.dirname(i)+
|
638
|
+
'/'+
|
639
|
+
File.basename(
|
640
|
+
i.delete_suffix(File.extname(i))
|
641
|
+
)+
|
642
|
+
'/'
|
643
|
+
opne 'Next creating the main directory at `'+sdir(main_directory)+'`.'
|
644
|
+
mkdir(main_directory) unless File.directory? main_directory
|
645
|
+
opne 'Next copying the content of the helper directory recursively '
|
646
|
+
opne 'from `'+sdir(helper_directory)+'`'
|
647
|
+
opne 'onto `'+sdir(
|
648
|
+
main_directory+File.basename(helper_directory)+'/'
|
649
|
+
)+'`.'
|
650
|
+
cpr(
|
651
|
+
helper_directory,
|
652
|
+
main_directory+File.basename(helper_directory)+'/'
|
653
|
+
)
|
654
|
+
a = main_directory+File.basename(helper_directory)+'/'
|
655
|
+
opne 'Relocating the files next from:'
|
656
|
+
e
|
657
|
+
e " #{sdir(a)}"
|
658
|
+
e
|
659
|
+
Dir[a+'*'].each {|entry|
|
660
|
+
mv(
|
661
|
+
entry,
|
662
|
+
main_directory
|
663
|
+
)
|
664
|
+
}
|
665
|
+
# ======================================================================= #
|
666
|
+
# And remove the directory:
|
667
|
+
# ======================================================================= #
|
668
|
+
remove_this_directory(a)
|
669
|
+
opne 'The content of the extracted (or rather, mounted) archive is:'
|
670
|
+
e
|
671
|
+
pp Dir["#{main_directory}*"]
|
672
|
+
e
|
673
|
+
end
|
674
|
+
|
675
|
+
# ========================================================================= #
|
676
|
+
# === try_to_extract_this_img_file
|
677
|
+
# ========================================================================= #
|
678
|
+
def try_to_extract_this_img_file(i)
|
679
|
+
opne 'Handling a squashfs .img file format next:'
|
680
|
+
name_without_extension = i.delete_suffix(File.extname(i))
|
681
|
+
mkdir(name_without_extension) unless File.directory? name_without_extension
|
682
|
+
esystem "mount -o loop -t squashfs #{i} #{name_without_extension}"
|
683
|
+
opne 'The content of the extracted (or rather, mounted) archive is:'
|
684
|
+
pp Dir["#{name_without_extension}*"]
|
685
|
+
end
|
686
|
+
|
687
|
+
# ========================================================================= #
|
688
|
+
# === do_show_the_full_name_of_the_archive
|
689
|
+
# ========================================================================= #
|
690
|
+
def do_show_the_full_name_of_the_archive
|
691
|
+
@internal_hash[:show_the_full_name_of_the_archive] = true
|
692
|
+
end
|
693
|
+
|
694
|
+
# ========================================================================= #
|
695
|
+
# === show_help (help tag)
|
696
|
+
#
|
697
|
+
# This method will show the available - and documented - help options
|
698
|
+
# for class Extracter.
|
699
|
+
#
|
700
|
+
# To call this method via the commandline try:
|
701
|
+
#
|
702
|
+
# extract --help
|
703
|
+
#
|
704
|
+
# ========================================================================= #
|
705
|
+
def show_help
|
706
|
+
e
|
707
|
+
opne 'How to extract archives, without helper scripts?'
|
708
|
+
e
|
709
|
+
e ' tar -zxvf foobar.tar.gz # → for .tar.gz'
|
710
|
+
e ' tar xvzf foobar.tgz # → for .tgz'
|
711
|
+
e ' tar xvfJ foobar.tar.xz # → for .tar.xz'
|
712
|
+
e ' tar jxf foobar.tar.bz2 # → for .tar.bz2'
|
713
|
+
e ' tar -xf foobar.tar.bz2 # → for .tbz'
|
714
|
+
e ' tar --lzip -xvf zutils-1.5.tar.lz # → for .tar.lz'
|
715
|
+
e ' unsquashfs foobar-1.2.3.sxz # → for .sxz'
|
716
|
+
e ' 7z x -so C:\home\x\src\htop\htop-3.0.5.tar.xz | 7z x -si -ttar # → on windows'
|
717
|
+
e
|
718
|
+
opne 'Furthermore, there are some commandline options that can'
|
719
|
+
opne 'be used for this class (class Extracter).'
|
720
|
+
e
|
721
|
+
e ' --to=/home/Temp # extract into the '\
|
722
|
+
'directory /home/Temp/'
|
723
|
+
e
|
724
|
+
end
|
725
|
+
|
726
|
+
# ========================================================================= #
|
727
|
+
# === prefix_namespace_with
|
728
|
+
# ========================================================================= #
|
729
|
+
def prefix_namespace_with(i)
|
730
|
+
@internal_hash[:namespace] = "#{i}#{@internal_hash[:namespace].dup}"
|
731
|
+
update_the_main_hash # Also update the opn-hash here.
|
732
|
+
end
|
733
|
+
|
734
|
+
# ========================================================================= #
|
735
|
+
# === prepare_the_hash_for_opn
|
736
|
+
# ========================================================================= #
|
737
|
+
def prepare_the_hash_for_opn(
|
738
|
+
use_this_hash = {
|
739
|
+
namespace: namespace?,
|
740
|
+
use_colours: use_colours?,
|
741
|
+
show_the_name: show_the_name?
|
742
|
+
}
|
743
|
+
)
|
744
|
+
# ======================================================================= #
|
745
|
+
# === :use_this_opn_hash
|
746
|
+
# ======================================================================= #
|
747
|
+
@internal_hash[:use_this_opn_hash] = use_this_hash
|
748
|
+
return @internal_hash[:use_this_opn_hash]
|
749
|
+
end; alias update_the_opn_hash prepare_the_hash_for_opn # === update_the_opn_hash
|
750
|
+
alias determine_default_opn_hash prepare_the_hash_for_opn # === determine_default_opn_hash
|
751
|
+
alias determine_the_default_opn_hash prepare_the_hash_for_opn # === determine_the_default_opn_hash
|
752
|
+
alias update_the_main_hash prepare_the_hash_for_opn # === update_the_main_hash
|
753
|
+
|
754
|
+
# ========================================================================= #
|
755
|
+
# === show_only_the_short_name_of_the_archive?
|
756
|
+
# ========================================================================= #
|
757
|
+
def show_only_the_short_name_of_the_archive?
|
758
|
+
@internal_hash[:show_only_the_short_name_of_the_archive]
|
759
|
+
end
|
760
|
+
|
761
|
+
# ========================================================================= #
|
762
|
+
# === set_run_simulation
|
763
|
+
#
|
764
|
+
# This should always default to false, if no other argument has been
|
765
|
+
# supplied.
|
766
|
+
# ========================================================================= #
|
767
|
+
def set_run_simulation(i = false)
|
768
|
+
@internal_hash[:run_simulation] = i
|
976
769
|
end
|
977
770
|
|
978
771
|
# ========================================================================= #
|
979
|
-
# ===
|
772
|
+
# === padded_extract_to?
|
980
773
|
# ========================================================================= #
|
981
|
-
def
|
982
|
-
|
983
|
-
end
|
984
|
-
|
774
|
+
def padded_extract_to?
|
775
|
+
" -C #{extract_to?} "
|
776
|
+
end
|
777
|
+
|
778
|
+
# ========================================================================= #
|
779
|
+
# === set_colour_for_directories
|
780
|
+
#
|
781
|
+
# Set the colour for directories to use.
|
782
|
+
# ========================================================================= #
|
783
|
+
def set_colour_for_directories(i)
|
784
|
+
@internal_hash[:colour_to_use_for_directories] = ::Colours.beautify(i)
|
785
|
+
end
|
786
|
+
|
787
|
+
# ========================================================================= #
|
788
|
+
# === do_not_show_name
|
789
|
+
#
|
790
|
+
# Tells us whether to use opn() or not.
|
791
|
+
# ========================================================================= #
|
792
|
+
def do_not_show_name
|
793
|
+
@internal_hash[:show_the_name] = false
|
794
|
+
end
|
795
|
+
|
796
|
+
# ========================================================================= #
|
797
|
+
# === check_whether_rar_is_available
|
798
|
+
#
|
799
|
+
# We try to find out whether unrar is available.
|
800
|
+
# ========================================================================= #
|
801
|
+
def check_whether_rar_is_available
|
802
|
+
is_available = false
|
803
|
+
ENV['PATH'].split(':').each {|entry|
|
804
|
+
is_available = true if File.exist? "#{entry}/unrar"
|
805
|
+
}
|
806
|
+
unless is_available
|
807
|
+
opne 'unrar appears to be unavailable. Please install it first.'
|
808
|
+
end
|
809
|
+
end
|
810
|
+
|
811
|
+
# ========================================================================= #
|
812
|
+
# === show_the_name?
|
813
|
+
# ========================================================================= #
|
814
|
+
def show_the_name?
|
815
|
+
@internal_hash[:show_the_name]
|
816
|
+
end
|
817
|
+
|
818
|
+
# ========================================================================= #
|
819
|
+
# === run_already?
|
820
|
+
# ========================================================================= #
|
821
|
+
def run_already?
|
822
|
+
@internal_hash[:run_already]
|
823
|
+
end
|
824
|
+
|
825
|
+
# ========================================================================= #
|
826
|
+
# === extract_to?
|
827
|
+
#
|
828
|
+
# Note that this method is guaranteed to return a String.
|
829
|
+
# ========================================================================= #
|
830
|
+
def extract_to?
|
831
|
+
@internal_hash[:extract_to].to_s
|
832
|
+
end; alias extract_to_this_location? extract_to? # === extract_to_this_location?
|
833
|
+
alias extracted_to? extract_to? # === extracted_to?
|
834
|
+
alias extracted_path? extract_to? # === extracted_path?
|
835
|
+
alias source_package_location extract_to? # === source_package
|
836
|
+
|
837
|
+
# ========================================================================= #
|
838
|
+
# === pad_opn_with_n_tokens
|
839
|
+
# ========================================================================= #
|
840
|
+
def pad_opn_with_n_tokens(n_tokens = nil)
|
841
|
+
if n_tokens
|
842
|
+
determine_default_opn_hash # Update this, just in case.
|
843
|
+
main_hash?.update(padding: n_tokens)
|
844
|
+
end
|
845
|
+
end; alias set_pad_opn_with_n_tokens pad_opn_with_n_tokens # === set_pad_opn_with_n_tokens
|
846
|
+
|
847
|
+
# ========================================================================= #
|
848
|
+
# === set_work_on_these_files
|
849
|
+
# ========================================================================= #
|
850
|
+
def set_work_on_these_files(
|
851
|
+
i = []
|
852
|
+
)
|
853
|
+
if i.is_a?(Array) and i.empty?
|
854
|
+
# ===================================================================== #
|
855
|
+
# === Check for .zip files
|
856
|
+
#
|
857
|
+
# In this case, try to see if the current directory has a .zip
|
858
|
+
# file. We will use this in that case.
|
859
|
+
# ===================================================================== #
|
860
|
+
is_there_a_zip_file = Dir['*.zip']
|
861
|
+
unless is_there_a_zip_file.empty?
|
862
|
+
use_this_zip_file = is_there_a_zip_file.first
|
863
|
+
notify_the_user_that_no_input_was_given_but_this_file_was_found(use_this_zip_file)
|
864
|
+
i << use_this_zip_file
|
865
|
+
end
|
866
|
+
is_there_at_the_least_one_tar_xz_file = Dir['*.tar.xz']
|
867
|
+
unless is_there_at_the_least_one_tar_xz_file.empty?
|
868
|
+
i << is_there_at_the_least_one_tar_xz_file.first
|
869
|
+
end
|
870
|
+
end
|
871
|
+
i = [i].compact.flatten.map {|entry|
|
872
|
+
unless File.exist? entry
|
873
|
+
entry = try_to_glob_on(entry)
|
874
|
+
end
|
875
|
+
entry
|
876
|
+
}
|
877
|
+
@internal_hash[:array_work_on_these_files] = i
|
878
|
+
end; alias set_input set_work_on_these_files # === set_input
|
879
|
+
|
880
|
+
# ========================================================================= #
|
881
|
+
# === extract_this_archive (extract tag)
|
882
|
+
# ========================================================================= #
|
883
|
+
def extract_this_archive(
|
884
|
+
i,
|
885
|
+
extract_to = extract_to?
|
886
|
+
)
|
887
|
+
i = File.absolute_path(i)
|
888
|
+
# ======================================================================= #
|
889
|
+
# First determine whether we can extract the archive or whether we can
|
890
|
+
# not:
|
891
|
+
# ======================================================================= #
|
892
|
+
unless ::Extracter.is_this_a_valid_archive?(i) or i.end_with?('.pdf')
|
893
|
+
opne 'The given input, '+i+', is not a valid archive format.'
|
894
|
+
return
|
895
|
+
end
|
896
|
+
# ======================================================================= #
|
897
|
+
# Next handle the situation when we are on Windows:
|
898
|
+
# ======================================================================= #
|
899
|
+
if ::Extracter.are_we_on_windows?
|
900
|
+
# ===================================================================== #
|
901
|
+
# On windows we will overrule this completely, for now.
|
902
|
+
# ===================================================================== #
|
903
|
+
Extract.this_on_windows(i)
|
904
|
+
return
|
905
|
+
end
|
906
|
+
if be_verbose?
|
907
|
+
if show_only_the_short_name_of_the_archive?
|
908
|
+
name_of_the_archive = File.basename(i)
|
909
|
+
opne "#{rev}Extracting `#{sfancy(name_of_the_archive)}#{rev}` "\
|
910
|
+
"to `#{sdir(extract_to)}#{rev}`."
|
911
|
+
else
|
912
|
+
opne "#{rev}Extracting `#{sfancy(i)}` to "\
|
913
|
+
"`#{sdir(extract_to)}#{rev}`."
|
914
|
+
end
|
915
|
+
end
|
916
|
+
unless File.writable? extract_to
|
917
|
+
copn; ewarn 'You do not have sufficient permissions to'
|
918
|
+
copn; ewarn "modify #{sdir(extract_to)}#{swarn('.')}"
|
919
|
+
return
|
920
|
+
end
|
921
|
+
# ===================================================================== #
|
922
|
+
# Next, pad it if it includes a ' ' character or (). This was
|
923
|
+
# disabled as of July 2022.
|
924
|
+
# ===================================================================== #
|
925
|
+
# i = pad(i) if i.include?(' ') or i.include?(')')
|
926
|
+
case i # case tag; those listed on top are more important.
|
927
|
+
# ===================================================================== #
|
928
|
+
# === 7z
|
929
|
+
# ===================================================================== #
|
930
|
+
when '.7z' # 7z does not accept the -C commandline.
|
931
|
+
# _ << '7za e' # <- Deprecated this variant as of 05.06.2020.
|
932
|
+
esystem "7z x #{i}"
|
933
|
+
# ===================================================================== #
|
934
|
+
# === .tar.xz
|
935
|
+
#
|
936
|
+
# Note that .txz is just .tar.xz. Support for .txz was added here
|
937
|
+
# in January of 2012.
|
938
|
+
# ===================================================================== #
|
939
|
+
when /\.tar\.xz$/i,
|
940
|
+
/\.txz$/i,
|
941
|
+
/\.xz$/i
|
942
|
+
esystem consider_verbosity_for(COMMAND_TO_EXTRACT_TAR_XZ_FILES)+
|
943
|
+
' '+i+padded_extract_to?
|
944
|
+
# ===================================================================== #
|
945
|
+
# === .rpm
|
946
|
+
#
|
947
|
+
# This entry point will handle .rpm files.
|
948
|
+
# ===================================================================== #
|
949
|
+
when /\.rpm$/i
|
950
|
+
name_of_the_directory = i.delete_suffix('.rpm')
|
951
|
+
mkdir(name_of_the_directory)
|
952
|
+
set_extract_to(File.absolute_path(name_of_the_directory))
|
953
|
+
cd(name_of_the_directory)
|
954
|
+
esystem 'rpm2cpio ../'+File.basename(i)+' | cpio -idmv'
|
955
|
+
return # Early return.
|
956
|
+
# ===================================================================== #
|
957
|
+
# === .tar
|
958
|
+
#
|
959
|
+
# This entry point is for simple .tar files.
|
960
|
+
# ===================================================================== #
|
961
|
+
when /\.tar$/i
|
962
|
+
esystem COMMAND_TO_EXTRACT_TAR_FILES+' '+i+padded_extract_to?
|
963
|
+
# ===================================================================== #
|
964
|
+
# === zip
|
965
|
+
# ===================================================================== #
|
966
|
+
when /.zip$/i,
|
967
|
+
/.xpi$/i,
|
968
|
+
/.docx$/i,
|
969
|
+
/.odt$/i, # .docx and .odt format types can be unpacked with zip too.
|
970
|
+
/.apkg$/
|
971
|
+
# =================================================================== #
|
972
|
+
# 'ar -jxf' # unzip #{what} <-- this should work as well.
|
973
|
+
# =================================================================== #
|
974
|
+
i = pad(i) if i.include?(' ') or i.include?(')')
|
975
|
+
esystem "unzip #{i}"
|
976
|
+
# ===================================================================== #
|
977
|
+
# === tgz
|
978
|
+
#
|
979
|
+
# This entry point will also handle ".tar.Z" files.
|
980
|
+
# ===================================================================== #
|
981
|
+
when /\.?tgz$/i,
|
982
|
+
/\.?tar.Z$/i,
|
983
|
+
/\.?taz$/i
|
984
|
+
esystem COMMAND_TO_EXTRACT_TGZ_FILES+' '+i+padded_extract_to?
|
985
|
+
# ===================================================================== #
|
986
|
+
# === .tar.bz2
|
987
|
+
# ===================================================================== #
|
988
|
+
when /\.tar\.bz2$/i,
|
989
|
+
/\.tbz$/i
|
990
|
+
esystem COMMAND_TO_EXTRACT_TAR_BZ2_FILES+' '+i+padded_extract_to?
|
991
|
+
# ===================================================================== #
|
992
|
+
# === gz
|
993
|
+
# ===================================================================== #
|
994
|
+
when /\.?gz$/i,
|
995
|
+
/\.?apk$/i
|
996
|
+
if i.include? '.tar' # Handle .tar.gz here.
|
997
|
+
esystem 'tar -zxvf '+i+padded_extract_to?
|
998
|
+
else
|
999
|
+
esystem "gunzip #{i}"
|
1000
|
+
end
|
1001
|
+
# ===================================================================== #
|
1002
|
+
# === .bz2
|
1003
|
+
# ===================================================================== #
|
1004
|
+
when /\.?bz2$/,
|
1005
|
+
/\.?tbz2$/
|
1006
|
+
if i.include? '.tar' # Treat it as a .tar file.
|
1007
|
+
esystem 'tar -vjxf '+i
|
1008
|
+
else
|
1009
|
+
esystem "bunzip2 #{i}"
|
1010
|
+
end
|
1011
|
+
# ===================================================================== #
|
1012
|
+
# === rar
|
1013
|
+
# ===================================================================== #
|
1014
|
+
when '.rar'
|
1015
|
+
check_whether_rar_is_available
|
1016
|
+
esystem "unrar e #{i}"
|
1017
|
+
# ===================================================================== #
|
1018
|
+
# === .zst
|
1019
|
+
#
|
1020
|
+
# This entry point is for e. g. "pymol-2.3.0-3-x86_64.pkg.tar.zst".
|
1021
|
+
# ===================================================================== #
|
1022
|
+
when '.zst',
|
1023
|
+
'.tar.zst'
|
1024
|
+
esystem COMMAND_TO_EXTRACT_ZST_ARCHIVES+' '+i
|
1025
|
+
# ===================================================================== #
|
1026
|
+
# === deb
|
1027
|
+
#
|
1028
|
+
# We could use dpkg-deb too, such as via "dpkg-deb". But using "ar"
|
1029
|
+
# seems to be the better choice.
|
1030
|
+
# ===================================================================== #
|
1031
|
+
when /\.?deb$/i
|
1032
|
+
esystem COMMAND_TO_EXTRACT_DEB_FILES+' '+i
|
1033
|
+
# ===================================================================== #
|
1034
|
+
# === gem
|
1035
|
+
#
|
1036
|
+
# The gem commands needs a specific --target=DIRECTORY option.
|
1037
|
+
# ===================================================================== #
|
1038
|
+
when /\.?gem$/i
|
1039
|
+
esystem GEM_UNPACK_COMMAND+' '+i+" --target=#{extract_to}"
|
1040
|
+
# ===================================================================== #
|
1041
|
+
# === lzma
|
1042
|
+
# ===================================================================== #
|
1043
|
+
when '.lzma'
|
1044
|
+
esystem "#{COMMAND_TO_EXTRACT_LZMA_FILES} #{i}"
|
1045
|
+
# ===================================================================== #
|
1046
|
+
# === bin
|
1047
|
+
#
|
1048
|
+
# This entry point allows the user to handle .bin files. In this
|
1049
|
+
# context, "handling" means to simply run that file as-is.
|
1050
|
+
# ===================================================================== #
|
1051
|
+
when /\.?bin$/i
|
1052
|
+
esystem("./#{i}")
|
1053
|
+
# ===================================================================== #
|
1054
|
+
# === iso
|
1055
|
+
# ===================================================================== #
|
1056
|
+
when /\.?iso$/i
|
1057
|
+
try_to_extract_this_iso_file(i)
|
1058
|
+
return
|
1059
|
+
# ===================================================================== #
|
1060
|
+
# === img
|
1061
|
+
#
|
1062
|
+
# Note that .img in this context refers to squafhs .img files.
|
1063
|
+
# ===================================================================== #
|
1064
|
+
when /\.?img$/i,
|
1065
|
+
/\.?squashfs$/i
|
1066
|
+
try_to_extract_this_img_file(i)
|
1067
|
+
return # Must return early in this case.
|
1068
|
+
# ===================================================================== #
|
1069
|
+
# === lz
|
1070
|
+
#
|
1071
|
+
# This entry point requires lzip to be installed.
|
1072
|
+
# ===================================================================== #
|
1073
|
+
when /\.?lz$/i,
|
1074
|
+
/\.?tar\.?lz$/i
|
1075
|
+
esystem("#{COMMAND_TO_EXTRACT_LZ_FILES} #{i}#{padded_extract_to?}")
|
1076
|
+
# ===================================================================== #
|
1077
|
+
# === mp4
|
1078
|
+
#
|
1079
|
+
# If it is a .mp4 file, we delegate to MultimediaParadise.extract_audio.
|
1080
|
+
#
|
1081
|
+
# Usage example:
|
1082
|
+
#
|
1083
|
+
# rubyextract foobar.mp4
|
1084
|
+
#
|
1085
|
+
# ===================================================================== #
|
1086
|
+
when /\.?mp4$/i
|
1087
|
+
begin
|
1088
|
+
require 'multimedia_paradise/audio/extract_audio/extract_audio.rb'
|
1089
|
+
rescue LoadError; end
|
1090
|
+
if Object.const_defined? :MultimediaParadise
|
1091
|
+
MultimediaParadise.extract_audio(i)
|
1092
|
+
end
|
1093
|
+
# ===================================================================== #
|
1094
|
+
# === ps
|
1095
|
+
# ===================================================================== #
|
1096
|
+
when/\.?ps$/i
|
1097
|
+
esystem 'ps2ascii '+i+padded_extract_to?
|
1098
|
+
# ===================================================================== #
|
1099
|
+
# === .jar
|
1100
|
+
# ===================================================================== #
|
1101
|
+
when /\.?jar$/i
|
1102
|
+
esystem COMMAND_TO_EXTRACT_JAR_ARCHIVES+' '+i
|
1103
|
+
# ===================================================================== #
|
1104
|
+
# === rpm
|
1105
|
+
# ===================================================================== #
|
1106
|
+
when '.rpm'
|
1107
|
+
esystem "#{COMMAND_TO_EXTRACT_BSDTAR_ARCHIVES} #{i}"
|
1108
|
+
# ===================================================================== #
|
1109
|
+
# === sxz
|
1110
|
+
# ===================================================================== #
|
1111
|
+
when '.sxz'
|
1112
|
+
esystem "unsquashfs #{i}"
|
1113
|
+
# ===================================================================== #
|
1114
|
+
# === pdf
|
1115
|
+
#
|
1116
|
+
# For pdf-files we will tap into the pdf_paradise project, if it
|
1117
|
+
# is available.
|
1118
|
+
# ===================================================================== #
|
1119
|
+
when /\.?pdf$/
|
1120
|
+
begin
|
1121
|
+
require 'pdf_paradise/utility_scripts/convert_pdf_to_text.rb'
|
1122
|
+
_ = PdfParadise::ConvertPdfToText.new(i)
|
1123
|
+
e _.output_file?
|
1124
|
+
rescue LoadError => error
|
1125
|
+
e 'No, not there.'
|
1126
|
+
pp error # Show the error to the user here.
|
1127
|
+
end
|
1128
|
+
return # Must return early in this case.
|
1129
|
+
else # else tag. We did not find the extension type.
|
1130
|
+
if File.exist? i
|
1131
|
+
notify_the_user_that_this_extension_has_not_been_registered_yet(i)
|
1132
|
+
else
|
1133
|
+
opne "#{rev}No file exists at `#{sfile(i)}#{rev}`."
|
1134
|
+
end
|
1135
|
+
end
|
1136
|
+
end; alias do_extract_to extract_this_archive # === do_extract_to
|
1137
|
+
alias do_extract_what_to extract_this_archive # === do_extract_what_to
|
1138
|
+
alias start extract_this_archive # === start
|
985
1139
|
|
986
1140
|
# ========================================================================= #
|
987
1141
|
# === run (run tag, def tag)
|
988
1142
|
# ========================================================================= #
|
989
1143
|
def run
|
990
1144
|
menu
|
1145
|
+
_ = commandline_arguments?
|
1146
|
+
_.flatten.select {|entry|
|
1147
|
+
File.file?(entry) or File.directory?(entry)
|
1148
|
+
}
|
1149
|
+
set_work_on_these_files(_)
|
991
1150
|
work_on_the_given_input
|
992
1151
|
end
|
993
1152
|
|
@@ -1013,13 +1172,16 @@ class Extracter < ::Extracter::Base # === Extracter::Extracter
|
|
1013
1172
|
# ========================================================================= #
|
1014
1173
|
# === Extracter::Extracter[]
|
1015
1174
|
# ========================================================================= #
|
1016
|
-
def self.[](
|
1175
|
+
def self.[](
|
1176
|
+
i = ARGV,
|
1177
|
+
extract_where_to = Extracter.return_pwd
|
1178
|
+
)
|
1017
1179
|
new(i, extract_where_to)
|
1018
1180
|
end
|
1019
1181
|
|
1020
1182
|
end
|
1021
1183
|
|
1022
|
-
#
|
1184
|
+
# ============================================================================ #
|
1023
1185
|
# === Extracter.extract_what_to
|
1024
1186
|
#
|
1025
1187
|
# Useage example goes like this:
|
@@ -1027,7 +1189,7 @@ end
|
|
1027
1189
|
# Extracter.extract_what_to('foo-1.0.tar.xz', '/tmp')
|
1028
1190
|
# Extracter.extract_what_to('/Depot/jjjj/tesseract-5.1.0.tar.xz', Dir.pwd+'/')
|
1029
1191
|
#
|
1030
|
-
#
|
1192
|
+
# ============================================================================ #
|
1031
1193
|
def self.extract_what_to(
|
1032
1194
|
what = ARGV,
|
1033
1195
|
extract_to = :default, # ← This can also be a Hash. It denotes where we want to extract to.
|
@@ -1041,16 +1203,17 @@ def self.extract_what_to(
|
|
1041
1203
|
&block
|
1042
1204
|
)
|
1043
1205
|
return _ # We must return the class, as other projects may depend on this.
|
1044
|
-
end; self.instance_eval { alias extract_this
|
1045
|
-
self.instance_eval { alias extract
|
1046
|
-
self.instance_eval { alias what_to
|
1047
|
-
self.instance_eval { alias new
|
1048
|
-
self.instance_eval { alias
|
1206
|
+
end; self.instance_eval { alias extract_this extract_what_to } # === Extracter.extract_this
|
1207
|
+
self.instance_eval { alias extract extract_what_to } # === Extracter.extract
|
1208
|
+
self.instance_eval { alias what_to extract_what_to } # === Extracter.what_to
|
1209
|
+
self.instance_eval { alias new extract_what_to } # === Extracter.new
|
1210
|
+
self.instance_eval { alias extract_what_to_on_windows extract_what_to } # === Extracter.extract_what_to_on_windows
|
1211
|
+
self.instance_eval { alias extract_it extract_what_to } # === Extracter.extract_it
|
1212
|
+
self.instance_eval { alias [] extract_what_to } # === Extracter[]
|
1049
1213
|
|
1050
1214
|
end
|
1051
1215
|
|
1052
1216
|
if __FILE__ == $PROGRAM_NAME
|
1053
|
-
_ = Extracter::Extracter.new(ARGV) { :do_not_run_yet }
|
1054
1217
|
if ARGV.size > 2
|
1055
1218
|
_ = Extracter::Extracter.new(ARGV, :default) { :do_not_run_yet }
|
1056
1219
|
else
|
@@ -1066,4 +1229,4 @@ end # rubyextracter
|
|
1066
1229
|
# extracter xfig-3.2.5.tar.bz2
|
1067
1230
|
# extract htop* /Depot/
|
1068
1231
|
# extract recode-3.7.tar.xz /Depot/
|
1069
|
-
# extract qt-4.8.6.tar.xz --to=/home/Temp
|
1232
|
+
# extract qt-4.8.6.tar.xz --to=/home/Temp
|