class Extracter::Extracter
Constants
- NAMESPACE
#¶ ↑
NAMESPACE
¶ ↑#¶ ↑
- SHOW_ONLY_THE_SHORT_NAME_OF_THE_ARCHIVE
#¶ ↑
SHOW_ONLY_THE_SHORT_NAME_OF_THE_ARCHIVE
¶ ↑If this constant is set to true then we will only show the shortened name of the archive in question by default.
#¶ ↑
Public Class Methods
#¶ ↑
Extracter::Extracter.extract_this
¶ ↑
This method provides a convenient API to extract something to a specified directory, as a class method. It defaults to the current working directory, as that is by far the most convenient way to extract a source tarball/archive.
#¶ ↑
# File lib/extracter/class/extracter.rb, line 991 def self.extract_this( i = ARGV, to = {}, # This may also be a String rather than a Hash. &block ) ::Extracter::Extracter.new(ARGV, to, &block) end
#¶ ↑
initialize¶ ↑
The first argument to this method should be the archive that the user wants to extract. This must be a (locally) existing archive, such as foobar.tar.xz or something similar.
The second argument to this method, called ‘extract_to`, specifies the target location, where this class will extract the archive into, if available. Some keywords and shortcuts exist for this option - for instance, TEMP means $MY_TEMP, which can be set by the user.
Specific usage example in pure Ruby:
x = Extracter.what_to('pry-0.9.9.4.gem', '/home/Temp')
#¶ ↑
# File lib/extracter/class/extracter.rb, line 71 def initialize( commandline_arguments = ARGV, extract_to = nil, run_already = true, &block ) register_sigint reset @internal_hash[:run_already] = run_already set_commandline_arguments( commandline_arguments ) if debug? # Some debug-information in this case. e "The first argument what is: `#{commandline_arguments}`" e "The second argument where_to is: `#{extract_to}`" end case run_already # ======================================================================= # # === :dont_run_yet # ======================================================================= # when :dont_run_yet, :do_not_run_yet, :default @internal_hash[:run_already] = false end set_extract_to(extract_to) if extract_to # ======================================================================= # # === Handle blocks next # ======================================================================= # if block_given? yielded = yield case yielded # ===================================================================== # # === :dont_run_yet # ===================================================================== # when :dont_run_yet, :do_not_run_yet, :default @internal_hash[:run_already] = false # ===================================================================== # # === :show_the_full_name_of_the_archive # ===================================================================== # when :show_the_full_name_of_the_archive do_show_the_full_name_of_the_archive end end run if run_already? end
Public Instance Methods
#¶ ↑
be_silent
¶ ↑
#¶ ↑
# File lib/extracter/class/extracter.rb, line 407 def be_silent set_be_verbose(false) end
#¶ ↑
check_whether_rar_is_available
¶ ↑
We try to find out whether unrar is available.
#¶ ↑
# File lib/extracter/class/extracter.rb, line 212 def check_whether_rar_is_available is_available = false ENV['PATH'].split(':').each {|entry| is_available = true if File.exist? "#{entry}/unrar" } unless is_available copn; e 'Sorry, unrar is not available. Please install it first.' end end
#¶ ↑
create_directory
(mkdir tag)¶ ↑
Use this to create directories.
#¶ ↑
# File lib/extracter/class/extracter.rb, line 842 def create_directory(i) FileUtils.mkdir_p(i) unless File.directory?(i) end
#¶ ↑
esystem (system tag, esystem tag)¶ ↑
#¶ ↑
# File lib/extracter/class/extracter.rb, line 899 def esystem( i, try_to_use_colours = try_to_use_colours? ) i = i.dup if i.frozen? # ======================================================================= # # Next, consider appending something onto the commandline. # ======================================================================= # _ = @internal_hash[:append_this_to_the_commandline] unless _.empty? if i.include? ' ' splitted = i.split(' ') splitted[0] << " #{_}" i = splitted.join(' ') else i << " #{_}" end end if run_simulation? copn; e 'As we are running in simulation mode, the following command ' copn; e 'is the one that we would have been used if we were to not run ' copn; e 'in simulation mode:' if be_verbose? if try_to_use_colours e ::Colours.steelblue(i) else e i end end else if be_verbose? if try_to_use_colours e ::Colours.steelblue(i) else e i end end # ===================================================================== # # Next, run the sys-command. # ===================================================================== # begin system i # =================================================================== # # We have to rescue here because unrar might not be available and # so on. # =================================================================== # rescue Exception => error e 'An error has happened upon attempting to run this system command:' e e " #{i}" e pp error; e '-----------'; pp error.class; e '-----------' end end end
#¶ ↑
extract_this_archive
(extract tag)¶ ↑
#¶ ↑
# File lib/extracter/class/extract_this_archive.rb, line 31 def extract_this_archive( i, extract_to = extract_to? ) i = File.absolute_path(i) # ======================================================================= # # Next handle the situation when we are on Windows: # ======================================================================= # if ::Extracter.are_we_on_windows? # ===================================================================== # # On windows we will overrule this completely, for now. # ===================================================================== # _ = UNPACK_COMMAND_TO_USE_ON_WINDOWS+' '+ File.absolute_path(i)+ ' | '+ SECOND_UNPACK_COMMAND_TO_USE_ON_WINDOWS esystem _ return end # ======================================================================= # # First determine whether we can extract the archive or whether we can # not: # ======================================================================= # if ::Extracter.is_this_a_valid_archive?(i) or i.end_with?('.pdf') if be_verbose? if show_only_the_short_name_of_the_archive? name_of_the_archive = File.basename(i) copn; e "Extracting `#{sfancy(name_of_the_archive)}` "\ "to `#{sdir(extract_to)}` next." else copn; e "Extracting `#{sfancy(i)}` to `#{sdir(extract_to)}` "\ "next." end end unless File.writable? extract_to copn; ewarn 'You do not have sufficient permissions to' copn; ewarn "modify #{sdir(extract_to)}." return end # ===================================================================== # # Next, pad it if it includes a ' ' character or (). This was # disabled as of July 2022. # ===================================================================== # # i = pad(i) if i.include?(' ') or i.include?(')') case i # case tag; those listed on top are more important. # ===================================================================== # # === .rpm # # This entry point will handle .rpm files. # ===================================================================== # when /\.rpm$/i name_of_the_directory = i.delete_suffix('.rpm') mkdir(name_of_the_directory) set_extract_to(File.absolute_path(name_of_the_directory)) cd(name_of_the_directory) esystem 'rpm2cpio ../'+File.basename(i)+' | cpio -idmv' return # Early return. # ===================================================================== # # === .tar.xz # # Note that .txz is just .tar.xz. Support for .txz was added here # in January of 2012. # ===================================================================== # when /\.tar\.xz$/i, /\.txz$/i, /\.xz$/i esystem consider_verbosity_for(COMMAND_TO_EXTRACT_TAR_XZ_FILES)+' '+i+padded_extract_to? # ===================================================================== # # === .tar # # This entry point is for simple .tar files. # ===================================================================== # when /\.tar$/i esystem COMMAND_TO_EXTRACT_TAR_FILES+' '+i+padded_extract_to? # ===================================================================== # # === zip # ===================================================================== # when /.zip$/i, /.xpi$/i, /.docx$/i, /.odt$/i, # .docx and .odt format types can be unpacked with zip too. /.apkg$/ # =================================================================== # # 'ar -jxf' # unzip #{what} <-- this should work as well. # =================================================================== # i = pad(i) if i.include?(' ') or i.include?(')') esystem "unzip #{i}" # ===================================================================== # # === tgz # # This entry point will also handle ".tar.Z" files. # ===================================================================== # when /\.?tgz$/i, /\.?tar.Z$/i, /\.?taz$/i esystem COMMAND_TO_EXTRACT_TGZ_FILES+' '+i+padded_extract_to? # ===================================================================== # # === 7z # ===================================================================== # when '.7z' # 7z does not accept the -C commandline. # _ << '7za e' # <- Deprecated this variant as of 05.06.2020. esystem "7z x #{i}" # ===================================================================== # # === .tar.bz2 # ===================================================================== # when /\.tar\.bz2$/i, /\.tbz$/i esystem COMMAND_TO_EXTRACT_TAR_BZ2_FILES+' '+i+padded_extract_to? # ===================================================================== # # === gz # ===================================================================== # when /\.?gz$/i, /\.?apk$/i if i.include? '.tar' # Handle .tar.gz here. esystem 'tar -zxvf '+i+padded_extract_to? else esystem 'gunzip '+i end # ===================================================================== # # === .bz2 # ===================================================================== # when /\.?bz2$/, /\.?tbz2$/ if i.include? '.tar' # Treat it as a .tar file. esystem 'tar -vjxf '+i else esystem 'bunzip2 '+i end # ===================================================================== # # === rar # ===================================================================== # when '.rar' check_whether_rar_is_available esystem 'unrar e '+i # ===================================================================== # # === .zst # # This entry point is for e. g. "pymol-2.3.0-3-x86_64.pkg.tar.zst". # ===================================================================== # when '.zst','.tar.zst' esystem COMMAND_TO_EXTRACT_ZST_ARCHIVES+' '+i # ===================================================================== # # === deb # # We could use dpkg-deb too, such as via "dpkg-deb". But using "ar" # seems to be the better choice. # ===================================================================== # when /\.?deb$/i esystem COMMAND_TO_EXTRACT_DEB_FILES+' '+i # ===================================================================== # # === gem # # The gem commands needs a specific --target=DIRECTORY option. # ===================================================================== # when /\.?gem$/i esystem GEM_UNPACK_COMMAND+' '+i+" --target=#{extract_to}" # ===================================================================== # # === lzma # ===================================================================== # when '.lzma' esystem "#{COMMAND_TO_EXTRACT_LZMA_FILES} #{i}" # ===================================================================== # # === bin # # This entry point allows the user to handle .bin files. In this # context, "handling" means to simply run that file as-is. # ===================================================================== # when /\.?bin$/i esystem("./#{i}") # ===================================================================== # # === iso # ===================================================================== # when /\.?iso$/i try_to_extract_this_iso_file(i) return # ===================================================================== # # === img # # Note that .img in this context refers to squafhs .img files. # ===================================================================== # when /\.?img$/i, /\.?squashfs$/i try_to_extract_this_img_file(i) return # Must return early in this case. # ===================================================================== # # === lz # # This entry point requires lzip to be installed. # ===================================================================== # when /\.?lz$/i, /\.?tar\.?lz$/i esystem("#{COMMAND_TO_EXTRACT_LZ_FILES} #{i}#{padded_extract_to?}") # ===================================================================== # # === mp4 # # If it is a .mp4 file, we delegate to MultimediaParadise.extract_audio. # # Usage example: # # rubyextract foobar.mp4 # # ===================================================================== # when /\.?mp4$/i begin require 'multimedia_paradise/audio/extract_audio/extract_audio.rb' rescue LoadError; end if Object.const_defined? :MultimediaParadise MultimediaParadise.extract_audio(i) end # ===================================================================== # # === ps # ===================================================================== # when/\.?ps$/i esystem 'ps2ascii '+i+padded_extract_to? # ===================================================================== # # === .jar # ===================================================================== # when /\.?jar$/i esystem COMMAND_TO_EXTRACT_JAR_ARCHIVES+' '+i # ===================================================================== # # === rpm # ===================================================================== # when '.rpm' esystem "#{COMMAND_TO_EXTRACT_BSDTAR_ARCHIVES} #{i}" # ===================================================================== # # === sxz # ===================================================================== # when '.sxz' esystem "unsquashfs #{i}" # ===================================================================== # # === pdf # # For pdf-files we will tap into the pdf_paradise project, if it # is available. # ===================================================================== # when /\.?pdf$/ begin require 'pdf_paradise/utility_scripts/convert_pdf_to_text.rb' _ = PdfParadise::ConvertPdfToText.new(i) e _.output_file? rescue LoadError => error e 'No, not there.' pp error # Show the error to the user here. end return # Must return early in this case. else # else tag. We did not find the extension type. notify_the_user_that_this_extension_has_not_been_registered_yet(i) end else if File.exist? i notify_the_user_that_this_extension_has_not_been_registered_yet(i) else opnn; e "No file exists at `#{sfile(i)}`." end end end
#¶ ↑
first_argument?¶ ↑
#¶ ↑
# File lib/extracter/class/extracter.rb, line 282 def first_argument? @commandline_arguments.first end
#¶ ↑
notify_the_user_that_this_extension_has_not_been_registered_yet
¶ ↑
#¶ ↑
# File lib/extracter/class/extracter.rb, line 849 def notify_the_user_that_this_extension_has_not_been_registered_yet(i) opnn; e "The archive at `#{i}` is #{tomato('not')}" opnn; e "registered as a permissive extension." fail_message_not_registered(i) end
#¶ ↑
pad (pad tag)¶ ↑
This method must be able to deal with ‘ ’ as well as with ‘()’.
The second character is the character that will be used for the padding.
#¶ ↑
# File lib/extracter/class/extracter.rb, line 376 def pad( i, with_this_character = "'" ) if i.include?('(') or i.include?(')') i.tr!('(','\(') i.tr!(')','\)') if i.include? ')' i = pad(i, '"') else return with_this_character+ i+ with_this_character end end
#¶ ↑
pad_opn_with_n_tokens
¶ ↑
#¶ ↑
# File lib/extracter/class/extracter.rb, line 472 def pad_opn_with_n_tokens(n_tokens = nil) if n_tokens determine_default_opn_hash # Update this, just in case. main_hash?.update(padding: n_tokens) end end
#¶ ↑
prepare_the_hash_for_opn
¶ ↑
# ¶ ↑
# File lib/extracter/class/extracter.rb, line 482 def prepare_the_hash_for_opn( use_this_hash = { namespace: namespace?, use_colours: use_colours? } ) # ======================================================================= # # === :use_this_opn_hash # ======================================================================= # @internal_hash[:use_this_opn_hash] = use_this_hash return @internal_hash[:use_this_opn_hash] end
#¶ ↑
remove_file_extension
¶ ↑
#¶ ↑
# File lib/extracter/class/extracter.rb, line 589 def remove_file_extension(i) _ = File.basename(i) return ::Extracter.remove_archive_type(_) end
#¶ ↑
report_to_the_user
¶ ↑
This method reports to the user. Usually this is done only via this file here though.
#¶ ↑
# File lib/extracter/class/extracter.rb, line 960 def report_to_the_user( i, extract_to = extract_to? ) if be_verbose? opnn; e 'Finished extracting to `'+sdir( extract_to+ remove_file_extension( File.basename(i) )+ # This is an Array. '/' )+'`.' end end
#¶ ↑
reset (reset tag)¶ ↑
#¶ ↑
Extracter::Base#reset
# File lib/extracter/class/extracter.rb, line 123 def reset super() # ======================================================================= # # === :try_to_use_colours # ======================================================================= # @internal_hash[:try_to_use_colours] = true # ======================================================================= # # === :colour_to_use_for_directories # ======================================================================= # @internal_hash[:colour_to_use_for_directories] = 'cyan' # ======================================================================= # # === :use_opn # ======================================================================= # @internal_hash[:use_opn] = true # ← Whether to use make use of Opn by default or not. # ======================================================================= # # === :show_the_full_name_of_the_archive # ======================================================================= # @internal_hash[:show_the_full_name_of_the_archive] = false # ======================================================================= # # === :debug # ======================================================================= # @internal_hash[:debug] = false # ======================================================================= # # === :append_this_to_the_commandline # # This variable can always be used to append onto the commandline. # That way we can pass additional options to "tar", for instance. # ======================================================================= # @internal_hash[:append_this_to_the_commandline] = ''.dup # ======================================================================= # # === :namespace # # Specify the main namespace to be used. This setting can be modified # at "runtime". # ======================================================================= # @internal_hash[:namespace] = NAMESPACE # ======================================================================= # # === :be_verbose # ======================================================================= # @internal_hash[:be_verbose] = true # ======================================================================= # # === :show_the_name # # If this variable is true then the name of the class will be shown # on the commandline, via opn(). # ======================================================================= # @internal_hash[:show_the_name] = false # ======================================================================= # # === :show_only_the_short_name_of_the_archive # ======================================================================= # @internal_hash[:show_only_the_short_name_of_the_archive] = SHOW_ONLY_THE_SHORT_NAME_OF_THE_ARCHIVE # ======================================================================= # # === :run_simulation # ======================================================================= # @internal_hash[:run_simulation] = false # ← Whether to run in simulation, or for "real". # ======================================================================= # # === :extract_to # ======================================================================= # @internal_hash[:extract_to] = return_pwd do_show_name # We will show the name usually. prepare_the_hash_for_opn # ======================================================================= # # === :use_colours # ======================================================================= # enable_colours end
#¶ ↑
set_be_verbose
¶ ↑
This sets the verbosity level of the class. Use only this method when you wish to modify the @be_verbose instance variable.
#¶ ↑
# File lib/extracter/class/extracter.rb, line 417 def set_be_verbose(i = false) @internal_hash[:be_verbose] = i end
#¶ ↑
set_extract_to
¶ ↑
This is the method that should be used to determine into which directory this class will extract archives into.
Note that this target can be modified from the commandline, if the user wants to do so.
#¶ ↑
# File lib/extracter/class/extracter.rb, line 612 def set_extract_to( i = :temp_dir ) if i.is_a?(Hash) and i.empty? i = :temp_dir end if i.is_a? Hash # ===================================================================== # # === :run_already # ===================================================================== # if i.has_key? :run_already @internal_hash[:run_already] = i.delete(:run_already) end # ===================================================================== # # === :prepend_this_namespace # ===================================================================== # if i.has_key? :prepend_this_namespace prefix_with_this = i.delete(:prepend_this_namespace) # Get rid of it from the Hash as well. prefix_namespace_with(prefix_with_this) end # ===================================================================== # # === :use_colours # ===================================================================== # if i.has_key? :use_colours set_use_colours(i.delete(:use_colours)) end # ===================================================================== # # === :verbosity # # Handle how verbose the class shall be. # ===================================================================== # if i.has_key? :verbosity set_be_verbose(i.delete(:verbosity)) # ===================================================================== # # === :be_verbose # ===================================================================== # elsif i.has_key? :be_verbose set_be_verbose(i.delete(:be_verbose)) end # ===================================================================== # # === :append_this_to_the_commandline # ===================================================================== # if i.has_key? :append_this_to_the_commandline @internal_hash[:append_this_to_the_commandline] = i.delete(:append_this_to_the_commandline) end # ===================================================================== # # === :use_opn # ===================================================================== # if i.has_key? :use_opn set_use_opn(i.delete(:use_opn)) end # ===================================================================== # # === :pad_opn_with_n_tokens # ===================================================================== # if i.has_key? :pad_opn_with_n_tokens set_pad_opn_with_n_tokens(i.delete(:pad_opn_with_n_tokens)) end # ===================================================================== # # === :run_simulation # ===================================================================== # if i.has_key? :run_simulation set_run_simulation(i.delete(:run_simulation)) end # ===================================================================== # # === :use_colours # ===================================================================== # if i.has_key? :use_colours set_use_colours(i.delete(use_colours)) end # ===================================================================== # # === :extract_to # # This entry point allows the user to specify another extract-to # directory. Note that :to is treated the same way as :extract_to. # # This entry point must come last. The idea is that it will then # become the new value for i. # ===================================================================== # if i.has_key? :extract_to i = i.delete(:extract_to) # ===================================================================== # # === :to # ===================================================================== # elsif i.has_key? :to i = i.delete(:to) end end case i # case tag # ======================================================================= # # === :default # ======================================================================= # when :default i = return_pwd # ======================================================================= # # === TEMP # ======================================================================= # when 'TEMP', 'MY_TEMP', 'MYTEMP', :temp_dir, nil i = TEMP_DIR end i = rds(i) i.gsub!(/--to=/,'') if i.include? '--to=' i = i.to_s.dup # We expect a String most definitely. @internal_hash[:extract_to] = i end
#¶ ↑
set_use_colours
¶ ↑
#¶ ↑
# File lib/extracter/class/extracter.rb, line 570 def set_use_colours(i) # ======================================================================= # # We must also sync this towards our main Hash, for opn(). The next # line of code achieves precisely that. # ======================================================================= # main_hash?.update(use_colours: i) @internal_hash[:try_to_use_colours] = i end
#¶ ↑
show_help
(help tag)¶ ↑
This method will show the available - and documented - help options for class Extracter
.
To call this method via the commandline try:
extract --help
# ¶ ↑
# File lib/extracter/class/extracter.rb, line 346 def show_help e opnn; e 'How to extract archives, without helper scripts?' e e ' tar -zxvf foobar.tar.gz # for .tar.gz' e ' tar xvzf foobar.tgz # for .tgz' e ' tar xvfJ foobar.tar.xz # for .tar.xz' e ' tar jxf foobar.tar.bz2 # for .tar.bz2' e ' tar -xf foobar.tar.bz2 # for .tbz' e ' tar --lzip -xvf zutils-1.5.tar.lz # for .tar.lz' e ' unsquashfs foobar-1.2.3.sxz # for .sxz' e ' 7z x -so C:\home\x\src\htop\htop-3.0.5.tar.xz | 6z x -si -ttar # on windows' e opnn; e 'Furthermore, there are some commandline options '\ 'that can' opnn; e 'be used for this class (class Extracter).' e e ' --to=/home/Temp # extract into the '\ 'directory /home/Temp/' e end
#¶ ↑
try_to_extract_this_img_file
¶ ↑
#¶ ↑
# File lib/extracter/class/extracter.rb, line 867 def try_to_extract_this_img_file(i) opnn; e 'Handling a squashfs .img file format next:' name_without_extension = i.delete_suffix(File.extname(i)) mkdir(name_without_extension) unless File.directory? name_without_extension esystem "mount -o loop -t squashfs #{i} #{name_without_extension}" e 'The content of the extracted (or rather, mounted) archive is:' pp Dir["#{name_without_extension}*"] end
#¶ ↑
try_to_extract_this_iso_file
¶ ↑
#¶ ↑
# File lib/extracter/class/extracter.rb, line 727 def try_to_extract_this_iso_file(i) opnn; e 'Extracting an .iso file is a bit more complicated '\ 'than extracting a .tar.gz tarball' opnn; e 'archive. This class will first create a helper '\ 'directory; then mount the .iso there,' opnn; e 'then copy the content to the main directory.' helper_directory = File.dirname(i)+ '/READ_ONLY_DIRECTORY_'+ File.basename( i.delete_suffix(File.extname(i)) )+ '/' mkdir(helper_directory) unless File.directory? helper_directory esystem 'mount -o loop '+i+' '+helper_directory e 'The helper directory in use is '\ '`'+sdir(File.absolute_path(helper_directory))+'`.' main_directory = File.dirname(i)+ '/'+ File.basename( i.delete_suffix(File.extname(i)) )+ '/' e 'Next creating the main directory at `'+sdir(main_directory)+'`.' mkdir(main_directory) unless File.directory? main_directory e 'Next copying the content of the helper directory recursively ' e 'from `'+sdir(helper_directory)+'`' e 'onto `'+sdir( main_directory+File.basename(helper_directory)+'/' )+'`.' cpr( helper_directory, main_directory+File.basename(helper_directory)+'/' ) a = main_directory+File.basename(helper_directory)+'/' e 'Relocating the files next from:' e e " #{sdir(a)}" e Dir[a+'*'].each {|entry| mv( entry, main_directory ) } # ======================================================================= # # And remove the directory: # ======================================================================= # remove_this_directory(a) e 'The content of the extracted (or rather, mounted) archive is:' e pp Dir["#{main_directory}*"] e end
#¶ ↑
use_this_opn_hash?¶ ↑
#¶ ↑
# File lib/extracter/class/extracter.rb, line 331 def use_this_opn_hash? @internal_hash[:use_this_opn_hash] end
#¶ ↑
work_on_the_given_input
¶ ↑
#¶ ↑
# File lib/extracter/class/extracter.rb, line 784 def work_on_the_given_input( array = commandline_arguments?, extract_to = extract_to? ) # ======================================================================= # # If the user supplied a directory then a random entry will be grabbed # from said directory. # ======================================================================= # if array.is_a?(String) and File.directory?(array) array = Dir[rds("#{array}/")+'*'].sample end case extract_to when nil extract_to = extract_to? end if array.empty? opnn; e 'No archive (input) was provided. Please provide the file' opnn; e 'that is to be extracted.' else array.each {|this_file| # =================================================================== # # Create the directory if it does not yet exist. # =================================================================== # create_directory(extract_to) unless File.directory?(extract_to) # =================================================================== # # Handle the case when the user did input a number. # =================================================================== # begin if this_file =~ /^\d$/ this_file = Dir['*'][( this_file.to_i - 1 )] unless File.exist?(this_file) end rescue ArgumentError => error e 'Error for '+sfancy(this_file)+':' pp error end # =================================================================== # # If the user supplied a directory then a random entry will be # grabbed from said directory. # # Usage example: # # rubyextracter /home/x/src/htop/ # # =================================================================== # if File.directory? this_file this_file = Dir[rds("#{this_file}/")+'*'].sample end extract_this_archive(this_file, extract_to) report_to_the_user(this_file, extract_to) } end end