]> git.phdru.name Git - bookmarks_db.git/blob - bkmk_objects.py
Store icon's URIs.
[bookmarks_db.git] / bkmk_objects.py
1 """
2    Objects to represent bookmarks.html structure
3
4    Written by Oleg Broytman. Copyright (C) 2000-2010 PhiloSoft Design.
5 """
6
7 import os, cgi
8 BKMK_FORMAT = os.environ.get("BKMK_FORMAT", "MOZILLA")
9
10
11 class Folder(list):
12    isFolder = 1
13    isBookmark = 0
14
15    def __init__(self, add_date=None, comment='', last_modified=None):
16       super(Folder, self).__init__()
17       self.comment = comment
18       self.add_date = add_date
19       self.last_modified = last_modified
20
21    def walk_depth(self, walker, level=0):
22       if hasattr(self, "header"): # root folder
23          prune = 0
24          walker.root_folder(self)
25       else:
26          prune = walker.prune_folder(self)
27          if not prune:
28             walker.start_folder(self, level)
29
30       if not prune:
31          for object in self:
32             if object.isFolder:
33                object.walk_depth(walker, level+1)
34             elif object.isBookmark:
35                walker.bookmark(object, level)
36             else:
37                walker.ruler(object, level)
38
39          walker.end_folder(self, level)
40
41
42 class Bookmark:
43    isFolder = 0
44    isBookmark = 1
45
46    def __init__(self, href, add_date, last_visit=None, last_modified=None,
47          keyword=None, comment='', icon_href=None, icon=None, charset=None):
48       self.href = href
49       self.add_date = add_date
50       self.last_visit = last_visit
51       self.last_modified = last_modified
52       self.keyword = keyword
53       self.comment = comment
54       self.icon_href = icon_href
55       self.icon = icon
56       self.charset = charset
57
58
59 class Ruler:
60    isFolder = 0
61    isBookmark = 0
62
63
64 class Walker:
65    """
66       Interface class. Any instance that will be passed to Folder.walk_depth
67       may be derived from this class. It is not mandatory - unlike Java
68       Python does not require interface classes; but it is convenient to have
69       some methods predefined to no-op, in case you do not want to
70       provide end_folder etc.
71    """
72
73    def root_folder(self, r):
74       pass
75
76    def start_folder(self, f, level):
77       pass
78
79    def end_folder(self, f, level):
80       pass
81
82    def bookmark(self, b, level):
83       pass
84
85    def ruler(self, r, level):
86       pass
87
88    def prune_folder(self, folder):
89       return 0
90
91
92 class Writer(Walker):
93    def __init__(self, outfile, prune=None):
94       self.outfile = outfile
95       self.prune = prune
96
97    def prune_folder(self, folder):
98       return self.prune == folder.name
99
100
101 class Robot:
102    def __init__(self, tempfname, log):
103       self.tempfname = tempfname
104       self.log = log
105
106    def stop(self):
107       pass # Nothing to do on cleanup
108
109
110 # Helper class to make inverese links (nodes linked to their parent)
111 class InverseLinker(Walker):
112    def root_folder(self, r):
113       self.parent_stack = [r]
114
115    def start_folder(self, f, level):
116       f.parent = self.parent_stack[-1]
117       self.parent_stack.append(f) # Push the folder onto the stack of parents
118
119    def end_folder(self, f, level):
120       del self.parent_stack[-1]   # Pop off the stack
121
122    def bookmark(self, b, level):
123       b.parent = self.parent_stack[-1]
124
125    def ruler(self, r, level):
126       r.parent = self.parent_stack[-1]
127
128
129 # Helper class to make linear represenatation of the tree
130 class Linear(Walker):
131    def root_folder(self, r):
132       r.linear = [r]
133       self.linear = r.linear
134
135    def add_object(self, object):
136       self.linear.append(object)
137
138    def start_folder(self, f, level):
139       self.add_object(f)
140
141    def bookmark(self, b, level):
142       self.add_object(b)
143
144    def ruler(self, r, level):
145       self.add_object(r)
146
147
148 # Helper - make linked linear represenatation of the tree, suitable to be stored in sequential storage
149 def make_linear(root_folder):
150    linker = InverseLinker()
151    root_folder.walk_depth(linker)
152
153    linear = Linear()
154    root_folder.walk_depth(linear)
155
156
157 # Helper, opposite of make_linear - make a tree from the linked linear representation
158 def make_tree(linear):
159    root_folder = linear[0]
160    del linear[0]
161
162    for object in linear:
163       object.parent.append(object)
164
165    return root_folder
166
167 def break_tree(linear):
168    del linear[0]
169
170    for object in linear:
171       del object.parent
172
173
174 def quote_title(title):
175    if BKMK_FORMAT == "MOZILLA":
176       title = title.replace("'", "'")
177    return title
178
179 def unquote_title(title):
180    if BKMK_FORMAT == "MOZILLA":
181       from HTMLParser import HTMLParser
182       title = HTMLParser().unescape(title.replace("&", '&'))
183       title = title.replace("'", "'")
184    return title