refactor: improve directory handling and globbing in to-m4b.sh; update .gitignore
This commit is contained in:
		
							parent
							
								
									351ea4bb43
								
							
						
					
					
						commit
						70919f1df5
					
				
					 2 changed files with 79 additions and 33 deletions
				
			
		
							
								
								
									
										5
									
								
								.gitignore
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										5
									
								
								.gitignore
									
										
									
									
										vendored
									
									
								
							| 
						 | 
					@ -1,5 +1,6 @@
 | 
				
			||||||
out/
 | 
					**
 | 
				
			||||||
src/
 | 
					!.gitignore
 | 
				
			||||||
 | 
					!to-m4b.sh
 | 
				
			||||||
 | 
					
 | 
				
			||||||
*~
 | 
					*~
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										107
									
								
								to-m4b.sh
									
										
									
									
									
								
							
							
						
						
									
										107
									
								
								to-m4b.sh
									
										
									
									
									
								
							| 
						 | 
					@ -98,9 +98,15 @@ get-book-directories() {
 | 
				
			||||||
  # - ${SRC}/<author>/<year> - <title> {<narrator>}/
 | 
					  # - ${SRC}/<author>/<year> - <title> {<narrator>}/
 | 
				
			||||||
  # Prints matched directories, one per line
 | 
					  # Prints matched directories, one per line
 | 
				
			||||||
  local src_root="${1}"
 | 
					  local src_root="${1}"
 | 
				
			||||||
  local -a results=()
 | 
					 | 
				
			||||||
  local dir leaf
 | 
					  local dir leaf
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # Ensure globbing is enabled locally (script uses set -f globally)
 | 
				
			||||||
 | 
					  local had_noglob=0
 | 
				
			||||||
 | 
					  case $- in
 | 
				
			||||||
 | 
					    *f*) had_noglob=1 ;;
 | 
				
			||||||
 | 
					  esac
 | 
				
			||||||
 | 
					  set +f
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # Iterate candidate depths using fast globbing (avoids slow full-recursive find)
 | 
					  # Iterate candidate depths using fast globbing (avoids slow full-recursive find)
 | 
				
			||||||
  for dir in "${src_root}"/*/*/ "${src_root}"/*/*/*/; do
 | 
					  for dir in "${src_root}"/*/*/ "${src_root}"/*/*/*/; do
 | 
				
			||||||
    [[ -d "$dir" ]] || continue
 | 
					    [[ -d "$dir" ]] || continue
 | 
				
			||||||
| 
						 | 
					@ -117,12 +123,18 @@ get-book-directories() {
 | 
				
			||||||
    fi
 | 
					    fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Quick check: directory contains at least one likely audio file
 | 
					    # Quick check: directory contains at least one likely audio file
 | 
				
			||||||
    if compgen -G "$dir"*.{mp3,m4a,m4b,aac,flac,wav} >/dev/null 2>&1; then
 | 
					    local found=0 ext
 | 
				
			||||||
      results+=("${dir%/}")
 | 
					    for ext in mp3 m4a m4b aac flac wav ogg; do
 | 
				
			||||||
    fi
 | 
					      if compgen -G "$dir"*."$ext" >/dev/null 2>&1; then
 | 
				
			||||||
 | 
					        found=1
 | 
				
			||||||
 | 
					        break
 | 
				
			||||||
 | 
					      fi
 | 
				
			||||||
 | 
					    done
 | 
				
			||||||
 | 
					    (( found )) && printf '%s\n' "${dir%/}"
 | 
				
			||||||
  done
 | 
					  done
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  printf '%s\n' "${results[@]}"
 | 
					  # Restore previous noglob state
 | 
				
			||||||
 | 
					  (( had_noglob )) && set -f || true
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
m4b-merge() {
 | 
					m4b-merge() {
 | 
				
			||||||
| 
						 | 
					@ -135,21 +147,38 @@ m4b-merge() {
 | 
				
			||||||
  local series="${7}"
 | 
					  local series="${7}"
 | 
				
			||||||
  local series_index=${8}
 | 
					  local series_index=${8}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # Ensure destination directory exists
 | 
				
			||||||
  mkdir -p "$(dirname "${output_file}")"
 | 
					  mkdir -p "$(dirname "${output_file}")"
 | 
				
			||||||
  nix run github:sandreas/m4b-tool#m4b-tool-libfdk -- \
 | 
					
 | 
				
			||||||
    merge \
 | 
					  # Build args; add series flags only when present (standalone-friendly)
 | 
				
			||||||
      -v \
 | 
					  local args=(
 | 
				
			||||||
      --jobs=6 \
 | 
					    merge
 | 
				
			||||||
      --audio-samplerate=44100 \
 | 
					    -v
 | 
				
			||||||
      --audio-quality=100 \
 | 
					    --jobs=6
 | 
				
			||||||
      --writer="${author}" \
 | 
					    --audio-samplerate=44100
 | 
				
			||||||
      --artist="${narrator}" \
 | 
					    --audio-quality=100
 | 
				
			||||||
      --title="${title}" \
 | 
					  )
 | 
				
			||||||
      --year="${year}" \
 | 
					  if [[ -n "${author}" ]]; then
 | 
				
			||||||
      --album="${series}" \
 | 
					    args+=("--writer=${author}")
 | 
				
			||||||
      --album-sort="${series_index}" \
 | 
					  fi
 | 
				
			||||||
      --output-file="${output_file}/" \
 | 
					  if [[ -n "${narrator}" ]]; then
 | 
				
			||||||
      -- "${source_dir}"
 | 
					    args+=("--artist=${narrator}")
 | 
				
			||||||
 | 
					  fi
 | 
				
			||||||
 | 
					  if [[ -n "${title}" ]]; then
 | 
				
			||||||
 | 
					    args+=("--album=${title}")
 | 
				
			||||||
 | 
					  fi
 | 
				
			||||||
 | 
					  if [[ -n "${year}" ]]; then
 | 
				
			||||||
 | 
					    args+=("--year=${year}")
 | 
				
			||||||
 | 
					  fi
 | 
				
			||||||
 | 
					  if [[ -n "${series}" ]]; then
 | 
				
			||||||
 | 
					    args+=("--series=${series}")
 | 
				
			||||||
 | 
					  fi
 | 
				
			||||||
 | 
					  if [[ -n "${series_index}" ]]; then
 | 
				
			||||||
 | 
					    args+=("--series-part=${series_index}")
 | 
				
			||||||
 | 
					  fi
 | 
				
			||||||
 | 
					  args+=("--output-file=${output_file}" -- "${source_dir}")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  nix run github:sandreas/m4b-tool#m4b-tool-libfdk -- "${args[@]}"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
main() {
 | 
					main() {
 | 
				
			||||||
| 
						 | 
					@ -157,28 +186,44 @@ main() {
 | 
				
			||||||
  local out_root="${OUT:-${script_dir}/out}"
 | 
					  local out_root="${OUT:-${script_dir}/out}"
 | 
				
			||||||
  local dir author narrator title year series series_index output_file
 | 
					  local dir author narrator title year series series_index output_file
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  mapfile -t dirs < <(get-book-directories "${src_root}")
 | 
					  # Build array of directories without using mapfile (Bash 3 compatibility)
 | 
				
			||||||
 | 
					  # Portable array fill (Bash 3): split on newlines only
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    IFS=$'\n'
 | 
				
			||||||
 | 
					    dirs=($(get-book-directories "${src_root}"))
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  for dir in "${dirs[@]}"; do
 | 
					  if ((${#dirs[@]})); then
 | 
				
			||||||
    eval "$(parse-vars "$dir")"
 | 
					    for dir in "${dirs[@]}"; do
 | 
				
			||||||
    if [[ -z "$title" ]]; then
 | 
					      eval "$(parse-vars "$dir")"
 | 
				
			||||||
      echo "Skipping '$dir': could not parse title" >&2
 | 
					      if [[ -z "$title" ]]; then
 | 
				
			||||||
      continue
 | 
					        echo "Skipping '$dir': could not parse title" >&2
 | 
				
			||||||
    fi
 | 
					        continue
 | 
				
			||||||
 | 
					      fi
 | 
				
			||||||
    if [[ -z "$author" ]]; then
 | 
					    if [[ -z "$author" ]]; then
 | 
				
			||||||
      echo "Skipping '$dir': could not parse author" >&2
 | 
					      echo "Skipping '$dir': could not parse author" >&2
 | 
				
			||||||
      continue
 | 
					      continue
 | 
				
			||||||
    fi
 | 
					    fi
 | 
				
			||||||
    # Construct output path: ${OUT}/<author>/<series or standalone>/<series_index - >title {narrator}.m4b
 | 
					    # Construct output path: ${OUT}/<author>/<series or standalone>/<series_index - >title {narrator}.m4b
 | 
				
			||||||
    if [[ -n "$series" ]]; then
 | 
					    if [[ -n "$series" ]]; then
 | 
				
			||||||
      output_file="${out_root}/${author}/${series}/${series_index:+${series_index} - }${title}${narrator:+ {${narrator}}}.m4b"
 | 
					      output_file="${out_root}/${author}/${series}/"
 | 
				
			||||||
 | 
					      [[ -n "$series_index" ]] && output_file+="Book ${series_index} - "
 | 
				
			||||||
 | 
					      [[ -n "$year" ]] && output_file+="${year} - "
 | 
				
			||||||
 | 
					      output_file+="${title}"
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
      output_file="${out_root}/${author}/${year:+${year} - }${title}${narrator:+ {${narrator}}}.m4b"
 | 
					      output_file="${out_root}/${author}/"
 | 
				
			||||||
 | 
					      [[ -n "$year" ]] && output_file+="${year} - "
 | 
				
			||||||
 | 
					      output_file+="${title}"
 | 
				
			||||||
    fi
 | 
					    fi
 | 
				
			||||||
 | 
					    [[ -n "$narrator" ]] && output_file+=" {${narrator}}"
 | 
				
			||||||
 | 
					    output_file+=".m4b"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    echo "Processing '$dir' -> '$output_file'"
 | 
					      echo "Processing '$dir' -> '$output_file'"
 | 
				
			||||||
    # m4b-merge "$output_file" "$dir" "$author" "$narrator" "$title" "$year" "$series" "$series_index"
 | 
					      m4b-merge "$output_file" "$dir" "$author" "$narrator" "$title" "$year" "$series" "$series_index"
 | 
				
			||||||
  done
 | 
					    done
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					    echo "No book directories found under '${src_root}'." >&2
 | 
				
			||||||
 | 
					  fi
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
main "$@"
 | 
					main "$@"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue