From 5ab622371316380046a9427b2a06f9ab45757350 Mon Sep 17 00:00:00 2001 From: Justin Yao Du Date: Sat, 7 Aug 2021 20:51:24 -0700 Subject: [PATCH] Initial commit --- LICENSE.md | 21 +++++ README.md | 31 +++++++ demo.png | Bin 0 -> 17132 bytes iscanimage | 263 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 315 insertions(+) create mode 100644 LICENSE.md create mode 100644 README.md create mode 100644 demo.png create mode 100755 iscanimage diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..a89f010 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,21 @@ +# MIT License + +Copyright (c) 2021 Justin Yao Du + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..bf0ecb6 --- /dev/null +++ b/README.md @@ -0,0 +1,31 @@ +# iscanimage + +`iscanimage` is an user-friendly command line program for operating scanner devices in Linux. It uses `scanimage` to do the actual scanning, as the name implies, but it adds many quality-of-life improvements for interactive use. + +## Features + +* Select a scanner device interactively +* Scan multiple files in one session +* Save all scanned files to a specified directory +* Name each file as you go (defaults to the current date and time) +* Evaluate custom commands before and after scanning each file + +## Installation + +Download the [iscanimage](iscanimage) script, make it executable, and drop it somewhere on your `$PATH`. + +## Usage + +Here's an example user session: + +![iscanimage demo in the terminal](demo.png) + +Try `iscanimage --help` for more details. + +## To Do + +* Create a proper manpage + +## License + +`iscanimage` is licensed under the [MIT License](LICENSE.md). diff --git a/demo.png b/demo.png new file mode 100644 index 0000000000000000000000000000000000000000..f129619ae6f6ad47e62ee6e53adf9fa97921d937 GIT binary patch literal 17132 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 rAETs&3RVpbPJtbzAhO+z*+159d1d 0 )); then + echog "Scanned ${num_scanned} file(s) to output directory: '${output_dir}'" + fi +} + +color_init() { + if [ ! "${colorize}" ]; then + [ -t 1 ] && colorize=1 || colorize=0 + fi + + if (( colorize )); then + c0="$(tput sgr0)" + cr="$(tput setaf 1)" + cg="$(tput setaf 2)" + cy="$(tput setaf 3)" + else + c0='' + cr='' + cg='' + cy='' + fi +} + +echor() { + echo "${cr}${1}${c0}" +} + +echog() { + echo "${cg}${1}${c0}" +} + +echoy() { + echo "${cy}${1}${c0}" +} + +parse_options() { + while (( ${#} )); do + case "${1}" in + -O|--output-dir|\ + -f|--format|\ + -d|--device|--device-name|\ + -B|--before|\ + -A|--after) + if (( ${#} < 2 )); then + die_usage "Option '${1}' requires an argument." + fi + parse_option_arg "${1}" "${2}" + shift + ;; + -l|-L|--list-devices) + load_devices + exit 0 + ;; + --color) + colorize=1 + ;; + --no-color) + colorize=0 + ;; + -v|--verbose) + verbose=1 + ;; + --) + shift + scanimage_options=("${@}") + return + ;; + -h|--help) + echo "${help_msg}" + exit 0 + ;; + --version) + echo "${version_msg}" + exit 0 + ;; + -*) + die_usage "Unrecognized option '${1}'." + ;; + *) + die_usage "Unexpected argument '${1}'." + ;; + esac + shift + done +} + +parse_option_arg() { + case "${1}" in + -O|--output-dir) + if [ ! -d "${2}" ]; then + echo "Output directory does not exist: '${2}'" + exit 1 + fi + output_dir="${2}" + ;; + -f|--format) + output_format="${2}" + ;; + -d|--device|--device-name) + selected_device="${2}" + ;; + -B|--before) + run_before="${2}" + ;; + -A|--after) + run_after="${2}" + ;; + esac +} + +die_usage() { + echo "${1}" + echo "Try '${name} --help' for more information." + exit 2 +} + +main() { + parse_options "${@}" + color_init + [ "${selected_device}" ] || select_device + scan_loop +} + +main "${@}"