Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import sys
- import time
- import itertools
- from xml.dom.minidom import parse, getDOMImplementation
- class ElementTransformator(object):
- icon_map = dict(creditcard='66',
- cryptokey='58',
- database='43',
- door='60',
- email='19',
- ftp='49',
- generic='13',
- phone='68',
- shell='30',
- website='57')
- fields = {'generic-hostname': 'url',
- 'generic-certificate': 'comment',
- 'generic-keyfile': 'username',
- 'generic-password': 'password',
- 'generic-username': 'username',
- 'generic-database': 'url',
- 'generic-location': 'comment',
- 'generic-code': 'password',
- 'generic-email': 'comment',
- 'generic-port': 'comment',
- 'generic-url': 'url',
- 'generic-pin': 'password',
- 'generic-domain': 'comment',
- 'phone-phonenumber': 'comment',
- 'creditcard-cardtype': None,
- 'creditcard-cardnumber': None,
- 'creditcard-expirydate': None,
- 'creditcard-ccv': None}
- def __init__(self, src_doc):
- self._src_doc = src_doc
- impl = getDOMImplementation()
- dt= impl.createDocumentType('KEEPASSX_DATABASE', None, None)
- self._dst_doc = impl.createDocument(None, 'database', dt)
- self._dst_doc.documentElement
- self._top_element = self._dst_doc.createElement('group')
- self._dst_doc.documentElement.appendChild(self._top_element)
- title = self._dst_doc.createElement('title')
- title.appendChild(self._dst_doc.createTextNode('Revelation Import'))
- self._top_element.appendChild(title)
- icon = self._dst_doc.createElement('icon')
- icon.appendChild(self._dst_doc.createTextNode('48'))
- self._top_element.appendChild(icon)
- self._unknown_counter = itertools.count().next
- self._make_entry_helper()
- def parse(self):
- try:
- dataelem = self._src_doc.getElementsByTagName('revelationdata')[0]
- except IndexError:
- return
- for child in dataelem.childNodes:
- try:
- tagname = child.tagName
- except AttributeError:
- continue
- if tagname == 'entry':
- self.parse_entry_elem(child)
- def write(self, dst):
- with open(dst, 'wb') as fout:
- #self._dst_doc.writexml(fout, encoding='utf-8', addindent=' ', newl='\n')
- self._dst_doc.writexml(fout, encoding='utf-8')
- def _make_entry_helper(self):
- unknown = lambda: 'unknown_%03d' % self._unknown_counter()
- none = lambda: None
- formatted_time_not = self._format_epoch_time()
- times = lambda: formatted_time_not
- self._entry_helper = dict(title=unknown,
- username=none,
- password=none,
- url=none,
- comment=none,
- icon=lambda: '0',
- creation=times,
- lastaccess=times,
- lastmod=times,
- expire=lambda: 'Nie')
- def parse_entry_elem(self, entry):
- enytry_type = entry.attributes['type'].value
- if enytry_type == 'folder':
- self._handle_folder(entry)
- return
- param_dict = {}
- e_title = e_comment = e_updated = None
- for c in entry.childNodes:
- try:
- tagname = c.tagName
- except AttributeError:
- # text node
- continue
- if tagname == 'name':
- e_title = self._textchilddata(c)
- if tagname == 'description':
- e_comment = self._textchilddata(c)
- if tagname == 'updated':
- e_updated = self._format_epoch_time(self._textchilddata(c))
- if tagname == 'field':
- self._parse_field(c, param_dict)
- if e_comment:
- try:
- from_field = param_dict['comment']
- except KeyError:
- from_field = ''
- param_dict['comment'] = '%s\n%s' % (e_comment, from_field)
- param_dict.update(dict(title=e_title,
- icon=self.icon_map[enytry_type],
- creation=e_updated,
- lastaccess=e_updated,
- lastmod=e_updated,
- expire=None))
- self._dump_entry(param_dict)
- def _format_epoch_time(self, epoch=None):
- if not epoch:
- epoch = time.time()
- return time.strftime('%Y-%m-%dT%H:%M:%S', time.localtime(float(epoch)))
- def _textchilddata(self, elem):
- try:
- data = elem.childNodes[0].data
- except IndexError:
- return None
- return data.encode(self._src_doc.encoding)
- def _dump_entry(self, edict):
- entry = self._dst_doc.createElement('entry')
- self._top_element.appendChild(entry)
- for membername, defaults in self._entry_helper.iteritems():
- value = edict.get(membername, None)
- if value is None:
- value = defaults()
- member = self._dst_doc.createElement(membername)
- if value:
- member.appendChild(self._dst_doc.createTextNode(value))
- entry.appendChild(member)
- def _parse_field(self, fieldelem, param=None):
- if param is None:
- param = {}
- try:
- field_id = fieldelem.attributes['id'].value
- except KeyError:
- print 'illegal field'
- return param
- try:
- key = self.fields[field_id]
- except KeyError:
- print 'unknown field: %s' % field_id
- return param
- if key:
- param[key] = self._textchilddata(fieldelem)
- def _handle_folder(self, elem):
- group = self._dst_doc.createElement('group')
- self._top_element.appendChild(group)
- parentgroup = self._top_element
- self._top_element = group
- groupname = None
- for c in elem.childNodes:
- try:
- tagname = c.tagName
- except AttributeError:
- # text node
- continue
- if tagname == 'name':
- groupname = self._textchilddata(c)
- elif tagname == 'entry':
- self.parse_entry_elem(c)
- if not groupname:
- groupname = 'unknown_%03d' % self._unknown_counter()
- title = self._dst_doc.createElement('title')
- title.appendChild(self._dst_doc.createTextNode(groupname))
- group.appendChild(title)
- icon = self._dst_doc.createElement('icon')
- icon.appendChild(self._dst_doc.createTextNode('48'))
- group.appendChild(icon)
- self._top_element = parentgroup
- def main(src, dst):
- with open(src) as inf:
- src_doc = parse(inf)
- et = ElementTransformator(src_doc)
- et.parse()
- et.write(dst)
- if __name__ == '__main__':
- try:
- s, d = sys.argv[1:3]
- except ValueError:
- print 'usage: %s <source Revelation XML DB path> <target KeePassX XML DB path>' % sys.argv[0]
- sys.exit(1)
- main(s, d)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement