Skip to content

Instantly share code, notes, and snippets.

@ShadowKyogre
Last active August 29, 2015 14:06
Show Gist options
  • Select an option

  • Save ShadowKyogre/dfdb0d83cdfce1714607 to your computer and use it in GitHub Desktop.

Select an option

Save ShadowKyogre/dfdb0d83cdfce1714607 to your computer and use it in GitHub Desktop.
Converts (firefox?) bookmark json format to a KeePassX compatible XML for importing.
import os
import json
#import uuid
from urllib.parse import urlparse
import xml.etree.ElementTree as ET
from datetime import datetime, timedelta
#http://stackoverflow.com/questions/12589952/convert-microsecond-timestamp-to-datetime-in-python
epoch = datetime(1970, 1, 1)
def indent(elem, level=0):
i = "\n" + level*"\t"
if len(elem):
if not elem.text or not elem.text.strip():
elem.text = i + "\t"
if not elem.tail or not elem.tail.strip():
elem.tail = i
for elem in elem:
indent(elem, level+1)
if not elem.tail or not elem.tail.strip():
elem.tail = i
else:
if level and (not elem.tail or not elem.tail.strip()):
elem.tail = i
def print_node(node, parent, livemark=False):
e = ET.SubElement(parent, "entry")
name = ET.SubElement(e, "title")
name.text = node["title"]
name = ET.SubElement(e, "username")
name = ET.SubElement(e, "password")
url = ET.SubElement(e, "url")
comment = ET.SubElement(e, "comment")
comment.text = ""
if livemark:
for item in node["annos"]:
if item["name"] == "livemark/feedURI":
url.text = item["value"]
elif item["name"] == "livemark/siteURI":
comment.text += "SiteURI: {}".format(item["value"])
else:
url.text = node["uri"]
if "annos" in node:
for item in node["annos"]:
if item["name"] == "bookmarkProperties/description":
comment.text += item["value"]
break
icon = ET.SubElement(e, "icon")
icon.text = "1"
#uuid = ET.SubElement(e, "uuid")
#uuid.text = str(uuid.uuid4())
creation = ET.SubElement(e, "creation")
creation.text = (epoch+timedelta(microseconds=node["dateAdded"])).isoformat()
lastmod = ET.SubElement(e, "lastmod")
lastmod.text = (epoch+timedelta(microseconds=node["lastModified"])).isoformat()
lastaccess = ET.SubElement(e, "lastaccess")
lastaccess.text = lastmod.text
#print(" "*lvl+node["title"]+" [url: {} ]".format(node["uri"]))
def check_annos_for_livemark(node):
annos = node.get("annos",[])
for item in annos:
if item["name"] == "livemark/feedURI":
return True
else:
return False
return False
def folder_recurse(node, parent):
livemark = check_annos_for_livemark(node)
if node["type"] == "text/x-moz-place-container" and not livemark:
#print(" "*lvl+node["title"]+" [Folder]")
ng = ET.SubElement(parent, "group")
title = ET.SubElement(ng, "title")
title.text = node["title"]
icon = ET.SubElement(ng, "icon")
icon.text = "48"
for loc in node.get("children", []):
folder_recurse(loc, ng)
elif livemark or (node["type"] == "text/x-moz-place" and urlparse(node['uri']).scheme != "place"):
print_node(node, parent, livemark=livemark)
root = None
if len(os.sys.argv) < 3:
print("Don't have input json file or output file location")
exit(1)
with open(os.sys.argv[1]) as contents:
firefox_bookmarks = json.load(contents)
root = ET.Element('database')
for loc in firefox_bookmarks["children"]:
if loc["type"] == "text/x-moz-place-container":
folder_recurse(loc, root)
elif loc["type"] == "text/x-moz-place" and urlparse(loc['uri']).scheme != "place":
print_node(loc, root)
with open(os.sys.argv[2], 'w', encoding='utf-8') as output:
indent(root)
output.write(ET.tostring(root).decode('utf-8'))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment