1+ # Installation script to install howdy
2+ # Runs completely independent of the others
3+
4+ # Import required modules
15import subprocess
26import time
37import sys
812import urllib .parse
913
1014def log (text ):
15+ """Print a nicely formatted line to stdout"""
1116 print ("\n >>> \033 [32m" + text + "\033 [0m\n " )
1217
1318def handleStatus (status ):
19+ """Abort if a command fails"""
1420 if (status != 0 ):
1521 print ("\033 [31mError while running last command\033 [0m" )
1622 sys .exit ()
1723
24+ # Check if we're running as root
1825user = os .getenv ("SUDO_USER" )
19-
2026if user is None :
2127 print ("Please run this script as a sudo user" )
2228 sys .exit ()
2329
30+ # Print some nice intro text
2431print ("\n \033 [33m HOWDY INSTALLER FOR UBUNTU\033 [0m" )
2532print (" Version 1, 2016/02/05\n " )
2633
34+ # Let it sink in
2735time .sleep (.5 )
2836log ("Installing required apt packages" )
2937
38+ # Install packages though apt
3039handleStatus (subprocess .call (["apt" , "install" , "-y" , "libpam-python" , "fswebcam" , "libopencv-dev" , "python-opencv" ]))
3140
3241log ("Starting camera check" )
3342
43+ # Get all devices
3444devices = os .listdir ("/dev" )
45+ # The picked video device id
3546picked = False
3647
48+ # Loop though all devices
3749for dev in devices :
50+ # Only use the video devices
3851 if (dev [:5 ] == "video" ):
3952 time .sleep (.5 )
4053
54+ # The full path to the device is the default name
4155 device_name = "/dev/" + dev
56+ # Get the udevadm details to try to get a better name
4257 udevadm = subprocess .check_output (["udevadm info -r --query=all -n " + device_name ], shell = True ).decode ("utf-8" )
4358
59+ # Loop though udevadm to search for a better name
4460 for line in udevadm .split ("\n " ):
61+ # Match it and encase it in quotes
4562 re_name = re .search ('product.*=(.*)$' , line , re .IGNORECASE )
46-
4763 if re_name :
4864 device_name = '"' + re_name .group (1 ) + '"'
4965
66+ # Show what device we're using
5067 print ("Trying " + device_name )
5168
69+ # Let fswebcam keep the camera open in the background
5270 sub = subprocess .Popen (["fswebcam -S 9999999999 -d /dev/" + dev + " /dev/null 2>/dev/null" ], shell = True , preexec_fn = os .setsid )
5371
72+ # Ask the user if this is the right one
5473 print ("\033 [33mOne of your cameras should now be on.\033 [0m" )
5574 ans = input ("Did your IR emitters turn on? [y/N]: " )
5675
76+ # The user has answered, kill fswebcam
5777 os .killpg (os .getpgid (sub .pid ), signal .SIGTERM )
5878
79+ # Set this camera as picked if the answer was yes, go to the next one if no
5980 if (ans .lower () == "y" ):
6081 picked = dev [5 :]
6182 break
6283 else :
6384 print ("Inerpeting as a \" NO\" \n " )
6485
86+ # Abort if no camera was picked
6587if (picked == False ):
6688 print ("\033 [31mNo suitable IR camera found\033 [0m" )
6789 sys .exit ()
6890
6991log ("Cloning dlib" )
7092
93+ # Clone the git to /tmp
7194handleStatus (subprocess .call (["git" , "clone" , "https://github.com/davisking/dlib.git" , "/tmp/dlib_clone" ]))
7295
7396log ("Building dlib" )
7497
98+ # Start the build without GPU
7599handleStatus (subprocess .call (["cd /tmp/dlib_clone/; python3 setup.py install --yes USE_AVX_INSTRUCTIONS --no DLIB_USE_CUDA" ], shell = True ))
76100
77101log ("Cleaning up dlib" )
78102
103+ # Remove the no longer needed git clone
79104handleStatus (subprocess .call (["rm" , "-rf" , "/tmp/dlib_clone" ]))
80105
81106log ("Installing face_recognition" )
82107
108+ # Install face_recognition though pip
83109handleStatus (subprocess .call (["pip3" , "install" , "face_recognition" ]))
84110
85111log ("Cloning howdy" )
86112
113+ # Make sure /lib/security exists
87114if not os .path .exists ("/lib/security" ):
88115 os .makedirs ("/lib/security" )
89116
117+ # Clone howdy into it
90118handleStatus (subprocess .call (["git" , "clone" , "https://github.com/Boltgolt/howdy.git" , "/lib/security/howdy" ]))
91119
120+ # Manually change the camera id to the one picked
92121for line in fileinput .input (["/lib/security/howdy/config.ini" ], inplace = 1 ):
93122 print (line .replace ("device_id = 1" , "device_id = " + picked ), end = "" )
94123
@@ -104,76 +133,103 @@ def handleStatus(status):
104133
105134log ("Adding howdy as PAM module" )
106135
136+ # Will be filled with the actual output lines
107137outlines = []
138+ # Will be fillled with lines that contain coloring
108139printlines = []
140+ # Track if the new lines have been insterted yet
109141inserted = False
110142
143+ # Open the PAM config file
111144with open ("/etc/pam.d/common-auth" ) as fp :
145+ # Read the first line
112146 line = fp .readline ()
113- cnt = 1
147+
114148 while line :
149+ # Add the line to the output directly, we're not deleting anything
115150 outlines .append (line )
116151
117- if line [:1 ] != "#" :
152+ # Print the comments in gray and don't insert into comments
153+ if line [:1 ] == "#" :
154+ printlines .append ("\033 [37m" + line + "\033 [0m" )
155+ else :
118156 printlines .append (line )
119157
158+ # If it's not a comment and we haven't inserted yet
120159 if not inserted :
160+ # Set both the comment and the linking line
121161 line_comment = "# Howdy IR face recognition\n "
122- line_Link = "auth sufficient pam_python.so /lib/security/howdy/pam.py\n \n "
162+ line_link = "auth sufficient pam_python.so /lib/security/howdy/pam.py\n \n "
123163
164+ # Add them to the output without any markup
124165 outlines .append (line_comment )
125- outlines .append (line_Link )
166+ outlines .append (line_link )
126167
168+ # Make the print orange to make it clear what's being added
127169 printlines .append ("\033 [33m" + line_comment + "\033 [0m" )
128- printlines .append ("\033 [33m" + line_Link + "\033 [0m" )
170+ printlines .append ("\033 [33m" + line_link + "\033 [0m" )
129171
172+ # Mark as inserted
130173 inserted = True
131- else :
132- printlines .append ("\033 [37m" + line + "\033 [0m" )
133174
175+ # Go to the next line
134176 line = fp .readline ()
135- cnt += 1
136177
178+ # Print a file Header
137179print ("\033 [33m" + ">>> START OF /etc/pam.d/common-auth" + "\033 [0m" )
138180
181+ # Loop though all printing lines and use the enters from the file
139182for line in printlines :
140183 print (line , end = "" )
141184
185+ # Print a footer
142186print ("\033 [33m" + ">>> END OF /etc/pam.d/common-auth" + "\033 [0m" + "\n " )
143187
188+ # Ask the user if this change is okay
144189print ("Lines will be insterted in /etc/pam.d/common-auth as shown above" )
145190ans = input ("Apply this change? [y/N]: " )
146191
192+ # Abort the whole thing if it's not
147193if (ans .lower () != "y" ):
148194 print ("Inerpeting as a \" NO\" , aborting" )
149195 sys .exit ()
150196
151197print ("Adding lines to PAM\n " )
152198
199+ # Write to PAM
153200common_auth = open ("/etc/pam.d/common-auth" , "w" )
154201common_auth .write ("" .join (outlines ))
155202common_auth .close ()
156203
204+ # From here onwards the installation is complete
205+ # We want to gather more information about the types or IR camera's
206+ # used though, and the following lines are data collection
207+
208+ # List all video devices
157209diag_out = "Video devices [IR=" + picked + "]\n "
158210diag_out += "```\n "
159211diag_out += subprocess .check_output (['ls /dev/ | grep video' ], shell = True ).decode ("utf-8" )
160212diag_out += "```\n "
161213
214+ # Get some info from the USB kernel listings
162215diag_out += "Lsusb output\n "
163216diag_out += "```\n "
164217diag_out += subprocess .check_output (['lsusb -vvvv | grep -i "Camera\|iFunction"' ], shell = True ).decode ("utf-8" )
165218diag_out += "```\n "
166219
220+ # Get camera information from video4linux
167221diag_out += "Udevadm\n "
168222diag_out += "```\n "
169223diag_out += subprocess .check_output (['udevadm info -r --query=all -n /dev/video' + picked + ' | grep -i "ID_BUS\|ID_MODEL_ID\|ID_VENDOR_ID\|ID_V4L_PRODUCT\|ID_MODEL"' ], shell = True ).decode ("utf-8" )
170224diag_out += "```"
171225
226+ # Print it all as a clickable link to a new github issue
172227print ("https://github.com/Boltgolt/howdy-reports/issues/new?title=Post-installation%20camera%20information&body=" + urllib .parse .quote_plus (diag_out ) + "\n " )
173228
229+ # Let the user know what to do with the link
174230print ("Installation complete." )
175231print ("If you want to help the development, please use the link above to post some camera-related information to github" )
176232
177- # Remove the installer if downloaded to tmp
233+ # Remove the installer if it was downloaded to / tmp
178234if os .path .exists ("/tmp/howdy_install.py" ):
179235 os .remove ("/tmp/howdy_install.py" )
0 commit comments