mirror of
https://github.com/boltgolt/howdy.git
synced 2024-09-12 09:41:18 +02:00
Added GUI listing, adding and deleting of models
This commit is contained in:
parent
a151338dac
commit
982641b92b
5 changed files with 167 additions and 124 deletions
2
howdy-gtk/debian/postinst
Normal file
2
howdy-gtk/debian/postinst
Normal file
|
@ -0,0 +1,2 @@
|
|||
#!/bin/sh
|
||||
pip3 install elevate
|
|
@ -76,7 +76,6 @@ class StickyWindow(gtk.Window):
|
|||
# Start GTK main loop
|
||||
gtk.main()
|
||||
|
||||
|
||||
def draw(self, widget, ctx):
|
||||
"""Draw the UI"""
|
||||
# Change cursor to the kill icon
|
||||
|
@ -123,7 +122,6 @@ class StickyWindow(gtk.Window):
|
|||
ctx.select_font_face("Arial", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL)
|
||||
ctx.show_text(subtext)
|
||||
|
||||
|
||||
def catch_stdin(self):
|
||||
"""Catch input from stdin and redraw"""
|
||||
global message, subtext
|
||||
|
@ -146,11 +144,11 @@ class StickyWindow(gtk.Window):
|
|||
# Fire this function again in 10ms, as we're waiting on IO in readline anyway
|
||||
gobject.timeout_add(10, self.catch_stdin)
|
||||
|
||||
|
||||
def exit(self, widget, context):
|
||||
"""Cleanly exit"""
|
||||
gtk.main_quit()
|
||||
|
||||
|
||||
# Make sure we quit on a SIGINT
|
||||
signal.signal(signal.SIGINT, signal.SIG_DFL)
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
<requires lib="gtk+" version="3.10"/>
|
||||
<object class="GtkWindow" id="mainwindow">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_top">5</property>
|
||||
<property name="title" translatable="yes" context="Window title">Howdy Configuration</property>
|
||||
<property name="window_position">center</property>
|
||||
<property name="icon">logo.png</property>
|
||||
|
@ -11,24 +12,26 @@
|
|||
<object class="GtkNotebook" id="notebook1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="show_border">False</property>
|
||||
<child>
|
||||
<object class="GtkPaned" id="paned1">
|
||||
<object class="GtkBox" id="box3">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkBox" id="box1">
|
||||
<object class="GtkBox" id="box4">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_left">5</property>
|
||||
<property name="margin_right">5</property>
|
||||
<property name="margin_top">5</property>
|
||||
<property name="spacing">10</property>
|
||||
<property name="spacing">5</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="userlabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="margin_left">10</property>
|
||||
<property name="label" translatable="yes">Active user:</property>
|
||||
<property name="label" translatable="yes">Showing saved models for:</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
|
@ -40,6 +43,7 @@
|
|||
<object class="GtkComboBoxText" id="userlist">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<signal name="changed" handler="on_user_change" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
|
@ -47,22 +51,6 @@
|
|||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="button2">
|
||||
<property name="label" translatable="yes">Add new model</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="margin_right">10</property>
|
||||
<property name="xalign">0.46000000834465027</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="pack_type">end</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="adduserbutton">
|
||||
<property name="label" translatable="yes">Add new user</property>
|
||||
|
@ -80,19 +68,23 @@
|
|||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="resize">False</property>
|
||||
<property name="shrink">True</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="modellistbox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_left">5</property>
|
||||
<property name="margin_right">5</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkSeparator" id="separator1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_top">5</property>
|
||||
<property name="margin_bottom">5</property>
|
||||
</object>
|
||||
<packing>
|
||||
|
@ -101,35 +93,74 @@
|
|||
<property name="position">0</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="box1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_right">5</property>
|
||||
<property name="margin_top">7</property>
|
||||
<property name="margin_bottom">5</property>
|
||||
<child>
|
||||
<object class="GtkTreeView" id="treeview3">
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="addbutton">
|
||||
<property name="label">gtk-add</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<child internal-child="selection">
|
||||
<object class="GtkTreeSelection" id="treeview-selection3"/>
|
||||
</child>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="xalign">0.5899999737739563</property>
|
||||
<property name="always_show_image">True</property>
|
||||
<signal name="clicked" handler="on_model_add" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="pack_type">end</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="deletebutton">
|
||||
<property name="label">gtk-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="always_show_image">True</property>
|
||||
<signal name="clicked" handler="on_model_delete" 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>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="resize">True</property>
|
||||
<property name="shrink">True</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="pack_type">end</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="tab_expand">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child type="tab">
|
||||
<object class="GtkLabel" id="modelstab">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_left">2</property>
|
||||
<property name="label" translatable="yes">Models</property>
|
||||
</object>
|
||||
<packing>
|
||||
|
@ -185,80 +216,4 @@
|
|||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<object class="GtkBox" id="modelrow">
|
||||
<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">5</property>
|
||||
<property name="margin_bottom">5</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">5</property>
|
||||
<child>
|
||||
<object class="GtkBox" id="box4">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkBox" id="box5">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="modelrowname">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">label</property>
|
||||
<property name="lines">3</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="label" translatable="yes">label</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="GtkButton" id="button1">
|
||||
<property name="label" translatable="yes">Delete</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="always_show_image">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="pack_type">end</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>
|
||||
</object>
|
||||
</interface>
|
||||
|
|
|
@ -5,6 +5,7 @@ import signal
|
|||
import sys
|
||||
import os
|
||||
import subprocess
|
||||
import elevate
|
||||
|
||||
# Make sure we have the libs we need
|
||||
gi.require_version("Gtk", "3.0")
|
||||
|
@ -31,6 +32,19 @@ class MainWindow(gtk.Window):
|
|||
self.userlist = self.builder.get_object("userlist")
|
||||
self.modellistbox = self.builder.get_object("modellistbox")
|
||||
|
||||
# Create a treeview that will list the model data
|
||||
self.treeview = gtk.TreeView()
|
||||
|
||||
# Set the coloums
|
||||
for i, column in enumerate(["ID", "Created", "Label"]):
|
||||
cell = gtk.CellRendererText()
|
||||
col = gtk.TreeViewColumn(column, cell, text=i)
|
||||
|
||||
self.treeview.append_column(col)
|
||||
|
||||
# Add the treeview
|
||||
self.modellistbox.add(self.treeview)
|
||||
|
||||
filelist = os.listdir("/lib/security/howdy/models")
|
||||
self.active_user = ""
|
||||
|
||||
|
@ -42,8 +56,6 @@ class MainWindow(gtk.Window):
|
|||
|
||||
self.userlist.set_active(0)
|
||||
|
||||
self.load_model_list()
|
||||
|
||||
self.window.show_all()
|
||||
# self.resize(300, 300)
|
||||
|
||||
|
@ -51,21 +63,94 @@ class MainWindow(gtk.Window):
|
|||
gtk.main()
|
||||
|
||||
def load_model_list(self):
|
||||
output = subprocess.check_output(["howdy", "list", "-U", self.active_user])
|
||||
"""(Re)load the model list"""
|
||||
|
||||
lines = output.decode("utf-8") .split("\n")[3:-2]
|
||||
print(lines)
|
||||
# Execute the list commond to get the models
|
||||
output = subprocess.check_output(["howdy", "list", "--plain", "-U", self.active_user])
|
||||
|
||||
newrow = self.builder.get_object("modelrow")
|
||||
# Split the output per line
|
||||
# lines = output.decode("utf-8").split("\n")
|
||||
lines = output.split("\n")
|
||||
|
||||
print(newrow.set_name("wat"))
|
||||
# Create a datamodel
|
||||
self.listmodel = gtk.ListStore(str, str, str)
|
||||
|
||||
self.modellistbox.add(newrow)
|
||||
newrow2 = self.builder.get_object("modelrow")
|
||||
# Add the models to the datamodel
|
||||
for i in range(len(lines)):
|
||||
self.listmodel.append(lines[i].split(","))
|
||||
|
||||
# print(newrow.get_object("modelrowname"))
|
||||
self.treeview.set_model(self.listmodel)
|
||||
|
||||
self.modellistbox.add(newrow2)
|
||||
def on_user_change(self, select):
|
||||
self.active_user = select.get_active_text()
|
||||
self.load_model_list()
|
||||
|
||||
def on_model_add(self, select):
|
||||
dialog = gtk.MessageDialog(parent=self, flags=gtk.DialogFlags.MODAL, type=gtk.MessageType.QUESTION, buttons=gtk.ButtonsType.OK_CANCEL)
|
||||
dialog.props.text = "Please enter a name for the new model, 24 characters max"
|
||||
dialog.set_title("Confirm Model Creation")
|
||||
# create the text input field
|
||||
entry = gtk.Entry()
|
||||
# create a horizontal box to pack the entry and a label
|
||||
hbox = gtk.HBox()
|
||||
hbox.pack_start(gtk.Label("Model name:"), False, 5, 5)
|
||||
hbox.pack_end(entry, True, True, 5)
|
||||
# some secondary text
|
||||
# add it and show it
|
||||
dialog.vbox.pack_end(hbox, True, True, 0)
|
||||
dialog.show_all()
|
||||
# go go go
|
||||
response = dialog.run()
|
||||
|
||||
text = entry.get_text()
|
||||
dialog.destroy()
|
||||
|
||||
if response == gtk.ResponseType.OK:
|
||||
dialog = gtk.MessageDialog(parent=self, flags=gtk.DialogFlags.MODAL)
|
||||
dialog.props.text = "Please look directly into the camera"
|
||||
dialog.set_title("Creating Model")
|
||||
dialog.show_all()
|
||||
|
||||
status, output = subprocess.getstatusoutput(["howdy add -y -U " + self.active_user])
|
||||
|
||||
dialog.destroy()
|
||||
|
||||
if status != 1:
|
||||
dialog = gtk.MessageDialog(parent=self, flags=gtk.DialogFlags.MODAL, type=gtk.MessageType.ERROR, buttons=gtk.ButtonsType.CLOSE)
|
||||
dialog.props.text = "Error while adding model, error code " + str(status) + ": \n\n"
|
||||
dialog.format_secondary_text(output)
|
||||
dialog.set_title("Howdy Error")
|
||||
dialog.run()
|
||||
dialog.destroy()
|
||||
|
||||
self.load_model_list()
|
||||
|
||||
def on_model_delete(self, select):
|
||||
selection = self.treeview.get_selection()
|
||||
(listmodel, rowlist) = selection.get_selected_rows()
|
||||
|
||||
if len(rowlist) == 1:
|
||||
id = listmodel.get_value(listmodel.get_iter(rowlist[0]), 0)
|
||||
name = listmodel.get_value(listmodel.get_iter(rowlist[0]), 2)
|
||||
|
||||
dialog = gtk.MessageDialog(parent=self, flags=gtk.DialogFlags.MODAL, buttons=gtk.ButtonsType.OK_CANCEL)
|
||||
dialog.props.text = "Are you sure you want to delete model " + id + " (" + name + ")?"
|
||||
dialog.set_title("Confirm Model Deletion")
|
||||
response = dialog.run()
|
||||
dialog.destroy()
|
||||
|
||||
if response == gtk.ResponseType.OK:
|
||||
status, output = subprocess.getstatusoutput(["howdy remove " + id + " -y -U " + self.active_user])
|
||||
|
||||
if status != 0:
|
||||
dialog = gtk.MessageDialog(parent=self, flags=gtk.DialogFlags.MODAL, type=gtk.MessageType.ERROR, buttons=gtk.ButtonsType.CLOSE)
|
||||
dialog.props.text = "Error while deleting model, error code " + str(status) + ": \n\n"
|
||||
dialog.format_secondary_text(output)
|
||||
dialog.set_title("Howdy Error")
|
||||
dialog.run()
|
||||
dialog.destroy()
|
||||
|
||||
self.load_model_list()
|
||||
|
||||
def exit(self, widget, context):
|
||||
"""Cleanly exit"""
|
||||
|
@ -76,5 +161,8 @@ class MainWindow(gtk.Window):
|
|||
# Make sure we quit on a SIGINT
|
||||
signal.signal(signal.SIGINT, signal.SIG_DFL)
|
||||
|
||||
# Make sure we run as sudo
|
||||
elevate.elevate()
|
||||
|
||||
# Open the GTK window
|
||||
window = MainWindow()
|
||||
|
|
|
@ -61,7 +61,7 @@ for enc in encodings:
|
|||
# Abort if no matching id was found
|
||||
if not found:
|
||||
print("No model with ID " + builtins.howdy_args.argument + " exists for " + user)
|
||||
sys.exit()
|
||||
sys.exit(1)
|
||||
|
||||
# Remove the entire file if this encoding is the only one
|
||||
if len(encodings) == 1:
|
||||
|
|
Loading…
Reference in a new issue