Create a gist now

Instantly share code, notes, and snippets.

@larsks /
Last active Dec 19, 2015

# Converts a Keepassx XML export to a format suitable
# for use with Vim and GPG as described in
import os
import sys
import argparse
import yaml
from lxml import etree
selected_elements = {
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()
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])
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:
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'):
if __name__ == '__main__':
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment