]> git.phdru.name Git - bookmarks_db.git/blob - bkmk_parser.py
Initial revision
[bookmarks_db.git] / bkmk_parser.py
1 """
2    Bookmarks parsers
3
4    Written by BroytMann, Mar 1997 - Feb 2000. Copyright (C) 1997-2000 PhiloSoft Design
5 """
6
7
8 import os, string, shutil
9 from htmllib import HTMLParser
10
11
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?
20       self.saved_data = ''
21       self.saved_anchor = None
22       self.saved_folder = None
23       self.saved_ruler = None
24
25
26    def flush(self):
27       if not self.outfile:
28          return
29
30       record_flushed = 0
31
32       if self.saved_anchor:
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)
35          self.flush_anchor()
36          self.saved_data = ''
37          record_flushed = 1
38          self.saved_anchor = None
39
40       if self.saved_folder:
41          name, add_date, comment = self.saved_folder
42          self.saved_folder = (name, add_date, comment + self.saved_data)
43          self.flush_folder()
44          self.saved_data = ''
45          record_flushed = 1
46          self.saved_folder = None
47
48       if self.saved_ruler:
49          self.flush_ruler()
50          record_flushed = 1
51          self.saved_ruler = None
52
53       if record_flushed:
54          self.record_no = self.record_no + 1
55
56       if self.saved_data <> '': # This may occur after ampersand
57          self.flag_out = 0
58
59
60
61
62    def close(self):
63       HTMLParser.close(self)
64
65       if self.outfile:
66          self.outfile.close()
67
68       if self.level <> 0:
69          print "Bad HTML: <DL> and </DL> mismatch; level=%d" % self.level
70
71
72    def handle_data(self, data):
73       if not self.outfile:
74          return
75
76       if data and (data[0] == '&'): # Ampersand parsed by SGMLlib
77          self.flag_out = 0
78
79       if self.flag_out == 2: # Process comment after <DD> or <HR>
80          if self.saved_anchor:
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)
83             data = '' # Used
84
85          if self.saved_folder:
86             name, add_date, comment = self.saved_folder
87             self.saved_folder = (name, add_date, comment + data)
88             data = '' # Used
89
90          self.flag_out = 0
91
92       if self.flag_out == 1:
93          self.flush()
94
95       if data and (data[0] <> '&') and (self.flag_out == 0):
96          self.flag_out = 1 # Set flag (to flush data on next call)
97
98       if data:
99          self.saved_data = self.saved_data + data
100
101
102    def anchor_bgn(self, href, add_date, last_visit, last_modified):
103       self.flush()
104       self.anchor = (href, add_date, last_visit, last_modified)
105
106
107    def anchor_end(self):
108       if self.anchor:
109          href, add_date, last_visit, last_modified = self.anchor
110          self.anchor = None
111          self.urls_no = self.urls_no + 1
112
113          self.saved_anchor = (self.saved_data, href, add_date, last_visit, last_modified, '')
114          self.saved_data = '' # Used
115
116
117    def start_a(self, attrs):
118       href = ''
119       add_date = ''
120       last_visit = ''
121       last_modified = ''
122
123       for attrname, value in attrs:
124          value = string.strip(value)
125          if attrname == 'href':
126             href = value
127          if attrname == 'add_date':
128             add_date = value
129          if attrname == 'last_visit':
130             last_visit = value
131          if attrname == 'last_modified':
132             last_modified = value
133
134       self.anchor_bgn(href, add_date, last_visit, last_modified)
135
136
137    def start_h3(self, attrs): # Navigator marks folders with <H3> tags
138       self.flush()
139       add_date = ''
140
141       for attrname, value in attrs:
142          value = string.strip(value)
143          if attrname == 'add_date':
144             add_date = value
145
146       self.saved_folder = ('', add_date, '')
147       self.flag_out = 0
148
149
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
154
155
156    def start_dl(self, attrs):
157       self.flush()
158
159       if not self.outfile: # We are starting output after 1st <DL> tag to skip header
160          self.open_outfile()
161
162       self.level = self.level + 1
163
164
165    def end_dl(self):
166       self.flush()
167       self.level = self.level - 1
168
169
170    def do_dd(self, attrs):
171       if self.outfile:
172          self.flag_out = 2 # Set flag to signal "comment starting"
173
174
175    def do_br(self, attrs):
176       if self.outfile:
177          self.saved_data = self.saved_data + "<BR>" # Add <BR>...
178          self.flag_out = 0 # ...and next line of comment to saved comment
179
180
181    def do_hr(self, attrs):
182       if self.outfile:
183          self.flush()
184          self.saved_ruler = 1
185
186
187    def handle_charref(self, name):
188       if self.outfile:
189          self.flag_out = 0
190          self.saved_data = "%s&%c" % (self.saved_data, chr(name))
191
192
193    def handle_entityref(self, name):
194       if self.outfile:
195          self.flag_out = 0
196          if self.entitydefs.has_key(name): # If it is one of the standard SGML entities - close it with semicolon
197             x = ';'
198          else:
199             x = ''
200          self.saved_data = "%s&%s%s" % (self.saved_data, name, x)
201
202
203    def open_outfile(self):
204       self.outfile = open("bookmarks.tmp", 'w')
205
206
207 class Bookmarks2Text(BookmarksParser):
208    def flush_anchor(self):
209       self.outfile.write("   "*(self.level-1) + str(self.saved_anchor) + '\n')
210
211
212    def flush_folder(self):
213       self.outfile.write("   "*(self.level-1) + str(self.saved_folder) + '\n')
214
215
216    def flush_ruler(self):
217       self.outfile.write("   "*(self.level-1) + "----------\n")
218
219
220    def __del__(self):
221       shutil.copy("bookmarks.tmp", "bookmarks.txt")
222       os.unlink("bookmarks.tmp")
223
224
225 class Bookmarks2Flad(BookmarksParser):
226    def __init__(self, formatter, verbose=0):
227       BookmarksParser.__init__(self, formatter, verbose)
228       self.flush_record = 0
229
230
231    def flush(self):
232       if not self.outfile:
233          return
234
235       record_flushed = 0
236
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')
240          else:
241             self.flush_record = 1
242
243       BookmarksParser.flush(self)
244
245
246    def flush_anchor(self):
247       name, href, add_date, last_visit, last_modified, comment = self.saved_anchor
248       self.outfile.write("""Level: %d
249 Title: %s
250 URL: %s
251 AddDate: %s
252 LastVisit: %s
253 LastModified: %s
254 Comment: %s
255 """ % (self.level, name, href, add_date, last_visit, last_modified, comment))
256
257    def flush_folder(self):
258       name, add_date, comment = self.saved_folder
259       self.outfile.write("""Level: %d
260 Folder: %s
261 AddDate: %s
262 Comment: %s
263 """ % (self.level, name, add_date, comment))
264
265    def flush_ruler(self):
266       self.outfile.write("Level: %s\nRuler: YES\n" % self.level)
267
268
269    def __del__(self):
270       shutil.copy("bookmarks.tmp", "bookmarks.db")
271       os.unlink("bookmarks.tmp")
272
273
274 class Bookmarks2Gadfly(BookmarksParser):
275    def open_outfile(self):
276       import gadfly
277       connection = gadfly.gadfly()
278       connection.startup("bookmarks", ".")
279       self.connection = connection
280
281       cursor = connection.cursor()
282       cursor.execute("""create table bookmarks (
283          rec_no integer,
284          level integer,
285          title varchar,
286          DATA varchar,
287          add_date integer,
288          last_visit integer,
289          last_modified integer,
290          comment varchar
291       )""")
292       self.outfile = cursor
293
294       self.template = """insert into bookmarks
295          (rec_no, level, title, DATA, add_date, last_visit, last_modified, comment)
296          values (?, ?, ?, ?, ?, ?, ?, ?)"""
297
298
299    def __del__(self):
300       self.connection.commit()
301
302
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)
308       )
309
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)
315       )
316
317    def flush_ruler(self):
318       self.outfile.execute(self.template,
319          (self.record_no, self.level, '', "Ruler",
320          '', '', '', '')
321       )