-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpixma_control.sh
executable file
·140 lines (121 loc) · 3.62 KB
/
pixma_control.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#!/bin/bash
# The amount of time (in seconds) to wait before checking a button press.
POLLING_TIMEOUT=3
# Ensure that these directories exist, and that the user running the script
# has write access to these directories.
OUTPUT_DIR=/srv/samba/_scans_
# Whether to keep the original scanned PNGs when converting to PDF.
KEEP_ORIGINAL=true
# Get the device name of the scanner
#
# Input: None
# Output: Scanimage device identifier
get_device_name () {
# According to the sane-pixma man page, the device name is always formatted
# as `pixma:XXXXYYYY_ZZZZZ`.
scanimage -L | sed "s/.*\(pixma:[A-Z0-9_]*\).*/\1/"
}
# Poll which button was pressed on the scanner
#
# Input: device identifier
# Output: target status
#
# Note: If multiple buttons have been pressed between two polls, the first poll
# will return the first button pressed. A second poll will return the last
# button that was pressed. All other button presses will be lost.
poll_target () {
# According to the sane-pixma man page, the status of the buttons can be
# read from the list of options using `scanimage -A`. There doesn't seem to
# a better way of doing this.
# Furthermore, we pipe stderr to stdout to prevent the "Output format is
# not set" message.
scanimage --device-name="$1" -A 2>&1 | grep "target" \
| sed "s/.*\[\([0-9]\)\].*/\1/"
}
# Create a temporary directory to hold scans
#
# Input: None
# Output: Directory path
create_tmp_dir () {
mktemp -d -t pixma-scan-XXXXXXXX
}
# Remove the temporary directory (and its contents)
#
# Input: Temporary directory path
# Output: None
remove_tmp_dir () {
rm -rf "$1"
}
# Create a temporary filename for scans
#
# Input: Temporary directory path, extension
# Output: Incremental filename
create_filename () {
echo scan-$(ls "$1"/scan-* 2>/dev/null | wc -l)."$2"
}
# Create a scan
#
# Input: Device name, output path, resolution
# Output: None
scan_image () {
scanimage \
--device-name="$1" \
--format="png" \
--resolution="$3" \
--output-file="$2"
}
# Core loop
# Obtain the device name
device=$(get_device_name)
echo "Using scanning device $device"
# Poll the button status every POLLING_TIMEOUT seconds
while [[ -n "${device}" ]]; do
action=$(poll_target $device)
if [[ $action -ne 0 ]]; then
echo "Scan request received. Action $action."
# Setup the scanning parameters
if [[ -z "${tmp_dir}" ]]; then
tmp_dir=$(create_tmp_dir)
resolution=300
echo "Temporary directory at $tmp_dir."
fi
# Start scanning
output_path="$tmp_dir/$(create_filename $tmp_dir png)"
echo "Scanning $output_path"
scan_image $device $output_path $resolution
# If we are making a copy, send it to the printer
if [[ $action -eq 1 ]]; then
echo "Printing $output_path"
lp "$output_path"
fi
# Save files if we are not creating a batch PDF
if [[ $action -ne 4 ]]; then
filename="scan-$(date +'%F-%H-%M-%S')"
# If we hit the send button, we want to convert to PDF and move it
if [[ $action -eq 3 ]]; then
echo "Converting scans to PDF and moving."
convert "$tmp_dir/*.png" -compress jpeg \
-quality 75 "$tmp_dir/out.pdf"
mv "$tmp_dir/out.pdf" \
"$OUTPUT_DIR/$filename.pdf"
# If we want to keep the original PNGs, we'll need to move them too
if $KEEP_ORIGINAL; then
echo "Moving original PNGs."
mkdir -p "$OUTPUT_DIR/_raw_/$filename"
cp "$tmp_dir/"* "$OUTPUT_DIR/_raw_/$filename"
fi
# Otherwise, we just want to move the scan
else
echo "Moving scan."
mv $output_path \
"$OUTPUT_DIR/$filename.png"
fi
# Delete the temporary directory
echo "Cleaning up."
remove_tmp_dir $tmp_dir
unset tmp_dir
fi
echo "Ready."
fi
sleep $POLLING_TIMEOUT
done