udev-device-plug-handler: Handle Canon LiDE400

When this scanner is plugged in, we want to start `scanimage` in batch
mode with button support, scanning into a pre-defined directory. Since
plug and unplug might happen multiple times a day and batch mode
overwrites files with the same name, we use date and time to define
directory and filename.
This commit is contained in:
MasterofJOKers 2024-02-03 13:59:22 +01:00
parent 0c2dd51ac1
commit 28901649dc
1 changed files with 57 additions and 0 deletions

View File

@ -1,5 +1,7 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
from datetime import datetime
import inspect import inspect
from pathlib import Path
import subprocess import subprocess
from typing import Dict, List, Optional, Union from typing import Dict, List, Optional, Union
@ -96,6 +98,61 @@ class UsbLogitechG930(KnownDevice):
print("Handled Logitech G930 Headset") print("Handled Logitech G930 Headset")
class CanonLIDE400(KnownDevice):
"""Represents our 2023-bought Canon flatbed scanner"""
UDEV_PROPS = {'PRODUCT': '4a9/1912/100'}
__process = None
@staticmethod
def check_available() -> bool:
cmd = "lsusb | grep 'LiDE 400'"
cp = subprocess.run(cmd, shell=True, stdout=subprocess.DEVNULL)
return cp.returncode == 0
@staticmethod
def handle_bind(device: Optional[pyudev.Device] = None) -> None:
if CanonLIDE400.__process is not None:
# in theory, uplugging the Scanner should have terminated/killed the process, but if something went wrong,
# we just try to kill it and proceed
CanonLIDE400.__process.kill()
now = datetime.now()
directory = Path('/srv/paperless/later/scanned/') / now.strftime('%Y-%m-%d')
# directory = Path('/home/joker/tmp/scanned/') / now.strftime('%Y-%m-%d')
directory.mkdir(exist_ok=True)
# TODO read config from ~/.config/udev-device-plug-handler/
# How should that look like? Directory list of arguments? Would be easiest and we just default to something.
# Could be nice to read the directory from there, too.
cmd = [
'scanimage',
'-d', 'pixma:04A91912_4B9054',
'-l', '0mm',
'-t', '0mm',
'-x', '210mm',
'-y', '297mm',
'--mode=Color',
'--resolution', '300dpi',
'--button-controlled=yes',
# '-p', # progress
f"--batch=scan_{now.strftime('%H%M%S')}_%04d.pnm"
]
CanonLIDE400.__process = subprocess.Popen(cmd, stdout=subprocess.DEVNULL, cwd=directory)
print("Handled Canon LiDE 400")
@staticmethod
def handle_remove(device: pyudev.Device) -> None:
if CanonLIDE400.__process is not None:
p = CanonLIDE400.__process
p.terminate()
try:
p.wait(timeout=3)
except subprocess.TimeoutExpired:
p.kill()
print("Handled Canon LiDE 400 unplug")
@click.command() @click.command()
@click.option('--debug', is_flag=True, help='Show all device changes instead of only handled.') @click.option('--debug', is_flag=True, help='Show all device changes instead of only handled.')
def main(debug: bool) -> None: def main(debug: bool) -> None: