Commented everything

This commit is contained in:
boltgolt 2018-02-13 23:22:13 +01:00
parent d7f8510226
commit 818be92838
10 changed files with 72 additions and 6 deletions

View file

@ -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 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. 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.

View file

@ -1,3 +1,6 @@
# Autocomplete file run in bash
# Will sugest arguments on tab
_howdy() { _howdy() {
local cur prev opts local cur prev opts
COMPREPLY=() COMPREPLY=()

10
cli.py
View file

@ -1,19 +1,26 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# CLI directly called by running the howdy command
# Import required modules
import sys import sys
import os import os
# Check if the minimum of 3 arugemnts has been met and print help otherwise
if (len(sys.argv) < 3): if (len(sys.argv) < 3):
print("Howdy IR face recognition help") print("Howdy IR face recognition help")
import cli.help import cli.help
sys.exit() sys.exit()
user = sys.argv[1] # The command given
cmd = sys.argv[2] 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: if cmd in ["list", "add", "remove", "clear"] and os.getenv("SUDO_USER") is None:
print("Please run this command with sudo") print("Please run this command with sudo")
sys.exit() sys.exit()
# Call the right files for the given command
if cmd == "list": if cmd == "list":
import cli.list import cli.list
elif cmd == "help": elif cmd == "help":
@ -26,6 +33,7 @@ elif cmd == "remove":
elif cmd == "clear": elif cmd == "clear":
import cli.clear import cli.clear
else: 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"]: if sys.argv[1] in ["list", "add", "remove", "clear", "help"]:
print("Usage: howdy <user> <command>") print("Usage: howdy <user> <command>")
else: else:

View file

@ -6,19 +6,21 @@ import time
import os import os
import sys import sys
import json import json
# Import config
import configparser 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: try:
import face_recognition import face_recognition
except ImportError as err: except ImportError as err:
print(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") print("pip3 show face_recognition")
sys.exit() sys.exit()
# Get the absolute path to the current file
path = os.path.dirname(os.path.abspath(__file__)) path = os.path.dirname(os.path.abspath(__file__))
# Read config from disk # Read config from disk
@ -87,16 +89,21 @@ except FileNotFoundError:
print("Adding face model for the user account " + user) print("Adding face model for the user account " + user)
# Set the default label
label = "Initial model" label = "Initial model"
# If models already exist, set that default label
if len(encodings) > 0: if len(encodings) > 0:
label = "Model #" + str(len(encodings) + 1) label = "Model #" + str(len(encodings) + 1)
# Ask the user for a custom label
label_in = input("Enter a label for this new model [" + 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 != "": if label_in != "":
label = label_in[:24] label = label_in[:24]
# Prepare the metadata for insertion
insert_model = { insert_model = {
"time": int(time.time()), "time": int(time.time()),
"label": label, "label": label,
@ -114,6 +121,7 @@ for delay in [30, 6, 0]:
time.sleep(.3) time.sleep(.3)
captureFrame(delay) captureFrame(delay)
# Insert full object into the list
encodings.append(insert_model) encodings.append(insert_model)
# Save the new encodings to disk # Save the new encodings to disk

View file

@ -1,3 +1,6 @@
# Clear all models by deleting the whole file
# Import required modules
import os import os
import sys import sys
@ -6,20 +9,25 @@ path = os.path.dirname(os.path.abspath(__file__))
# Get the passed user # Get the passed user
user = sys.argv[1] user = sys.argv[1]
# Check if the models folder is there
if not os.path.exists(path + "/../models"): if not os.path.exists(path + "/../models"):
print("No models created yet, can't clear them if they don't exist") print("No models created yet, can't clear them if they don't exist")
sys.exit() sys.exit()
# Check if the user has a models file to delete
if not os.path.isfile(path + "/../models/" + user + ".dat"): if not os.path.isfile(path + "/../models/" + user + ".dat"):
print(user + " has no models or they have been cleared already") print(user + " has no models or they have been cleared already")
sys.exit() sys.exit()
# Double check with the user
print("This will clear all models for " + user) print("This will clear all models for " + user)
ans = input("Do you want to continue [y/N]: ") ans = input("Do you want to continue [y/N]: ")
# Abort if they don't answer y or Y
if (ans.lower() != "y"): if (ans.lower() != "y"):
print('\nInerpeting as a "NO"') print('\nInerpeting as a "NO"')
sys.exit() sys.exit()
# Delete otherwise
os.remove(path + "/../models/" + user + ".dat") os.remove(path + "/../models/" + user + ".dat")
print("\nModels cleared") print("\nModels cleared")

View file

@ -1,3 +1,5 @@
# Prints a simple help page for the CLI
print(""" print("""
Usage: Usage:
howdy <user> <command> [argument] howdy <user> <command> [argument]

View file

@ -1,18 +1,25 @@
# List all models for a user
# Import required modules
import sys import sys
import os import os
import json import json
import time import time
# Get the absolute path and the username
path = os.path.dirname(os.path.realpath(__file__)) + "/.." path = os.path.dirname(os.path.realpath(__file__)) + "/.."
user = sys.argv[1] user = sys.argv[1]
# Check if the models file has been created yet
if not os.path.exists(path + "/models"): if not os.path.exists(path + "/models"):
print("Face models have not been initialized yet, please run:") print("Face models have not been initialized yet, please run:")
print("\n\thowdy " + user + " add\n") print("\n\thowdy " + user + " add\n")
sys.exit(1) sys.exit(1)
# Path to the models file
enc_file = path + "/models/" + user + ".dat" enc_file = path + "/models/" + user + ".dat"
# Try to load the models file and abort if the user does not have it yet
try: try:
encodings = json.load(open(enc_file)) encodings = json.load(open(enc_file))
except FileNotFoundError: except FileNotFoundError:
@ -20,13 +27,20 @@ except FileNotFoundError:
print("\n\thowdy " + user + " add\n") print("\n\thowdy " + user + " add\n")
sys.exit(1) sys.exit(1)
# Print a header
print("Known face models for " + user + ":") print("Known face models for " + user + ":")
print("\n\t\033[1;29mID Date Label\033[0m") print("\n\t\033[1;29mID Date Label\033[0m")
# Loop through all encodings and print info about them
for enc in encodings: for enc in encodings:
# Start with a tab and print the id
print("\t" + str(enc["id"]), end="") print("\t" + str(enc["id"]), end="")
# Print padding spaces after the id
print((4 - len(str(enc["id"]))) * " ", end="") 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="") print(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(enc["time"])), end="")
# End with the label
print(" " + enc["label"]) print(" " + enc["label"])
# Add a closing enter
print() print()

View file

@ -1,23 +1,31 @@
# Remove a encoding from the models file
# Import required modules
import sys import sys
import os import os
import json import json
# Get the absolute path and the username
path = os.path.dirname(os.path.realpath(__file__)) + "/.." path = os.path.dirname(os.path.realpath(__file__)) + "/.."
user = sys.argv[1] user = sys.argv[1]
# Check if enough arguments have been passed
if len(sys.argv) == 3: if len(sys.argv) == 3:
print("Please add the ID of the model to remove as an argument") print("Please add the ID of the model to remove as an argument")
print("You can find the IDs by running:") print("You can find the IDs by running:")
print("\n\thowdy " + user + " list\n") print("\n\thowdy " + user + " list\n")
sys.exit(1) sys.exit(1)
# Check if the models file has been created yet
if not os.path.exists(path + "/models"): if not os.path.exists(path + "/models"):
print("Face models have not been initialized yet, please run:") print("Face models have not been initialized yet, please run:")
print("\n\thowdy " + user + " add\n") print("\n\thowdy " + user + " add\n")
sys.exit(1) sys.exit(1)
# Path to the models file
enc_file = path + "/models/" + user + ".dat" enc_file = path + "/models/" + user + ".dat"
# Try to load the models file and abort if the user does not have it yet
try: try:
encodings = json.load(open(enc_file)) encodings = json.load(open(enc_file))
except FileNotFoundError: except FileNotFoundError:
@ -25,35 +33,45 @@ except FileNotFoundError:
print("\n\thowdy " + user + " add\n") print("\n\thowdy " + user + " add\n")
sys.exit(1) sys.exit(1)
# Tracks if a encoding with that id has been found
found = False found = False
# Loop though all encodings and check if they match the argument
for enc in encodings: for enc in encodings:
if str(enc["id"]) == sys.argv[3]: if str(enc["id"]) == sys.argv[3]:
# Double check with the user
print('This will remove the model called "' + enc["label"] + '" for ' + user) print('This will remove the model called "' + enc["label"] + '" for ' + user)
ans = input("Do you want to continue [y/N]: ") ans = input("Do you want to continue [y/N]: ")
# Abort if the answer isn't yes
if (ans.lower() != "y"): if (ans.lower() != "y"):
print('\nInerpeting as a "NO"') print('\nInerpeting as a "NO"')
sys.exit() sys.exit()
# Mark as found and print an enter
found = True found = True
print() print()
break break
# Abort if no matching id was found
if not found: if not found:
print("No model with ID " + sys.argv[3] + " exists for " + user) print("No model with ID " + sys.argv[3] + " exists for " + user)
sys.exit() sys.exit()
# Remove the entire file if this encoding is the only one
if len(encodings) == 1: if len(encodings) == 1:
os.remove(path + "/models/" + user + ".dat") os.remove(path + "/models/" + user + ".dat")
print("Removed last model, howdy disabled for user") print("Removed last model, howdy disabled for user")
else: else:
# A place holder to contain the encodings that will remain
new_encodings = [] new_encodings = []
# Loop though all encodin and only add thos that don't need to be removed
for enc in encodings: for enc in encodings:
if str(enc["id"]) != sys.argv[3]: if str(enc["id"]) != sys.argv[3]:
new_encodings.append(enc) new_encodings.append(enc)
# Save this new set to disk
with open(enc_file, "w") as datafile: with open(enc_file, "w") as datafile:
json.dump(new_encodings, datafile) json.dump(new_encodings, datafile)

View file

@ -73,12 +73,17 @@ while True:
# Don't remove ret, it doesn't work without it # Don't remove ret, it doesn't work without it
ret, frame = video_capture.read() ret, frame = video_capture.read()
# Get the height and with of the image
height, width = frame.shape[:2] height, width = frame.shape[:2]
# If the hight is too high
if max_height < height: if max_height < height:
# Calculate the amount the image has to shrink
scaling_factor = max_height / float(height) 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) 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] scale_height, scale_width = frame.shape[:2]
# Convert from BGR to RGB # Convert from BGR to RGB

View file

@ -80,7 +80,7 @@ handleStatus(subprocess.call(["rm", "-rf", "/tmp/dlib_clone"]))
log("Installing face_recognition") log("Installing face_recognition")
handleStatus(subprocess.call(["pip3", "install", "face_recognition", "sty"])) handleStatus(subprocess.call(["pip3", "install", "face_recognition"]))
log("Cloning howdy") log("Cloning howdy")