/
scanimages
executable file
·116 lines (107 loc) · 4.52 KB
/
scanimages
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
#!/usr/bin/env python3
# jbin - Joe's miscellaneous scripts, tools and configs
# scanimages: Scan a bunch of images and convert them/name them correctly
# Copyright (C) 2020-2021 Johannes Bauer
#
# This file is part of jbin.
#
# jbin is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; this program is ONLY licensed under
# version 3 of the License, later versions are explicitly excluded.
#
# jbin is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with jbin. If not, see <http://www.gnu.org/licenses/>.
#
# Johannes Bauer <JohannesBauer@gmx.de>
import os
import sys
import json
import subprocess
import collections
import tempfile
import shutil
from FriendlyArgumentParser import FriendlyArgumentParser
parser = FriendlyArgumentParser(description = "Simple scanning application.")
parser.add_argument("--create-config", action = "store_true", help = "Create example configuration file if it does not yet exist.")
parser.add_argument("-c", "--config", metavar = "filename", default = "~/.config/jbin/scanimages.json", help = "Configuration filename to use. Defaults to %(default)s.")
parser.add_argument("-v", "--verbose", action = "count", default = 0, help = "Increases verbosity. Can be specified multiple times to increase.")
parser.add_argument("profile", metavar = "profile", type = str, nargs = "?", help = "Name of scanning profile. Defaults to 'default' if there is only one profile present.")
args = parser.parse_args(sys.argv[1:])
if args.profile is None:
profile = "default"
else:
profile = args.profile
config_filename = os.path.expanduser(args.config)
if args.create_config and (not os.path.exists(args.config)):
config = collections.OrderedDict((
("default", collections.OrderedDict((
("device", "devicename:001"),
("filename", "page_%03d.png"),
("resolution", 300),
("mode", "color"),
("offset_mm", [ 0, 0 ]),
("size_mm", [ 210, 297 ]),
))),
("foo", collections.OrderedDict((
("device", "multipager:001"),
("filename", "page_%03d.png"),
("resolution", 150),
("mode", "gray"),
("offset_mm", [ 0, 0 ]),
("size_mm", [ 210, 297 ]),
("multipage", True),
("include_page_size", True),
))),
))
with open(config_filename, "w") as f:
json.dump(config, f, indent = 4)
f.write("\n")
with open(config_filename) as f:
config = json.load(f)
if profile not in config:
print("No such profile: %s (have only %s)." % (profile, ", ".join(sorted(config))), file = sys.stderr)
sys.exit(1)
config = config[profile]
file_format = os.path.splitext(config["filename"])[1].lstrip(".")
dev_str = config.get("device", "default device")
pages_scanned = 0
while True:
multipage = config.get("multipage", False)
input("%d pages scanned so far. Ready to scan next %s on %s (mode %s with %d dpi)? Press ENTER to continue..." % (pages_scanned, "batch" if multipage else "page", dev_str, config["mode"], config["resolution"]))
with tempfile.TemporaryDirectory() as tmpdir:
cmd = [ "scanimage" ]
cmd += [ "--format=%s" % (file_format) ]
if "device" in config:
cmd += [ "-d", config["device"] ]
cmd += [ "--resolution", str(config["resolution"]), "--mode", config["mode"] ]
if "source" in config:
cmd += [ "--source=%s" % (config["source"]) ]
if "offset_mm" in config:
cmd += [ "-l", str(config["offset_mm"][0]), "-t", str(config["offset_mm"][1]) ]
if "size_mm" in config:
cmd += [ "-x", str(config["size_mm"][0]), "-y", str(config["size_mm"][1]) ]
if config.get("include_page_size"):
cmd += [ "--page-width=%s" % (config["size_mm"][0]), "--page-height=%s" % (config["size_mm"][1]) ]
if config.get("multipage"):
cmd += [ "--batch=%s/output%%05d.%s" % (tmpdir, file_format) ]
else:
cmd += [ "-o", "%s/output.%s" % (tmpdir, file_format) ]
next_filename = config["filename"] % (pages_scanned + 1)
try:
print("Scanning: %s" % (next_filename))
subprocess.check_call(cmd)
except subprocess.CalledProcessError as e:
print("Failed scan: %s" % (e))
filenames = sorted(os.listdir(tmpdir))
print("Scanned %d page(s)." % (len(filenames)))
for filename in filenames:
src_filename = "%s/%s" % (tmpdir, filename)
dst_filename = config["filename"] % (pages_scanned + 1)
shutil.move(src_filename, dst_filename)
pages_scanned += 1