Last active
August 29, 2015 14:13
-
-
Save prurigro/ee68ecdb6e34aa295bc7 to your computer and use it in GitHub Desktop.
A zbar wrapper utility to read barcodes from various sources
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
# | |
# CodeGet: A zbar wrapper utility to read barcodes from various sources | |
# | |
# Version: 1.4.8 | |
# | |
# Written by Kevin MacMartin and released under the MIT license | |
# | |
# Requirements: | |
# base64 | converts to and from base64 encoding | |
# file | detect information about files | |
# fswebcam | grabs images from the webcam | |
# scrot | grabs screenshots from the desktop | |
# xclip | saves decoded text to the clipboard | |
# zbar (zbarimg) | decodes text from barcodes | |
# | |
# Store /dev/stdin in $stdin if any input is given | |
[[ $(file /dev/fd/0) =~ pipe:\[[0-9]*\]$ ]] \ | |
&& stdin=$(base64 /dev/stdin) | |
# Variables | |
script_name="${0//*\/}" | |
temp_file="/tmp/${script_name}.tmp.jpeg" | |
zbar_args='--raw' | |
dependencies=('base64' 'file' 'fswebcam' 'scrot' 'xclip' 'zbarimg') | |
# Colours | |
[[ -t 1 ]] && { | |
c_d=$'\e[1;30m' # GREY | |
c_r=$'\e[1;31m' # RED | |
c_g=$'\e[1;32m' # GREEN | |
c_y=$'\e[1;33m' # YELLOW | |
c_b=$'\e[1;34m' # BLUE | |
c_m=$'\e[1;35m' # VIOLET | |
c_t=$'\e[1;36m' # TEAL | |
c_w=$'\e[1;37m' # WHITE | |
c_c=$'\e[0m' # DISABLES COLOUR | |
} | |
# Function: display help and exit with a status of $1 | |
function help() { | |
printf '\n%s\n\n' "${c_m}CodeGet$c_c: Scan visible zbar-compatible barcodes from the screen" | |
printf '%s\n' "${c_b}USAGE$c_c" | |
printf ' %s %s %s\n\n' "$c_y$script_name" "$c_d[${c_b}OPTION$c_d]" "$c_d[${c_r}FILE$c_d]$c_c" | |
printf '%s\n' "${c_b}OPTIONS$c_c" | |
printf ' %-20s %s\n' "$c_w-c → $c_c" 'output to the clipboard instead of stdout' | |
printf ' %-20s %s\n' "$c_w-v → $c_c" 'include barcode metadata in the output' | |
printf ' %-20s %s\n' "$c_w-w → $c_c" 'use the webcam as an input source' | |
printf ' %-20s %s\n\n' "$c_w-h → $c_c" 'display this help and exit' | |
printf '%s\n' "${c_b}SOURCES$c_c" | |
printf ' %-18s %s\n' "${c_m}display$c_c" "the current ${c_m}display$c_c is scanned by default" | |
printf ' %-18s %s\n' "${c_m}file$c_c" "a ${c_m}file$c_c is scanned when provided as an argument" | |
printf ' %-18s %s\n' "${c_m}stdin$c_c" "an image file sent to ${c_m}stdin$c_c is used when provided" | |
printf ' %-18s %s\n\n' "${c_m}webcam$c_c" "the webcam is scanned when the $c_w-w$c_c flag is set" | |
exit "$1" | |
} | |
# Function: display $1 (and help if set by $2), then exit with an failed status | |
function error_exit() { | |
printf '\n%s %s\n' "${c_r}ERROR:$c_c" "$1" >&2 | |
if [[ "$2" = 'help' ]]; then | |
help 1 | |
else | |
printf '\n' | |
fi | |
exit 1 | |
} | |
# Test for programs required by this script before running | |
declare -a missing_dependencies=() | |
for dep in "${dependencies[@]}"; do | |
type -P "$dep" >/dev/null \ | |
|| missing_dependencies=( ${missing_dependencies[@]} "$dep" ) | |
done | |
[[ -n "${missing_dependencies[*]}" ]] && { | |
error_exit "${c_w}missing dependencies ($( | |
for (( x=0; x < ${#missing_dependencies[@]}; x++ )); do | |
printf '%s' "$c_m${missing_dependencies[$x]}$c_c" | |
(( (( x + 1 )) < ${#missing_dependencies[@]} )) && printf '%s' ', ' | |
done | |
)$c_w)$c_c" | |
} | |
# Unset variables that should be set by parsed arguments | |
unset clipboard input_source input_file zbar_verbose | |
# Read stdin into $stdin and set as the input source if it's an image | |
[[ -n "$stdin" && $(file - < <(base64 -d <<< "$stdin")) =~ image\ data ]] \ | |
&& input_source=stdin | |
# Parse command-line arguments to set config variables to the values selected by the user | |
while (( "$#" )); do | |
case "$1" in | |
-c) | |
clipboard=1 | |
;; | |
-w) | |
input_source=webcam | |
;; | |
-v) | |
zbar_verbose=1 | |
;; | |
-h|--help) | |
help 0 | |
;; | |
*) | |
[[ -f "$1" ]] \ | |
|| error_exit "$1 is not a file or valid argument" 'help' | |
[[ -z "$input_source" ]] && { | |
input_source=file | |
input_file="$1" | |
} | |
;; | |
esac | |
shift | |
done | |
# Add the quiet flag if verbose hasn't been set | |
(( "$zbar_verbose" )) \ | |
|| zbar_args+=' -q' | |
# Set the input source to display if one hasn't already been set | |
[[ -z "$input_source" ]] \ | |
&& input_source=display | |
# Remove the old temporary image file if one exists | |
[[ -f "$temp_file" ]] \ | |
&& rm "$temp_file" | |
# Set the number of tries attempts to make based on input type | |
if [[ "$input_source" = 'webcam' ]]; then | |
maxtries=8 | |
else | |
maxtries=1 | |
fi | |
# Attempt to decode input source barcodes until successful or reaching $maxtries | |
tries=0; while [[ -z "$code_text" ]]; do | |
# Exit the loop if $tries >= $maxtries, otherwise add one to $tries | |
(( tries >= maxtries )) && break | |
(( tries++ )) | |
# Create the temporary image file using the selected input source | |
case "$input_source" in | |
display) | |
# input_source: display | |
scrot "$temp_file" | |
;; | |
file) | |
# input_source: file | |
cp "$input_file" "$temp_file" | |
;; | |
stdin) | |
# input_source: stdin | |
base64 -d <<< "$stdin" > "$temp_file" | |
;; | |
webcam) | |
# input_source: webcam | |
fswebcam -q -r 1280x720 "$temp_file" | |
;; | |
esac | |
# Exit with an error if $temp_file doesn't exist | |
[[ -f "$temp_file" ]] \ | |
|| error_exit "Failed to save $temp_file" | |
# Decode barcodes contained in the temporary image file | |
code_text="$(zbarimg $zbar_args "$temp_file")" | |
done | |
# Clean up the temporary image file | |
[[ -f "$temp_file" ]] \ | |
&& rm "$temp_file" | |
# Send the decoded text to the clipboard or stdout | |
[[ -n "$code_text" ]] && { | |
if (( "$clipboard" )); then | |
printf '%s' "$code_text" | xclip -in -selection clipboard | |
else | |
printf '%s\n' "$code_text" | |
fi | |
} | |
# Exit successfully | |
exit 0 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment