- Add compressed file cleanup

- Add multi-file compression
- Fix compression handling for files with spaces in them
This commit is contained in:
icenine451 2023-03-15 17:19:04 -04:00
parent 5c3e6767c4
commit f5c6a70c9c
4 changed files with 248 additions and 62 deletions

View file

@ -73,9 +73,9 @@ verify_space() {
# USAGE: verify_space $source_dir $dest_dir # USAGE: verify_space $source_dir $dest_dir
# Function returns "true" if there is enough space, "false" if there is not # Function returns "true" if there is enough space, "false" if there is not
source_size=$(du -sk $1 | awk '{print $1}') source_size=$(du -sk "$1" | awk '{print $1}')
source_size=$((source_size+(source_size/10))) # Add 10% to source size for safety source_size=$((source_size+(source_size/10))) # Add 10% to source size for safety
dest_avail=$(df -k --output=avail $2 | tail -1) dest_avail=$(df -k --output=avail "$2" | tail -1)
if [[ $source_size -ge $dest_avail ]]; then if [[ $source_size -ge $dest_avail ]]; then
echo "false" echo "false"
@ -88,13 +88,13 @@ move() {
# Function to move a directory from one parent to another # Function to move a directory from one parent to another
# USAGE: move $source_dir $dest_dir # USAGE: move $source_dir $dest_dir
if [[ ! -d "$2/$(basename $1)" ]]; then if [[ ! -d "$2/$(basename "$1")" ]]; then
if [[ $(verify_space $1 $2) ]]; then if [[ $(verify_space "$1" "$2") ]]; then
( (
if [[ ! -d $2 ]]; then # Create destination directory if it doesn't already exist if [[ ! -d "$2" ]]; then # Create destination directory if it doesn't already exist
mkdir -pv $2 mkdir -pv "$2"
fi fi
mv -v -t $2 $1 mv -v -t "$2" "$1"
) | ) |
zenity --icon-name=net.retrodeck.retrodeck --progress --no-cancel --pulsate --auto-close \ zenity --icon-name=net.retrodeck.retrodeck --progress --no-cancel --pulsate --auto-close \
--window-icon="/app/share/icons/hicolor/scalable/apps/net.retrodeck.retrodeck.svg" \ --window-icon="/app/share/icons/hicolor/scalable/apps/net.retrodeck.retrodeck.svg" \
@ -121,28 +121,30 @@ compress_to_chd () {
# USAGE: compress_to_chd $full_path_to_input_file $full_path_to_output_file # USAGE: compress_to_chd $full_path_to_input_file $full_path_to_output_file
echo "Compressing file $1 to $2.chd" echo "Compressing file $1 to $2.chd"
/app/bin/chdman createcd -i $1 -o $2.chd /app/bin/chdman createcd -i "$1" -o "$2".chd
} }
validate_for_chd () { validate_for_chd () {
# Function for validating chd compression candidates, and compresses if validation passes. Supports .cue, .iso and .gdi formats ONLY # Function for validating chd compression candidates, and compresses if validation passes. Supports .cue, .iso and .gdi formats ONLY
# USAGE: validate_for_chd $input_file # USAGE: validate_for_chd $input_file
local file=$1 local file="$1"
local file_validated="false" local file_validated="false"
current_run_log_file="chd_compression_$(basename $file).log" current_run_log_file="chd_compression_$(basename "$file").log"
echo "Validating file:" $file > "$logs_folder/$current_run_log_file" echo "Validating file:" "$file" > "$logs_folder/$current_run_log_file"
if [[ "$file" == *".cue" ]] || [[ "$file" == *".gdi" ]] || [[ "$file" == *".iso" ]]; then if [[ "$file" == *".cue" ]] || [[ "$file" == *".gdi" ]] || [[ "$file" == *".iso" ]]; then
echo ".cue/.iso/.gdi file detected" >> $logs_folder/$current_run_log_file echo ".cue/.iso/.gdi file detected" >> "$logs_folder/$current_run_log_file"
local file_path=$(dirname $(realpath $file)) local file_path=$(dirname "$(realpath "$file")")
local file_base_name=$(basename $file) local file_base_name=$(basename "$file")
local file_name=${file_base_name%.*} local file_name=${file_base_name%.*}
echo "File base path:" $file_path >> "$logs_folder/$current_run_log_file"
echo "File base name:" $file_name >> "$logs_folder/$current_run_log_file"
if [[ "$file" == *".cue" ]]; then # Validate .cue file if [[ "$file" == *".cue" ]]; then # Validate .cue file
local cue_bin_files=$(grep -o -P "(?<=FILE \").*(?=\".*$)" $file) echo "Validating .cue associated .bin files" >> "$logs_folder/$current_run_log_file"
for line in $cue_bin_files local cue_bin_files=$(grep -o -P "(?<=FILE \").*(?=\".*$)" "$file")
echo "Associated bin files read:" >> "$logs_folder/$current_run_log_file"
printf '%s\n' "$cue_bin_files" >> "$logs_folder/$current_run_log_file"
while IFS= read -r line
do do
echo "looking for $file_path/$line" >> "$logs_folder/$current_run_log_file"
if [[ -f "$file_path/$line" ]]; then if [[ -f "$file_path/$line" ]]; then
echo ".bin file found at $file_path/$line" >> "$logs_folder/$current_run_log_file" echo ".bin file found at $file_path/$line" >> "$logs_folder/$current_run_log_file"
file_validated="true" file_validated="true"
@ -152,7 +154,7 @@ validate_for_chd () {
file_validated="false" file_validated="false"
break break
fi fi
done done < <(printf '%s\n' "$cue_bin_files")
if [[ $file_validated == "true" ]]; then if [[ $file_validated == "true" ]]; then
echo $file_validated echo $file_validated
fi fi
@ -165,6 +167,51 @@ validate_for_chd () {
fi fi
} }
cli_compress_file() {
# This function will compress a single file passed from the CLI arguments
# USAGE: cli_compress_file $full_file_path
local file="$1"
echo "Looking for" "$file"
current_run_log_file="chd_compression_$(basename "$file").log"
if [[ ! -z "$file" ]]; then
if [[ -f "$file" ]]; then
if [[ $(validate_for_chd "$file") == "true" ]]; then
read -p "RetroDECK will now attempt to compress your selected game. Press Enter key to continue..."
read -p "Do you want to have the original file removed after compression is complete? Please answer y/n and press Enter: " post_compression_cleanup
local filename_no_path=$(basename "$file")
local filename_no_extension="${filename_no_path%.*}"
local source_file=$(dirname "$(realpath "$file")")"/"$(basename "$file")
local dest_file=$(dirname "$(realpath "$file")")"/""$filename_no_extension"
echo "Compressing $filename_no_path"
compress_to_chd "$source_file" "$dest_file"
if [[ $post_compression_cleanup == [yY] ]]; then # Remove file(s) if requested
if [[ "$file" == *".cue" ]]; then
local cue_bin_files=$(grep -o -P "(?<=FILE \").*(?=\".*$)" "$file")
local file_path=$(dirname "$(realpath "$file")")
while IFS= read -r line
do # Remove associated .bin files
echo "Removing file "$line""
rm -f "$file_path/$line"
done < <(printf '%s\n' "$cue_bin_files") # Remove original .cue file
echo "Removing file "$filename_no_path""
rm -f $(realpath "$file")
else
echo "Removing file "$filename_no_path""
rm -f $(realpath "$file")
fi
fi
else
printf "An error occured during the compression process. Please see the following log entries for details:\n\n"
cat "$logs_folder/$current_run_log_file"
fi
else
echo "File not found, please specify the full path to the file to be compressed."
fi
else
echo "Please use this command format \"--compress <cue/gdi/iso file to compress>\""
fi
}
desktop_mode_warning() { desktop_mode_warning() {
# This function is a generic warning for issues that happen when running in desktop mode. # This function is a generic warning for issues that happen when running in desktop mode.
# Running in desktop mode can be verified with the following command: if [[ ! $XDG_CURRENT_DESKTOP == "gamescope" ]]; then # Running in desktop mode can be verified with the following command: if [[ ! $XDG_CURRENT_DESKTOP == "gamescope" ]]; then
@ -803,9 +850,6 @@ citra_init() {
dir_prep "$rdhome/.logs/citra" "/var/data/citra-emu/log" dir_prep "$rdhome/.logs/citra" "/var/data/citra-emu/log"
cp -fv $emuconfigs/citra-qt-config.ini /var/config/citra-emu/qt-config.ini cp -fv $emuconfigs/citra-qt-config.ini /var/config/citra-emu/qt-config.ini
sed -i 's#~/retrodeck#'$rdhome'#g' /var/config/citra-emu/qt-config.ini sed -i 's#~/retrodeck#'$rdhome'#g' /var/config/citra-emu/qt-config.ini
#TODO: do the same with roms folders after new variables is pushed (check even the others qt-emu)
#But actually everything is always symlinked to retrodeck/roms so it might be not needed
#sed -i 's#~/retrodeck#'$rdhome'#g' /var/config/citra-emu/qt-config.ini
} }
rpcs3_init() { rpcs3_init() {

@ -1 +1 @@
Subproject commit 3ac77f545ddf0ac581bc89d7b915c23eb18f841b Subproject commit ae5d7192c6a37f2c754fd92685a72d514931131a

View file

@ -41,24 +41,7 @@ https://retrodeck.net
exit exit
;; ;;
--compress*) --compress*)
read -p "RetroDECK will now attempt to compress your selected game. The original game will still exist and will need to be removed manually after the process completes. Press any key to continue..." cli_compress_file "$2"
if [[ ! -z $2 ]]; then
if [[ -f $2 ]]; then
current_run_log_file="chd_compression_"$(date +"%Y_%m_%d_%I_%M_%p").log""
if [[ $(validate_for_chd $2) == "true" ]]; then
filename_no_path=$(basename $2)
filename_no_extension=${filename_no_path%.*}
compress_to_chd $(dirname $(realpath $2))/$(basename $2) $(dirname $(realpath $2))/$filename_no_extension
else
printf "An error occured during the compression process. Please see the following log entries for details:\n\n"
cat $logs_folder/$current_run_log_file
fi
else
echo "File not found, please specify the full path to the file to be compressed."
fi
else
echo "Please use this command format \"--compress <cue/gdi/iso file to compress>\""
fi
exit exit
;; ;;
--configurator*) --configurator*)
@ -73,10 +56,10 @@ https://retrodeck.net
read -p "You are about to reset $emulator to default settings. Press 'y' to continue, 'n' to stop: " response read -p "You are about to reset $emulator to default settings. Press 'y' to continue, 'n' to stop: " response
if [[ $response == [yY] ]]; then if [[ $response == [yY] ]]; then
cli_emulator_reset $emulator cli_emulator_reset $emulator
read -p "The process has been completed, press any key to start RetroDECK." read -p "The process has been completed, press Enter key to start RetroDECK."
shift # Continue launch after previous command is finished shift # Continue launch after previous command is finished
else else
read -p "The process has been cancelled, press any key to exit." read -p "The process has been cancelled, press Enter key to exit."
exit exit
fi fi
else else
@ -89,22 +72,22 @@ https://retrodeck.net
read -p "Press 'y' to continue, 'n' to stop: " response read -p "Press 'y' to continue, 'n' to stop: " response
if [[ $response == [yY] ]]; then if [[ $response == [yY] ]]; then
tools_init tools_init
read -p "The process has been completed, press any key to start RetroDECK." read -p "The process has been completed, press Enter key to start RetroDECK."
shift # Continue launch after previous command is finished shift # Continue launch after previous command is finished
else else
read -p "The process has been cancelled, press any key to exit." read -p "The process has been cancelled, press Enter key to exit."
exit exit
fi fi
;; ;;
--reset-retrodeck*) --reset-retrodeck*)
echo "You are about to reset RetroDECK completely." echo "You are about to reset RetroDECK completely!"
read -p "Press 'y' to continue, 'n' to stop: " response read -p "Press 'y' to continue, 'n' to stop: " response
if [[ $response == [yY] ]]; then if [[ $response == [yY] ]]; then
rm -f "$lockfile" rm -f "$lockfile"
read -p "The process has been completed, press any key to start the initial RetroDECK setup process." read -p "The process has been completed, press Enter key to start the initial RetroDECK setup process."
shift # Continue launch after previous command is finished shift # Continue launch after previous command is finished
else else
read -p "The process has been cancelled, press any key to exit." read -p "The process has been cancelled, press Enter key to exit."
exit exit
fi fi
;; ;;

View file

@ -343,21 +343,42 @@ configurator_retroarch_options_dialog() {
} }
configurator_compress_single_game_dialog() { configurator_compress_single_game_dialog() {
file_to_compress=$(file_browse "Game to compress") local file=$(file_browse "Game to compress")
if [[ ! -z $file_to_compress ]]; then if [[ ! -z "$file" ]]; then
if [[ $(validate_for_chd $file_to_compress) == "true" ]]; then if [[ $(validate_for_chd "$file") == "true" ]]; then
local post_compression_cleanup=$(configurator_compression_cleanup_dialog)
local filename_no_path=$(basename "$file")
local filename_no_extension="${filename_no_path%.*}"
local source_file=$(dirname "$(realpath "$file")")"/"$(basename "$file")
local dest_file=$(dirname "$(realpath "$file")")"/""$filename_no_extension"
( (
filename_no_path=$(basename $file_to_compress) echo "# Compressing $filename_no_path, please wait..."
filename_no_extension=${filename_no_path%.*} compress_to_chd "$source_file" "$dest_file"
compress_to_chd $(dirname $(realpath $file_to_compress))/$(basename $file_to_compress) $(dirname $(realpath $file_to_compress))/$filename_no_extension if [[ $post_compression_cleanup == "true" ]]; then # Remove file(s) if requested
if [[ "$file" == *".cue" ]]; then
local cue_bin_files=$(grep -o -P "(?<=FILE \").*(?=\".*$)" "$file")
local file_path=$(dirname "$(realpath "$file")")
while IFS= read -r line
do
echo "# Removing file $line"
rm -f "$file_path/$line"
done < <(printf '%s\n' "$cue_bin_files")
echo "# Removing file $filename_no_path"
rm -f "$file"
else
echo "# Removing file $filename_no_path"
rm -f "$file"
fi
fi
) | ) |
zenity --icon-name=net.retrodeck.retrodeck --progress --no-cancel --pulsate --auto-close \ zenity --icon-name=net.retrodeck.retrodeck --progress --no-cancel --pulsate --auto-close \
--window-icon="/app/share/icons/hicolor/scalable/apps/net.retrodeck.retrodeck.svg" \ --window-icon="/app/share/icons/hicolor/scalable/apps/net.retrodeck.retrodeck.svg" \
--title "RetroDECK Configurator Utility - Compression in Progress" \ --title "RetroDECK Configurator Utility - Compression in Progress"
--text="Compressing game $filename_no_path, please wait." configurator_generic_dialog "The compression process is complete!"
configurator_compress_games_dialog
else else
configurator_generic_dialog "File type not recognized. Supported file types are .cue, .gdi and .iso" configurator_generic_dialog "File type not recognized. Supported file types are .cue, .gdi and .iso"
configurator_compress_single_game_dialog configurator_compress_games_dialog
fi fi
else else
configurator_generic_dialog "No file selected, returning to main menu" configurator_generic_dialog "No file selected, returning to main menu"
@ -365,11 +386,149 @@ configurator_compress_single_game_dialog() {
fi fi
} }
configurator_compress_games_dialog() { configurator_compress_multi_game_dialog() {
# This is currently a placeholder for a dialog where you can compress a single game or multiple at once. Currently only the single game option is available, so is launched by default. # This dialog will display any games it finds to be compressable, from the systems listed under each compression type in
local compression_format=$1
local compressable_game=""
local compressable_games_list=()
local all_compressable_games=()
local compressable_systems_list=$(sed -n '/\['"$compression_format"'\]/, /\[/{ /\['"$compression_format"'\]/! { /\[/! p } }' $compression_targets | sed '/^$/d')
configurator_generic_dialog "This utility will compress a single game into .CHD format.\n\nPlease select the game to be compressed in the next dialog: supported file types are .cue, .iso and .gdi\n\nThe original game files will be untouched and will need to be removed manually." while IFS= read -r system # Find and validate all games that are able to be compressed with this compression type
configurator_compress_single_game_dialog do
if [[ $compression_format == "chd" ]]; then
compression_candidates=$(find "$roms_folder/$system" -type f \( -name "*.cue" -o -name "*.iso" -o -name "*.gdi" \) ! -path "*.m3u*")
# TODO: Add ZIP file compression search here
fi
while IFS= read -r game
do
if [[ $(validate_for_chd "$game") == "true" ]]; then
all_compressable_games=("${all_compressable_games[@]}" "$game")
compressable_games_list=("${compressable_games_list[@]}" "false" "${game#$roms_folder}" "$game")
fi
done < <(printf '%s\n' "$compression_candidates")
done < <(printf '%s\n' "$compressable_systems_list")
choice=$(zenity \
--list --width=1200 --height=720 \
--checklist --hide-column=3 --ok-label="Compress Selected" --extra-button="Compress All" \
--separator="," --print-column=3 \
--text="Choose which games to compress:" \
--column "Compress?" \
--column "Game" \
--column "Game Full Path" \
"${compressable_games_list[@]}")
local rc=$?
if [[ $rc == "0" && ! -z $choice ]]; then # User clicked "Compress Selected" with at least one game selected
local post_compression_cleanup=$(configurator_compression_cleanup_dialog)
IFS="," read -ra games_to_compress <<< "$choice"
(
for file in "${games_to_compress[@]}"; do
local filename_no_path=$(basename "$file")
local filename_no_extension="${filename_no_path%.*}"
local source_file=$(dirname "$(realpath "$file")")"/"$(basename "$file")
local dest_file=$(dirname "$(realpath "$file")")"/""$filename_no_extension"
echo "# Compressing $filename_no_path" # Update Zenity dialog text
compress_to_chd "$source_file" "$dest_file"
if [[ $post_compression_cleanup == "true" ]]; then # Remove file(s) if requested
if [[ "$file" == *".cue" ]]; then
local cue_bin_files=$(grep -o -P "(?<=FILE \").*(?=\".*$)" "$file")
local file_path=$(dirname "$(realpath "$file")")
while IFS= read -r line
do
echo "# Removing file $line"
rm -f "$file_path/$line"
done < <(printf '%s\n' "$cue_bin_files")
echo "# Removing file $filename_no_path"
rm -f $(realpath "$file")
else
echo "# Removing file $filename_no_path"
rm -f "$(realpath "$file")"
fi
fi
done
) |
zenity --icon-name=net.retrodeck.retrodeck --progress --no-cancel --pulsate --auto-close \
--window-icon="/app/share/icons/hicolor/scalable/apps/net.retrodeck.retrodeck.svg" \
--title "RetroDECK Configurator Utility - Compression in Progress"
else
if [[ ! -z $choice ]]; then # User clicked "Compress All"
local post_compression_cleanup=$(configurator_compression_cleanup_dialog)
(
for file in "${all_compressable_games[@]}"; do
local filename_no_path=$(basename "$file")
local filename_no_extension="${filename_no_path%.*}"
local source_file=$(dirname "$(realpath "$file")")"/"$(basename "$file")
local dest_file=$(dirname "$(realpath "$file")")"/""$filename_no_extension"
echo "# Compressing $filename_no_path" # Update Zenity dialog text
compress_to_chd "$source_file" "$dest_file"
if [[ $post_compression_cleanup == "true" ]]; then # Remove file(s) if requested
if [[ "$file" == *".cue" ]]; then
local cue_bin_files=$(grep -o -P "(?<=FILE \").*(?=\".*$)" "$file")
local file_path=$(dirname "$(realpath "$file")")
while IFS= read -r line
do
echo "# Removing file $line"
rm -f "$file_path/$line"
done < <(printf '%s\n' "$cue_bin_files")
echo "# Removing file $filename_no_path"
rm -f $(realpath "$file")
else
echo "# Removing file $filename_no_path"
rm -f $(realpath "$file")
fi
fi
done
) |
zenity --icon-name=net.retrodeck.retrodeck --progress --no-cancel --pulsate --auto-close \
--window-icon="/app/share/icons/hicolor/scalable/apps/net.retrodeck.retrodeck.svg" \
--title "RetroDECK Configurator Utility - Compression in Progress"
configurator_generic_dialog "The compression process is complete!"
configurator_compress_games_dialog
else
configurator_compress_games_dialog
fi
fi
}
configurator_compression_cleanup_dialog() {
zenity --icon-name=net.retrodeck.retrodeck --question --no-wrap --cancel-label="No" --ok-label="Yes" \
--window-icon="/app/share/icons/hicolor/scalable/apps/net.retrodeck.retrodeck.svg" \
--title "RetroDECK Compression Cleanup" \
--text="Do you want to remove old files after they are compressed?\n\nClicking \"No\" will leave all files behind which will need to be cleaned up manually and may result in game duplicates showing in the RetroDECK library."
local rc=$? # Capture return code, as "Yes" button has no text value
if [[ $rc == "0" ]]; then # If user clicked "Yes"
echo "true"
else # If "No" was clicked
echo "false"
fi
}
configurator_compress_games_dialog() {
choice=$(zenity --list --title="RetroDECK Configurator Utility - Change Options" --cancel-label="Back" \
--window-icon="/app/share/icons/hicolor/scalable/apps/net.retrodeck.retrodeck.svg" --width=1200 --height=720 \
--column="Choice" --column="Action" \
"Compress Single Game" "Compress a single game into a compatible format" \
"Compress Multiple Games - CHD" "Compress one or more games compatible with the CHD format" )
case $choice in
"Compress Single Game" )
configurator_compress_single_game_dialog
;;
"Compress Multiple Games - CHD" )
configurator_compress_multi_game_dialog "chd"
;;
# TODO: Add ZIP compression option
"" ) # No selection made or Back button clicked
configurator_welcome_dialog
;;
esac
} }
configurator_check_multifile_game_structure() { configurator_check_multifile_game_structure() {