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
|
#!/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}")
|