Guess what setting you meant based on levenshtein.

This commit is contained in:
Thomas Adamcik 2012-09-01 11:46:58 +02:00
parent fc4dcc3529
commit 3c2576a629

View File

@ -12,6 +12,7 @@ from mopidy.utils.log import indent
logger = logging.getLogger('mopidy.utils.settings')
class SettingsProxy(object):
def __init__(self, default_settings_module):
self.default = self._get_settings_dict_from_module(
@ -151,11 +152,17 @@ def validate_settings(defaults, settings):
u'Available bitrates are 96, 160, and 320.')
if setting not in defaults:
errors[setting] = u'Unknown setting. Is it misspelled?'
errors[setting] = u'Unknown setting.'
suggestion = did_you_mean(setting, defaults)
if suggestion:
errors[setting] += u' Did you mean %s?' % suggestion
continue
return errors
def list_settings_optparse_callback(*args):
"""
Prints a list of all settings.
@ -167,6 +174,7 @@ def list_settings_optparse_callback(*args):
print format_settings_list(settings)
sys.exit(0)
def format_settings_list(settings):
errors = settings.get_errors()
lines = []
@ -181,8 +189,37 @@ def format_settings_list(settings):
lines.append(u' Error: %s' % errors[key])
return '\n'.join(lines)
def mask_value_if_secret(key, value):
if key.endswith('PASSWORD') and value:
return u'********'
else:
return value
def did_you_mean(setting, defaults):
"""Suggest most likely setting based on levenshtein."""
candidates = [(levenshtein(setting, d), d) for d in defaults]
candidates.sort()
if candidates[0][0] <= 3:
return candidates[0][1]
return None
def levenshtein(a, b, max=3):
"Calculates the Levenshtein distance between a and b."
n, m = len(a), len(b)
if n > m:
return levenshtein(b, a)
current = xrange(n+1)
for i in xrange(1,m+1):
previous, current = current, [i]+[0]*n
for j in xrange(1,n+1):
add, delete = previous[j]+1, current[j-1]+1
change = previous[j-1]
if a[j-1] != b[i-1]:
change = change + 1
current[j] = min(add, delete, change)
return current[n]