134 lines
4.8 KiB
Bash
134 lines
4.8 KiB
Bash
#!/bin/bash
|
|
# Archive extraction handler for torrent-mover
|
|
|
|
# extract_single_archive: Extract a single archive with proper error handling
|
|
extract_single_archive() {
|
|
local archive="$1"
|
|
local target_dir="$2"
|
|
local archive_type="${archive##*.}"
|
|
local extract_success=1
|
|
local tmp_marker="${target_dir}/.extraction_in_progress"
|
|
|
|
# Create extraction marker to indicate incomplete extraction
|
|
touch "${tmp_marker}"
|
|
|
|
# Ensure proper permissions for extraction directory
|
|
chmod 775 "${target_dir}"
|
|
chown ${TORRENT_USER:-debian-transmission}:${TORRENT_GROUP:-debian-transmission} "${target_dir}"
|
|
|
|
# Extract based on archive type
|
|
case "${archive_type,,}" in # Use lowercase comparison
|
|
rar)
|
|
log_debug "Extracting RAR archive: ${archive}"
|
|
# Check which unrar variant is available
|
|
if command -v unrar-free &>/dev/null; then
|
|
# unrar-free has different syntax
|
|
retry_command "unrar-free x \"${archive}\" \"${target_dir}\"" 3 10
|
|
else
|
|
retry_command "unrar x -o- \"${archive}\" \"${target_dir}\"" 3 10
|
|
fi
|
|
extract_success=$?
|
|
;;
|
|
zip)
|
|
log_debug "Extracting ZIP archive: ${archive}"
|
|
retry_command "unzip -o \"${archive}\" -d \"${target_dir}\"" 3 10
|
|
extract_success=$?
|
|
;;
|
|
7z|7zip)
|
|
log_debug "Extracting 7Z archive: ${archive}"
|
|
retry_command "7z x \"${archive}\" -o\"${target_dir}\"" 3 10
|
|
extract_success=$?
|
|
;;
|
|
*)
|
|
log_error "Unknown archive type: ${archive_type}"
|
|
extract_success=1
|
|
;;
|
|
esac
|
|
|
|
# Apply consistent permissions to all extracted files and directories
|
|
if [[ ${extract_success} -eq 0 ]]; then
|
|
log_debug "Setting permissions for extracted files in ${target_dir}"
|
|
find "${target_dir}" -type d -exec chmod 775 {} \;
|
|
find "${target_dir}" -type f -exec chmod 664 {} \;
|
|
find "${target_dir}" -exec chown ${TORRENT_USER:-debian-transmission}:${TORRENT_GROUP:-debian-transmission} {} \;
|
|
|
|
# Remove the extraction marker to indicate successful completion
|
|
rm -f "${tmp_marker}"
|
|
return 0
|
|
else
|
|
log_error "Extraction failed for ${archive}"
|
|
# Keep marker to indicate failed extraction
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# handle_archives: Process all archives in a source directory
|
|
# Returns: 0 if all archives extracted successfully or no archives found, 1 if any failed
|
|
handle_archives() {
|
|
local src="$1" dst="$2"
|
|
local overall_success=0
|
|
local archive_found=0
|
|
local extraction_errors=0
|
|
|
|
# Check if source and destination are valid
|
|
if [[ ! -d "${src}" ]]; then
|
|
log_error "Source directory missing: ${src}"
|
|
return 1
|
|
fi
|
|
|
|
if [[ ! -d "${dst}" ]]; then
|
|
log_error "Destination directory missing: ${dst}"
|
|
return 1
|
|
fi
|
|
|
|
# Find all archives and extract them
|
|
find "${src}" -type f \( -iname "*.rar" -o -iname "*.zip" -o -iname "*.7z" \) | while read -r arch; do
|
|
archive_found=1
|
|
log_info "Processing archive: ${arch}"
|
|
|
|
# Create extraction subdirectory
|
|
local base
|
|
base=$(basename "${arch}")
|
|
local subdir="${dst}/${base%.*}"
|
|
|
|
if ! mkdir -p "${subdir}"; then
|
|
log_error "Failed to create subdirectory ${subdir} for archive extraction"
|
|
extraction_errors=$((extraction_errors + 1))
|
|
continue
|
|
fi
|
|
|
|
# Extract the archive
|
|
if ! extract_single_archive "${arch}" "${subdir}"; then
|
|
log_error "Extraction failed for ${arch}"
|
|
extraction_errors=$((extraction_errors + 1))
|
|
else
|
|
log_info "Archive ${arch} extracted successfully to ${subdir}"
|
|
log_info "Archive ${arch} retained in source until ratio limits are reached."
|
|
fi
|
|
done
|
|
|
|
# Check for cleanup of any incomplete extractions from previous runs
|
|
find "${dst}" -name ".extraction_in_progress" | while read -r marker; do
|
|
local problem_dir=$(dirname "${marker}")
|
|
log_warn "Found incomplete extraction in ${problem_dir} from previous run"
|
|
|
|
# Option 1: Remove incomplete directory
|
|
# rm -rf "${problem_dir}"
|
|
|
|
# Option 2: Mark as incomplete but leave content
|
|
touch "${problem_dir}/.incomplete_extraction"
|
|
rm -f "${marker}"
|
|
done
|
|
|
|
# Return success if no archives found or all extracted successfully
|
|
if [[ ${archive_found} -eq 0 ]]; then
|
|
log_debug "No archives found in ${src}"
|
|
return 0
|
|
elif [[ ${extraction_errors} -eq 0 ]]; then
|
|
log_info "All archives extracted successfully"
|
|
return 0
|
|
else
|
|
log_warn "${extraction_errors} archives failed to extract properly"
|
|
return 1
|
|
fi
|
|
} |