diff --git a/info.plist b/info.plist
index a8e629a..e99d87f 100644
--- a/info.plist
+++ b/info.plist
@@ -58,6 +58,19 @@
+ E51C31A6-DF82-4087-BE7B-A7A588C49BCA
+
+
+ destinationuid
+ FD54DB02-354D-478D-A10D-AB7D69256AD9
+ modifiers
+ 0
+ modifiersubtext
+
+ vitoclose
+
+
+
createdby
Przemek KamiĆski
@@ -76,6 +89,8 @@
alfredfiltersresultsmatchmode
0
+ argumenttreatemptyqueryasnil
+
argumenttrimmode
0
argumenttype
@@ -114,7 +129,7 @@
uid
7DD3BDE5-A157-42E5-9376-F681FB50A4EE
version
- 2
+ 3
config
@@ -147,14 +162,14 @@
clipboardtext
{query}
transient
-
+
type
alfred.workflow.output.clipboard
uid
C7B97C94-3D0B-471E-96EE-A441A1FAB184
version
- 2
+ 3
config
@@ -207,6 +222,8 @@
alfredfiltersresultsmatchmode
0
+ argumenttreatemptyqueryasnil
+
argumenttrimmode
0
argumenttype
@@ -245,7 +262,7 @@
uid
967E625E-D870-4298-9A7A-97C043740D99
version
- 2
+ 3
config
@@ -270,10 +287,81 @@
version
2
+
+ config
+
+ concurrently
+
+ escaping
+ 102
+ script
+ /usr/local/bin/bash pass-autocomplete.sh "{query}"
+ scriptargtype
+ 0
+ scriptfile
+
+ type
+ 0
+
+ type
+ alfred.workflow.action.script
+ uid
+ FD54DB02-354D-478D-A10D-AB7D69256AD9
+ version
+ 2
+
+
+ config
+
+ alfredfiltersresults
+
+ alfredfiltersresultsmatchmode
+ 0
+ argumenttreatemptyqueryasnil
+
+ argumenttrimmode
+ 0
+ argumenttype
+ 0
+ escaping
+ 102
+ keyword
+ passa
+ queuedelaycustom
+ 3
+ queuedelayimmediatelyinitially
+
+ queuedelaymode
+ 0
+ queuemode
+ 1
+ runningsubtext
+
+ script
+ python pass-filter.py "{query}"
+ scriptargtype
+ 0
+ scriptfile
+
+ subtext
+
+ title
+ Autotype
+ type
+ 0
+ withspace
+
+
+ type
+ alfred.workflow.input.scriptfilter
+ uid
+ E51C31A6-DF82-4087-BE7B-A7A588C49BCA
+ version
+ 3
+
readme
- A workflow to integrate with Pass - the standard Unix password manager.
-See the README file at https://github.com/CGenie/alfred-pass for more info.
+
uidata
06C9C4A9-38CE-441A-8D06-E2F2D8B39B60
@@ -325,6 +413,20 @@ See the README file at https://github.com/CGenie/alfred-pass for more info.ypos
60
+ E51C31A6-DF82-4087-BE7B-A7A588C49BCA
+
+ xpos
+ 295
+ ypos
+ 430
+
+ FD54DB02-354D-478D-A10D-AB7D69256AD9
+
+ xpos
+ 505
+ ypos
+ 430
+
version
0.3.4
diff --git a/pass-autocomplete.sh b/pass-autocomplete.sh
new file mode 100755
index 0000000..d50399c
--- /dev/null
+++ b/pass-autocomplete.sh
@@ -0,0 +1,52 @@
+#!/usr/bin/env bash
+
+set -e
+
+
+QUERY=$1
+PATH=/usr/local/bin:$PATH
+
+AUTOTYPE_field='autotype'
+default_autotype="user :tab pass"
+URL_field='url'
+USERNAME_field='user'
+
+allData="$(pass show $QUERY)"
+
+function doType {
+ echo "tell application \"System Events\" to keystroke \"$1\"" | osascript
+}
+
+function doStroke {
+ echo "tell application \"System Events\" to key code $1" | osascript
+}
+
+declare -A stuff
+pass_key_value=$(printf '%s\n' "${allData}" | tail -n+2 | grep ': ')
+while read -r LINE; do
+ _id="${LINE%%: *}"
+ _val="${LINE#* }"
+ stuff["${_id}"]=${_val}
+done < <(printf '%s\n' "${pass_key_value}")
+
+password="${allData%%$'\n'*}"
+stuff["pass"]=${password}
+
+if test "${stuff['autotype']+autotype}"; then
+ :
+else
+ stuff["autotype"]="${USERNAME_field} :tab pass"
+fi
+
+pass_content="$(for key in "${!stuff[@]}"; do printf '%s\n' "${key}: ${stuff[$key]}"; done)"
+
+for word in ${stuff["$AUTOTYPE_field"]}; do
+ case "$word" in
+ ":tab") doStroke 48;;
+ ":space") doStroke 49;;
+ ":delay") sleep "${delay}";;
+ ":enter") doStroke 36;;
+ *) doType "${stuff[${word}]}";;
+ esac
+done
+
diff --git a/pass-filter.py b/pass-filter.py
index 4728377..e1bc9a3 100755
--- a/pass-filter.py
+++ b/pass-filter.py
@@ -4,57 +4,35 @@
import os
import sys
import string
-
-fuzzysearch = True
-try:
- from fuzzywuzzy import process
-except:
- fuzzysearch = False
+import glob
QUERY = sys.argv[1]
HOME = os.environ['HOME']
-PASS_DIR = os.environ.get('PASSWORD_STORE_DIR',os.path.join(HOME, '.password-store/'))
-
+PASS_DIR = os.environ.get('PASSWORD_STORE_DIR', os.path.join(HOME, '.password-store/'))
# TODO: list_passwords creates cache of passwords for first time
def list_passwords():
- ret = []
+ ret = [f for f in glob.glob(PASS_DIR+ "/**/*.gpg")]
+ replaced = list(map(lambda x : x.replace('.gpg','').replace(PASS_DIR, ''), ret))
- for root, dirnames, filenames in os.walk(PASS_DIR, True, None, True):
- for filename in fnmatch.filter(filenames, '*.gpg'):
- ret.append(os.path.join(root, filename.replace('.gpg','')).replace(PASS_DIR, ''))
- return sorted(ret, key=lambda s: s.lower())
+ #for root, dirnames, filenames in os.walk(PASS_DIR):
+ # for filename in fnmatch.filter(filenames, '*.gpg'):
+ # ret.append(os.path.join(root, filename.replace('.gpg','')).replace(PASS_DIR, ''))
+ return sorted(replaced, key=lambda s: s.lower())
def search_passwords(query):
- ''' Search passwords using the Fuzzy search method if fuzzywuzzy is available,
- or default to the filter-based search otherwise'''
- if fuzzysearch:
- return search_passwords_fuzzy(query)
- return search_passwords_filter(query)
-
-
-def search_passwords_fuzzy(query):
- ''' Search passwords using the Fuzzy search method using fuzzywuzzy'''
- passwords = list_passwords()
- return [entry[0] for entry in process.extract(query, passwords)]
-
-
-def search_passwords_filter(query):
- ''' Search passwords using the filter-based search, which doesn't require fuzzywuzzy'''
ret = []
terms = filter(lambda x: x, query.lower().split())
passwords = list_passwords()
-
for password in passwords:
for t in terms:
if t not in password.lower():
break
else:
ret.append(password)
-
return ret