diff --git a/howdy-gtk/bin/howdy-gtk.in b/howdy-gtk/bin/howdy-gtk.in new file mode 100644 index 0000000..1ea89f7 --- /dev/null +++ b/howdy-gtk/bin/howdy-gtk.in @@ -0,0 +1,3 @@ +#!/bin/sh + +env python3 "@script_path@" "$@" \ No newline at end of file diff --git a/howdy-gtk/meson.build b/howdy-gtk/meson.build new file mode 100644 index 0000000..a542977 --- /dev/null +++ b/howdy-gtk/meson.build @@ -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', +) \ No newline at end of file diff --git a/howdy-gtk/src/authsticky.py b/howdy-gtk/src/authsticky.py index 9d80867..4a8c8a3 100644 --- a/howdy-gtk/src/authsticky.py +++ b/howdy-gtk/src/authsticky.py @@ -3,6 +3,7 @@ import cairo import gi import signal import sys +import paths_factory import os from i18n import _ @@ -32,9 +33,7 @@ class StickyWindow(gtk.Window): 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) diff --git a/howdy-gtk/src/onboarding.py b/howdy-gtk/src/onboarding.py index a941493..e6a4aa7 100644 --- a/howdy-gtk/src/onboarding.py +++ b/howdy-gtk/src/onboarding.py @@ -3,6 +3,7 @@ import os import re import time import subprocess +import paths_factory from i18n import _ @@ -22,7 +23,7 @@ class OnboardingWindow(gtk.Window): 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") @@ -67,29 +68,17 @@ class OnboardingWindow(gtk.Window): 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() diff --git a/howdy-gtk/src/paths.py.in b/howdy-gtk/src/paths.py.in new file mode 100644 index 0000000..91f2bf5 --- /dev/null +++ b/howdy-gtk/src/paths.py.in @@ -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@") \ No newline at end of file diff --git a/howdy-gtk/src/paths_factory.py b/howdy-gtk/src/paths_factory.py new file mode 100644 index 0000000..b02a900 --- /dev/null +++ b/howdy-gtk/src/paths_factory.py @@ -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 diff --git a/howdy-gtk/src/tab_video.py b/howdy-gtk/src/tab_video.py index 2a8617a..4f151b2 100644 --- a/howdy-gtk/src/tab_video.py +++ b/howdy-gtk/src/tab_video.py @@ -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 @@ -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")) diff --git a/howdy-gtk/src/window.py b/howdy-gtk/src/window.py index 737b7a4..f43e35d 100644 --- a/howdy-gtk/src/window.py +++ b/howdy-gtk/src/window.py @@ -7,6 +7,7 @@ import elevate import subprocess from i18n import _ +import paths_factory # Make sure we have the libs we need gi.require_version("Gtk", "3.0") @@ -26,7 +27,7 @@ class MainWindow(gtk.Window): 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") @@ -49,7 +50,7 @@ class MainWindow(gtk.Window): # 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 @@ -120,7 +121,7 @@ signal.signal(signal.SIGINT, signal.SIG_DFL) 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() diff --git a/howdy/meson.build b/howdy/meson.build new file mode 100644 index 0000000..7edf76f --- /dev/null +++ b/howdy/meson.build @@ -0,0 +1 @@ +subdir('src') \ No newline at end of file diff --git a/howdy/src/compare.py b/howdy/src/compare.py index ccc4a40..00d0348 100644 --- a/howdy/src/compare.py +++ b/howdy/src/compare.py @@ -154,7 +154,7 @@ gtk_pipe = sys.stdout if gtk_stdout else subprocess.DEVNULL # Start the auth ui, register it to be always be closed on exit try: - gtk_proc = subprocess.Popen(["../howdy-gtk/src/init.py", "--start-auth-ui"], stdin=subprocess.PIPE, stdout=gtk_pipe, stderr=gtk_pipe) + gtk_proc = subprocess.Popen(["howdy-gtk", "--start-auth-ui"], stdin=subprocess.PIPE, stdout=gtk_pipe, stderr=gtk_pipe) atexit.register(exit) except FileNotFoundError: pass diff --git a/howdy/src/meson.build b/howdy/src/meson.build index 2fc7ec8..2f4fbc7 100644 --- a/howdy/src/meson.build +++ b/howdy/src/meson.build @@ -1,23 +1,11 @@ +if meson.is_subproject() project('howdy', 'cpp', license: 'MIT', version: 'beta', meson_version: '>= 0.64.0') +endif py = import('python').find_installation() py.dependency() -confdir = get_option('config_dir') != '' ? get_option('config_dir') : join_paths(get_option('sysconfdir'), 'howdy') -dlibdatadir = get_option('dlib_data_dir') != '' ? get_option('dlib_data_dir') : join_paths(confdir, 'dlib-data') -usermodelsdir = get_option('user_models_dir') != '' ? get_option('user_models_dir') : join_paths(confdir, 'models') -datadir = get_option('data_dir') != '' ? get_option('data_dir') : join_paths(get_option('prefix'), get_option('datadir'), 'howdy') -logpath = get_option('log_path') - -config_path = join_paths(confdir, 'config.ini') - -py_conf = configuration_data({ - 'config_dir': confdir, - 'dlib_data_dir': dlibdatadir, - 'user_models_dir': usermodelsdir, - 'data_dir': datadir, - 'log_path': logpath, -}) +py_conf = configuration_data(paths_dict) py_paths = configure_file( input: 'paths.py.in', diff --git a/howdy/src/paths_factory.py b/howdy/src/paths_factory.py index 0995243..5716ca5 100644 --- a/howdy/src/paths_factory.py +++ b/howdy/src/paths_factory.py @@ -40,8 +40,8 @@ def snapshot_path(snapshot: str) -> str: return str(snapshots_dir_path() / snapshot) -def user_models_dir_path() -> str: - return str(paths.user_models_dir) +def user_models_dir_path() -> PurePath: + return paths.user_models_dir def logo_path() -> str: diff --git a/meson.build b/meson.build new file mode 100644 index 0000000..4b92a19 --- /dev/null +++ b/meson.build @@ -0,0 +1,21 @@ +project('howdy', 'cpp', license: 'MIT', version: 'beta', meson_version: '>= 0.64.0') + +confdir = get_option('config_dir') != '' ? get_option('config_dir') : join_paths(get_option('sysconfdir'), 'howdy') +dlibdatadir = get_option('dlib_data_dir') != '' ? get_option('dlib_data_dir') : join_paths(confdir, 'dlib-data') +usermodelsdir = get_option('user_models_dir') != '' ? get_option('user_models_dir') : join_paths(confdir, 'models') +datadir = get_option('data_dir') != '' ? get_option('data_dir') : join_paths(get_option('prefix'), get_option('datadir'), 'howdy') +logpath = get_option('log_path') + +config_path = join_paths(confdir, 'config.ini') + +paths_dict = { + 'config_dir': confdir, + 'dlib_data_dir': dlibdatadir, + 'user_models_dir': usermodelsdir, + 'data_dir': datadir, + 'log_path': logpath, +} + +# We need to keep this order beause howdy-gtk defines the gtk script path +subdir('howdy-gtk') +subdir('howdy') \ No newline at end of file diff --git a/howdy/src/meson.options b/meson.options similarity index 100% rename from howdy/src/meson.options rename to meson.options diff --git a/howdy/src/meson_options.txt b/meson_options.txt similarity index 100% rename from howdy/src/meson_options.txt rename to meson_options.txt