зеркало из https://github.com/microsoft/InQRy.git
139 строки
5.4 KiB
Python
139 строки
5.4 KiB
Python
import re
|
|
import subprocess
|
|
import sys
|
|
from tkinter import Button, E, Entry, Label, OptionMenu, StringVar, Tk, W, messagebox
|
|
|
|
from inqry.asset_qrcode import AssetQRCode
|
|
from inqry.form_instructions import FormInstructions
|
|
from inqry.system_specs.systemspecs import SystemSpecs
|
|
|
|
|
|
class InQRyGUI: # TODO: Extract GUI attributes to methods
|
|
def __init__(self):
|
|
self.specs = SystemSpecs()
|
|
self.form_instructions = FormInstructions(self.specs)
|
|
self.asset_qr = AssetQRCode()
|
|
|
|
self.root_window = Tk()
|
|
self.root_window.title('InQRy')
|
|
|
|
self.form_options_label = Label(self.root_window, text='Form Factor:')
|
|
self.form_options_label.grid(row=1, column=1, sticky=E)
|
|
|
|
self.form_options = tuple(self.form_instructions.form_types.keys())[0:2]
|
|
self.form_selection = StringVar()
|
|
self.form_selection.set(self.form_options[0])
|
|
self.form_menu = OptionMenu(self.root_window, self.form_selection, *self.form_options)
|
|
self.form_menu.grid(row=1, column=2, sticky=W)
|
|
|
|
self.qrcode_options_label = Label(self.root_window, text='QR Code Type:')
|
|
self.qrcode_options_label.grid(row=2, column=1, sticky=E)
|
|
|
|
self.qrcode_options = ['Create Asset', 'New Model']
|
|
self.qrcode_selection = StringVar()
|
|
self.qrcode_selection.set(self.qrcode_options[0])
|
|
self.qrcode_menu = OptionMenu(self.root_window, self.qrcode_selection, *self.qrcode_options)
|
|
self.qrcode_menu.grid(row=2, column=2, sticky=W)
|
|
|
|
self.alias_label = Label(self.root_window, text='Alias:')
|
|
self.alias_label.grid(row=3, column=1, sticky=E)
|
|
|
|
self.alias_entry = Entry(self.root_window)
|
|
self.alias_entry.grid(row=3, column=2)
|
|
|
|
self.asset_tag_label = Label(self.root_window, text='Asset Tag:')
|
|
self.asset_tag_label.grid(row=4, column=1, sticky=E)
|
|
|
|
self.asset_tag_entry = Entry(self.root_window)
|
|
self.asset_tag_entry.grid(row=4, column=2)
|
|
|
|
# Instantiate the "Show" button for door-to-door inventory
|
|
self.generate_qr_button = Button(self.root_window, text='Show QR Code', command=self.display)
|
|
self.generate_qr_button.grid(row=5, column=1)
|
|
|
|
self.generate_qr_button = Button(self.root_window, text='Save QR Code to Desktop', command=self.save)
|
|
self.generate_qr_button.grid(row=5, column=2)
|
|
|
|
def save(self):
|
|
data = self.gather_user_input()
|
|
try:
|
|
filename = data[2] + '-' + data[1]
|
|
except TypeError:
|
|
filename = data[3] + '-' + data[0]
|
|
try:
|
|
return self.asset_qr.save(filename, self.form_instructions.gui_helper(*data))
|
|
except TypeError:
|
|
print('Improper formatting.')
|
|
except FileExistsError:
|
|
error_message_box('File already exists.')
|
|
|
|
def display(self):
|
|
data = self.gather_user_input()
|
|
return self.asset_qr.display(self.form_instructions.gui_helper(*data))
|
|
|
|
def gather_user_input(self) -> tuple:
|
|
if self.qrcode_selection.get() == 'New Model':
|
|
return self.qrcode_selection.get(), None, None, self.form_selection.get()
|
|
|
|
return self.qrcode_selection.get(), self.get_asset_tag(), self.get_alias(), self.form_selection.get()
|
|
|
|
def _validate_field_contents(self, contents, field):
|
|
patterns = {'Alias': (re.compile(r'^(v\-)?[A-Za-z]+$'),
|
|
'The Alias has to be a v- followed by more then one letter. The v- can be ommited.'),
|
|
'Asset Tag': (re.compile(r'^E?\d{7}$'),
|
|
'The Asset Tag has to be an E followed by 7 numbers. The E can be ommited.')}
|
|
|
|
validator, human_readable = patterns[field]
|
|
|
|
if bool(re.match(validator, contents)):
|
|
return contents
|
|
|
|
error_message = '{} is not properly formatted.'.format(field)
|
|
error_message_box(error_message)
|
|
raise ValueError(error_message)
|
|
|
|
def get_alias(self):
|
|
return self._validate_field_contents(self.alias_entry.get(), 'Alias')
|
|
|
|
def get_asset_tag(self):
|
|
return self._validate_field_contents(self.asset_tag_entry.get(), 'Asset Tag')
|
|
|
|
def obtain_default_dimensions_for_the_root_gui_object(self):
|
|
return tuple(int(_) for _ in self.root_window.geometry().split('+')[0].split('x'))
|
|
|
|
def calculate_center_coordinates(self, screen_dimension, current_dimension):
|
|
return (screen_dimension // 2) - (current_dimension // 2)
|
|
|
|
def center(self):
|
|
self.root_window.update_idletasks()
|
|
size = self.obtain_default_dimensions_for_the_root_gui_object()
|
|
height = size[0]
|
|
width = size[1]
|
|
|
|
x = self.calculate_center_coordinates(self.root_window.winfo_screenwidth(), height)
|
|
y = self.calculate_center_coordinates(self.root_window.winfo_screenheight(), width)
|
|
self.root_window.geometry('{}x{}+{}+{}'.format(height, width, x, y))
|
|
|
|
|
|
def error_message_box(message: str):
|
|
messagebox.showerror('Oops!', message)
|
|
|
|
|
|
def mobile_capability(): # TODO: Re-implement mobile_capability() into GUI
|
|
if sys.platform == 'darwin':
|
|
try:
|
|
subprocess.check_output(['/usr/local/bin/cfgutil'])
|
|
return 'active'
|
|
except FileNotFoundError:
|
|
print(
|
|
'''
|
|
No such file or directory: "/usr/local/bin/cfgutil"
|
|
|
|
You must install cfgutil using Apple Configurator in order to
|
|
use InQRy with a mobile device.
|
|
'''
|
|
)
|
|
return 'disable'
|
|
else:
|
|
pass
|