Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

build: add meson build system #803

Merged
merged 31 commits into from
Sep 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
488176a
Put all path variables into a separate module.
arrowd Mar 30, 2023
53a6ea5
chore: move man page
musikid Jun 19, 2023
2d24800
build: add meson build system
musikid Jun 19, 2023
452dac8
ci: fix workflow
musikid Jun 19, 2023
d95f5e2
fix: replace deprecated function
musikid Jun 25, 2023
87017fa
fix: use build options to configure paths
musikid Jun 25, 2023
c12dce0
refactor: add path factory to not recreate paths
musikid Jun 25, 2023
a30fbd3
build: remove license_files
musikid Jun 25, 2023
5d3e69d
build: add meson_options.txt for compatibility
musikid Jun 25, 2023
c97164f
ci: use latest meson version
musikid Jun 25, 2023
73adb06
build: add paths_factory file
musikid Jun 25, 2023
c9e24e3
fix: convert paths to string
musikid Jun 25, 2023
81db5c3
fix: use correct shebang
musikid Jun 25, 2023
6122219
build: add .clang-tidy to root src folder
musikid Jun 25, 2023
8bc95ef
fix: convert to string when necessary
musikid Jun 25, 2023
d0ca17b
refactor: add data dir for logo
musikid Jun 25, 2023
a92a3aa
feat: add config path to PAM module
musikid Jun 25, 2023
37a59a0
style: change clang tidy configuration
musikid Jun 25, 2023
54ba84e
fix: convert to string
musikid Jun 25, 2023
1f8ee26
refactor: use only paths_factory
musikid Jun 25, 2023
241bc6b
feat: add meson root script with howdy-gtk
musikid Jun 26, 2023
ef2187a
ci: fix workflow
musikid Jun 26, 2023
9b20bc2
ci: fix argument
musikid Jun 26, 2023
19f5b8d
build: remove mandatory modules
musikid Jun 27, 2023
a74ee5a
build: move datadir variable
musikid Jul 2, 2023
93a3d71
Merge branch 'beta' into meson
boltgolt Sep 5, 2023
7ce795b
Merge branch 'beta' into meson
musikid Sep 12, 2023
5133d05
refactor: rename variable
musikid Sep 12, 2023
29f218d
build: templatize autocomplete and pam-config
musikid Sep 12, 2023
0eb3eeb
build: fix pamdir path
musikid Sep 12, 2023
466c859
refactor: remove useless conversion
musikid Sep 12, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .clang-tidy
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Checks: 'clang-diagnostic-*,clang-analyser-*,-clang-diagnostic-unused-command-line-argument,google-*,bugprone-*,modernize-*,performance-*,portability-*,readability-*,-bugprone-easily-swappable-*,-readability-magic-numbers,-google-readability-todo'
WarningsAsErrors: 'clang-diagnostic-*,clang-analyser-*,-clang-diagnostic-unused-command-line-argument,google-*,bugprone-*,modernize-*,performance-*,portability-*,readability-*,-bugprone-easily-swappable-*,-readability-magic-numbers,-google-readability-todo'
CheckOptions:
- key: readability-function-cognitive-complexity.Threshold
value: '50'

# vim:syntax=yaml
7 changes: 5 additions & 2 deletions .github/workflows/check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,19 @@ jobs:
- name: Install required libraries
run: >
sudo apt-get update && sudo apt-get install -y
python3 python3-pip python3-setuptools python3-wheel ninja-build meson
python3 python3-pip python3-setuptools python3-wheel
cmake make build-essential clang-tidy
libpam0g-dev libinih-dev libevdev-dev
python3-dev libopencv-dev

- name: Install meson
run: sudo python3 -m pip install meson ninja

- uses: actions/checkout@v2

- name: Build
run: |
meson setup build howdy/src/pam
meson setup build
ninja -C build

- name: Check source code
Expand Down
3 changes: 3 additions & 0 deletions howdy-gtk/bin/howdy-gtk.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/sh

env python3 "@script_path@" "$@"
82 changes: 82 additions & 0 deletions howdy-gtk/meson.build
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
if meson.is_subproject()
project('howdy-gtk', license: 'MIT', version: 'beta', meson_version: '>= 0.64.0')
endif

datadir = get_option('prefix') / get_option('datadir') / 'howdy-gtk'
py_conf = configuration_data(paths_dict)
py_conf.set('data_dir', datadir)


py_paths = configure_file(
input: 'src/paths.py.in',
output: 'paths.py',
configuration: py_conf,
)

sources = files(
'src/authsticky.py',
'src/i18n.py',
'src/init.py',
'src/onboarding.py',
'src/paths_factory.py',
'src/tab_models.py',
'src/tab_video.py',
'src/window.py',
)

py = import('python').find_installation(
# modules: ['gi', 'elevate']
)
py.dependency()

if get_option('install_in_site_packages')
pysourcesinstalldir = join_paths(py.get_install_dir(), 'howdy-gtk')
else
pysourcesinstalldir = get_option('py_sources_dir') != '' ? get_option('py_sources_dir') : join_paths(get_option('prefix'), get_option('libdir'), 'howdy-gtk')
endif

if get_option('install_in_site_packages')
py.install_sources(
sources,
py_paths,
subdir: 'howdy-gtk',
install_mode: 'r--r--r--',
install_tag: 'py_sources',
)
else
install_data(
sources,
py_paths,
install_dir: pysourcesinstalldir,
install_mode: 'r--r--r--',
install_tag: 'py_sources',
)
endif

logos = files(
'src/logo.png',
'src/logo_about.png',
)
install_data(logos, install_dir: datadir)

interface_files = files(
'src/main.glade',
'src/onboarding.glade',
)
install_data(interface_files, install_dir: datadir)

cli_path = join_paths(pysourcesinstalldir, 'init.py')
conf_data = configuration_data({ 'script_path': cli_path })

bin_name = 'howdy-gtk'
bin = configure_file(
input: 'bin/howdy-gtk.in',
output: bin_name,
configuration: conf_data
)
install_data(
bin,
install_mode: 'rwxr-xr-x',
install_dir: get_option('prefix') / get_option('bindir'),
install_tag: 'bin',
)
5 changes: 2 additions & 3 deletions howdy-gtk/src/authsticky.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import gi
import signal
import sys
import paths_factory
import os

from i18n import _
Expand Down Expand Up @@ -32,9 +33,7 @@ def __init__(self):
gtk.Window.__init__(self)

# Get the absolute or relative path to the logo file
logo_path = "/usr/lib/howdy-gtk/logo.png"
if not os.access(logo_path, os.R_OK):
logo_path = "./logo.png"
logo_path = paths_factory.logo_path()

# Create image and calculate scale size based on image size
self.logo_surface = cairo.ImageSurface.create_from_png(logo_path)
Expand Down
21 changes: 5 additions & 16 deletions howdy-gtk/src/onboarding.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import re
import time
import subprocess
import paths_factory

from i18n import _

Expand All @@ -22,7 +23,7 @@ def __init__(self):
self.connect("delete_event", self.exit)

self.builder = gtk.Builder()
self.builder.add_from_file("./onboarding.glade")
self.builder.add_from_file(paths_factory.onboarding_wireframe_path())
self.builder.connect_signals(self)

self.window = self.builder.get_object("onboardingwindow")
Expand Down Expand Up @@ -67,29 +68,17 @@ def go_next_slide(self, button=None):
self.execute_slide6()

def execute_slide1(self):
conf_path = "/etc/howdy"

self.downloadoutputlabel = self.builder.get_object("downloadoutputlabel")
eventbox = self.builder.get_object("downloadeventbox")
eventbox.modify_bg(gtk.StateType.NORMAL, gdk.Color(red=0, green=0, blue=0))

for lib_site in ("/lib", "/usr/lib", "/lib64", "/usr/lib64"):
if os.path.exists(lib_site + "/security/howdy/"):
break
else:
lib_site = None

if lib_site is None:
self.downloadoutputlabel.set_text(_("Unable to find Howdy's installation location"))
return


if os.path.exists(conf_path + "/dlib-data/shape_predictor_5_face_landmarks.dat"):
# TODO: Better way to do this?
if os.path.exists(paths_factory.dlib_data_dir_path() / "shape_predictor_5_face_landmarks.dat"):
self.downloadoutputlabel.set_text(_("Datafiles have already been downloaded!\nClick Next to continue"))
self.enable_next()
return

self.proc = subprocess.Popen("./install.sh", stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True, cwd=conf_path + "/howdy/dlib-data")
self.proc = subprocess.Popen("./install.sh", stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True, cwd=paths_factory.dlib_data_dir_path())

self.download_lines = []
self.read_download_line()
Expand Down
13 changes: 13 additions & 0 deletions howdy-gtk/src/paths.py.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from pathlib import PurePath

# Define the absolute path to the config directory
config_dir = PurePath("@config_dir@")

# Define the absolute path to the DLib models data directory
dlib_data_dir = PurePath("@dlib_data_dir@")

# Define the absolute path to the Howdy user models directory
user_models_dir = PurePath("@user_models_dir@")

# Define the absolute path to the Howdy data directory
data_dir = PurePath("@data_dir@")
32 changes: 32 additions & 0 deletions howdy-gtk/src/paths_factory.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
from pathlib import PurePath
import paths


def config_file_path() -> str:
"""Return the path to the config file"""
return str(paths.config_dir / "config.ini")


def user_models_dir_path() -> PurePath:
"""Return the path to the user models directory"""
return paths.user_models_dir


def logo_path() -> str:
"""Return the path to the logo file"""
return str(paths.data_dir / "logo.png")


def onboarding_wireframe_path() -> str:
"""Return the path to the onboarding wireframe file"""
return str(paths.data_dir / "onboarding.glade")


def main_window_wireframe_path() -> str:
"""Return the path to the main window wireframe file"""
return str(paths.data_dir / "main.glade")


def dlib_data_dir_path() -> PurePath:
"""Return the path to the dlib data directory"""
return paths.dlib_data_dir
3 changes: 2 additions & 1 deletion howdy-gtk/src/tab_video.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import configparser

from i18n import _
import paths_factory

from gi.repository import Gtk as gtk
from gi.repository import Gdk as gdk
Expand All @@ -17,7 +18,7 @@ def on_page_switch(self, notebook, page, page_num):

try:
self.config = configparser.ConfigParser()
self.config.read("/etc/howdy/config.ini")
self.config.read(paths_factory.config_file_path())
except Exception:
print(_("Can't open camera"))

Expand Down
7 changes: 4 additions & 3 deletions howdy-gtk/src/window.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import subprocess

from i18n import _
import paths_factory

# Make sure we have the libs we need
gi.require_version("Gtk", "3.0")
Expand All @@ -26,7 +27,7 @@ def __init__(self):
self.connect("delete_event", self.exit)

self.builder = gtk.Builder()
self.builder.add_from_file("./main.glade")
self.builder.add_from_file(paths_factory.main_window_wireframe_path())
self.builder.connect_signals(self)

self.window = self.builder.get_object("mainwindow")
Expand All @@ -49,7 +50,7 @@ def __init__(self):
# Add the treeview
self.modellistbox.add(self.treeview)

filelist = os.listdir("/etc/howdy/models")
filelist = os.listdir(paths_factory.user_models_dir_path())
self.active_user = ""

self.userlist.items = 0
Expand Down Expand Up @@ -120,7 +121,7 @@ def exit(self, widget, context):
elevate.elevate()

# If no models have been created yet or when it is forced, start the onboarding
if "--force-onboarding" in sys.argv or not os.path.exists("/etc/howdy/models"):
if "--force-onboarding" in sys.argv or not os.path.exists(paths_factory.user_models_dir_path()):
import onboarding
onboarding.OnboardingWindow()

Expand Down
2 changes: 1 addition & 1 deletion howdy/debian/howdy.manpages
Original file line number Diff line number Diff line change
@@ -1 +1 @@
debian/howdy.1
howdy.1
File renamed without changes.
1 change: 1 addition & 0 deletions howdy/meson.build
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
subdir('src')
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

_howdy() {
local cur prev opts
local config_path="@config_path@"
source _variables
COMPREPLY=()
# The argument typed so far
cur="${COMP_WORDS[COMP_CWORD]}"
Expand All @@ -20,7 +22,7 @@ _howdy() {
;;
# For disable, grab the current "disabled" config option and give the reverse
"disable")
local status=$(cut -d'=' -f2 <<< $(cat /etc/howdy/config.ini | grep 'disabled =') | xargs echo -n)
local status=$(cut -d'=' -f2 <<< $(cat $config_path | grep 'disabled =') | xargs echo -n)

[ "$status" == "false" ] && COMPREPLY="true" || COMPREPLY="false"
return 0
Expand Down
3 changes: 3 additions & 0 deletions howdy/src/bin/howdy.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/sh

env python3 "@script_path@" "$@"
22 changes: 10 additions & 12 deletions howdy/src/cli/add.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import configparser
import builtins
import numpy as np
import paths_factory

from recorders.video_capture import VideoCapture
from i18n import _
Expand All @@ -26,39 +27,36 @@
# OpenCV needs to be imported after dlib
import cv2

# Define the absolute path to the config directory
config_path = "/etc/howdy"

# Test if at lest 1 of the data files is there and abort if it's not
if not os.path.isfile(config_path + "/dlib-data/shape_predictor_5_face_landmarks.dat"):
if not os.path.isfile(paths_factory.shape_predictor_5_face_landmarks_path()):
print(_("Data files have not been downloaded, please run the following commands:"))
print("\n\tcd " + config_path + "/dlib-data")
print("\n\tcd " + paths_factory.dlib_data_dir_path())
print("\tsudo ./install.sh\n")
sys.exit(1)

# Read config from disk
config = configparser.ConfigParser()
config.read(config_path + "/config.ini")
config.read(paths_factory.config_file_path())

use_cnn = config.getboolean("core", "use_cnn", fallback=False)
if use_cnn:
face_detector = dlib.cnn_face_detection_model_v1(config_path + "/dlib-data/mmod_human_face_detector.dat")
face_detector = dlib.cnn_face_detection_model_v1(paths_factory.mmod_human_face_detector_path())
else:
face_detector = dlib.get_frontal_face_detector()

pose_predictor = dlib.shape_predictor(config_path + "/dlib-data/shape_predictor_5_face_landmarks.dat")
face_encoder = dlib.face_recognition_model_v1(config_path + "/dlib-data/dlib_face_recognition_resnet_model_v1.dat")
pose_predictor = dlib.shape_predictor(paths_factory.shape_predictor_5_face_landmarks_path())
face_encoder = dlib.face_recognition_model_v1(paths_factory.dlib_face_recognition_resnet_model_v1_path())

user = builtins.howdy_user
# The permanent file to store the encoded model in
enc_file = config_path + "/models/" + user + ".dat"
enc_file = paths_factory.user_model_path(user)
# Known encodings
encodings = []

# Make the ./models folder if it doesn't already exist
if not os.path.exists(config_path + "/models"):
if not os.path.exists(paths_factory.user_models_dir_path()):
print(_("No face model folder found, creating one"))
os.makedirs(config_path + "/models")
os.makedirs(paths_factory.user_models_dir_path())

# To try read a premade encodings file if it exists
try:
Expand Down
Loading
Loading