Skip to content

Commit

Permalink
Extract files by MIME and refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
cfgnunes committed Jan 14, 2025
1 parent 272f491 commit 79a1a4c
Showing 1 changed file with 91 additions and 13 deletions.
104 changes: 91 additions & 13 deletions Archive/Extract Here
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ _get_command() {
local preferred_commands=""
local command=""

# Define the preferred commands for each archive format.
# Determine the preferred commands based on the file extension.
case "${input_file,,}" in
*.tar.bz | *.tbz | *.tar.bz2 | *.tbz2 | *.tb2) preferred_commands="tar+bzip2 unar 7za" ;;
*.tar.gz | *.tgz) preferred_commands="tar+gzip unar 7za" ;;
Expand Down Expand Up @@ -205,25 +205,95 @@ _get_command() {
*.zoo) preferred_commands="unar" ;;
*.zpaq) preferred_commands="zpaq" ;;
*.zst) preferred_commands="zstd" ;;
*) preferred_commands="bsdtar+unar+7za" ;;
*)
# For unknown extensions, determine the MIME type.
# NOTE: See the file: /usr/share/mime/packages/freedesktop.org.xml
local file_mime=""
file_mime=$(_get_file_mime "$input_file")

case "${file_mime,,}" in
"application/x-7z-compressed") preferred_commands="7za unar bsdtar" ;; # *.7z
"application/x-ace") preferred_commands="unar" ;; # *.ace
"application/x-alz") preferred_commands="unar" ;; # *.alz
"application/x-archive") preferred_commands="ar bsdtar" ;; # *.ar
"application/x-arc") preferred_commands="unar" ;; # *.arc
"application/x-arj") preferred_commands="unar" ;; # *.arj
"application/bzip2") preferred_commands="bzip2 unar 7za" ;; # *.bz | *.bz2
"application/x-bzip") preferred_commands="bzip2 unar 7za" ;; # *.bz | *.bz2
"application/x-bzip2") preferred_commands="bzip2 unar 7za" ;; # *.bz | *.bz2
"application/vnd.ms-cab-compressed") preferred_commands="cabextract bsdtar unar" ;; # *.cab
"application/x-cpio") preferred_commands="cpio unar bsdtar" ;; # *.cpio
"application/vnd.debian.binary-package") preferred_commands="ar" ;; # *.deb | *.udeb
"application/pgp-encrypted") preferred_commands="gpg" ;; # *.gpg | *.asc | *.pgp
"application/gzip") preferred_commands="gzip unar 7za" ;; # *.gz
"application/x-gzip") preferred_commands="gzip unar 7za" ;; # *.gz
"application/x-iso9660-image") preferred_commands="xorriso bsdtar" ;; # *.iso
"application/x-lrzip") preferred_commands="lrzip" ;; # *.lrz
"application/x-lzip") preferred_commands="lzip" ;; # *.lz
"application/x-lz4") preferred_commands="lz4" ;; # *.lz4
"application/x-lha") preferred_commands="lha unar" ;; # *.lzh | *.lzs | *.lha
"application/x-lzh-compressed") preferred_commands="lha unar" ;; # *.lzh | *.lzs | *.lha
"application/x-lzma") preferred_commands="xz unar" ;; # *.lzma
"application/x-lzop") preferred_commands="lzop" ;; # *.lzo
"application/x-msi") preferred_commands="unar" ;; # *.msi
"application/x-pak") preferred_commands="unar" ;; # *.pak
"application/vnd.rar") preferred_commands="unrar unar bsdtar" ;; # *.rar
"application/x-rar-compressed") preferred_commands="unrar unar bsdtar" ;; # *.rar
"application/x-rar") preferred_commands="unrar unar bsdtar" ;; # *.rar
"application/stuffit") preferred_commands="unar" ;; # *.sit
"application/x-sit") preferred_commands="unar" ;; # *.sit
"application/x-stuffit") preferred_commands="unar" ;; # *.sit
"application/vnd.squashfs") preferred_commands="unsquashfs" ;; # *.sqsh | *.squashfs | *.sfs
"application/x-xar") preferred_commands="unar bsdtar" ;; # *.xar
"application/x-xz") preferred_commands="xz unar 7za" ;; # *.xz
"application/x-compress") preferred_commands="gzip unar" ;; # *.z
"application/x-zip-compressed") preferred_commands="7za bsdtar unar unzip" ;; # *.zip
"application/x-zip") preferred_commands="7za bsdtar unar unzip" ;; # *.zip
"application/zip") preferred_commands="7za bsdtar unar unzip" ;; # *.zip
"application/x-zoo") preferred_commands="unar" ;; # *.zoo
"application/zstd") preferred_commands="zstd" ;; # *.zstd
"application/octet-stream")
# For generic binary files, try further identification.
local file_information=""
file_information=$(file --dereference --brief \
-- "$input_file" 2>/dev/null)

case "${file_information,,}" in
"gpg "* | "pgp "*) preferred_commands="gpg" ;;
*)
# Default extractor chain for unknown binary files.
preferred_commands="bsdtar+unar+7za"
;;
esac
;;
*)
# Default extractor chain for unrecognized MIME types.
preferred_commands="bsdtar+unar+7za"
;;
esac
;;
esac

# Convert the preferred commands string to an array.
local preferred_commands_array=()
IFS=" " read -r -a preferred_commands_array <<<"$preferred_commands"

# Determine the command to use based on the command status.
if [[ "$command_status" == "default" ]]; then
# The default command is the first command of preferred commands.
# Use the first preferred command as the default.
command=${preferred_commands_array[0]}
elif [[ "$command_status" == "available" ]]; then
# Get the available command in the system.
# Find the first available command on the system.
local preferred_command=""
for preferred_command in "${preferred_commands_array[@]}"; do
if [[ "$preferred_command" == *"+"* ]]; then
# Check if all commands in a composite command exist.
if _all_commands_exists "${preferred_command//+/ }"; then
command=$preferred_command
break
fi
elif _command_exists "$preferred_command"; then
# Use the first available command.
command=$preferred_command
break
fi
Expand Down Expand Up @@ -367,7 +437,7 @@ _run_command() {
"zstd") std_output=$(zstd -d -c -- "$input_file" >"$filename") ;;
"bsdtar+unar+7za")
exit_code=1

# Default extractor chain for unrecognized files.
# Try to extract with 'bsdtar'.
if ((exit_code != 0)); then
std_output=$(bsdtar -xf "$input_file" 2>&1)
Expand Down Expand Up @@ -411,11 +481,13 @@ _run_command() {
chmod --recursive u+rw -- .
fi

# Get the list of root items (files or directories) in the 'temp_dir_output' directory.
# Get the list of root items (files or directories)
# in the 'temp_dir_output' directory.
local root_items=""
root_items=$(find . -mindepth 1 -maxdepth 1 2>/dev/null)

# Count the number of items (using word count to count lines, similar to the original wc -l).
# Count the number of items (using word count to count lines,
# similar to the original wc -l).
local count_root_items=""
count_root_items=$(wc -l <<<"$root_items")

Expand All @@ -434,16 +506,22 @@ _run_command() {
__temp_dir_pop || return 1

# Move the items to the correct directory.
if [[ "$single_root_item" == "$filename" ]] || [[ "$(_strip_filename_extension "$single_root_item")" == "$filename" ]]; then
if [[ "$single_root_item" == "$filename" ]] ||
[[ "$(_strip_filename_extension "$single_root_item")" == "$filename" ]]; then
# For archives with "one item with the same name of the archive".
# For example: "README.txt.tar.gz" or "README.tar.gz".
_move_file "rename" "$temp_dir_output/$single_root_item" "$output_dir/$single_root_item"
elif [[ "$single_root_item" == "squashfs-root" ]] && [[ "$command" == "unsquashfs" ]]; then
_move_file "rename" \
"$temp_dir_output/$single_root_item" "$output_dir/$single_root_item"
elif [[ "$single_root_item" == "squashfs-root" ]] &&
[[ "$command" == "unsquashfs" ]]; then
# For the "squashfs" archive format.
_move_file "rename" "$temp_dir_output/$single_root_item" "$output_dir/$filename"
_move_file "rename" \
"$temp_dir_output/$single_root_item" "$output_dir/$filename"
else
# For archives with "one item with a different name of the archive" or "multiple items".
_move_file "rename" "$temp_dir_output" "$output_dir/$filename"
# For archives with "one item with a different
# name of the archive" or "multiple items".
_move_file "rename" \
"$temp_dir_output" "$output_dir/$filename"
fi

__temp_dir_remove
Expand Down

0 comments on commit 79a1a4c

Please sign in to comment.