Commit 08ec9e9643a6

Vincent Demeester <vincent@sbr.pm>
2025-12-15 12:03:05
style(pkgs): Reformat audible-converter script with consistent indentation
- Convert spaces to tabs for consistent code style - Align function formatting throughout the script - Improve readability without changing functionality Signed-off-by: Vincent Demeester <vincent@sbr.pm>
1 parent 9f66914
Changed files (1)
pkgs
audible-converter
pkgs/audible-converter/convert.sh
@@ -10,7 +10,7 @@ OUTPUT_DIR="${AUDIBLE_OUTPUT_DIR:-$HOME/audiobooks}"
 QUALITY="${AUDIBLE_QUALITY:-best}"
 FORMAT="${AUDIBLE_FORMAT:-m4b}"
 AUTHCODE="${AUDIBLE_AUTHCODE:-}"
-CLEANUP_ON_EXIT="${AUDIBLE_CLEANUP_ON_EXIT:-false}"  # Set to 'true' to auto-cleanup temp files
+CLEANUP_ON_EXIT="${AUDIBLE_CLEANUP_ON_EXIT:-false}" # Set to 'true' to auto-cleanup temp files
 
 # Colors for output
 RED='\033[0;31m'
@@ -20,20 +20,20 @@ NC='\033[0m' # No Color
 
 # Logging functions
 log_info() {
-    echo -e "${GREEN}[INFO]${NC} $*"
+	echo -e "${GREEN}[INFO]${NC} $*"
 }
 
 log_warn() {
-    echo -e "${YELLOW}[WARN]${NC} $*"
+	echo -e "${YELLOW}[WARN]${NC} $*"
 }
 
 log_error() {
-    echo -e "${RED}[ERROR]${NC} $*"
+	echo -e "${RED}[ERROR]${NC} $*"
 }
 
 # Usage information
 usage() {
-    cat <<EOF
+	cat <<EOF
 Usage: $(basename "$0") [OPTIONS] [COMMAND]
 
 Audible to Audiobookshelf converter - Downloads and converts audiobooks
@@ -79,347 +79,351 @@ EOF
 
 # Check dependencies
 check_dependencies() {
-    local deps=("audible" "aaxtomp3" "ffmpeg" "mediainfo" "jq")
-    local missing=()
+	local deps=("audible" "aaxtomp3" "ffmpeg" "mediainfo" "jq")
+	local missing=()
 
-    for dep in "${deps[@]}"; do
-        if ! command -v "$dep" &> /dev/null; then
-            missing+=("$dep")
-        fi
-    done
+	for dep in "${deps[@]}"; do
+		if ! command -v "$dep" &>/dev/null; then
+			missing+=("$dep")
+		fi
+	done
 
-    if [ ${#missing[@]} -ne 0 ]; then
-        log_error "Missing required dependencies: ${missing[*]}"
-        log_error "Please install: nix-shell -p audible-cli aaxtomp3 ffmpeg mediainfo jq"
-        exit 1
-    fi
+	if [ ${#missing[@]} -ne 0 ]; then
+		log_error "Missing required dependencies: ${missing[*]}"
+		log_error "Please install: nix-shell -p audible-cli aaxtomp3 ffmpeg mediainfo jq"
+		exit 1
+	fi
 }
 
 # Check if authenticated with Audible
 check_auth() {
-    if ! audible library list &> /dev/null; then
-        log_error "Not authenticated with Audible"
-        log_error "Please run: audible quickstart"
-        exit 1
-    fi
+	if ! audible library list &>/dev/null; then
+		log_error "Not authenticated with Audible"
+		log_error "Please run: audible quickstart"
+		exit 1
+	fi
 }
 
 # Create directories
 setup_dirs() {
-    mkdir -p "$TEMP_DIR"
-    mkdir -p "$OUTPUT_DIR"
+	mkdir -p "$TEMP_DIR"
+	mkdir -p "$OUTPUT_DIR"
 }
 
 # Cleanup temporary files (manual or via AUDIBLE_CLEANUP_ON_EXIT=true)
 # By default, we keep temp files to reuse downloaded AAX files on subsequent runs
 cleanup() {
-    if [ -d "$TEMP_DIR" ]; then
-        log_info "Cleaning up temporary files in: $TEMP_DIR"
-        rm -rf "$TEMP_DIR"
-        log_info "Cleanup complete"
-    fi
+	if [ -d "$TEMP_DIR" ]; then
+		log_info "Cleaning up temporary files in: $TEMP_DIR"
+		rm -rf "$TEMP_DIR"
+		log_info "Cleanup complete"
+	fi
 }
 
 # Download entire library
 download_all() {
-    log_info "Exporting library metadata..."
-    local library_json="$TEMP_DIR/library.json"
+	log_info "Exporting library metadata..."
+	local library_json="$TEMP_DIR/library.json"
 
-    audible library export --format json --output "$library_json"
+	audible library export --format json --output "$library_json"
 
-    local total_books
-    total_books=$(jq length "$library_json")
-    log_info "Found $total_books books in library"
+	local total_books
+	total_books=$(jq length "$library_json")
+	log_info "Found $total_books books in library"
 
-    local count=0
-    jq -r '.[].asin' "$library_json" | while read -r asin; do
-        count=$((count + 1))
-        log_info "Downloading book $count/$total_books (ASIN: $asin)..."
+	local count=0
+	jq -r '.[].asin' "$library_json" | while read -r asin; do
+		count=$((count + 1))
+		log_info "Downloading book $count/$total_books (ASIN: $asin)..."
 
-        if ! audible download \
-            --asin "$asin" \
-            --aax \
-            --quality "$QUALITY" \
-            --output-dir "$TEMP_DIR" 2>&1; then
-            log_warn "Failed to download ASIN: $asin (may already be downloaded)"
-        fi
-    done
+		if ! audible download \
+			--asin "$asin" \
+			--aax-fallback \
+			--chapter \
+			--annotation \
+			--pdf \
+			--cover \
+			--quality "$QUALITY" \
+			--output-dir "$TEMP_DIR" 2>&1; then
+			log_warn "Failed to download ASIN: $asin (may already be downloaded)"
+		fi
+	done
 }
 
 # Download specific book by ASIN
 download_book() {
-    local asin="$1"
-    log_info "Downloading book ASIN: $asin..."
+	local asin="$1"
+	log_info "Downloading book ASIN: $asin..."
 
-    audible download \
-        --asin "$asin" \
-        --aax \
-        --quality "$QUALITY" \
-        --output-dir "$TEMP_DIR"
+	audible download \
+		--asin "$asin" \
+		--aax \
+		--quality "$QUALITY" \
+		--output-dir "$TEMP_DIR"
 }
 
 # Convert AAX files to M4B
 # Usage: convert_books [directory|file]
 convert_books() {
-    local source_path="${1:-$TEMP_DIR}"
-    local aax_files=()
+	local source_path="${1:-$TEMP_DIR}"
+	local aax_files=()
 
-    # Determine if we're converting a directory or a single file
-    if [ -d "$source_path" ]; then
-        # Find all AAX files in directory using find
-        log_info "Searching for AAX files in: $source_path"
-        mapfile -t aax_files < <(find "$source_path" -maxdepth 1 -type f -name "*.aax" -o -name "*.AAX")
+	# Determine if we're converting a directory or a single file
+	if [ -d "$source_path" ]; then
+		# Find all AAX files in directory using find
+		log_info "Searching for AAX files in: $source_path"
+		mapfile -t aax_files < <(find "$source_path" -maxdepth 1 -type f -name "*.aax" -o -name "*.AAX")
 
-        if [ ${#aax_files[@]} -eq 0 ]; then
-            log_warn "No AAX files found in $source_path"
-            return 0
-        fi
-        log_info "Found ${#aax_files[@]} AAX file(s)"
-    elif [ -f "$source_path" ]; then
-        # Single file
-        aax_files=("$source_path")
-    else
-        log_error "Invalid path: $source_path"
-        return 1
-    fi
+		if [ ${#aax_files[@]} -eq 0 ]; then
+			log_warn "No AAX files found in $source_path"
+			return 0
+		fi
+		log_info "Found ${#aax_files[@]} AAX file(s)"
+	elif [ -f "$source_path" ]; then
+		# Single file
+		aax_files=("$source_path")
+	else
+		log_error "Invalid path: $source_path"
+		return 1
+	fi
 
-    local total_files=${#aax_files[@]}
-    log_info "Converting $total_files AAX file(s) to $FORMAT format..."
+	local total_files=${#aax_files[@]}
+	log_info "Converting $total_files AAX file(s) to $FORMAT format..."
 
-    # Get authcode (either provided or from audible-cli)
-    local authcode="$AUTHCODE"
-    if [ -z "$authcode" ]; then
-        # Try to get activation bytes from audible-cli
-        log_info "Attempting to retrieve activation bytes from audible-cli..."
-        if authcode=$(audible activation-bytes 2>/dev/null); then
-            if [ -n "$authcode" ]; then
-                log_info "Using activation bytes from audible-cli: $authcode"
-            else
-                log_warn "Activation bytes command succeeded but returned empty value"
-                authcode=""
-            fi
-        else
-            log_warn "Could not retrieve activation bytes from audible-cli"
-            authcode=""
-        fi
-    fi
+	# Get authcode (either provided or from audible-cli)
+	local authcode="$AUTHCODE"
+	if [ -z "$authcode" ]; then
+		# Try to get activation bytes from audible-cli
+		log_info "Attempting to retrieve activation bytes from audible-cli..."
+		if authcode=$(audible activation-bytes 2>/dev/null); then
+			if [ -n "$authcode" ]; then
+				log_info "Using activation bytes from audible-cli: $authcode"
+			else
+				log_warn "Activation bytes command succeeded but returned empty value"
+				authcode=""
+			fi
+		else
+			log_warn "Could not retrieve activation bytes from audible-cli"
+			authcode=""
+		fi
+	fi
 
-    # Base aaxtomp3 options (no --batch, we'll loop instead)
-    local aaxtomp3_opts=(--target_dir "$OUTPUT_DIR" --no-clobber)
+	# Base aaxtomp3 options (no --batch, we'll loop instead)
+	local aaxtomp3_opts=(--target_dir "$OUTPUT_DIR" --no-clobber)
 
-    # Add authcode if available, otherwise use audible-cli data
-    if [ -n "$authcode" ]; then
-        aaxtomp3_opts+=(--authcode "$authcode")
-    else
-        log_warn "No authcode available, trying --use-audible-cli-data flag"
-        aaxtomp3_opts+=(--use-audible-cli-data)
-    fi
+	# Add authcode if available, otherwise use audible-cli data
+	if [ -n "$authcode" ]; then
+		aaxtomp3_opts+=(--authcode "$authcode")
+	else
+		log_warn "No authcode available, trying --use-audible-cli-data flag"
+		aaxtomp3_opts+=(--use-audible-cli-data)
+	fi
 
-    case "$FORMAT" in
-        m4b)
-            aaxtomp3_opts+=(--single)
-            ;;
-        mp3)
-            aaxtomp3_opts+=(--codec libmp3lame)
-            ;;
-        m4a)
-            # Default M4A output
-            ;;
-        *)
-            log_error "Unknown format: $FORMAT"
-            exit 1
-            ;;
-    esac
+	case "$FORMAT" in
+	m4b)
+		aaxtomp3_opts+=(--single)
+		;;
+	mp3)
+		aaxtomp3_opts+=(--codec libmp3lame)
+		;;
+	m4a)
+		# Default M4A output
+		;;
+	*)
+		log_error "Unknown format: $FORMAT"
+		exit 1
+		;;
+	esac
 
-    # Convert each file individually (--batch doesn't work with --authcode)
-    # Note: --no-clobber flag makes aaxtomp3 skip existing files automatically
-    local converted=0
-    local failed=0
-    local current=0
+	# Convert each file individually (--batch doesn't work with --authcode)
+	# Note: --no-clobber flag makes aaxtomp3 skip existing files automatically
+	local converted=0
+	local failed=0
+	local current=0
 
-    log_info "Starting conversion loop for ${#aax_files[@]} files..."
+	log_info "Starting conversion loop for ${#aax_files[@]} files..."
 
-    for aax_file in "${aax_files[@]}"; do
-        local base_filename
-        base_filename=$(basename "$aax_file")
-        current=$((current + 1))
+	for aax_file in "${aax_files[@]}"; do
+		local base_filename
+		base_filename=$(basename "$aax_file")
+		current=$((current + 1))
 
-        log_info "[$current/$total_files] Converting: $base_filename"
-        echo "----------------------------------------"
+		log_info "[$current/$total_files] Converting: $base_filename"
+		echo "----------------------------------------"
 
-        # Run aaxtomp3 directly (let output flow to terminal)
-        # Temporarily disable exit-on-error for this command
-        set +e
-        aaxtomp3 "${aaxtomp3_opts[@]}" "$aax_file"
-        local exit_code=$?
-        set -e
+		# Run aaxtomp3 directly (let output flow to terminal)
+		# Temporarily disable exit-on-error for this command
+		set +e
+		aaxtomp3 "${aaxtomp3_opts[@]}" "$aax_file"
+		local exit_code=$?
+		set -e
 
-        if [ $exit_code -eq 0 ]; then
-            converted=$((converted + 1))
-            log_info "✓ Successfully converted: $base_filename"
-        else
-            failed=$((failed + 1))
-            log_warn "✗ Failed to convert: $base_filename (exit code: $exit_code)"
-        fi
-        echo ""
-    done
+		if [ $exit_code -eq 0 ]; then
+			converted=$((converted + 1))
+			log_info "✓ Successfully converted: $base_filename"
+		else
+			failed=$((failed + 1))
+			log_warn "✗ Failed to convert: $base_filename (exit code: $exit_code)"
+		fi
+		echo ""
+	done
 
-    # Report summary
-    local skipped=$((total_files - converted - failed))
-    log_info "Conversion complete!"
-    log_info "  Converted: $converted/$total_files"
-    if [ $skipped -gt 0 ]; then
-        log_info "  Skipped: $skipped/$total_files (already existed)"
-    fi
-    if [ $failed -gt 0 ]; then
-        log_warn "  Failed: $failed/$total_files"
-        log_error ""
-        log_error "If you got 'Missing authcode' errors, follow these steps:"
-        log_error "  1. Authenticate with Audible:"
-        log_error "     audible quickstart"
-        log_error ""
-        log_error "  2. Verify activation bytes are available:"
-        log_error "     audible activation-bytes"
-        log_error ""
-        log_error "  3. Alternatively, provide authcode manually:"
-        log_error "     --authcode YOUR_ACTIVATION_BYTES"
-        log_error "     or: export AUDIBLE_AUTHCODE=YOUR_ACTIVATION_BYTES"
-        exit 1
-    fi
-    log_info "Books saved to: $OUTPUT_DIR"
+	# Report summary
+	local skipped=$((total_files - converted - failed))
+	log_info "Conversion complete!"
+	log_info "  Converted: $converted/$total_files"
+	if [ $skipped -gt 0 ]; then
+		log_info "  Skipped: $skipped/$total_files (already existed)"
+	fi
+	if [ $failed -gt 0 ]; then
+		log_warn "  Failed: $failed/$total_files"
+		log_error ""
+		log_error "If you got 'Missing authcode' errors, follow these steps:"
+		log_error "  1. Authenticate with Audible:"
+		log_error "     audible quickstart"
+		log_error ""
+		log_error "  2. Verify activation bytes are available:"
+		log_error "     audible activation-bytes"
+		log_error ""
+		log_error "  3. Alternatively, provide authcode manually:"
+		log_error "     --authcode YOUR_ACTIVATION_BYTES"
+		log_error "     or: export AUDIBLE_AUTHCODE=YOUR_ACTIVATION_BYTES"
+		exit 1
+	fi
+	log_info "Books saved to: $OUTPUT_DIR"
 }
 
 # List Audible library
 list_library() {
-    log_info "Fetching Audible library..."
-    audible library list | jq -r '.[] | "\(.title) by \(.authors) (ASIN: \(.asin))"'
+	log_info "Fetching Audible library..."
+	audible library list | jq -r '.[] | "\(.title) by \(.authors) (ASIN: \(.asin))"'
 }
 
 # Sync library (download and convert new books)
 sync_library() {
-    log_info "Syncing Audible library..."
-    download_all
-    convert_books
+	log_info "Syncing Audible library..."
+	download_all
+	convert_books
 }
 
 # Main function
 main() {
-    local command="sync"
-    local -a positional_args=()
+	local command="sync"
+	local -a positional_args=()
 
-    # Parse arguments
-    while [[ $# -gt 0 ]]; do
-        case $1 in
-            -o|--output)
-                OUTPUT_DIR="$2"
-                shift 2
-                ;;
-            -t|--temp)
-                TEMP_DIR="$2"
-                shift 2
-                ;;
-            -q|--quality)
-                QUALITY="$2"
-                shift 2
-                ;;
-            -f|--format)
-                FORMAT="$2"
-                shift 2
-                ;;
-            -a|--authcode)
-                AUTHCODE="$2"
-                shift 2
-                ;;
-            -h|--help)
-                usage
-                exit 0
-                ;;
-            download-all|download|convert|sync|list)
-                command="$1"
-                shift
-                ;;
-            -*)
-                log_error "Unknown option: $1"
-                usage
-                exit 1
-                ;;
-            *)
-                # Collect positional arguments (file paths, ASINs, etc.)
-                positional_args+=("$1")
-                shift
-                ;;
-        esac
-    done
+	# Parse arguments
+	while [[ $# -gt 0 ]]; do
+		case $1 in
+		-o | --output)
+			OUTPUT_DIR="$2"
+			shift 2
+			;;
+		-t | --temp)
+			TEMP_DIR="$2"
+			shift 2
+			;;
+		-q | --quality)
+			QUALITY="$2"
+			shift 2
+			;;
+		-f | --format)
+			FORMAT="$2"
+			shift 2
+			;;
+		-a | --authcode)
+			AUTHCODE="$2"
+			shift 2
+			;;
+		-h | --help)
+			usage
+			exit 0
+			;;
+		download-all | download | convert | sync | list)
+			command="$1"
+			shift
+			;;
+		-*)
+			log_error "Unknown option: $1"
+			usage
+			exit 1
+			;;
+		*)
+			# Collect positional arguments (file paths, ASINs, etc.)
+			positional_args+=("$1")
+			shift
+			;;
+		esac
+	done
 
-    # Optionally cleanup on exit (default: keep files for reuse)
-    if [ "$CLEANUP_ON_EXIT" = "true" ]; then
-        log_info "Auto-cleanup enabled (AUDIBLE_CLEANUP_ON_EXIT=true)"
-        trap cleanup EXIT
-    else
-        log_info "Keeping temp files in $TEMP_DIR for reuse (set AUDIBLE_CLEANUP_ON_EXIT=true to auto-delete)"
-    fi
+	# Optionally cleanup on exit (default: keep files for reuse)
+	if [ "$CLEANUP_ON_EXIT" = "true" ]; then
+		log_info "Auto-cleanup enabled (AUDIBLE_CLEANUP_ON_EXIT=true)"
+		trap cleanup EXIT
+	else
+		log_info "Keeping temp files in $TEMP_DIR for reuse (set AUDIBLE_CLEANUP_ON_EXIT=true to auto-delete)"
+	fi
 
-    # Check dependencies
-    check_dependencies
+	# Check dependencies
+	check_dependencies
 
-    # Setup directories
-    setup_dirs
+	# Setup directories
+	setup_dirs
 
-    # Execute command
-    case $command in
-        download-all)
-            check_auth
-            download_all
-            ;;
-        download)
-            if [ ${#positional_args[@]} -eq 0 ]; then
-                log_error "ASIN required for download command"
-                usage
-                exit 1
-            fi
-            check_auth
-            download_book "${positional_args[0]}"
-            ;;
-        convert)
-            if [ ${#positional_args[@]} -eq 0 ]; then
-                log_error "File or directory path required for convert command"
-                usage
-                exit 1
-            fi
-            # Get the last positional argument as the path
-            local convert_path="${positional_args[-1]}"
-            if [ ! -e "$convert_path" ]; then
-                log_error "Path not found: $convert_path"
-                exit 1
-            fi
+	# Execute command
+	case $command in
+	download-all)
+		check_auth
+		download_all
+		;;
+	download)
+		if [ ${#positional_args[@]} -eq 0 ]; then
+			log_error "ASIN required for download command"
+			usage
+			exit 1
+		fi
+		check_auth
+		download_book "${positional_args[0]}"
+		;;
+	convert)
+		if [ ${#positional_args[@]} -eq 0 ]; then
+			log_error "File or directory path required for convert command"
+			usage
+			exit 1
+		fi
+		# Get the last positional argument as the path
+		local convert_path="${positional_args[-1]}"
+		if [ ! -e "$convert_path" ]; then
+			log_error "Path not found: $convert_path"
+			exit 1
+		fi
 
-            # If it's a directory, convert all AAX files in it
-            # If it's a file, convert just that specific file
-            if [ -d "$convert_path" ]; then
-                log_info "Converting all AAX files in directory: $convert_path"
-                convert_books "$convert_path"
-            elif [ -f "$convert_path" ]; then
-                log_info "Converting single file: $(basename "$convert_path")"
-                convert_books "$convert_path"
-            else
-                log_error "Path must be a file or directory: $convert_path"
-                exit 1
-            fi
-            ;;
-        sync)
-            check_auth
-            sync_library
-            ;;
-        list)
-            check_auth
-            list_library
-            ;;
-        *)
-            log_error "Unknown command: $command"
-            usage
-            exit 1
-            ;;
-    esac
+		# If it's a directory, convert all AAX files in it
+		# If it's a file, convert just that specific file
+		if [ -d "$convert_path" ]; then
+			log_info "Converting all AAX files in directory: $convert_path"
+			convert_books "$convert_path"
+		elif [ -f "$convert_path" ]; then
+			log_info "Converting single file: $(basename "$convert_path")"
+			convert_books "$convert_path"
+		else
+			log_error "Path must be a file or directory: $convert_path"
+			exit 1
+		fi
+		;;
+	sync)
+		check_auth
+		sync_library
+		;;
+	list)
+		check_auth
+		list_library
+		;;
+	*)
+		log_error "Unknown command: $command"
+		usage
+		exit 1
+		;;
+	esac
 }
 
 # Run main function