about summary refs log tree commit diff stats
path: root/pkgs/by-name/co/con2pdf
diff options
context:
space:
mode:
authorBenedikt Peetz <benedikt.peetz@b-peetz.de>2024-05-23 13:26:22 +0200
committerBenedikt Peetz <benedikt.peetz@b-peetz.de>2024-05-23 13:26:22 +0200
commit204731c0a69136c9cebcb54f1afecf5145e26bbe (patch)
treefc9132e5dc74e4a8e1327cdd411839a90f9410aa /pkgs/by-name/co/con2pdf
parentrefactor(sys): Modularize and move to `modules/system` or `pkgs` (diff)
downloadnixos-config-204731c0a69136c9cebcb54f1afecf5145e26bbe.tar.gz
nixos-config-204731c0a69136c9cebcb54f1afecf5145e26bbe.zip
refactor(pkgs): Categorize into `by-name` shards
This might not be the perfect way to organize a package set --
especially if the set is not nearly the size of nixpkgs -- but it is
_at_ least a way of organization.
Diffstat (limited to 'pkgs/by-name/co/con2pdf')
-rwxr-xr-xpkgs/by-name/co/con2pdf/con2pdf.sh234
-rw-r--r--pkgs/by-name/co/con2pdf/package.nix33
2 files changed, 267 insertions, 0 deletions
diff --git a/pkgs/by-name/co/con2pdf/con2pdf.sh b/pkgs/by-name/co/con2pdf/con2pdf.sh
new file mode 100755
index 00000000..08bf8998
--- /dev/null
+++ b/pkgs/by-name/co/con2pdf/con2pdf.sh
@@ -0,0 +1,234 @@
+#! /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"
diff --git a/pkgs/by-name/co/con2pdf/package.nix b/pkgs/by-name/co/con2pdf/package.nix
new file mode 100644
index 00000000..8eb994fd
--- /dev/null
+++ b/pkgs/by-name/co/con2pdf/package.nix
@@ -0,0 +1,33 @@
+{
+  sysLib,
+  writeText,
+  # dependencies
+  sane-backends,
+  imagemagick,
+  coreutils,
+  fd,
+}:
+sysLib.writeShellScript {
+  name = "con2pdf";
+  src = ./con2pdf.sh;
+  generateCompletions = true;
+  keepPath = false;
+  dependencies = [
+    sane-backends
+    imagemagick
+    coreutils
+    fd
+  ];
+  replacementStrings = {
+    DEVICE_FUNCTION =
+      # This is here, because escaping the whole function, to use it in the shell script
+      # directly just isn't possible
+      writeText "DEVICE_FUNCTION"
+      /*
+      bash
+      */
+      ''
+        scanimage -L | awk 'BEGIN { FS = "`" } { gsub(/'.*/, "", $2); print $2 }'
+      '';
+  };
+}