Skip to content
Snippets Groups Projects
Commit 3490fe63 authored by ulif's avatar ulif
Browse files

Allow also list of wordlists

instead of a single wordlist only. This way we will be able to generate
not only random sequences of words, but also phrases with a syntactic
structure. These are easier to memorize.
parent d52626bb
No related branches found
No related tags found
No related merge requests found
......@@ -114,8 +114,8 @@ def handle_options(args):
"Get randomness from this source. Possible values: `%s'. "
"Default: system" % "', `".join(sorted(random_sources))))
parser.add_argument(
'-w', '--wordlist', default='en_eff', choices=wordlist_names,
metavar="NAME",
'-w', '--wordlist', default=['en_eff'], choices=wordlist_names,
metavar="NAME", nargs='*',
help=(
"Use words from this wordlist. Possible values: `%s'. "
"Wordlists are stored in the folder displayed below. "
......@@ -182,12 +182,17 @@ def get_passphrase(options=None):
"""
if options is None:
options = handle_options(args=[])
if options.infile is None:
options.infile = get_wordlist_path(options.wordlist)
word_list = WordList(options.infile)
rnd_source = get_random_sources()[options.randomsource]
rnd = rnd_source(options)
words = [rnd.choice(list(word_list)) for x in range(options.num)]
words = []
paths = [options.infile]
if paths == [None]:
paths = [get_wordlist_path(x) for x in options.wordlist]
wordlists = [list(WordList(path)) for path in paths]
for x_ in range(options.num):
for wordlist in wordlists:
words.append(rnd.choice(wordlist))
if options.caps:
words = [x.capitalize() for x in words]
result = options.delimiter.join(words)
......
......@@ -24,6 +24,7 @@ try:
except ImportError: # pragma: no cover
from ConfigParser import SafeConfigParser as SafeParser # Python 2.x
import os
import re
OPTIONS_DEFAULTS = dict(
......@@ -33,11 +34,15 @@ OPTIONS_DEFAULTS = dict(
delimiter="",
randomsource="system",
verbose=0,
wordlist="en_eff",
wordlist=["en_eff"],
dice_sides=6,
)
#: valid wordlist names
RE_WLIST_NAME = re.compile(r'(?![\w\-]+).')
def valid_locations():
"""The list of valid paths we look up for config files.
"""
......@@ -62,6 +67,12 @@ def get_configparser(path_list=None):
return found, parser
def string_to_wlist_list(text):
"""Split string into list of valid wordlist names.
"""
return [name for name in re.split(RE_WLIST_NAME, text) if name != ""]
def get_config_dict(
path_list=None, defaults_dict=OPTIONS_DEFAULTS, section="diceware"):
"""Get config values found in files from `path_list`.
......@@ -88,6 +99,8 @@ def get_config_dict(
result[key] = parser.getboolean(section, key)
elif isinstance(val, int):
result[key] = parser.getint(section, key)
elif key == "wordlist":
result[key] = string_to_wlist_list(parser.get(section, key))
else:
result[key] = parser.get(section, key).strip("\"'")
return result
......@@ -43,7 +43,7 @@ class TestHandleOptions(object):
assert options.version is False
assert options.delimiter == ""
assert options.randomsource == "system"
assert options.wordlist == "en_eff"
assert options.wordlist == ["en_eff"]
assert options.verbose == 0
def test_handle_options_infile(self, tmpdir):
......@@ -121,9 +121,9 @@ class TestHandleOptions(object):
wordlist_names = get_wordlist_names()
for name in wordlist_names:
options = handle_options(['-w', name])
assert options.wordlist == name
assert options.wordlist == [name]
options = handle_options(['--wordlist', name])
assert options.wordlist == name
assert options.wordlist == [name]
def test_handle_options_wordlist_rejects_invalid(self, capsys):
# we can choose only existing wordlists
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment