--- /dev/null
+"""
+ Bookmarks storage manager - json.
+
+ Written by Broytman, Jul 2010. Copyright (C) 2010 PhiloSoft Design
+"""
+
+
+try:
+ import json
+except ImportError:
+ import simplejson as json
+
+from bkmk_objects import Folder, Bookmark, Ruler, Walker
+
+
+class storage_json(Walker):
+ filename = "bookmarks_db.json"
+
+ def root_folder(self, f):
+ self.dict = {}
+
+ def start_folder(self, f, level):
+ pass
+
+ def bookmark(self, b, level):
+ pass
+
+ def ruler(self, r, level):
+ pass
+
+ def store(self, root_folder):
+ root_folder.walk_depth(self)
+
+ outfile = open(self.filename, 'wb')
+ json.dump(self.dict, outfile)
+ outfile.close()
+ del self.dict
+
+
+ def load(self):
+ infile = open(self.filename, 'rb')
+ bkmk_s = infile.read()
+ infile.close()
+
+ # Work around a bug in Mozilla - remove the trailing comma
+ bkmk_s = bkmk_s.strip().replace(',]', ']')
+ bookmarks_dict = json.loads(bkmk_s)
+
+ root_folder = Folder()
+ root_folder.header = ''
+ self.folder_stack = [root_folder]
+ self.current_folder = root_folder
+
+ self.load_folder(root_folder, bookmarks_dict)
+ if self.folder_stack:
+ raise RuntimeError('Excessive folder stack: %s' % self.folder_stack)
+
+ return root_folder
+
+ def load_folder(self, folder, _dict):
+ if _dict["type"] != "text/x-moz-place-container":
+ raise ValueError("Root object is not a Mozilla container")
+
+ folder.id = _dict["id"]
+ folder.index = _dict.get("index")
+ folder.parent_idx = _dict.get("parent")
+
+ folder.name = encode(_dict["title"])
+ folder.href = _dict.get("uri")
+ folder.comment = ''
+ folder.add_date = _dict["dateAdded"]
+ folder.last_modified = _dict["lastModified"]
+
+ for record in _dict["children"]:
+ if record["type"] == "text/x-moz-place":
+ bookmark = Bookmark(
+ href=record["uri"],
+ add_date=record.get("dateAdded"),
+ last_modified=record.get("lastModified"),
+ charset=record.get("charset"))
+ bookmark.id = record["id"]
+ bookmark.parent_idx = record["parent"]
+ bookmark.name = encode(record["title"])
+ self.current_folder.append(bookmark)
+
+ elif record["type"] == "text/x-moz-place-container":
+ folder = Folder(
+ add_date=record["dateAdded"], comment=None,
+ last_modified=record["lastModified"])
+ folder.id = record["id"]
+ folder.parent_idx = record["parent"]
+ folder.name = encode(record["title"])
+ self.current_folder.append(folder)
+ self.folder_stack.append(folder)
+ self.current_folder = folder
+ self.load_folder(folder, record)
+
+ elif record["type"] == "text/x-moz-place-separator":
+ ruler = Ruler()
+ ruler.add_date = record["dateAdded"]
+ ruler.id = record["id"]
+ ruler.index = record["index"]
+ ruler.last_modified = record["lastModified"]
+ ruler.parent_idx = record["parent"]
+ ruler.name = encode(record["title"])
+ self.current_folder.append(ruler)
+
+ else:
+ raise ValueError('Unknown record type "%s"' % record["type"])
+
+ del self.folder_stack[-1]
+ if self.folder_stack:
+ self.current_folder = self.folder_stack[-1]
+ else:
+ self.current_folder = None
+
+def encode(title):
+ return title.encode("UTF-8", "xmlcharrefreplace")