mirror of
https://github.com/boltgolt/howdy.git
synced 2024-09-19 09:51:19 +02:00
Added entire onboarding flow
This commit is contained in:
parent
4f3188cae5
commit
9f4c1a7fe6
5 changed files with 758 additions and 9 deletions
|
@ -2,6 +2,21 @@
|
|||
<!-- Generated with glade 3.18.3 -->
|
||||
<interface domain="howdy">
|
||||
<requires lib="gtk+" version="3.10"/>
|
||||
<object class="GtkImage" id="iconadd">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="stock">gtk-add</property>
|
||||
</object>
|
||||
<object class="GtkImage" id="iconadduser">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="stock">gtk-add</property>
|
||||
</object>
|
||||
<object class="GtkImage" id="icondelete">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="stock">gtk-delete</property>
|
||||
</object>
|
||||
<object class="GtkWindow" id="mainwindow">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_top">5</property>
|
||||
|
@ -57,7 +72,9 @@
|
|||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="image_position">bottom</property>
|
||||
<property name="image">iconadduser</property>
|
||||
<property name="relief">none</property>
|
||||
<property name="always_show_image">True</property>
|
||||
<signal name="clicked" handler="on_user_add" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
|
@ -113,11 +130,11 @@
|
|||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="addbutton">
|
||||
<property name="label">gtk-add</property>
|
||||
<property name="label">Add</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="image">iconadd</property>
|
||||
<property name="xalign">0.5899999737739563</property>
|
||||
<property name="always_show_image">True</property>
|
||||
<signal name="clicked" handler="on_model_add" swapped="no"/>
|
||||
|
@ -131,12 +148,12 @@
|
|||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="deletebutton">
|
||||
<property name="label">gtk-delete</property>
|
||||
<property name="label">Delete</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="margin_right">5</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="image">icondelete</property>
|
||||
<property name="always_show_image">True</property>
|
||||
<signal name="clicked" handler="on_model_delete" swapped="no"/>
|
||||
</object>
|
470
howdy-gtk/src/onboarding.glade
Normal file
470
howdy-gtk/src/onboarding.glade
Normal file
|
@ -0,0 +1,470 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generated with glade 3.18.3 -->
|
||||
<interface>
|
||||
<requires lib="gtk+" version="3.12"/>
|
||||
<object class="GtkImage" id="iconcancel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_right">4</property>
|
||||
<property name="stock">gtk-cancel</property>
|
||||
</object>
|
||||
<object class="GtkImage" id="iconfinish">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_right">5</property>
|
||||
<property name="stock">gtk-apply</property>
|
||||
</object>
|
||||
<object class="GtkImage" id="iconforward">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_left">4</property>
|
||||
<property name="stock">gtk-go-forward</property>
|
||||
</object>
|
||||
<object class="GtkImage" id="iconscan">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_left">5</property>
|
||||
<property name="stock">gtk-media-play</property>
|
||||
</object>
|
||||
<object class="GtkWindow" id="onboardingwindow">
|
||||
<property name="width_request">500</property>
|
||||
<property name="height_request">400</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="title" translatable="yes">Welcome to Howdy</property>
|
||||
<property name="window_position">center</property>
|
||||
<property name="icon">logo.png</property>
|
||||
<property name="type_hint">menu</property>
|
||||
<property name="gravity">center</property>
|
||||
<child>
|
||||
<object class="GtkBox" id="slidecontainer">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="resize_mode">immediate</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkBox" id="slide4">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="no_show_all">True</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label9">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_top">20</property>
|
||||
<property name="label" translatable="yes">Setup is done!</property>
|
||||
<attributes>
|
||||
<attribute name="weight" value="bold"/>
|
||||
</attributes>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label10">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_left">10</property>
|
||||
<property name="margin_right">10</property>
|
||||
<property name="margin_top">10</property>
|
||||
<property name="margin_bottom">20</property>
|
||||
<property name="label" translatable="yes">We're done! Howdy is now active on this computer. Try doing anything you would normally have to type your password for to authenticate, like running a command with sudo.
|
||||
|
||||
You can open the Howdy Configurator later on to change more advanced settings or add additional models. Press Finish below to close this window. </property>
|
||||
<property name="justify">center</property>
|
||||
<property name="wrap">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="slide3">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="no_show_all">True</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label4">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_top">20</property>
|
||||
<property name="label" translatable="yes">Adding a face model</property>
|
||||
<attributes>
|
||||
<attribute name="weight" value="bold"/>
|
||||
</attributes>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label5">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_left">10</property>
|
||||
<property name="margin_right">10</property>
|
||||
<property name="margin_top">10</property>
|
||||
<property name="margin_bottom">20</property>
|
||||
<property name="label" translatable="yes">To authenticate you Howdy needs to save a model of your face to recognise you. Press the Scan button below to start the facial scan.</property>
|
||||
<property name="justify">center</property>
|
||||
<property name="wrap">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="box1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="scanbutton">
|
||||
<property name="label" translatable="yes">Start face scan</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="has_focus">True</property>
|
||||
<property name="is_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="margin_left">50</property>
|
||||
<property name="margin_right">50</property>
|
||||
<property name="image">iconscan</property>
|
||||
<property name="relief">none</property>
|
||||
<property name="image_position">right</property>
|
||||
<property name="always_show_image">True</property>
|
||||
<signal name="clicked" handler="on_scanbutton_click" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="slide2">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="no_show_all">True</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label2">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_top">20</property>
|
||||
<property name="label" translatable="yes">Configuring webcam</property>
|
||||
<attributes>
|
||||
<attribute name="weight" value="bold"/>
|
||||
</attributes>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label3">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_left">10</property>
|
||||
<property name="margin_right">10</property>
|
||||
<property name="margin_top">10</property>
|
||||
<property name="margin_bottom">20</property>
|
||||
<property name="label" translatable="yes">Howdy will search your system automatically for any available cameras, so make sure your webcam is connected. After detection a list of usable webcams will be shown. Pick the one you want to use and click Next.</property>
|
||||
<property name="justify">center</property>
|
||||
<property name="wrap">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="devicelistbox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="opacity">0.89000000000000001</property>
|
||||
<property name="margin_left">10</property>
|
||||
<property name="margin_right">10</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="loadinglabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_top">15</property>
|
||||
<property name="label" translatable="yes">Testing your webcams, please wait...</property>
|
||||
<attributes>
|
||||
<attribute name="style" value="italic"/>
|
||||
</attributes>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="slide1">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="no_show_all">True</property>
|
||||
<property name="margin_bottom">10</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label8">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_top">20</property>
|
||||
<property name="label" translatable="yes">Downloading data files</property>
|
||||
<attributes>
|
||||
<attribute name="weight" value="bold"/>
|
||||
</attributes>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_left">10</property>
|
||||
<property name="margin_right">10</property>
|
||||
<property name="margin_top">10</property>
|
||||
<property name="margin_bottom">20</property>
|
||||
<property name="label" translatable="yes">Howdy needs three pre trained facial recognition datasets to be able to recognise you, which will be downloaded now. You can see the download progress below.</property>
|
||||
<property name="justify">center</property>
|
||||
<property name="wrap">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEventBox" id="downloadeventbox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="downloadoutputlabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_left">10</property>
|
||||
<property name="margin_right">10</property>
|
||||
<property name="margin_top">10</property>
|
||||
<property name="label" translatable="yes">Starting download...</property>
|
||||
<property name="justify">center</property>
|
||||
<attributes>
|
||||
<attribute name="foreground" value="#f3f3f3f3f3f3"/>
|
||||
<attribute name="background" value="#000000000000"/>
|
||||
</attributes>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="slide0">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkImage" id="image2">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_top">20</property>
|
||||
<property name="margin_bottom">10</property>
|
||||
<property name="xpad">7</property>
|
||||
<property name="ypad">13</property>
|
||||
<property name="pixbuf">logo_about.png</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label6">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_top">5</property>
|
||||
<property name="label" translatable="yes">Welcome to Howdy!</property>
|
||||
<attributes>
|
||||
<attribute name="scale" value="2"/>
|
||||
</attributes>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label7">
|
||||
<property name="width_request">100</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="halign">center</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="margin_left">20</property>
|
||||
<property name="margin_right">20</property>
|
||||
<property name="margin_top">10</property>
|
||||
<property name="label" translatable="yes">This wizard will walk you through the setup process and automatically configure Howdy for you. Press next to continue.</property>
|
||||
<property name="justify">center</property>
|
||||
<property name="wrap">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">6</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="navigationbar">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_bottom">10</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="cancelbutton">
|
||||
<property name="label" translatable="yes">Cancel</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="margin_left">10</property>
|
||||
<property name="image">iconcancel</property>
|
||||
<property name="always_show_image">True</property>
|
||||
<signal name="clicked" handler="exit" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="nextbutton">
|
||||
<property name="label" translatable="yes">Next</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="has_focus">True</property>
|
||||
<property name="is_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="margin_right">10</property>
|
||||
<property name="image">iconforward</property>
|
||||
<property name="relief">none</property>
|
||||
<property name="image_position">right</property>
|
||||
<property name="always_show_image">True</property>
|
||||
<signal name="clicked" handler="go_next_slide" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="pack_type">end</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="finishbutton">
|
||||
<property name="label" translatable="yes">Finish setup</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="no_show_all">True</property>
|
||||
<property name="margin_right">10</property>
|
||||
<property name="image">iconfinish</property>
|
||||
<property name="relief">none</property>
|
||||
<property name="always_show_image">True</property>
|
||||
<signal name="clicked" handler="exit" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="pack_type">end</property>
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="pack_type">end</property>
|
||||
<property name="position">7</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
256
howdy-gtk/src/onboarding.py
Normal file
256
howdy-gtk/src/onboarding.py
Normal file
|
@ -0,0 +1,256 @@
|
|||
import sys
|
||||
import os
|
||||
import re
|
||||
import time
|
||||
import subprocess
|
||||
|
||||
from i18n import _
|
||||
|
||||
from gi.repository import Gtk as gtk
|
||||
from gi.repository import Gdk as gdk
|
||||
from gi.repository import GObject as gobject
|
||||
from gi.repository import Pango as pango
|
||||
|
||||
|
||||
class OnboardingWindow(gtk.Window):
|
||||
def __init__(self):
|
||||
"""Initialize the sticky window"""
|
||||
print("create")
|
||||
# Make the class a GTK window
|
||||
gtk.Window.__init__(self)
|
||||
|
||||
self.connect("destroy", self.exit)
|
||||
self.connect("delete_event", self.exit)
|
||||
|
||||
self.builder = gtk.Builder()
|
||||
self.builder.add_from_file("./onboarding.glade")
|
||||
self.builder.connect_signals(self)
|
||||
|
||||
self.window = self.builder.get_object("onboardingwindow")
|
||||
self.nextbutton = self.builder.get_object("nextbutton")
|
||||
|
||||
self.slides = [
|
||||
self.builder.get_object("slide0"),
|
||||
self.builder.get_object("slide1"),
|
||||
self.builder.get_object("slide2"),
|
||||
self.builder.get_object("slide3"),
|
||||
self.builder.get_object("slide4")
|
||||
]
|
||||
|
||||
self.window.show_all()
|
||||
self.window.resize(500, 400)
|
||||
|
||||
self.window.current_slide = 0
|
||||
|
||||
# Start GTK main loop
|
||||
gtk.main()
|
||||
|
||||
def go_next_slide(self, button=None):
|
||||
self.nextbutton.set_sensitive(False)
|
||||
|
||||
self.slides[self.window.current_slide].hide()
|
||||
# self.window.current_slide += 1
|
||||
self.slides[self.window.current_slide + 1].show()
|
||||
self.window.current_slide += 1
|
||||
|
||||
if self.window.current_slide == 1:
|
||||
self.execute_slide1()
|
||||
elif self.window.current_slide == 2:
|
||||
gobject.timeout_add(10, self.execute_slide2)
|
||||
elif self.window.current_slide == 3:
|
||||
self.execute_slide3()
|
||||
elif self.window.current_slide == 4:
|
||||
self.execute_slide4()
|
||||
|
||||
def execute_slide1(self):
|
||||
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))
|
||||
|
||||
if os.path.exists("/lib/security/howdy/dlib-data/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="/lib/security/howdy/dlib-data")
|
||||
|
||||
self.download_lines = []
|
||||
self.read_download_line()
|
||||
|
||||
def read_download_line(self):
|
||||
line = self.proc.stdout.readline()
|
||||
print(line)
|
||||
self.download_lines.append(line.decode("utf-8"))
|
||||
|
||||
if len(self.download_lines) > 10:
|
||||
self.download_lines.pop(0)
|
||||
|
||||
self.downloadoutputlabel.set_text(" ".join(self.download_lines))
|
||||
|
||||
if line:
|
||||
gobject.timeout_add(10, self.read_download_line)
|
||||
return
|
||||
|
||||
# Wait for the process to finish and check the status code
|
||||
if self.proc.wait(5) != 0:
|
||||
self.show_error(_("Error while downloading datafiles"), " ".join(self.download_lines))
|
||||
|
||||
self.downloadoutputlabel.set_text(_("Done!\nClick Next to continue"))
|
||||
self.enable_next()
|
||||
|
||||
def execute_slide2(self):
|
||||
def is_gray(frame):
|
||||
for row in frame:
|
||||
for pixel in row:
|
||||
if not pixel[0] == pixel[1] == pixel[2]:
|
||||
return False
|
||||
return True
|
||||
|
||||
try:
|
||||
import cv2
|
||||
except Exception:
|
||||
self.show_error(_("Error while importing OpenCV2"), _("Try reinstalling cv2"))
|
||||
|
||||
device_ids = os.listdir("/dev/v4l/by-path")
|
||||
device_rows = []
|
||||
|
||||
if not device_ids:
|
||||
self.show_error(_("No webcams found on system"), _("Please configure your camera yourself if you are sure a compatible camera is connected"))
|
||||
|
||||
# Loop though all devices
|
||||
for dev in device_ids:
|
||||
time.sleep(.5)
|
||||
|
||||
# The full path to the device is the default name
|
||||
device_path = "/dev/v4l/by-path/" + dev
|
||||
device_name = dev
|
||||
|
||||
# Get the udevadm details to try to get a better name
|
||||
udevadm = subprocess.check_output(["udevadm info -r --query=all -n " + device_path], shell=True).decode("utf-8")
|
||||
|
||||
# Loop though udevadm to search for a better name
|
||||
for line in udevadm.split("\n"):
|
||||
# Match it and encase it in quotes
|
||||
re_name = re.search('product.*=(.*)$', line, re.IGNORECASE)
|
||||
if re_name:
|
||||
device_name = re_name.group(1)
|
||||
|
||||
try:
|
||||
capture = cv2.VideoCapture(device_path)
|
||||
capture.grab()
|
||||
ret, frame = capture.read()
|
||||
except Exception:
|
||||
device_rows.append([device_name, device_path, -9, _("No, camera can't be opened")])
|
||||
continue
|
||||
|
||||
if not is_gray(frame):
|
||||
device_rows.append([device_name, device_path, -5, _("No, not an infrared camera")])
|
||||
continue
|
||||
|
||||
time.sleep(.2)
|
||||
|
||||
ret, frame = capture.read()
|
||||
|
||||
if not is_gray(frame):
|
||||
device_rows.append([device_name, device_path, -5, _("No, not an infrared camera")])
|
||||
continue
|
||||
|
||||
device_rows.append([device_name, device_path, 5, _("Yes, compatible infrared camera")])
|
||||
|
||||
capture.release()
|
||||
|
||||
device_rows = sorted(device_rows, key=lambda k: -k[2])
|
||||
|
||||
self.loadinglabel = self.builder.get_object("loadinglabel")
|
||||
self.devicelistbox = self.builder.get_object("devicelistbox")
|
||||
|
||||
self.treeview = gtk.TreeView()
|
||||
self.treeview.set_vexpand(True)
|
||||
|
||||
# Set the coloums
|
||||
for i, column in enumerate([_("Camera identifier or path"), _("Recommended")]):
|
||||
cell = gtk.CellRendererText()
|
||||
cell.set_property("ellipsize", pango.EllipsizeMode.END)
|
||||
col = gtk.TreeViewColumn(column, cell, text=i)
|
||||
self.treeview.append_column(col)
|
||||
|
||||
# Add the treeview
|
||||
self.devicelistbox.add(self.treeview)
|
||||
|
||||
# Create a datamodel
|
||||
self.listmodel = gtk.ListStore(str, str, str)
|
||||
|
||||
for device in device_rows:
|
||||
self.listmodel.append([device[0], device[3], device[1]])
|
||||
|
||||
self.treeview.set_model(self.listmodel)
|
||||
self.treeview.set_cursor(0)
|
||||
|
||||
self.loadinglabel.hide()
|
||||
self.treeview.show()
|
||||
self.enable_next()
|
||||
|
||||
def execute_slide3(self):
|
||||
selection = self.treeview.get_selection()
|
||||
(listmodel, rowlist) = selection.get_selected_rows()
|
||||
|
||||
if len(rowlist) != 1:
|
||||
self.show_error(_("Error selecting camera"))
|
||||
|
||||
device_path = listmodel.get_value(listmodel.get_iter(rowlist[0]), 2)
|
||||
self.proc = subprocess.Popen("howdy set device_path " + device_path, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True)
|
||||
|
||||
self.window.set_focus(self.builder.get_object("scanbutton"))
|
||||
|
||||
def on_scanbutton_click(self, button):
|
||||
status = self.proc.wait(2)
|
||||
|
||||
if status != 0:
|
||||
self.show_error(_("Error setting camera path"), _("Please set the camera path manually"))
|
||||
|
||||
self.dialog = gtk.MessageDialog(parent=self, flags=gtk.DialogFlags.MODAL)
|
||||
self.dialog.set_title(_("Creating Model"))
|
||||
self.dialog.props.text = _("Please look directly into the camera")
|
||||
self.dialog.show_all()
|
||||
|
||||
# Wait a bit to allow the user to read the dialog
|
||||
gobject.timeout_add(600, self.run_add)
|
||||
|
||||
def run_add(self):
|
||||
status, output = subprocess.getstatusoutput(["howdy add -y"])
|
||||
print(output)
|
||||
|
||||
self.dialog.destroy()
|
||||
|
||||
if status != 0:
|
||||
self.show_error(_("Can't save face model"), output)
|
||||
|
||||
gobject.timeout_add(10, self.go_next_slide)
|
||||
|
||||
def execute_slide4(self):
|
||||
self.nextbutton.hide()
|
||||
self.builder.get_object("cancelbutton").hide()
|
||||
|
||||
finishbutton = self.builder.get_object("finishbutton")
|
||||
finishbutton.show()
|
||||
self.window.set_focus(finishbutton)
|
||||
|
||||
def enable_next(self):
|
||||
self.nextbutton.set_sensitive(True)
|
||||
self.window.set_focus(self.nextbutton)
|
||||
|
||||
def show_error(self, error, secon=""):
|
||||
dialog = gtk.MessageDialog(parent=self, flags=gtk.DialogFlags.MODAL, type=gtk.MessageType.ERROR, buttons=gtk.ButtonsType.CLOSE)
|
||||
dialog.set_title(_("Howdy Error"))
|
||||
dialog.props.text = error
|
||||
dialog.format_secondary_text(secon)
|
||||
|
||||
dialog.run()
|
||||
|
||||
dialog.destroy()
|
||||
self.exit()
|
||||
|
||||
def exit(self, widget=None):
|
||||
"""Cleanly exit"""
|
||||
gtk.main_quit()
|
||||
sys.exit(0)
|
|
@ -28,7 +28,7 @@ class MainWindow(gtk.Window):
|
|||
self.connect("delete_event", self.exit)
|
||||
|
||||
self.builder = gtk.Builder()
|
||||
self.builder.add_from_file("./ui.glade")
|
||||
self.builder.add_from_file("./main.glade")
|
||||
self.builder.connect_signals(self)
|
||||
|
||||
self.window = self.builder.get_object("mainwindow")
|
||||
|
@ -41,9 +41,7 @@ class MainWindow(gtk.Window):
|
|||
|
||||
# Set the coloums
|
||||
for i, column in enumerate([_("ID"), _("Created"), _("Label")]):
|
||||
cell = gtk.CellRendererText()
|
||||
col = gtk.TreeViewColumn(column, cell, text=i)
|
||||
|
||||
col = gtk.TreeViewColumn(column, gtk.CellRendererText(), text=i)
|
||||
self.treeview.append_column(col)
|
||||
|
||||
# Add the treeview
|
||||
|
@ -114,6 +112,13 @@ signal.signal(signal.SIGINT, signal.SIG_DFL)
|
|||
# Make sure we run as sudo
|
||||
elevate.elevate()
|
||||
|
||||
# If no models have been created yet, start the onboarding
|
||||
if os.path.exists("/lib/security/howdy/models"):
|
||||
import onboarding
|
||||
onboarding.OnboardingWindow()
|
||||
|
||||
sys.exit(0)
|
||||
|
||||
# Class is split so it isn't too long, import split functions
|
||||
import tab_models
|
||||
MainWindow.on_user_add = tab_models.on_user_add
|
||||
|
|
|
@ -21,5 +21,6 @@ else
|
|||
fi
|
||||
|
||||
# Uncompress the data files and delete the original archive
|
||||
echo " "
|
||||
echo "Unpacking..."
|
||||
bzip2 -d -f *.bz2
|
||||
|
|
Loading…
Reference in a new issue