]> git.phdru.name Git - bookmarks_db.git/commitdiff
Implemented JSON loading.
authorOleg Broytman <phd@phdru.name>
Thu, 22 Jul 2010 19:02:38 +0000 (19:02 +0000)
committerOleg Broytman <phd@phdru.name>
Thu, 22 Jul 2010 19:02:38 +0000 (19:02 +0000)
git-svn-id: file:///home/phd/archive/SVN/bookmarks_db/trunk@232 fdd5c36f-1aea-0310-aeeb-c58d7e2b6c23

Storage/bkmk_stjson.py [new file with mode: 0644]

diff --git a/Storage/bkmk_stjson.py b/Storage/bkmk_stjson.py
new file mode 100644 (file)
index 0000000..32efdff
--- /dev/null
@@ -0,0 +1,118 @@
+"""
+    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")