#!/usr/bin/env python3 # Startdate: 2024-09-22-1 15:33 # Purpose: backend for fprintd_tk that uses fprintd-* binaries, in case I ever rewrite this to use dbus directly? # Dependencies: # /usr/bin/fprintd-* # Improve: # add a verbose/debug param to everything? import os, subprocess, re _user = os.getenv("USER") fre = re.compile ("^.* - #[0-9]+: ([^ ]+)$") prevent_success_messages = [ "no-match", "failed to claim", "not enrolled for user" ] def get_enrolled_fingers(user = None): # return list of full strings of fingers that are enrolled. enrolled_fingers = [] if user is None: user = _user proc = subprocess.Popen( ["fprintd-list",user], stdout = subprocess.PIPE, universal_newlines = True # or maybe text=True ) #print(result.stdout) while True: line = proc.stdout.readline() if not line: break if fre.match(line): #print(f"Got {fre.match(line).groups()[0]}") enrolled_fingers.append(fre.match(line).groups()[0].strip()) elif re.match("^.*No devices available.*", line): # WORKHERE: we should rerun the program in a second or two return [] else: #print(f"Not-matching: {line}",end="") pass return enrolled_fingers def fprintd_action(action, finger, status_function = None, user = None): if user is None: user = _user if action == "enroll": command = ["fprintd-enroll","-f",finger,user] elif action == "verify": command = ["fprintd-verify","-f",finger,user] elif action == "delete": command = ["fprintd-delete",user] else: if status_function: status_function(f"Invalid action {action}") return False proc = subprocess.Popen( command, stdout = subprocess.PIPE, universal_newlines = True ) old_line = "INITIAL_LINE" dupe_count = 0 while True: line = proc.stdout.readline() if not line: break display_line = line if line == old_line: dupe_count = dupe_count + 1 display_line = line.strip() + str(f" (x{dupe_count})") else: dupe_count = 1 old_line = line if status_function: status_function(display_line) # If you want to react to any lines. #if re.match("^.*verify-match (done).*",line): # proc.kill() # return "verify-match" # so the process has ended, now what? proc.kill() if status_function: if display_line: display = True for i in prevent_success_messages: if i in display_line: display = False break if display: status_function(f"Succeeded! {display_line}")