1 """Objects to represent bookmarks.html structure
3 This file is a part of Bookmarks database and Internet robot.
6 __version__ = "$Revision$"[11:-2]
7 __revision__ = "$Id$"[5:-2]
8 __date__ = "$Date$"[7:-2]
9 __author__ = "Oleg Broytman <phd@phdru.name>"
10 __copyright__ = "Copyright (C) 2000-2011 PhiloSoft Design"
11 __license__ = "GNU GPL"
14 BKMK_FORMAT = os.environ.get("BKMK_FORMAT", "MOZILLA")
21 def __init__(self, add_date=None, comment='', last_modified=None):
22 super(Folder, self).__init__()
23 self.comment = comment
24 self.add_date = add_date
25 self.last_modified = last_modified
27 def walk_depth(self, walker, level=0):
28 if hasattr(self, "header"): # root folder
30 walker.root_folder(self)
32 prune = walker.prune_folder(self)
34 walker.start_folder(self, level)
39 object.walk_depth(walker, level+1)
40 elif object.isBookmark:
41 walker.bookmark(object, level)
43 walker.ruler(object, level)
45 walker.end_folder(self, level)
52 def __init__(self, href, add_date, last_visit=None, last_modified=None,
53 keyword=None, comment='', icon_href=None, icon=None, charset=None):
55 self.add_date = add_date
56 self.last_visit = last_visit
57 self.last_modified = last_modified
58 self.keyword = keyword
59 self.comment = comment
60 self.icon_href = icon_href
62 self.charset = charset
72 Interface class. Any instance that will be passed to Folder.walk_depth
73 may be derived from this class. It is not mandatory - unlike Java
74 Python does not require interface classes; but it is convenient to have
75 some methods predefined to no-op, in case you do not want to
76 provide end_folder etc.
79 def root_folder(self, r):
82 def start_folder(self, f, level):
85 def end_folder(self, f, level):
88 def bookmark(self, b, level):
91 def ruler(self, r, level):
94 def prune_folder(self, folder):
99 def __init__(self, outfile, prune=None):
100 self.outfile = outfile
103 def prune_folder(self, folder):
104 return self.prune == folder.name
108 def __init__(self, log):
112 pass # Nothing to do on cleanup
115 # Helper class to make inverese links (nodes linked to their parent)
116 class InverseLinker(Walker):
117 def root_folder(self, r):
118 self.parent_stack = [r]
120 def start_folder(self, f, level):
121 f.parent = self.parent_stack[-1]
122 self.parent_stack.append(f) # Push the folder onto the stack of parents
124 def end_folder(self, f, level):
125 del self.parent_stack[-1] # Pop off the stack
127 def bookmark(self, b, level):
128 b.parent = self.parent_stack[-1]
130 def ruler(self, r, level):
131 r.parent = self.parent_stack[-1]
134 # Helper class to make linear represenatation of the tree
135 class Linear(Walker):
136 def root_folder(self, r):
138 self.linear = r.linear
140 def add_object(self, object):
141 self.linear.append(object)
143 def start_folder(self, f, level):
146 def bookmark(self, b, level):
149 def ruler(self, r, level):
153 # Helper - make linked linear represenatation of the tree, suitable to be stored in sequential storage
154 def make_linear(root_folder):
155 linker = InverseLinker()
156 root_folder.walk_depth(linker)
159 root_folder.walk_depth(linear)
162 # Helper, opposite of make_linear - make a tree from the linked linear representation
163 def make_tree(linear):
164 root_folder = linear[0]
167 for object in linear:
168 object.parent.append(object)
172 def break_tree(linear):
175 for object in linear:
179 def quote_title(title):
180 if BKMK_FORMAT == "MOZILLA":
181 title = title.replace("'", "'")
184 def unquote_title(title):
185 if BKMK_FORMAT == "MOZILLA":
186 from HTMLParser import HTMLParser
187 title = HTMLParser().unescape(title.replace("&", '&'))
188 title = title.replace("'", "'")