aboutsummaryrefslogtreecommitdiffstats
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.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 }'
+ '';
+ };
+}