python
June 3, 2019

Генератор паролей с буфером обмена и оповещениями Linux

Начнём с импорта зависимостей.

from pynput import keyboard
import random
import notify2
import pyautogui
import pyperclip
import time
from datetime import datetime

Скрипт был проверен на новой Убунту disco django.

После импортов нам надо создать нотификатор:

notify2.init('Password Generator')

Затем идёт код функции рандома:

def random4ik():
    pas = random.choice(list("1234567890abcdfghigklmnopqrstuvyxwzABCDFGHIGKMNOPQRSTUVYXWZ"))
    for x in range(36): 
        pas = pas + random.choice(list("!@#$%^&*()_+-1234567890abcdefghigklmnopqrstuvyxwzABCDEFGHIGKLMNOPQRSTUVYXWZ1234567890!@#$%^&*()_+-"))
    return pas

Итак, random.choice выберет первый символ нашего пароля, затем он передаст его дальше в цикл, в цикле мы будет складывать буквы по одной. то есть - каждый проход цикла будет добавлять один случайный символ к нашей строке. Символы вы можете заменить на свои, вставить символы которых нет на клавиатуре для более сложного пароля. По итогу функция нам возвращает рандомную строку размером - 36 символов.

Затем идёт функция которая записывает пароль в файл, добавляет в буфер обмена и выдаёт оповещение.

def pass_gen():
    f = open("pass_log.txt", "a")
    random_pass = random4ik()
    print(random_pass)
    pyperclip.copy(str(random_pass))
    n = notify2.Notification('Password ready', str(random_pass))
    n.show()
    f.write(f"======== {str(datetime.now(tz=None))[:-7]} ========\n\n{random_pass}\n\n")
    return random_pass

Тут всё довольно таки просто. Сначала мы открываем файл на дозапись, чему соответствует атрибут "а", затем записываем нашу функцию рандома в переменную. Далее вы выводим наш рандомный пароль в терминал, далее с помощью pyperclip.copy мы заносим его в буфер обмена, затем создаем нотификатор (оповещение) что пароль был скопирован в буфер обмена и сам пароль, после чего показываем оповещение. Затем мы записываем это всё в файл и возвращаем рандомный пароль, это нам будет нужно для другой функции.

Далее будет функция которую по сути можно было бы и не делать. Она будет вставлять за нас наш текст из буфера обмена.

Она принимает в себя аргумент text, далее с помощью библиотеки pyautogui она его печатает на клавиатуре. Задержка нужна, необходима для корректной работы. А вот и сама функция в 2 строки:

def paste_pass(text):
    time.sleep(0.15)
    pyautogui.typewrite(text)

Затем идут хоткеи

COMBINATION = {keyboard.Key.ctrl,keyboard.Key.alt, keyboard.KeyCode.from_char('a')}
COMBINATION2 = {keyboard.Key.ctrl, keyboard.Key.alt, keyboard.KeyCode.from_char('e')}

current = set()

Тут мы задаём нужные нам хоткеи, как их правильно задавать вы можете посмотреть на сайте проекта keyboard https://pypi.org/project/keyboard/
Ну и код я брал вот от сюда:
https://github.com/moses-palmer/pynput/issues/20#issuecomment-348675059

Затем идёт функция которая отлавливает нажатия на хоткеи:

def on_press(key):
    if key in COMBINATION:
        current.add(key)
        if all(k in current for k in COMBINATION):
            pass_gen()
    elif key in COMBINATION2:
        current.add(key)
        if all(k in current for k in COMBINATION2):
            paste_pass(pass_gen())

Её мы будем запускать через цикл with. В функции мы проверяем сочетания клавиш которые были нажаты. Сверяем их со списком. Ну и соответственно исходя из хоткея - выполняем действия. Далее идёт функция из документации.

def on_release(key):
    try:
        current.remove(key)
    except KeyError:
        pass

Она просто тут должна быть. Проверяет клавиши и удаляет если не наш хоткей.

Ну и наконец самые главные 2 строки которые запускают сие чудо

with keyboard.Listener(on_press=on_press, on_release=on_release) as listener:
    listener.join()

Видео как это работает можете посмотреть вот тут:

https://radikal.ru/video/RxrFhLSX5cR
А теперь полный листинг программы:

from pynput import keyboard
import random
import notify2
import pyautogui
import pyperclip
import time
from datetime import datetime

notify2.init('Password Generator')

def random4ik():
    pas = random.choice(list("1234567890abcdfghigklmnopqrstuvyxwzABCDFGHIGKMNOPQRSTUVYXWZ"))
    for x in range(36): 
        pas = pas + random.choice(list("!@#$%^&*()_+-1234567890abcdefghigklmnopqrstuvyxwzABCDEFGHIGKLMNOPQRSTUVYXWZ1234567890!@#$%^&*()_+-"))
    return pas

def pass_gen():
    f = open("pass_log.txt", "a")
    random_pass = random4ik()
    print(random_pass)
    pyperclip.copy(str(random_pass))
    n = notify2.Notification('Password ready', str(random_pass))
    n.show()
    f.write(f"======== {str(datetime.now(tz=None))[:-7]} ========\n\n{random_pass}\n\n")
    return random_pass


def paste_pass(text):
    time.sleep(0.15)
    pyautogui.typewrite(text)

COMBINATION = {keyboard.Key.ctrl,keyboard.Key.alt, keyboard.KeyCode.from_char('a')}
COMBINATION2 = {keyboard.Key.ctrl, keyboard.Key.alt, keyboard.KeyCode.from_char('e')}

current = set()

def on_press(key):
    if key in COMBINATION:
        current.add(key)
        if all(k in current for k in COMBINATION):
            pass_gen()
    elif key in COMBINATION2:
        current.add(key)
        if all(k in current for k in COMBINATION2):
            paste_pass(pass_gen())

def on_release(key):
    try:
        current.remove(key)
    except KeyError:
        pass

with keyboard.Listener(on_press=on_press, on_release=on_release) as listener:
    listener.join()
Мой код не идеален, я пишу костыли, вы всегда можете написать лучше и модифицировать мой код.