```bash #!/bin/bash # Torrent Copy / Rename / Delete Utility # # Description: # Selects completed torrents from a remote Deluge server, copies them # locally, optionally renames the downloaded files, and finally removes # the remote torrents. # # Workflow: # 1. List files from the configured remote torrent directory. # 2. Optionally select individual files. # 3. Confirm and copy selected files locally. # 4. Confirm and rename copied files. # 5. Confirm and remove the remote files. # # Usage: # ./torrent_copy.sh [options] # # Options: # -y Automatically answer "yes" to all confirmations. # -m Use the remote Mega torrent directory. # -yt Use the remote YouTube torrent directory. # -l Select individual files interactively. # -f Copy files to the configured torrent destination. # -d Copy files to the current directory. # -help Display this help. # # Examples: # ./torrent_copy.sh # ./torrent_copy.sh -y # ./torrent_copy.sh -l # ./torrent_copy.sh -m -l # ./torrent_copy.sh -yt -f # ./torrent_copy.sh -d # # Requirements: # - bash # - ssh # - scp # - Remote SSH access to "serverhost" # - /home/lucas/scripts/rename_episodes.sh # set -o pipefail # --------------------------------------------------------------------------- # Configuration # --------------------------------------------------------------------------- readonly REMOTE_HOST="serverhost" readonly REMOTE_USER="deluge-user" readonly DEFAULT_DEST="/data/Nextcloud/Filme/New/" readonly TORRENT_DEST="/data/Torrents" readonly RENAME_SCRIPT="/home/lucas/scripts/rename_episodes.sh" REMOTE_PATH="/torrent/complete/" DESTINATION="$DEFAULT_DEST" ASSUME_YES=false LIST_MODE=false # --------------------------------------------------------------------------- # Help # --------------------------------------------------------------------------- usage() { cat <&2 usage >&2 exit 1 ;; esac shift done } # --------------------------------------------------------------------------- # Helpers # --------------------------------------------------------------------------- confirm() { local message=$1 if [[ "$ASSUME_YES" == true ]]; then return 0 fi printf '%s (y/*) ' "$message" read -r -n 1 answer printf '\n' [[ "$answer" == "y" ]] } die() { echo "Error: $*" >&2 exit 1 } # --------------------------------------------------------------------------- # Get remote file list # --------------------------------------------------------------------------- get_file_list() { local remote_listing echo "Remote directory: $REMOTE_PATH" echo "Destination: $DESTINATION" echo if ! remote_listing=$( ssh "$REMOTE_USER@$REMOTE_HOST" \ "find '$REMOTE_PATH' -mindepth 1 -maxdepth 1 -printf '%f\n'" ); then die "Unable to retrieve remote file list." fi if [[ -z "$remote_listing" ]]; then echo "Nothing to copy/delete." exit 0 fi mapfile -t FILES <<< "$remote_listing" } # --------------------------------------------------------------------------- # Select individual files # --------------------------------------------------------------------------- select_files() { local file local selected=() echo "Select files:" echo for file in "${FILES[@]}"; do if confirm "Copy '$file'?"; then selected+=("$file") else echo "Skipping '$file'" fi done FILES=("${selected[@]}") } # --------------------------------------------------------------------------- # Copy files # --------------------------------------------------------------------------- copy_files() { local file local remote_file [[ ${#FILES[@]} -gt 0 ]] || { echo "Nothing to copy." return } echo printf 'Files to copy:\n' printf ' %s\n' "${FILES[@]}" echo if ! confirm "Copy files?"; then echo "Nothing copied." return 1 fi for file in "${FILES[@]}"; do echo "Copying: $file" # Pass the remote path as a single SSH/SCP argument. remote_file="${REMOTE_USER}@${REMOTE_HOST}:${REMOTE_PATH}${file}" if ! scp -r "$remote_file" "$DESTINATION/"; then die "Copy failed: $file" fi done echo "Torrents copied." } # --------------------------------------------------------------------------- # Rename files # --------------------------------------------------------------------------- rename_files() { local file local filepath [[ ${#FILES[@]} -gt 0 ]] || { echo "Nothing to rename." return } echo printf 'Files to rename:\n' printf ' %s\n' "${FILES[@]}" echo if ! confirm "Rename files?"; then echo "Nothing renamed." return fi if [[ ! -x "$RENAME_SCRIPT" && ! -f "$RENAME_SCRIPT" ]]; then die "Rename script not found: $RENAME_SCRIPT" fi for file in "${FILES[@]}"; do filepath="${DESTINATION%/}/$file" echo "Renaming: $filepath" if [[ -d "$filepath" ]]; then echo "$filepath is a directory." bash "$RENAME_SCRIPT" \ -del \ -files \ -dir \ -repair \ -path "$filepath" elif [[ -f "$filepath" ]]; then echo "$filepath is a file." bash "$RENAME_SCRIPT" \ -files \ -file "$filepath" else echo "Warning: $filepath is neither a directory nor a regular file." fi done echo "Rename complete." } # --------------------------------------------------------------------------- # Delete remote files # --------------------------------------------------------------------------- delete_files() { local file local remote_file [[ ${#FILES[@]} -gt 0 ]] || { echo "Nothing to remove." return } echo printf 'Remote files to remove:\n' printf ' %s\n' "${FILES[@]}" echo if ! confirm "Delete remote files?"; then echo "Nothing removed." return fi for file in "${FILES[@]}"; do echo "Removing: $file" remote_file="${REMOTE_PATH}${file}" if ! ssh "$REMOTE_USER@$REMOTE_HOST" \ "rm -rf -- '$remote_file'"; then echo "Warning: failed to remove '$file'." >&2 fi done echo "Torrents removed." } # --------------------------------------------------------------------------- # Main # --------------------------------------------------------------------------- main() { parse_args "$@" get_file_list if [[ "$LIST_MODE" == true ]]; then select_files fi [[ ${#FILES[@]} -gt 0 ]] || { echo "No files selected." exit 0 } copy_files || exit 1 rename_files delete_files } main "$@" ```