aboutsummaryrefslogtreecommitdiff
path: root/fprintd_tk.py
diff options
context:
space:
mode:
authorB. Stack <bgstack15@gmail.com>2024-09-22 20:41:52 -0400
committerB. Stack <bgstack15@gmail.com>2024-09-22 20:41:52 -0400
commit6ab41891eacbfa910e73c7d521df01ab395d015c (patch)
treef916232de6a62ce2fb36422c7bef11b50fb5d9bc /fprintd_tk.py
downloadfprintd-tk-6ab41891eacbfa910e73c7d521df01ab395d015c.tar.gz
fprintd-tk-6ab41891eacbfa910e73c7d521df01ab395d015c.tar.bz2
fprintd-tk-6ab41891eacbfa910e73c7d521df01ab395d015c.zip
initial commit
Diffstat (limited to 'fprintd_tk.py')
-rwxr-xr-xfprintd_tk.py149
1 files changed, 149 insertions, 0 deletions
diff --git a/fprintd_tk.py b/fprintd_tk.py
new file mode 100755
index 0000000..8fe0ab6
--- /dev/null
+++ b/fprintd_tk.py
@@ -0,0 +1,149 @@
+#!/usr/bin/env python3
+# Startdate: 2024-09-22-1 14:26
+# Purpose: tkinter desktop gui app for management fingerprint enrollments
+# Dependencies:
+# python3-tkstackrpms, python3-tk, python3-pil
+# References:
+# stackrpms_tk.py
+# Improve:
+# implement delete
+# implement enroll
+#
+
+import tkinter as tk, os, tkinter.filedialog, sys, threading
+import tkstackrpms as stk
+import fprintd_tk_lib as lib
+from PIL import Image, ImageTk
+
+# todo: load images array?
+
+ABOUT_TEXT = """
+fprintd_tk \"Gui for fprintd\"
+(C) 2024 bgstack15
+SPDX-License-Identifier: GPL-3.0-only
+Icons adapted from Numix-Icon-Theme-Circle (GPL 3)
+"""
+
+# configurable by admin
+img_path = os.path.join(os.path.dirname(os.path.realpath(__file__)),"images")
+
+# These will be used a lot in the program.
+str_hands = ["left","right"]
+str_fingers = ["thumb","index-finger","middle-finger","ring-finger","little-finger"]
+str_all = []
+for h in str_hands:
+ for f in str_fingers:
+ str_all.append(f"{h}-{f}")
+
+class App(tk.Frame):
+ def __init__(self, master):
+ super().__init__(master)
+ self.master.title("Gui for fprintd")
+ imgicon = stk.get_scaled_icon("fingerprint-gui",24,"default", "","apps")
+ self.master.tk.call("wm","iconphoto",self.master._w,imgicon)
+ menu = tk.Menu(self.master)
+ menu_file = tk.Menu(menu,tearoff=0)
+ menu_file.add_command(label="Delete...", command=self.func_delete, underline=0)
+ menu_file.add_separator()
+ menu_file.add_command(label="Exit", command=self.func_exit, underline=1)
+ menu.add_cascade(label="File",menu=menu_file,underline=0)
+ menu_help = tk.Menu(menu,tearoff=0)
+ menu_help.add_command(label="About", command=self.func_about, underline=0)
+ menu.add_cascade(label="Help",menu=menu_help,underline=0)
+ self.master.config(menu=menu)
+ self.grid() # use this instead of pack()
+
+ # statusbar variable
+ self.statustext = tk.StringVar()
+
+ # prepare finger images
+ try:
+ img_path + ""
+ except:
+ img_path = os.path.join(os.path.dirname(os.path.realpath(__file__)),"images")
+ self.img_notenrolled = ImageTk.PhotoImage(stk.image_from_svg(os.path.join(img_path,"fingerprint-gui.svg"),32))
+ self.img_enrolled = ImageTk.PhotoImage(stk.image_from_svg(os.path.join(img_path,"fingerprint-enrolled.svg"),32))
+
+ self.frm_actions = tk.Frame(self.master)
+ self.frm_actions.grid(row=0,column=0)
+ self.action = tk.IntVar(value=1)
+ stk.Radiobutton(self.frm_actions,value=1,text="enroll",variable=self.action,underline=0).grid(row=0,column=0)
+ stk.Radiobutton(self.frm_actions,value=2,text="verify",variable=self.action,underline=0).grid(row=1,column=0)
+
+ # array of fingers
+ # we want 2 rows, 5 columns
+ self.frm_fingers = tk.Frame(self.master)
+ self.frm_fingers.grid(row=0,column=1)
+ self.fingers = []
+ hand = 0
+ while hand < 2:
+ finger = 0
+ while finger < 5:
+ fnum = finger if hand==1 else len(str_fingers)-finger-1
+ #print(f"While preparing hand {hand}, evaluating finger {finger}, which might need to be number {fnum}")
+ tf = str_hands[hand] + "-" + str_fingers[fnum]
+ self.fingers.append(tk.Button(self.frm_fingers,text=tf,padx=0,pady=0,command=lambda f=tf: self.func_finger_button(f),image=self.img_notenrolled,compound="top"))
+ self.fingers[-1].grid(row=hand,column=finger)
+ finger = finger + 1
+ hand = hand + 1
+ # because the underline business does not work on the radio button itself
+ # somehow the keypress takse over the lambda first var, so just set a dummy value, and pass our useful value as second parameter.
+ self.master.bind("<Alt-e>",lambda a=1,b=1: self.set_action(a,b))
+ self.master.bind("<Alt-v>",lambda a=1,b=2: self.set_action(a,b))
+
+ # status bar
+ stk.StatusBar(self.master,var=self.statustext)
+ # and now, load data into form for the first time
+ self.load_data_into_form()
+
+ def set_action(self, keypress, a):
+ #print(f"DEBUG: got keypress {keypress}, a={a}")
+ # this is used by Alt+E, Alt+V to select the radio buttons for enroll, verify, etc.
+ self.action.set(a)
+
+ def load_data_into_form(self):
+ self.enrolled_fingers = lib.get_enrolled_fingers()
+ print(f"DEBUG (load_data_into_form): got enrolled fingers {self.enrolled_fingers}")
+ for i in self.fingers:
+ if str(i.cget('text')) in self.enrolled_fingers:
+ i.config(image=self.img_enrolled)
+ else:
+ i.config(image=self.img_notenrolled)
+
+ # functions
+ def func_about(self):
+ """ Display about dialog. """
+ tk.messagebox.Message(title="About",message=ABOUT_TEXT,icon="info").show()
+
+ def func_exit(self):
+ # in case we need to manually do stuff
+ # otherwise command=self.client_exit would have sufficed.
+ self.master.quit()
+
+ def func_finger_button(self, finger):
+ print(f"DEBUG: func_finger_button finger {finger}, action {self.action.get()}")
+ action = self.action.get()
+ if 1 == action: # enroll
+ try:
+ # WORKHERE: pass a tk text var to set for intermediate operations?
+ self.statustext.set(lib.enroll_finger(finger, self.func_update_status))
+ except Exception as e:
+ self.statustext.set(e)
+ elif 2 == action: # verify
+ #print(f"stub action: verify, finger {finger}")
+ t1 = threading.Thread(target=lib.verify_finger,args=(finger, self.func_update_status))
+ t1.run()
+ self.load_data_into_form()
+
+ def func_update_status(self, msg):
+ msg = msg.strip()
+ print(f"DEBUG: func_update_status called with msg {msg}",file=sys.stderr)
+ self.statustext.set(msg)
+
+ def func_delete(self):
+ print(f"stub, please ask user if he is certain to delete all enrolled fingerprints")
+
+# main
+root = tk.Tk()
+fprintd_tk = App(root)
+fprintd_tk.mainloop()
bgstack15