]> git.phdru.name Git - bookmarks_db.git/blob - bkmk_objects.py
Added docstrings, __{version,revision,etc}__ boilerplates.
[bookmarks_db.git] / bkmk_objects.py
1 """Objects to represent bookmarks.html structure
2
3 This file is a part of Bookmarks database and Internet robot.
4 """
5
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"
12
13 import os, cgi
14 BKMK_FORMAT = os.environ.get("BKMK_FORMAT", "MOZILLA")
15
16
17 class Folder(list):
18    isFolder = 1
19    isBookmark = 0
20
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
26
27    def walk_depth(self, walker, level=0):
28       if hasattr(self, "header"): # root folder
29          prune = 0
30          walker.root_folder(self)
31       else:
32          prune = walker.prune_folder(self)
33          if not prune:
34             walker.start_folder(self, level)
35
36       if not prune:
37          for object in self:
38             if object.isFolder:
39                object.walk_depth(walker, level+1)
40             elif object.isBookmark:
41                walker.bookmark(object, level)
42             else:
43                walker.ruler(object, level)
44
45          walker.end_folder(self, level)
46
47
48 class Bookmark:
49    isFolder = 0
50    isBookmark = 1
51
52    def __init__(self, href, add_date, last_visit=None, last_modified=None,
53          keyword=None, comment='', icon_href=None, icon=None, charset=None):
54       self.href = href
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
61       self.icon = icon
62       self.charset = charset
63
64
65 class Ruler:
66    isFolder = 0
67    isBookmark = 0
68
69
70 class Walker:
71    """
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.
77    """
78
79    def root_folder(self, r):
80       pass
81
82    def start_folder(self, f, level):
83       pass
84
85    def end_folder(self, f, level):
86       pass
87
88    def bookmark(self, b, level):
89       pass
90
91    def ruler(self, r, level):
92       pass
93
94    def prune_folder(self, folder):
95       return 0
96
97
98 class Writer(Walker):
99    def __init__(self, outfile, prune=None):
100       self.outfile = outfile
101       self.prune = prune
102
103    def prune_folder(self, folder):
104       return self.prune == folder.name
105
106
107 class Robot:
108    def __init__(self, log):
109       self.log = log
110
111    def stop(self):
112       pass # Nothing to do on cleanup
113
114
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]
119
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
123
124    def end_folder(self, f, level):
125       del self.parent_stack[-1]   # Pop off the stack
126
127    def bookmark(self, b, level):
128       b.parent = self.parent_stack[-1]
129
130    def ruler(self, r, level):
131       r.parent = self.parent_stack[-1]
132
133
134 # Helper class to make linear represenatation of the tree
135 class Linear(Walker):
136    def root_folder(self, r):
137       r.linear = [r]
138       self.linear = r.linear
139
140    def add_object(self, object):
141       self.linear.append(object)
142
143    def start_folder(self, f, level):
144       self.add_object(f)
145
146    def bookmark(self, b, level):
147       self.add_object(b)
148
149    def ruler(self, r, level):
150       self.add_object(r)
151
152
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)
157
158    linear = Linear()
159    root_folder.walk_depth(linear)
160
161
162 # Helper, opposite of make_linear - make a tree from the linked linear representation
163 def make_tree(linear):
164    root_folder = linear[0]
165    del linear[0]
166
167    for object in linear:
168       object.parent.append(object)
169
170    return root_folder
171
172 def break_tree(linear):
173    del linear[0]
174
175    for object in linear:
176       del object.parent
177
178
179 def quote_title(title):
180    if BKMK_FORMAT == "MOZILLA":
181       title = title.replace("'", "&#39;")
182    return title
183
184 def unquote_title(title):
185    if BKMK_FORMAT == "MOZILLA":
186       from HTMLParser import HTMLParser
187       title = HTMLParser().unescape(title.replace("&amp;", '&'))
188       title = title.replace("&#39;", "'")
189    return title