about summary refs log blame commit diff stats
path: root/sys/nixpkgs/pkgs/scripts/source/apps/con2pdf.sh
blob: 08bf8998ff1bf8e03ac0eca6ed4d1b54970c42e5 (plain) (tree)
1
2
3
4
5
6
7
8
9
                    
 
                             
                                                   
 
                               
                 
                         
            
                         
               
 

                           
        
             

                                     
                                   
 
                         
                                                                                   



                                                                       
                                                                               
                        
                                                     
                        
                                                                      
 
                                                       
 
                                                                               
          
                                  
                                                                        
                                      









                                                                                        
   
 
            


                                         


                                                                                                                                                              
                                                    



                                                

                         
 
                 
                                   
                                                                  
                                                    
                                              
                     
                                                                                    
                                   
                                     
          
                                                          
 
 
                

                       


                                                                                                              
                                                    



                                                

                         
 
             
                          
                                   
                                              
                           
                                                    
                     
                                                                     
                                     
          
                                                          
 
                  

                    
 
          
                           
                                   
                            
                        
 
                                                                               
        
                                   
                                                                          
 
        



                                          





                                                                                
                                
                                     
                             




                                                 
                                      
                                       
                                      





                                                                            
                     






                       

        



                             

                        























                                                                        
        
           
    
                                                                       
#! /usr/bin/env dash

# shellcheck source=/dev/null
SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH

# needed for help() and version
# shellcheck disable=2034
AUTHORS="Soispha"
# shellcheck disable=2034
YEARS="2023"
# shellcheck disable=2034
VERSION="1.0.0"

# NAME is from the wrapper
# shellcheck disable=SC2269
NAME="$NAME"
help() {
    cat <<EOF
Scan images and turn them into a pdf.

Usage:
    $NAME [OPTIONS] --name --device

OPTIONS:
    --out-dir | -o [FILE]
                            Path to place the generated pdf files (default: ./pdf).

    --name | -n NAME
                            Name for the pdf files (e.g. <NAME>_1.pdf).

    --num-pages | -p NUM
                            Number of pages to merge into one pdf (default: 1).

    --device | -d DEVICE
                            Device used for scanning.

    --method | -m METHOD
                            Method to use for scanning (default: ADF).

    --help | -h
                            Display this help and exit.

    --version | -v
                            Display version and copyright information and exit.
ARGUMENTS:
    FILE := [[fd . --max-depth 3]]
                            A name of a file to store, default is: ./pdf

    NAME | * := [[fd . --max-depth 3]]
                            The basename of the generated files

    NUM | *([0-9]) := 0 | 1 | 2 | 3 | 4
                            Possible numbers of pages, can be more than 4

    DEVICE := [[$(cat %DEVICE_FUNCTION)]]
                            Possible scanner names

    METHOD := ADF | Flatbed
                            The scanning method to use, not all scanners support both of
                            these. The default is ADF
EOF
}

scan_adf() {
    device="$1"
    sides_per_page="$2"
    method="ADF"
    for i in $(seq "$sides_per_page"); do
        do_until_success \
            "scanimage --format=tiff --progress --source='$method' --device='$device' --batch=%d.tif --batch-increment='$sides_per_page' --batch-start='$i'" \
            "warn 'Retrying scan, as we assume a network error!'"

        if [ "$sides_per_page" -ne 1 ]; then
            msg "Finished turn, please change side!"
            readp "Press enter to continue" noop
        fi
    done
}
process_images_adf() {
    tiff_temp_path="$1"
    output_directory="$2"
    name="$3"

    counter=0
    pdf_counter=0
    image_cache="$(mktmp)"
    while read -r scanned_image; do
        dbg "$scanned_image (scanned_image) at $counter (counter)"
        echo "$scanned_image" >>"$image_cache"
        : $((counter += 1))
        if [ "$counter" = "$number_of_pages" ]; then
            dbg "$counter == $number_of_pages"
            counter=0
            convert_images "$image_cache" "${name}_$pdf_counter" "$output_directory"
            : $((pdf_counter += 1))
            printf "" >"$image_cache"
        fi
    done <"$(tmp_pipe fd . "$tiff_temp_path" "|" sort -V)"
}

scan_flatbed() {
    device="$1"
    number_of_pages"$2"
    method="Flatbed"
    for i in $(seq "$number_of_pages"); do
        do_until_success \
            "scanimage --format=tiff --progress --source='$method' --device='$device' --output-file=$i.tiff" \
            "warn 'Retrying scan, as we assume a network error!'"
        if [ "$number_of_pages" -ne 1 ]; then
            msg "Finished turn, please change side!"
            readp "Press enter to continue" noop
        fi
    done
}
process_images_flatbed() {
    tiff_temp_path="$1"
    output_directory="$2"
    name="$3"

    counter=0
    image_cache="$(mktmp)"
    while read -r scanned_image; do
        echo "$scanned_image" >>"$image_cache"
        : $((counter += 1))
        if [ "$counter" = "$number_of_pages" ]; then
            counter=0
            convert_images "$image_cache" "$name" "$output_directory"
            printf "" >"$image_cache"
        fi
    done <"$(tmp_pipe fd . "$tiff_temp_path" "|" sort -V)"
}
convert_images() {
    image_cache="$1"
    pdf_name="$2"
    output_dir="$3"

    set --
    while read -r image; do
        dbg "setting image: $image"
        set -- "$@" "$image"
    done <"$image_cache"

    while [ -e "$output_dir/${pdf_name}.pdf" ]; do
        pdf_name="${pdf_name}_$(tr -dc 'A-Za-z0-9' </dev/urandom | head -c 25)"
    done
    dbg "using pdf_name: $pdf_name"
    convert "$@" -compress jpeg -quality 100 "$output_dir/${pdf_name}.pdf"
}

scan() {
    number_of_pages="$1"
    device="$2"
    output_directory="$(readlink -f "$3")"
    name="$4"
    method="$5"

    [ -z "$number_of_pages" ] && die "Parameter 'number_of_pages' is not set!"
    [ -z "$device" ] && die "Parameter 'device' is not set!"
    [ -z "$output_directory" ] && die "Parameter 'output_directory' is not set!"
    [ -z "$name" ] && die "Parameter 'name' is not set!"
    [ -z "$method" ] && die "Parameter 'method' is not set!"

    tiff_temp_path="$(mktmp -d)"
    cd "$tiff_temp_path" || die "Bug"

    msg "Started scanning..."
    if [ "$method" = "Flatbed" ]; then
        scan_flatbed "$device" "$number_of_pages"
    else
        scan_adf "$device" "$number_of_pages"
    fi

    msg "Creating output directory..."
    mkdir "$output_directory"
    cd "$output_directory" || die "Bug"

    msg "Converting images to pdfs..."
    if [ "$method" = "Flatbed" ]; then
        process_images_flatbed "$tiff_temp_path" "$output_directory" "$name"
    else
        process_images_adf "$tiff_temp_path" "$output_directory" "$name"
    fi
}

for input in "$@"; do
    case "$input" in
    "--help" | "-h")
        help
        exit 0
        ;;
    "--version" | "-v")
        version
        exit 0
        ;;
    esac
done

number_of_pages="1"
unset device
output_directory="$(pwd)/pdf"
unset name
method="ADF"

while [ "$#" -ne 0 ]; do
    case "$1" in
    "--help" | "-h") ;;
    "--version" | "-v") ;;
    "--out-dir" | "-o")
        shift 1
        output_directory="$1"
        ;;
    "--name" | "-n")
        shift 1
        name="$1"
        ;;
    "--num-pages" | "-p")
        shift 1
        number_of_pages="$1"
        ;;
    "--device" | "-d")
        shift 1
        device="$1"
        ;;
    "--method" | "-m")
        shift 1
        method="$1"
        ;;
    *)
        die "Command line arg $1 does not exist. See --help for a list."
        ;;
    esac
    shift 1
done
scan "$number_of_pages" "$device" "$output_directory" "$name" "$method"