zaz-pass/source/pythonpath/zpass.py

349 lines
8.1 KiB
Python

#!/usr/bin/env python3
import string
import random
import easymacro as app
from stats import PasswordStats
_ = None
PREFIX = 'zazpass'
DEFAULT_LENGTH = 25
DEFAULT_CHARACTERS = (
string.ascii_uppercase +
string.ascii_lowercase +
string.digits +
string.punctuation)
def main(id_extension, args, path_locales):
global _
if args == 'insert':
_password_insert()
return
if args == 'copy':
_password_copy()
return
_ = app.install_locales(path_locales)
_password_generate(id_extension)
return
def _from_config():
characters = ''
config = app.get_config('setting', PREFIX)
length = config.get('length', DEFAULT_LENGTH)
if config:
if config['letters']:
characters += string.ascii_uppercase
if config['letters2']:
characters += string.ascii_lowercase
if config['digits']:
characters += string.digits
if config['punctuation']:
characters += string.punctuation
else:
characters = DEFAULT_CHARACTERS
return list(characters), length
def _from_controls(dialog):
characters = ''
length = int(dialog.txt_length.value)
if dialog.chk_letters.value:
characters += string.ascii_uppercase
if dialog.chk_letters2.value:
characters += string.ascii_lowercase
if dialog.chk_digits.value:
characters += string.digits
if dialog.chk_punctuation.value:
characters += string.punctuation
if not characters:
dialog.chk_letters.value = True
characters = string.ascii_uppercase
return list(characters), length
def _get_data(dialog):
if dialog is None:
characters, lenght = _from_config()
else:
characters, lenght = _from_controls(dialog)
return characters, lenght
def _generate(dialog=None):
characters, length = _get_data(dialog)
random.shuffle(characters)
password = [random.choice(characters) for i in range(length)]
random.shuffle(password)
password = ''.join(password)
return password
def _password_insert():
for cell in app.selection:
cell.str = _generate()
return
def _password_copy():
app.clipboard.set(_generate())
return
def _password_generate(id_extension):
config = app.get_config('setting', prefix=PREFIX)
dialog = _create_dialog(id_extension)
length = config.get('length', DEFAULT_LENGTH)
letters = True
letters2 = True
digits = True
punctuation = True
if config:
letters = config['letters']
letters2 = config['letters2']
digits = config['digits']
punctuation = config['punctuation']
dialog.chk_letters.value = letters
dialog.chk_letters2.value = letters2
dialog.chk_digits.value = digits
dialog.chk_punctuation.value = punctuation
dialog.txt_length.value = length
dialog.txt_password.value = _generate(dialog)
dialog.open()
return
class Controllers(object):
def __init__(self, dialog):
self.d = dialog
def cmd_close_action(self, event):
self.d.close()
return
def cmd_switch_action(self, event):
char = self.d.txt_password.echochar
name_image = 'eye-close.svg'
if char == '*':
self.d.txt_password.echochar = ''
name_image = 'eye-open.svg'
else:
self.d.txt_password.echochar = '*'
path_image = app.paths.join(self.d.path_images, name_image)
self.d.cmd_switch.image = path_image
self.d.txt_password.set_focus()
return
def cmd_insert_action(self, event):
for cell in app.selection:
cell.str = self.d.txt_password.value
self.d.close()
return
def _save_config(self):
data = dict(
length = self.d.txt_length.int,
letters = self.d.chk_letters.value,
letters2 = self.d.chk_letters2.value,
digits = self.d.chk_digits.value,
punctuation = self.d.chk_punctuation.value,
)
app.set_config('setting', data, PREFIX)
return
def _new_password(self, save=True):
stats = PasswordStats(_generate(self.d))
self.d.txt_password.value = stats.password
if save:
self._save_config()
return
def cmd_new_action(self, event):
self._new_password(False)
return
def txt_length_after_click(self, event):
self._new_password()
return
def chk_letters_after_click(self, event):
self._new_password()
return
def chk_letters2_after_click(self, event):
self._new_password()
return
def chk_digits_after_click(self, event):
self._new_password()
return
def chk_punctuation_after_click(self, event):
self._new_password()
return
@app.catch_exception
def _create_dialog(id_extension):
BUTTON_WH = 16
CHK_WIDTH = 25
attr = dict(
Name = 'Dialog',
Title = _('Generate Password'),
Width = 200,
Height = 100,
)
dialog = app.create_dialog(attr)
dialog.id = id_extension
dialog.events = Controllers
attr = dict(
Type = 'Text',
Name = 'txt_password',
Width = 150,
Height = 12,
X = 5,
Y = 10,
EchoChar = ord('*'),
)
dialog.add_control(attr)
attr = dict(
Type = 'Button',
Name = 'cmd_switch',
Width = BUTTON_WH,
Height = BUTTON_WH,
ImageURL = 'eye-close.svg',
FocusOnClick = True,
)
dialog.add_control(attr)
attr = dict(
Type = 'Button',
Name = 'cmd_new',
Width = BUTTON_WH,
Height = BUTTON_WH,
ImageURL = 'new.svg',
)
dialog.add_control(attr)
attr = dict(
Type = 'Label',
Name = 'lbl_title_length',
Label = _('Length: '),
Width = 50,
Height = BUTTON_WH,
Border = 1,
Align = 2,
VerticalAlign = 1,
)
dialog.add_control(attr)
attr = dict(
Type = 'Numeric',
Name = 'txt_length',
Width = 50,
Height = BUTTON_WH,
DecimalAccuracy = 0,
Spin = True,
Value = 25,
ValueStep = 1,
ValueMin = 10,
ValueMax = 100,
)
dialog.add_control(attr)
attr = dict(
Type = 'CheckBox',
Name = 'chk_letters',
Label = 'A-Z',
Width = CHK_WIDTH,
Height = BUTTON_WH,
)
dialog.add_control(attr)
attr = dict(
Type = 'CheckBox',
Name = 'chk_letters2',
Label = 'a-z',
Width = CHK_WIDTH,
Height = BUTTON_WH,
)
dialog.add_control(attr)
attr = dict(
Type = 'CheckBox',
Name = 'chk_digits',
Label = '0-9',
Width = CHK_WIDTH,
Height = BUTTON_WH,
)
dialog.add_control(attr)
attr = dict(
Type = 'CheckBox',
Name = 'chk_punctuation',
Label = string.punctuation,
Width = CHK_WIDTH * 4,
Height = BUTTON_WH,
)
dialog.add_control(attr)
attr = dict(
Type = 'Button',
Name = 'cmd_insert',
Label = _('~Insert'),
Width = 70,
Height = BUTTON_WH,
ImageURL = 'insert.svg',
ImagePosition = 1,
)
dialog.add_control(attr)
attr = dict(
Type = 'Button',
Name = 'cmd_close',
Label = _('~Close'),
Width = 70,
Height = BUTTON_WH,
ImageURL = 'close.svg',
ImagePosition = 1,
)
dialog.add_control(attr)
dialog.cmd_switch.move(dialog.txt_password, x=3, y=-2)
dialog.cmd_new.move(dialog.cmd_switch, x=3, y=0)
dialog.lbl_title_length.move(dialog.txt_password)
dialog.txt_length.move(dialog.lbl_title_length, x=3, y=0)
dialog.chk_letters.move(dialog.lbl_title_length)
dialog.chk_letters2.move(dialog.chk_letters, x=3, y=0)
dialog.chk_digits.move(dialog.chk_letters2, x=3, y=0)
dialog.chk_punctuation.move(dialog.chk_digits, x=3, y=0)
dialog.center(dialog.cmd_insert, y=-5)
dialog.center(dialog.cmd_close, y=-5)
dialog.center((dialog.cmd_close, dialog.cmd_insert))
return dialog