Source code for i3pystatus.random_password
from i3pystatus import Module
import random
import string
import subprocess
[docs]class RandomPassword(Module):
"""
Generates a random password and copies it to the clipboard. Useful if you use any password manager and you want to generate a password in the moment and save it later in you manager's database.
Uses `SystemRandom` class as a cryptographically secure pseudo-number generator - <https://docs.python.org/3/library/random.html#random.SystemRandom>
- Requires `xsel` or `xclip` for copying to the clipboard.
- Generates a new password with a left click by default.
- Generates a password with a default length of 12 and with lowercase, uppercase, digits and special symbols.
.. rubric:: Available formatters
* `{length}` — length of generated password
"""
settings = (
("format", "Format string to be displayed in the status bar"),
("length", "Length of the generated password"),
("charset", "Dictionary containing character types to be included in the password"),
("cliptool", "Currently supports xsel and xclip"),
("color", "HTML color hex code #RRGGBB"),
)
format = ''
length = 12
charset = ['lowercase', 'uppercase', 'digits', 'special']
cliptool = None
color = None
on_doubleleftclick = 'generate_password'
def init(self):
# Finds out if either xsel or xclip exist
self._find_cliptool()
cdict = {
'length': self.length
}
self.output = {
"full_text": self.format.format(**cdict)
}
if self.color:
self.output["color"] = self.color
def _find_cliptool(self):
if subprocess.call(['which', 'xsel'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) == 0:
self.cliptool = 'xsel'
self._clip_params = ['-b', '-i']
elif subprocess.call(['which', 'xclip'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) == 0:
self.cliptool = 'xclip'
self._clip_params = ['-selection', 'c']
# Asserts that either xsel or xclip was found
assert self.cliptool and self._clip_params, 'It was no possible to find xsel or xclip installed in your system.'
def generate_password(self):
# If a blank list is provided for the charset, it will generate an empty password
chars = ''
if 'lowercase' in self.charset:
chars = string.ascii_lowercase
if 'uppercase' in self.charset:
chars += string.ascii_uppercase
if 'digits' in self.charset:
chars += string.digits
if 'special' in self.charset:
chars += string.punctuation
passwd = ''.join(random.SystemRandom().choice(chars) for x in range(self.length))
p = subprocess.Popen([self.cliptool, self._clip_params[0], self._clip_params[1]], stdin=subprocess.PIPE, close_fds=True)
p.communicate(input=passwd.encode('utf-8'))