diff --git a/functions.sh b/functions.sh index d3b22788..ae848507 100644 --- a/functions.sh +++ b/functions.sh @@ -73,9 +73,9 @@ verify_space() { # USAGE: verify_space $source_dir $dest_dir # 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 - 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 echo "false" @@ -88,13 +88,13 @@ move() { # Function to move a directory from one parent to another # USAGE: move $source_dir $dest_dir - if [[ ! -d "$2/$(basename $1)" ]]; then - if [[ $(verify_space $1 $2) ]]; then + if [[ ! -d "$2/$(basename "$1")" ]]; then + if [[ $(verify_space "$1" "$2") ]]; then ( - if [[ ! -d $2 ]]; then # Create destination directory if it doesn't already exist - mkdir -pv $2 + if [[ ! -d "$2" ]]; then # Create destination directory if it doesn't already exist + mkdir -pv "$2" fi - mv -v -t $2 $1 + mv -v -t "$2" "$1" ) | zenity --icon-name=net.retrodeck.retrodeck --progress --no-cancel --pulsate --auto-close \ --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 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 () { # Function for validating chd compression candidates, and compresses if validation passes. Supports .cue, .iso and .gdi formats ONLY # USAGE: validate_for_chd $input_file - local file=$1 + local file="$1" local file_validated="false" - current_run_log_file="chd_compression_$(basename $file).log" - echo "Validating file:" $file > "$logs_folder/$current_run_log_file" + current_run_log_file="chd_compression_$(basename "$file").log" + echo "Validating file:" "$file" > "$logs_folder/$current_run_log_file" if [[ "$file" == *".cue" ]] || [[ "$file" == *".gdi" ]] || [[ "$file" == *".iso" ]]; then - echo ".cue/.iso/.gdi file detected" >> $logs_folder/$current_run_log_file - local file_path=$(dirname $(realpath $file)) - local file_base_name=$(basename $file) + echo ".cue/.iso/.gdi file detected" >> "$logs_folder/$current_run_log_file" + local file_path=$(dirname "$(realpath "$file")") + local file_base_name=$(basename "$file") 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 - local cue_bin_files=$(grep -o -P "(?<=FILE \").*(?=\".*$)" $file) - for line in $cue_bin_files + echo "Validating .cue associated .bin files" >> "$logs_folder/$current_run_log_file" + 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 + echo "looking for $file_path/$line" >> "$logs_folder/$current_run_log_file" if [[ -f "$file_path/$line" ]]; then echo ".bin file found at $file_path/$line" >> "$logs_folder/$current_run_log_file" file_validated="true" @@ -152,7 +154,7 @@ validate_for_chd () { file_validated="false" break fi - done + done < <(printf '%s\n' "$cue_bin_files") if [[ $file_validated == "true" ]]; then echo $file_validated fi @@ -165,6 +167,51 @@ validate_for_chd () { 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 \"" + fi +} + desktop_mode_warning() { # 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 @@ -841,9 +888,6 @@ citra_init() { dir_prep "$rdhome/.logs/citra" "/var/data/citra-emu/log" 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 - #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() { diff --git a/rd-submodules/shared-modules b/rd-submodules/shared-modules index 3ac77f54..ae5d7192 160000 --- a/rd-submodules/shared-modules +++ b/rd-submodules/shared-modules @@ -1 +1 @@ -Subproject commit 3ac77f545ddf0ac581bc89d7b915c23eb18f841b +Subproject commit ae5d7192c6a37f2c754fd92685a72d514931131a diff --git a/retrodeck.sh b/retrodeck.sh index f650dc4f..634c38b7 100644 --- a/retrodeck.sh +++ b/retrodeck.sh @@ -41,24 +41,7 @@ https://retrodeck.net exit ;; --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..." - 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 \"" - fi + cli_compress_file "$2" exit ;; --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 if [[ $response == [yY] ]]; then 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 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 fi else @@ -89,22 +72,22 @@ https://retrodeck.net read -p "Press 'y' to continue, 'n' to stop: " response if [[ $response == [yY] ]]; then 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 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 fi ;; --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 if [[ $response == [yY] ]]; then 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 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 fi ;; diff --git a/tools/configurator.sh b/tools/configurator.sh index e13698bd..32cf0af5 100644 --- a/tools/configurator.sh +++ b/tools/configurator.sh @@ -359,21 +359,42 @@ configurator_retroarch_options_dialog() { } configurator_compress_single_game_dialog() { - file_to_compress=$(file_browse "Game to compress") - if [[ ! -z $file_to_compress ]]; then - if [[ $(validate_for_chd $file_to_compress) == "true" ]]; then + local file=$(file_browse "Game to compress") + if [[ ! -z "$file" ]]; 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) - filename_no_extension=${filename_no_path%.*} - compress_to_chd $(dirname $(realpath $file_to_compress))/$(basename $file_to_compress) $(dirname $(realpath $file_to_compress))/$filename_no_extension + echo "# Compressing $filename_no_path, please wait..." + 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 "$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 \ - --window-icon="/app/share/icons/hicolor/scalable/apps/net.retrodeck.retrodeck.svg" \ - --title "RetroDECK Configurator Utility - Compression in Progress" \ - --text="Compressing game $filename_no_path, please wait." + --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_generic_dialog "File type not recognized. Supported file types are .cue, .gdi and .iso" - configurator_compress_single_game_dialog + configurator_compress_games_dialog fi else configurator_generic_dialog "No file selected, returning to main menu" @@ -382,26 +403,25 @@ configurator_compress_single_game_dialog() { } configurator_compress_multi_game_dialog() { -# This dialog will display any games it finds to be compressable, from the systems listed under each compression type in compression_targets.cfg -# USAGE: configurator_compress_multi_game_dialog $compression_type - + # 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_for_selection=() + local compressable_games_list=() local all_compressable_games=() - local compressable_systems_for_selection=$(sed -n '/\['"$compression_format"'\]/, /\[/{ /\['"$compression_format"'\]/! { /\[/! p } }' $compression_targets | sed '/^$/d') + local compressable_systems_list=$(sed -n '/\['"$compression_format"'\]/, /\[/{ /\['"$compression_format"'\]/! { /\[/! p } }' $compression_targets | sed '/^$/d') while IFS= read -r system # Find and validate all games that are able to be compressed with this compression type 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_for_selection=("${compressable_games_for_selection[@]}" "false" "${game#$roms_folder}" $game) - fi + 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") @@ -413,35 +433,118 @@ configurator_compress_multi_game_dialog() { --column "Compress?" \ --column "Game" \ --column "Game Full Path" \ - "${compressable_games_for_selection[@]}") + "${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 game in "${games_to_compress[@]}"; do - local filename_no_path=$(basename $game) - local filename_no_extension=${filename_no_path%.*} - compress_to_chd $(dirname $(realpath $game))/$(basename $game) $(dirname $(realpath $game))/$filename_no_extension + ( + 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 # Games were selected to be compressed - #echo "Compressing all games" - for game in "${all_compressable_games[@]}"; do - local filename_no_path=$(basename $game) - local filename_no_extension=${filename_no_path%.*} - compress_to_chd $(dirname $(realpath $game))/$(basename $game) $(dirname $(realpath $game))/$filename_no_extension - done + 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 - echo "No games being compressed" + configurator_compress_games_dialog fi fi } -configurator_compress_games_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. +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_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." - configurator_compress_single_game_dialog +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() {