mirror of
https://github.com/boltgolt/howdy.git
synced 2024-09-12 09:41:18 +02:00
build: add meson build system
Add Meson as a build system for the whole howdy package, which allow better flexibility for the paths configuration. Generate a python module, which contains the paths used by the other modules and the header containing the paths for the PAM module.
This commit is contained in:
parent
53a6ea5eb1
commit
2d2480054d
18 changed files with 189 additions and 40 deletions
3
howdy/src/bin/howdy.in
Normal file
3
howdy/src/bin/howdy.in
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
/usr/bin/env python3 "@script_path@" "$@"
|
|
@ -28,7 +28,7 @@ except ImportError as err:
|
||||||
import cv2
|
import cv2
|
||||||
|
|
||||||
# Test if at lest 1 of the data files is there and abort if it's not
|
# Test if at lest 1 of the data files is there and abort if it's not
|
||||||
if not os.path.isfile(paths.dlib_data_dir + "shape_predictor_5_face_landmarks.dat"):
|
if not os.path.isfile(paths.dlib_data_dir / "shape_predictor_5_face_landmarks.dat"):
|
||||||
print(_("Data files have not been downloaded, please run the following commands:"))
|
print(_("Data files have not been downloaded, please run the following commands:"))
|
||||||
print("\n\tcd " + paths.dlib_data_dir)
|
print("\n\tcd " + paths.dlib_data_dir)
|
||||||
print("\tsudo ./install.sh\n")
|
print("\tsudo ./install.sh\n")
|
||||||
|
@ -36,20 +36,20 @@ if not os.path.isfile(paths.dlib_data_dir + "shape_predictor_5_face_landmarks.da
|
||||||
|
|
||||||
# Read config from disk
|
# Read config from disk
|
||||||
config = configparser.ConfigParser()
|
config = configparser.ConfigParser()
|
||||||
config.read(paths.config_dir + "/config.ini")
|
config.read(paths.config_dir / "config.ini")
|
||||||
|
|
||||||
use_cnn = config.getboolean("core", "use_cnn", fallback=False)
|
use_cnn = config.getboolean("core", "use_cnn", fallback=False)
|
||||||
if use_cnn:
|
if use_cnn:
|
||||||
face_detector = dlib.cnn_face_detection_model_v1(paths.dlib_data_dir + "mmod_human_face_detector.dat")
|
face_detector = dlib.cnn_face_detection_model_v1(paths.dlib_data_dir / "mmod_human_face_detector.dat")
|
||||||
else:
|
else:
|
||||||
face_detector = dlib.get_frontal_face_detector()
|
face_detector = dlib.get_frontal_face_detector()
|
||||||
|
|
||||||
pose_predictor = dlib.shape_predictor(paths.dlib_data_dir + "shape_predictor_5_face_landmarks.dat")
|
pose_predictor = dlib.shape_predictor(paths.dlib_data_dir / "shape_predictor_5_face_landmarks.dat")
|
||||||
face_encoder = dlib.face_recognition_model_v1(paths.dlib_data_dir + "dlib_face_recognition_resnet_model_v1.dat")
|
face_encoder = dlib.face_recognition_model_v1(paths.dlib_data_dir / "dlib_face_recognition_resnet_model_v1.dat")
|
||||||
|
|
||||||
user = builtins.howdy_user
|
user = builtins.howdy_user
|
||||||
# The permanent file to store the encoded model in
|
# The permanent file to store the encoded model in
|
||||||
enc_file = paths.user_models_dir + user + ".dat"
|
enc_file = paths.user_models_dir / f"{user}.dat"
|
||||||
# Known encodings
|
# Known encodings
|
||||||
encodings = []
|
encodings = []
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ if not os.path.exists(paths.user_models_dir):
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
# Check if the user has a models file to delete
|
# Check if the user has a models file to delete
|
||||||
if not os.path.isfile(paths.user_models_dir + user + ".dat"):
|
if not os.path.isfile(paths.user_models_dir / f"{user}.dat"):
|
||||||
print(_("{} has no models or they have been cleared already").format(user))
|
print(_("{} has no models or they have been cleared already").format(user))
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
@ -33,5 +33,5 @@ if not builtins.howdy_args.y:
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
# Delete otherwise
|
# Delete otherwise
|
||||||
os.remove(paths.user_models_dir + user + ".dat")
|
os.remove(paths.user_models_dir / f"{user}.dat")
|
||||||
print(_("\nModels cleared"))
|
print(_("\nModels cleared"))
|
||||||
|
|
|
@ -20,4 +20,4 @@ elif os.path.isfile("/etc/alternatives/editor"):
|
||||||
editor = "/etc/alternatives/editor"
|
editor = "/etc/alternatives/editor"
|
||||||
|
|
||||||
# Open the editor as a subprocess and fork it
|
# Open the editor as a subprocess and fork it
|
||||||
subprocess.call([editor, paths.config_dir + "config.ini"])
|
subprocess.call([editor, paths.config_dir / "config.ini"])
|
||||||
|
|
|
@ -11,7 +11,7 @@ import paths
|
||||||
from i18n import _
|
from i18n import _
|
||||||
|
|
||||||
# Get the absolute filepath
|
# Get the absolute filepath
|
||||||
config_path = os.path.dirname(paths.config_dir) + "/config.ini"
|
config_path = paths.config_dir.parent / "config.ini"
|
||||||
|
|
||||||
# Read config from disk
|
# Read config from disk
|
||||||
config = configparser.ConfigParser()
|
config = configparser.ConfigParser()
|
||||||
|
|
|
@ -19,7 +19,7 @@ if not os.path.exists(paths.user_models_dir):
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
# Path to the models file
|
# Path to the models file
|
||||||
enc_file = paths.user_models_dir + user + ".dat"
|
enc_file = paths.user_models_dir / f"{user}.dat"
|
||||||
|
|
||||||
# Try to load the models file and abort if the user does not have it yet
|
# Try to load the models file and abort if the user does not have it yet
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -27,7 +27,7 @@ if not os.path.exists(paths.user_models_dir):
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
# Path to the models file
|
# Path to the models file
|
||||||
enc_file = paths.user_models_dir + user + ".dat"
|
enc_file = paths.user_models_dir / f"{user}.dat"
|
||||||
|
|
||||||
# Try to load the models file and abort if the user does not have it yet
|
# Try to load the models file and abort if the user does not have it yet
|
||||||
try:
|
try:
|
||||||
|
@ -71,7 +71,7 @@ if not found:
|
||||||
|
|
||||||
# Remove the entire file if this encoding is the only one
|
# Remove the entire file if this encoding is the only one
|
||||||
if len(encodings) == 1:
|
if len(encodings) == 1:
|
||||||
os.remove(paths.user_models_dir + user + ".dat")
|
os.remove(paths.user_models_dir / f"{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
|
# A place holder to contain the encodings that will remain
|
||||||
|
|
|
@ -10,7 +10,7 @@ import paths
|
||||||
from i18n import _
|
from i18n import _
|
||||||
|
|
||||||
# Get the absolute filepath
|
# Get the absolute filepath
|
||||||
config_path = os.path.dirname(paths.config_dir) + "/config.ini"
|
config_path = paths.config_dir / "/config.ini"
|
||||||
|
|
||||||
# Check if enough arguments have been passed
|
# Check if enough arguments have been passed
|
||||||
if len(builtins.howdy_args.arguments) < 2:
|
if len(builtins.howdy_args.arguments) < 2:
|
||||||
|
|
|
@ -12,7 +12,7 @@ from i18n import _
|
||||||
|
|
||||||
# Read the config
|
# Read the config
|
||||||
config = configparser.ConfigParser()
|
config = configparser.ConfigParser()
|
||||||
config.read(paths.config_dir + "config.ini")
|
config.read(paths.config_dir / "config.ini")
|
||||||
|
|
||||||
# Start video capture
|
# Start video capture
|
||||||
video_capture = VideoCapture(config)
|
video_capture = VideoCapture(config)
|
||||||
|
|
|
@ -20,7 +20,7 @@ path = "/etc/howdy"
|
||||||
|
|
||||||
# Read config from disk
|
# Read config from disk
|
||||||
config = configparser.ConfigParser()
|
config = configparser.ConfigParser()
|
||||||
config.read(paths.config_dir + "config.ini")
|
config.read(paths.config_dir / "config.ini")
|
||||||
|
|
||||||
if config.get("video", "recording_plugin", fallback="opencv") != "opencv":
|
if config.get("video", "recording_plugin", fallback="opencv") != "opencv":
|
||||||
print(_("Howdy has been configured to use a recorder which doesn't support the test command yet, aborting"))
|
print(_("Howdy has been configured to use a recorder which doesn't support the test command yet, aborting"))
|
||||||
|
@ -60,20 +60,20 @@ use_cnn = config.getboolean('core', 'use_cnn', fallback=False)
|
||||||
|
|
||||||
if use_cnn:
|
if use_cnn:
|
||||||
face_detector = dlib.cnn_face_detection_model_v1(
|
face_detector = dlib.cnn_face_detection_model_v1(
|
||||||
paths.dlib_data_dir + "mmod_human_face_detector.dat"
|
paths.dlib_data_dir / "mmod_human_face_detector.dat"
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
face_detector = dlib.get_frontal_face_detector()
|
face_detector = dlib.get_frontal_face_detector()
|
||||||
|
|
||||||
pose_predictor = dlib.shape_predictor(paths.dlib_data_dir + "shape_predictor_5_face_landmarks.dat")
|
pose_predictor = dlib.shape_predictor(paths.dlib_data_dir / "shape_predictor_5_face_landmarks.dat")
|
||||||
face_encoder = dlib.face_recognition_model_v1(paths.dlib_data_dir + "dlib_face_recognition_resnet_model_v1.dat")
|
face_encoder = dlib.face_recognition_model_v1(paths.dlib_data_dir / "dlib_face_recognition_resnet_model_v1.dat")
|
||||||
|
|
||||||
encodings = []
|
encodings = []
|
||||||
models = None
|
models = None
|
||||||
|
|
||||||
try:
|
try:
|
||||||
user = builtins.howdy_user
|
user = builtins.howdy_user
|
||||||
models = json.load(open(paths.user_models_dir + user + ".dat"))
|
models = json.load(open(paths.user_models_dir / f"{user}.dat"))
|
||||||
|
|
||||||
for model in models:
|
for model in models:
|
||||||
encodings += model["data"]
|
encodings += model["data"]
|
||||||
|
|
|
@ -49,7 +49,7 @@ def init_detector(lock):
|
||||||
global face_detector, pose_predictor, face_encoder
|
global face_detector, pose_predictor, face_encoder
|
||||||
|
|
||||||
# Test if at lest 1 of the data files is there and abort if it's not
|
# Test if at lest 1 of the data files is there and abort if it's not
|
||||||
if not os.path.isfile(paths.dlib_data_dir + "shape_predictor_5_face_landmarks.dat"):
|
if not os.path.isfile(paths.dlib_data_dir / "shape_predictor_5_face_landmarks.dat"):
|
||||||
print(_("Data files have not been downloaded, please run the following commands:"))
|
print(_("Data files have not been downloaded, please run the following commands:"))
|
||||||
print("\n\tcd " + paths.dlib_data_dir)
|
print("\n\tcd " + paths.dlib_data_dir)
|
||||||
print("\tsudo ./install.sh\n")
|
print("\tsudo ./install.sh\n")
|
||||||
|
@ -58,13 +58,13 @@ def init_detector(lock):
|
||||||
|
|
||||||
# Use the CNN detector if enabled
|
# Use the CNN detector if enabled
|
||||||
if use_cnn:
|
if use_cnn:
|
||||||
face_detector = dlib.cnn_face_detection_model_v1(paths.dlib_data_dir + "mmod_human_face_detector.dat")
|
face_detector = dlib.cnn_face_detection_model_v1(paths.dlib_data_dir / "mmod_human_face_detector.dat")
|
||||||
else:
|
else:
|
||||||
face_detector = dlib.get_frontal_face_detector()
|
face_detector = dlib.get_frontal_face_detector()
|
||||||
|
|
||||||
# Start the others regardless
|
# Start the others regardless
|
||||||
pose_predictor = dlib.shape_predictor(paths.dlib_data_dir + "shape_predictor_5_face_landmarks.dat")
|
pose_predictor = dlib.shape_predictor(paths.dlib_data_dir / "shape_predictor_5_face_landmarks.dat")
|
||||||
face_encoder = dlib.face_recognition_model_v1(paths.dlib_data_dir + "dlib_face_recognition_resnet_model_v1.dat")
|
face_encoder = dlib.face_recognition_model_v1(paths.dlib_data_dir / "dlib_face_recognition_resnet_model_v1.dat")
|
||||||
|
|
||||||
# Note the time it took to initialize detectors
|
# Note the time it took to initialize detectors
|
||||||
timings["ll"] = time.time() - timings["ll"]
|
timings["ll"] = time.time() - timings["ll"]
|
||||||
|
@ -127,7 +127,7 @@ face_encoder = None
|
||||||
|
|
||||||
# Try to load the face model from the models folder
|
# Try to load the face model from the models folder
|
||||||
try:
|
try:
|
||||||
models = json.load(open(paths.user_models_dir + user + ".dat"))
|
models = json.load(open(paths.user_models_dir / f"{user}.dat"))
|
||||||
|
|
||||||
for model in models:
|
for model in models:
|
||||||
encodings += model["data"]
|
encodings += model["data"]
|
||||||
|
@ -140,7 +140,7 @@ if len(models) < 1:
|
||||||
|
|
||||||
# Read config from disk
|
# Read config from disk
|
||||||
config = configparser.ConfigParser()
|
config = configparser.ConfigParser()
|
||||||
config.read(paths.config_dir + "config.ini")
|
config.read(paths.config_dir / "config.ini")
|
||||||
|
|
||||||
# Get all config values needed
|
# Get all config values needed
|
||||||
use_cnn = config.getboolean("core", "use_cnn", fallback=False)
|
use_cnn = config.getboolean("core", "use_cnn", fallback=False)
|
||||||
|
|
129
howdy/src/meson.build
Normal file
129
howdy/src/meson.build
Normal file
|
@ -0,0 +1,129 @@
|
||||||
|
project('howdy', 'cpp', license: 'MIT', license_files: '../LICENSE', version: 'beta', meson_version: '>= 1.1.0')
|
||||||
|
|
||||||
|
py = import('python').find_installation()
|
||||||
|
py.dependency()
|
||||||
|
|
||||||
|
confdir = join_paths(get_option('sysconfdir'), 'howdy')
|
||||||
|
dlibdatadir = join_paths(confdir, 'dlib-data')
|
||||||
|
usermodelsdir = join_paths(confdir, 'models')
|
||||||
|
logpath = '/var/log/howdy'
|
||||||
|
|
||||||
|
py_conf = configuration_data({
|
||||||
|
'config_dir': confdir,
|
||||||
|
'dlib_data_dir': dlibdatadir,
|
||||||
|
'user_models_dir': usermodelsdir,
|
||||||
|
'log_path': logpath,
|
||||||
|
})
|
||||||
|
|
||||||
|
py_paths = configure_file(
|
||||||
|
input: 'paths.py.in',
|
||||||
|
output: 'paths.py',
|
||||||
|
configuration: py_conf,
|
||||||
|
)
|
||||||
|
|
||||||
|
py_sources = [
|
||||||
|
'cli/__init__.py',
|
||||||
|
'cli/add.py',
|
||||||
|
'cli/clear.py',
|
||||||
|
'cli/config.py',
|
||||||
|
'cli/disable.py',
|
||||||
|
'cli/list.py',
|
||||||
|
'cli/remove.py',
|
||||||
|
'cli/set.py',
|
||||||
|
'cli/snap.py',
|
||||||
|
'cli/test.py',
|
||||||
|
'cli.py',
|
||||||
|
'compare.py',
|
||||||
|
'i18n.py',
|
||||||
|
'recorders/__init__.py',
|
||||||
|
'recorders/ffmpeg_reader.py',
|
||||||
|
'recorders/pyv4l2_reader.py',
|
||||||
|
'recorders/v4l2.py',
|
||||||
|
'recorders/video_capture.py',
|
||||||
|
'rubberstamps/__init__.py',
|
||||||
|
'rubberstamps/hotkey.py',
|
||||||
|
'rubberstamps/nod.py',
|
||||||
|
'snapshot.py',
|
||||||
|
py_paths,
|
||||||
|
]
|
||||||
|
|
||||||
|
# Include PAM module
|
||||||
|
compare_script_path = join_paths(py.get_install_dir(), 'howdy', 'compare.py')
|
||||||
|
subdir('pam')
|
||||||
|
|
||||||
|
py.install_sources(
|
||||||
|
py_sources,
|
||||||
|
subdir: 'howdy',
|
||||||
|
preserve_path: true,
|
||||||
|
)
|
||||||
|
|
||||||
|
install_data('logo.png', install_tag: 'meta')
|
||||||
|
|
||||||
|
install_data('config.ini', install_dir: confdir, install_mode: 'rwxr--r--', install_tag: 'config')
|
||||||
|
|
||||||
|
install_data('dlib-data/install.sh', install_dir: dlibdatadir, install_mode: 'rwxr--r--')
|
||||||
|
|
||||||
|
install_data('dlib-data/Readme.md', install_dir: dlibdatadir, install_mode: 'r--r--r--', install_tag: 'docs')
|
||||||
|
install_man('../howdy.1')
|
||||||
|
|
||||||
|
# if get_option('fetch_dlib_data')
|
||||||
|
# downloader = find_program('wget')
|
||||||
|
# bunzip2 = find_program('bunzip2')
|
||||||
|
|
||||||
|
# links = [
|
||||||
|
# 'https://github.com/davisking/dlib-models/raw/master/dlib_face_recognition_resnet_model_v1.dat.bz2',
|
||||||
|
# 'https://github.com/davisking/dlib-models/raw/master/mmod_human_face_detector.dat.bz2',
|
||||||
|
# 'https://github.com/davisking/dlib-models/raw/master/shape_predictor_5_face_landmarks.dat.bz2'
|
||||||
|
# ]
|
||||||
|
|
||||||
|
# archived_model_files = [
|
||||||
|
# 'dlib_face_recognition_resnet_model_v1.dat.bz2',
|
||||||
|
# 'shape_predictor_5_face_landmarks.dat.bz2',
|
||||||
|
# 'mmod_human_face_detector.dat.bz2'
|
||||||
|
# ]
|
||||||
|
|
||||||
|
# download = run_command(
|
||||||
|
# 'download',
|
||||||
|
# links,
|
||||||
|
# output: archived_model_files,
|
||||||
|
# command: [downloader, '-O', '@OUTPUT@', '@INPUT@']
|
||||||
|
# )
|
||||||
|
|
||||||
|
# model_files = [
|
||||||
|
# 'dlib_face_recognition_resnet_model_v1.dat',
|
||||||
|
# 'shape_predictor_5_face_landmarks.dat',
|
||||||
|
# 'mmod_human_face_detector.dat'
|
||||||
|
# ]
|
||||||
|
|
||||||
|
# models = custom_target(
|
||||||
|
# 'models',
|
||||||
|
# input: archived_model_files,
|
||||||
|
# output: model_files,
|
||||||
|
# command: [bunzip2, '-k', '@INPUT@'],
|
||||||
|
# )
|
||||||
|
|
||||||
|
# install_data(
|
||||||
|
# model_files,
|
||||||
|
# install_dir: join_paths(get_option('prefix'), get_option('libdir'), 'dlib_models'),
|
||||||
|
# )
|
||||||
|
|
||||||
|
# endif
|
||||||
|
|
||||||
|
py_path = py.get_install_dir()
|
||||||
|
cli_path = join_paths(py_path, 'howdy', 'cli.py')
|
||||||
|
|
||||||
|
conf_data = configuration_data({ 'script_path': cli_path })
|
||||||
|
|
||||||
|
bin_name = 'howdy'
|
||||||
|
|
||||||
|
bin = configure_file(
|
||||||
|
input: 'bin/howdy.in',
|
||||||
|
output: bin_name,
|
||||||
|
configuration: conf_data
|
||||||
|
)
|
||||||
|
|
||||||
|
install_data(
|
||||||
|
bin,
|
||||||
|
install_mode: 'rwxr-xr-x',
|
||||||
|
install_dir: get_option('bindir'),
|
||||||
|
)
|
2
howdy/src/meson.options
Normal file
2
howdy/src/meson.options
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
option('pam_dir', type: 'string', value: '/lib/security', description: 'Set the pam_howdy destination directory')
|
||||||
|
#option('fetch_dlib_data', type: 'boolean', value: false, description: 'Download dlib data files')
|
|
@ -41,12 +41,12 @@
|
||||||
#include "enter_device.hh"
|
#include "enter_device.hh"
|
||||||
#include "main.hh"
|
#include "main.hh"
|
||||||
#include "optional_task.hh"
|
#include "optional_task.hh"
|
||||||
|
#include "paths.hh"
|
||||||
|
|
||||||
const auto DEFAULT_TIMEOUT =
|
const auto DEFAULT_TIMEOUT =
|
||||||
std::chrono::duration<int, std::chrono::milliseconds::period>(100);
|
std::chrono::duration<int, std::chrono::milliseconds::period>(100);
|
||||||
const auto MAX_RETRIES = 5;
|
const auto MAX_RETRIES = 5;
|
||||||
const auto PYTHON_EXECUTABLE = "python3";
|
const auto PYTHON_EXECUTABLE = "python3";
|
||||||
const auto COMPARE_PROCESS_PATH = "/lib/security/howdy/compare.py";
|
|
||||||
|
|
||||||
#define S(msg) gettext(msg)
|
#define S(msg) gettext(msg)
|
||||||
|
|
||||||
|
@ -80,7 +80,8 @@ auto howdy_error(int status,
|
||||||
syslog(LOG_ERR, "Failure, image too dark");
|
syslog(LOG_ERR, "Failure, image too dark");
|
||||||
break;
|
break;
|
||||||
case CompareError::INVALID_DEVICE:
|
case CompareError::INVALID_DEVICE:
|
||||||
syslog(LOG_ERR, "Failure, not possible to open camera at configured path");
|
syslog(LOG_ERR,
|
||||||
|
"Failure, not possible to open camera at configured path");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
conv_function(PAM_ERROR_MSG,
|
conv_function(PAM_ERROR_MSG,
|
||||||
|
@ -321,7 +322,8 @@ auto identify(pam_handle_t *pamh, int flags, int argc, const char **argv,
|
||||||
// Wait for the end either of the child or the password input
|
// Wait for the end either of the child or the password input
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> lock(mutx);
|
std::unique_lock<std::mutex> lock(mutx);
|
||||||
convar.wait(lock, [&] { return confirmation_type != ConfirmationType::Unset; });
|
convar.wait(lock,
|
||||||
|
[&] { return confirmation_type != ConfirmationType::Unset; });
|
||||||
}
|
}
|
||||||
|
|
||||||
// The password has been entered or an error has occurred
|
// The password has been entered or an error has occurred
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
project('pam_howdy', 'cpp', version: '0.1.0', default_options: ['cpp_std=c++14'])
|
|
||||||
|
|
||||||
inih_cpp = dependency('INIReader', fallback: ['inih', 'INIReader_dep'])
|
inih_cpp = dependency('INIReader', fallback: ['inih', 'INIReader_dep'])
|
||||||
libevdev = dependency('libevdev')
|
libevdev = dependency('libevdev')
|
||||||
libpam = meson.get_compiler('cpp').find_library('pam')
|
libpam = meson.get_compiler('cpp').find_library('pam')
|
||||||
|
@ -8,6 +6,16 @@ threads = dependency('threads')
|
||||||
# Translations
|
# Translations
|
||||||
subdir('po')
|
subdir('po')
|
||||||
|
|
||||||
|
# Paths
|
||||||
|
paths = { 'compare_script_path': compare_script_path }
|
||||||
|
|
||||||
|
paths_h = configure_file(
|
||||||
|
input: 'paths.hh.in',
|
||||||
|
output: 'paths.hh',
|
||||||
|
configuration: paths,
|
||||||
|
install_dir: get_option('pam_dir')
|
||||||
|
)
|
||||||
|
|
||||||
shared_library(
|
shared_library(
|
||||||
'pam_howdy',
|
'pam_howdy',
|
||||||
'main.cc',
|
'main.cc',
|
||||||
|
@ -18,7 +26,10 @@ shared_library(
|
||||||
threads,
|
threads,
|
||||||
libevdev,
|
libevdev,
|
||||||
],
|
],
|
||||||
|
link_depends: [
|
||||||
|
paths_h,
|
||||||
|
],
|
||||||
install: true,
|
install: true,
|
||||||
install_dir: '/lib/security',
|
install_dir: get_option('pam_dir'),
|
||||||
name_prefix: ''
|
name_prefix: ''
|
||||||
)
|
)
|
||||||
|
|
1
howdy/src/pam/paths.hh.in
Normal file
1
howdy/src/pam/paths.hh.in
Normal file
|
@ -0,0 +1 @@
|
||||||
|
const auto COMPARE_PROCESS_PATH = "@compare_script_path@";
|
|
@ -1,12 +1,13 @@
|
||||||
|
from pathlib import PurePath
|
||||||
|
|
||||||
# Define the absolute path to the config directory
|
# Define the absolute path to the config directory
|
||||||
config_dir = "/etc/howdy/"
|
config_dir = PurePath("@config_dir@")
|
||||||
|
|
||||||
# Define the absolute path to the DLib models data directory
|
# Define the absolute path to the DLib models data directory
|
||||||
dlib_data_dir = config_dir + "/dlib-data/"
|
dlib_data_dir = PurePath("@dlib_data_dir@")
|
||||||
|
|
||||||
# Define the absolute path to the Howdy user models directory
|
# Define the absolute path to the Howdy user models directory
|
||||||
user_models_dir = config_dir + "/models/"
|
user_models_dir = PurePath("@user_models_dir@")
|
||||||
|
|
||||||
# Define path to any howdy logs
|
# Define path to any howdy logs
|
||||||
log_path = "/var/log/howdy"
|
log_path = PurePath("@log_path@")
|
|
@ -52,13 +52,13 @@ def generate(frames, text_lines):
|
||||||
# Made sure a snapshot folder exist
|
# Made sure a snapshot folder exist
|
||||||
if not os.path.exists(paths.log_path):
|
if not os.path.exists(paths.log_path):
|
||||||
os.makedirs(paths.log_path)
|
os.makedirs(paths.log_path)
|
||||||
if not os.path.exists(paths.log_path + "/snapshots"):
|
if not os.path.exists(paths.log_path / "snapshots"):
|
||||||
os.makedirs(paths.log_path + "/snapshots")
|
os.makedirs(paths.log_path / "snapshots")
|
||||||
|
|
||||||
# Generate a filename based on the current time
|
# Generate a filename based on the current time
|
||||||
filename = datetime.datetime.utcnow().strftime("%Y%m%dT%H%M%S.jpg")
|
filename = datetime.datetime.utcnow().strftime("%Y%m%dT%H%M%S.jpg")
|
||||||
# Write the image to that file
|
# Write the image to that file
|
||||||
cv2.imwrite(paths.log_path + "/snapshots/" + filename, snap)
|
cv2.imwrite(paths.log_path / "snapshots" / filename, snap)
|
||||||
|
|
||||||
# Return the saved file location
|
# Return the saved file location
|
||||||
return paths.log_path + "/snapshots/" + filename
|
return paths.log_path / "/snapshots/" / filename
|
||||||
|
|
Loading…
Reference in a new issue