4 Written by BroytMann, Mar 1997 - Feb 2000. Copyright (C) 1997-2000 PhiloSoft Design
8 import os, string, shutil
9 from htmllib import HTMLParser
12 class BookmarksParser(HTMLParser): # Parser for Navigator's bookmarks (abstract class)
13 def __init__(self, formatter, verbose=0):
14 HTMLParser.__init__(self, formatter, verbose)
15 self.urls_no = 0 # cross-reference counter
16 self.record_no = 1 # record counter
17 self.outfile = None # output file
18 self.level = 0 # Indentation level
19 self.flag_out = 0 # Is it time to flush?
21 self.saved_anchor = None
22 self.saved_folder = None
23 self.saved_ruler = None
33 name, href, add_date, last_visit, last_modified, comment = self.saved_anchor
34 self.saved_anchor = (name, href, add_date, last_visit, last_modified, comment + self.saved_data)
38 self.saved_anchor = None
41 name, add_date, comment = self.saved_folder
42 self.saved_folder = (name, add_date, comment + self.saved_data)
46 self.saved_folder = None
51 self.saved_ruler = None
54 self.record_no = self.record_no + 1
56 if self.saved_data <> '': # This may occur after ampersand
63 HTMLParser.close(self)
69 print "Bad HTML: <DL> and </DL> mismatch; level=%d" % self.level
72 def handle_data(self, data):
76 if data and (data[0] == '&'): # Ampersand parsed by SGMLlib
79 if self.flag_out == 2: # Process comment after <DD> or <HR>
81 name, href, add_date, last_visit, last_modified, comment = self.saved_anchor
82 self.saved_anchor = (name, href, add_date, last_visit, last_modified, comment + data)
86 name, add_date, comment = self.saved_folder
87 self.saved_folder = (name, add_date, comment + data)
92 if self.flag_out == 1:
95 if data and (data[0] <> '&') and (self.flag_out == 0):
96 self.flag_out = 1 # Set flag (to flush data on next call)
99 self.saved_data = self.saved_data + data
102 def anchor_bgn(self, href, add_date, last_visit, last_modified):
104 self.anchor = (href, add_date, last_visit, last_modified)
107 def anchor_end(self):
109 href, add_date, last_visit, last_modified = self.anchor
111 self.urls_no = self.urls_no + 1
113 self.saved_anchor = (self.saved_data, href, add_date, last_visit, last_modified, '')
114 self.saved_data = '' # Used
117 def start_a(self, attrs):
123 for attrname, value in attrs:
124 value = string.strip(value)
125 if attrname == 'href':
127 if attrname == 'add_date':
129 if attrname == 'last_visit':
131 if attrname == 'last_modified':
132 last_modified = value
134 self.anchor_bgn(href, add_date, last_visit, last_modified)
137 def start_h3(self, attrs): # Navigator marks folders with <H3> tags
141 for attrname, value in attrs:
142 value = string.strip(value)
143 if attrname == 'add_date':
146 self.saved_folder = ('', add_date, '')
150 def end_h3(self): # End of folder
151 name, add_date, comment = self.saved_folder
152 self.saved_folder = (name + self.saved_data, add_date, comment)
153 self.saved_data = '' # Used
156 def start_dl(self, attrs):
159 if not self.outfile: # We are starting output after 1st <DL> tag to skip header
162 self.level = self.level + 1
167 self.level = self.level - 1
170 def do_dd(self, attrs):
172 self.flag_out = 2 # Set flag to signal "comment starting"
175 def do_br(self, attrs):
177 self.saved_data = self.saved_data + "<BR>" # Add <BR>...
178 self.flag_out = 0 # ...and next line of comment to saved comment
181 def do_hr(self, attrs):
187 def handle_charref(self, name):
190 self.saved_data = "%s&%c" % (self.saved_data, chr(name))
193 def handle_entityref(self, name):
196 if self.entitydefs.has_key(name): # If it is one of the standard SGML entities - close it with semicolon
200 self.saved_data = "%s&%s%s" % (self.saved_data, name, x)
203 def open_outfile(self):
204 self.outfile = open("bookmarks.tmp", 'w')
207 class Bookmarks2Text(BookmarksParser):
208 def flush_anchor(self):
209 self.outfile.write(" "*(self.level-1) + str(self.saved_anchor) + '\n')
212 def flush_folder(self):
213 self.outfile.write(" "*(self.level-1) + str(self.saved_folder) + '\n')
216 def flush_ruler(self):
217 self.outfile.write(" "*(self.level-1) + "----------\n")
221 shutil.copy("bookmarks.tmp", "bookmarks.txt")
222 os.unlink("bookmarks.tmp")
225 class Bookmarks2Flad(BookmarksParser):
226 def __init__(self, formatter, verbose=0):
227 BookmarksParser.__init__(self, formatter, verbose)
228 self.flush_record = 0
237 if self.saved_anchor or self.saved_folder or self.saved_ruler or self.saved_data:
238 if self.flush_record:
239 self.outfile.write('\n')
241 self.flush_record = 1
243 BookmarksParser.flush(self)
246 def flush_anchor(self):
247 name, href, add_date, last_visit, last_modified, comment = self.saved_anchor
248 self.outfile.write("""Level: %d
255 """ % (self.level, name, href, add_date, last_visit, last_modified, comment))
257 def flush_folder(self):
258 name, add_date, comment = self.saved_folder
259 self.outfile.write("""Level: %d
263 """ % (self.level, name, add_date, comment))
265 def flush_ruler(self):
266 self.outfile.write("Level: %s\nRuler: YES\n" % self.level)
270 shutil.copy("bookmarks.tmp", "bookmarks.db")
271 os.unlink("bookmarks.tmp")
274 class Bookmarks2Gadfly(BookmarksParser):
275 def open_outfile(self):
277 connection = gadfly.gadfly()
278 connection.startup("bookmarks", ".")
279 self.connection = connection
281 cursor = connection.cursor()
282 cursor.execute("""create table bookmarks (
289 last_modified integer,
292 self.outfile = cursor
294 self.template = """insert into bookmarks
295 (rec_no, level, title, DATA, add_date, last_visit, last_modified, comment)
296 values (?, ?, ?, ?, ?, ?, ?, ?)"""
300 self.connection.commit()
303 def flush_anchor(self):
304 name, href, add_date, last_visit, last_modified, comment = self.saved_anchor
305 self.outfile.execute(self.template,
306 (self.record_no, self.level, name, href,
307 add_date, last_visit, last_modified, comment)
310 def flush_folder(self):
311 name, add_date, comment = self.saved_folder
312 self.outfile.execute(self.template,
313 (self.record_no, self.level, name, "Folder",
314 add_date, '', '', comment)
317 def flush_ruler(self):
318 self.outfile.execute(self.template,
319 (self.record_no, self.level, '', "Ruler",