From 818be928385a060441d2517f6ae32d2e830f3c8a Mon Sep 17 00:00:00 2001 From: boltgolt Date: Tue, 13 Feb 2018 23:22:13 +0100 Subject: [PATCH] Commented everything --- README.md | 2 +- autocomplete.sh | 3 +++ cli.py | 10 +++++++++- cli/add.py | 14 +++++++++++--- cli/clear.py | 8 ++++++++ cli/help.py | 2 ++ cli/list.py | 14 ++++++++++++++ cli/remove.py | 18 ++++++++++++++++++ compare.py | 5 +++++ installer.py | 2 +- 10 files changed, 72 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 931a046..14af4b9 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ Run the installer by pasting (`ctrl+shift+V`) the following command into the ter wget -O /tmp/howdy_install.py https://raw.githubusercontent.com/Boltgolt/howdy/master/installer.py && sudo python3 /tmp/howdy_install.py ``` -This will guide you through the installation. When that's done run `howdy add` to add a face model for the current user. +This will guide you through the installation. When that's done run `howdy USER add` and replace `USER` with your username to add a face model. If nothing went wrong we should be able to run sudo by just showing your face. Open a new terminal and run `sudo -i` to see it in action. diff --git a/autocomplete.sh b/autocomplete.sh index 117ba6e..8c16937 100644 --- a/autocomplete.sh +++ b/autocomplete.sh @@ -1,3 +1,6 @@ +# Autocomplete file run in bash +# Will sugest arguments on tab + _howdy() { local cur prev opts COMPREPLY=() diff --git a/cli.py b/cli.py index b25a8c3..e820426 100755 --- a/cli.py +++ b/cli.py @@ -1,19 +1,26 @@ #!/usr/bin/env python3 + +# CLI directly called by running the howdy command + +# Import required modules import sys import os +# Check if the minimum of 3 arugemnts has been met and print help otherwise if (len(sys.argv) < 3): print("Howdy IR face recognition help") import cli.help sys.exit() -user = sys.argv[1] +# The command given cmd = sys.argv[2] +# Requre sudo for comamnds that need root rights to read the model files if cmd in ["list", "add", "remove", "clear"] and os.getenv("SUDO_USER") is None: print("Please run this command with sudo") sys.exit() +# Call the right files for the given command if cmd == "list": import cli.list elif cmd == "help": @@ -26,6 +33,7 @@ elif cmd == "remove": elif cmd == "clear": import cli.clear else: + # If the comand is invalid, check if the user hasn't swapped the username and command if sys.argv[1] in ["list", "add", "remove", "clear", "help"]: print("Usage: howdy ") else: diff --git a/cli/add.py b/cli/add.py index f4fe2cb..9b2e6d9 100644 --- a/cli/add.py +++ b/cli/add.py @@ -6,19 +6,21 @@ import time import os import sys import json - -# Import config import configparser + +# Try to import face_recognition and give a nice error if we can't +# Add should be the first point where import issues show up try: import face_recognition except ImportError as err: print(err) - print("\nCan't import face_recognition module, check the output of") + print("\nCan't import the face_recognition module, check the output of") print("pip3 show face_recognition") sys.exit() +# Get the absolute path to the current file path = os.path.dirname(os.path.abspath(__file__)) # Read config from disk @@ -87,16 +89,21 @@ except FileNotFoundError: print("Adding face model for the user account " + user) +# Set the default label label = "Initial model" +# If models already exist, set that default label if len(encodings) > 0: label = "Model #" + str(len(encodings) + 1) +# Ask the user for a custom label label_in = input("Enter a label for this new model [" + label + "]: ") +# Set the custom label (if any) and limit it to 24 characters if label_in != "": label = label_in[:24] +# Prepare the metadata for insertion insert_model = { "time": int(time.time()), "label": label, @@ -114,6 +121,7 @@ for delay in [30, 6, 0]: time.sleep(.3) captureFrame(delay) +# Insert full object into the list encodings.append(insert_model) # Save the new encodings to disk diff --git a/cli/clear.py b/cli/clear.py index 3d12715..4cd56c2 100644 --- a/cli/clear.py +++ b/cli/clear.py @@ -1,3 +1,6 @@ +# Clear all models by deleting the whole file + +# Import required modules import os import sys @@ -6,20 +9,25 @@ path = os.path.dirname(os.path.abspath(__file__)) # Get the passed user user = sys.argv[1] +# Check if the models folder is there if not os.path.exists(path + "/../models"): print("No models created yet, can't clear them if they don't exist") sys.exit() +# Check if the user has a models file to delete if not os.path.isfile(path + "/../models/" + user + ".dat"): print(user + " has no models or they have been cleared already") sys.exit() +# Double check with the user print("This will clear all models for " + user) ans = input("Do you want to continue [y/N]: ") +# Abort if they don't answer y or Y if (ans.lower() != "y"): print('\nInerpeting as a "NO"') sys.exit() +# Delete otherwise os.remove(path + "/../models/" + user + ".dat") print("\nModels cleared") diff --git a/cli/help.py b/cli/help.py index 3b7641e..2b09848 100644 --- a/cli/help.py +++ b/cli/help.py @@ -1,3 +1,5 @@ +# Prints a simple help page for the CLI + print(""" Usage: howdy [argument] diff --git a/cli/list.py b/cli/list.py index 64e7480..ff37b10 100644 --- a/cli/list.py +++ b/cli/list.py @@ -1,18 +1,25 @@ +# List all models for a user + +# Import required modules import sys import os import json import time +# Get the absolute path and the username path = os.path.dirname(os.path.realpath(__file__)) + "/.." user = sys.argv[1] +# Check if the models file has been created yet if not os.path.exists(path + "/models"): print("Face models have not been initialized yet, please run:") print("\n\thowdy " + user + " add\n") sys.exit(1) +# Path to the models file enc_file = path + "/models/" + user + ".dat" +# Try to load the models file and abort if the user does not have it yet try: encodings = json.load(open(enc_file)) except FileNotFoundError: @@ -20,13 +27,20 @@ except FileNotFoundError: print("\n\thowdy " + user + " add\n") sys.exit(1) +# Print a header print("Known face models for " + user + ":") print("\n\t\033[1;29mID Date Label\033[0m") +# Loop through all encodings and print info about them for enc in encodings: + # Start with a tab and print the id print("\t" + str(enc["id"]), end="") + # Print padding spaces after the id print((4 - len(str(enc["id"]))) * " ", end="") + # Format the time as ISO in the local timezone print(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(enc["time"])), end="") + # End with the label print(" " + enc["label"]) +# Add a closing enter print() diff --git a/cli/remove.py b/cli/remove.py index e4edf6a..4322839 100644 --- a/cli/remove.py +++ b/cli/remove.py @@ -1,23 +1,31 @@ +# Remove a encoding from the models file + +# Import required modules import sys import os import json +# Get the absolute path and the username path = os.path.dirname(os.path.realpath(__file__)) + "/.." user = sys.argv[1] +# Check if enough arguments have been passed if len(sys.argv) == 3: print("Please add the ID of the model to remove as an argument") print("You can find the IDs by running:") print("\n\thowdy " + user + " list\n") sys.exit(1) +# Check if the models file has been created yet if not os.path.exists(path + "/models"): print("Face models have not been initialized yet, please run:") print("\n\thowdy " + user + " add\n") sys.exit(1) +# Path to the models file enc_file = path + "/models/" + user + ".dat" +# Try to load the models file and abort if the user does not have it yet try: encodings = json.load(open(enc_file)) except FileNotFoundError: @@ -25,35 +33,45 @@ except FileNotFoundError: print("\n\thowdy " + user + " add\n") sys.exit(1) +# Tracks if a encoding with that id has been found found = False +# Loop though all encodings and check if they match the argument for enc in encodings: if str(enc["id"]) == sys.argv[3]: + # Double check with the user print('This will remove the model called "' + enc["label"] + '" for ' + user) ans = input("Do you want to continue [y/N]: ") + # Abort if the answer isn't yes if (ans.lower() != "y"): print('\nInerpeting as a "NO"') sys.exit() + # Mark as found and print an enter found = True print() break +# Abort if no matching id was found if not found: print("No model with ID " + sys.argv[3] + " exists for " + user) sys.exit() +# Remove the entire file if this encoding is the only one if len(encodings) == 1: os.remove(path + "/models/" + user + ".dat") print("Removed last model, howdy disabled for user") else: + # A place holder to contain the encodings that will remain new_encodings = [] + # Loop though all encodin and only add thos that don't need to be removed for enc in encodings: if str(enc["id"]) != sys.argv[3]: new_encodings.append(enc) + # Save this new set to disk with open(enc_file, "w") as datafile: json.dump(new_encodings, datafile) diff --git a/compare.py b/compare.py index 6c5adc4..101f9fe 100644 --- a/compare.py +++ b/compare.py @@ -73,12 +73,17 @@ while True: # Don't remove ret, it doesn't work without it ret, frame = video_capture.read() + # Get the height and with of the image height, width = frame.shape[:2] + # If the hight is too high if max_height < height: + # Calculate the amount the image has to shrink scaling_factor = max_height / float(height) + # Apply that factor to the frame frame = cv2.resize(frame, None, fx=scaling_factor, fy=scaling_factor, interpolation=cv2.INTER_AREA) + # Save the new size for diagnostics scale_height, scale_width = frame.shape[:2] # Convert from BGR to RGB diff --git a/installer.py b/installer.py index fc876a2..7759d71 100644 --- a/installer.py +++ b/installer.py @@ -80,7 +80,7 @@ handleStatus(subprocess.call(["rm", "-rf", "/tmp/dlib_clone"])) log("Installing face_recognition") -handleStatus(subprocess.call(["pip3", "install", "face_recognition", "sty"])) +handleStatus(subprocess.call(["pip3", "install", "face_recognition"])) log("Cloning howdy")