--- contrib/importers/keepassx2pass-no_camel_case.py | 107 +++++++++++++++++++++++ 1 file changed, 107 insertions(+)
diff --git a/contrib/importers/keepassx2pass-no_camel_case.py b/contrib/importers/keepassx2pass-no_camel_case.py new file mode 100755 index 0000000..8d028b1 --- /dev/null +++ b/contrib/importers/keepassx2pass-no_camel_case.py @@ -0,0 +1,107 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# Copyright (C) 2012 Juhamatti Niemelä <[email protected]>. All Rights Reserved. +# This file is licensed under the GPLv2+. Please see COPYING for more information. + +import sys +import re +import os + +from subprocess import Popen, PIPE +from xml.etree import ElementTree + + +def cleanTitle(title): + # make the title more command line friendly + + title = re.sub(" ", "_", title) + title = re.sub("'", "", title) + title = re.sub("\W", "-", title) + + total_changes = 1 + while total_changes > 0: + total_changes = 0 + (title, changes) = re.subn("__+", "_", title) + total_changes = total_changes + changes + (title, changes) = re.subn("(--+|_-|-_)", "-", title) + total_changes = total_changes + changes + + title = re.sub("[-_]+$", "", title) + title = re.sub("^[-_]+", "", title) + + return title + + +def pass_entry_exists(entry): + full_path = os.environ['HOME'] + '/.password-store' + entry + '.gpg' + print full_path + "\n" + + try: + file = open(full_path); + except IOError as e: + return False + + return True + + +def path_for(element, path=''): + """ Generate path name from elements title and current path """ + title_text = element.find('title').text + if title_text is None: + title_text = "unknown" + title = cleanTitle(title_text) + + # Check for uniqueness, and make it unique if we have to + entry_path = '/'.join([path,title]) + serial_number = 1 + while pass_entry_exists(entry_path): + serial_number = serial_number + 1 + entry_path = '/'.join([path, "{0}-{1:d}".format(title, serial_number)]) + + return entry_path + + +def password_data(element): + """ Return password data and additional info if available from + password entry element. """ + passwd = element.find('password').text + ret = passwd + "\n" if passwd else "\n" + for field in ['title','username', 'url', 'comment']: + fel = element.find(field) + children = [unicode(e.text or '') + unicode(e.tail or '') for e in list(fel)] + if len(children) > 0: + children.insert(0, '') + text = (fel.text or '') + "\n".join(children) + if len(text) > 0: + ret = "%s%s: %s\n" % (ret, fel.tag, text) + return ret + + +def import_entry(element, path=''): + """ Import new password entry to password-store using pass insert + command """ + print "Importing " + path_for(element, path) + proc = Popen(['pass', 'insert', '--multiline', '--force', + path_for(element, path)], + stdin=PIPE, stdout=PIPE) + proc.communicate(password_data(element).encode('utf8')) + proc.wait() + + +def import_group(element, path=''): + """ Import all entries and sub-groups from given group """ + npath = path_for(element, path) + for group in element.findall('group'): + import_group(group, npath) + for entry in element.findall('entry'): + import_entry(entry, npath) + + +def main(xml_file): + """ Parse given KeepassX XML file and import password groups from it """ + for group in ElementTree.parse(xml_file).findall('group'): + import_group(group) + +if __name__ == '__main__': + main(sys.argv[1]) -- 2.1.4
_______________________________________________ Password-Store mailing list [email protected] http://lists.zx2c4.com/mailman/listinfo/password-store
