Create a gist now

Instantly share code, notes, and snippets.

@larsks /cvtpasswd.py
Last active Dec 19, 2015

What would you like to do?
#!/usr/bin/python
# Converts a Keepassx XML export to a format suitable
# for use with Vim and GPG as described in
# http://pig-monkey.com/2013/04/4/password-management-vim-gnupg/
import os
import sys
import argparse
import yaml
from lxml import etree
selected_elements = {
'title',
'expire',
'username',
'password',
'url',
'comment',
}
skip_groups = { 'backup' }
entrycount = 0
def parse_args():
p = argparse.ArgumentParser()
return p.parse_args()
def process_entry(child, tags):
'''Generates a single entry on stdout.'''
global entrycount
entrycount += 1
newentry = {'tags': ' '.join(x.replace(' ', '_') for x in tags)}
for ele in child:
if ele.tag in selected_elements:
if ele.tag in ['comment']:
text = '\n'.join(ele.itertext()).strip()
elif ele.text:
text = ele.text.strip()
else:
continue
if text:
newentry[ele.tag] = text
newentry['label'] = next(
x for x in [ newentry.get('title'), newentry.get('url'),
'entry_%04d' % entrycount ]
if x
)
print '%(label)s{{{' % newentry
for k in sorted(newentry.keys()):
if k == 'label': continue
if not k in ['comment'] or len(newentry[k]) < 40:
print '\t%s: %s' % (k,newentry[k])
else:
print '\t%s: {{{' % k
for line in newentry[k].split('\n'):
print '\t%s' % line
print '\t}}}'
print '}}}'
def process_group(group, tags=None):
'''Process all entries in a group. Recursively handles subgroups.'''
if tags is None:
tags = []
groupname = group.find('title').text.lower()
if groupname in skip_groups:
return
tags = tags + [groupname]
for child in group:
if child.tag == 'group':
process_group(child, tags)
elif child.tag == 'entry':
process_entry(child, tags)
def main():
opts = parse_args()
doc = etree.parse(sys.stdin)
for group in doc.xpath('group'):
process_group(group)
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment