Browse files

Implement fuzzy search and ranking

The regex based method to find key matches does not work very well for deeper
hierarchies and partial matching of the hierarchy levels. This approach uses the
SequenceMatcher from the difflib module to compute a score for an entry and rank
them accordingly.

This change also filters out all hidden file system entries to avoid traversing
and evaluating Git repositories which are commonly used to store pass storages.
  • Loading branch information...
matze committed Sep 4, 2017
1 parent d400a05 commit 119a5c42f0e43226d371e5fec7b3dc7f2ca2e903
Showing with 18 additions and 14 deletions.
  1. +18 −14
@@ -27,8 +27,9 @@
from os import getenv
from os import walk
from os.path import expanduser
from os.path import expanduser, join as path_join
import re
import difflib
import subprocess
import dbus
@@ -81,22 +82,25 @@ def LaunchSearch(self, terms, timestamp):
def get_result_set(self, terms):
names = []
for term in terms:
names += self.get_password_names(term)
return set(names)
name = ' '.join(terms)
matcher = difflib.SequenceMatcher(b=name, autojunk=False)
matches = []
def get_password_names(self, name):
names = []
for root, dirs, files in walk(self.password_store):
dir_path = root[len(self.password_store) + 1:]
for file in files:
file_path = '{0}/{1}'.format(dir_path, file)
if re.match(r'.*{0}.*\.gpg$'.format(name),
return names
if dir_path.startswith('.'):
for filename in files:
path = path_join(dir_path, filename)
score = matcher.ratio()
if score >= 0.5:
matches.append((score, path[:-4]))
return [x[1] for x in sorted(matches, key=lambda x: x[0], reverse=True)]
def send_password_to_gpaste(self, name):
pass_cmd =

0 comments on commit 119a5c4

Please sign in to comment.