]> git.phdru.name Git - bookmarks_db.git/blob - bkmk_parser.py
Set unicode encoding/decoding error mode to "replace".
[bookmarks_db.git] / bkmk_parser.py
1 """
2    Parser for Netscape Navigator's and Mozilla's bookmarks.html
3
4    Written by BroytMann. Copyright (C) 1997-2003 PhiloSoft Design
5 """
6
7
8 import sys, os
9 from m_lib.net.www.html import HTMLParser
10 from bkmk_objects import Folder, Bookmark, Ruler
11
12
13 DEBUG = os.environ.has_key("BKMK_DEBUG")
14
15 if DEBUG:
16    def debug(note):
17       print note
18
19    def dump_names(folder_stack):
20       l = []
21       for object in folder_stack:
22          if object.isFolder:
23             l.append(object.name)
24       return "'%s'" % "' '".join(l)
25
26 else:
27    def debug(note):
28       pass
29    dump_names = debug
30
31
32 DEFAULT_CHARSET = None
33
34 class BkmkParser(HTMLParser):
35    def __init__(self):
36       HTMLParser.__init__(self)
37
38       self.urls = 0
39       self.objects = 0
40
41       self.charset = ""
42       self.recode = None
43
44
45    def handle_data(self, data):
46       if data:
47          if DEFAULT_CHARSET:
48             data = unicode(data, self.charset, "replace").encode(DEFAULT_CHARSET, "replace")
49          self.accumulator += data
50
51
52    # Mozilla - get charset
53    def do_meta(self, attrs):
54       http_equiv = ""
55       content = ""
56
57       for attrname, value in attrs:
58          value = value.strip()
59          if attrname == 'http-equiv':
60             http_equiv = value.lower()
61          elif attrname == 'content':
62             content = value
63
64       if http_equiv == "content-type":
65          try:
66             # extract charset from "text/html; charset=UTF-8"
67             self.charset = content.split('=')[1]
68          except IndexError:
69             pass
70          else:
71             global DEFAULT_CHARSET
72             DEFAULT_CHARSET = sys.getdefaultencoding()
73
74
75    def start_title(self, attrs):
76       self.accumulator += "<TITLE>"
77
78    def end_title(self):
79       self.accumulator += "</TITLE>"
80
81
82    # Start root folder
83    def start_h1(self, attrs):
84       root_folder = Folder()
85       self.current_object = root_folder
86       self.root_folder = root_folder
87       self.current_folder = root_folder
88       self.folder_stack = [root_folder]
89
90       self.root_folder.header = self.accumulator.strip()
91       self.accumulator = ''
92
93    def end_h1(self):
94       accumulator = self.accumulator
95       self.accumulator = ''
96
97       debug("Root folder name: `%s'" % accumulator)
98       self.root_folder.name = accumulator
99
100
101    # Start next folder
102    def start_h3(self, attrs):
103       for attrname, value in attrs:
104          value = value.strip()
105          if attrname == 'add_date':
106             add_date = value
107
108       debug("New folder...")
109       folder = Folder(add_date)
110       self.current_object = folder
111       self.current_folder.append(folder)
112       self.folder_stack.append(folder) # push new folder
113       self.current_folder = folder
114       self.objects += 1
115
116    def end_h3(self):
117       accumulator = self.accumulator
118       self.accumulator = ''
119
120       debug("Folder name: `%s'" % accumulator)
121       self.current_folder.name = accumulator
122
123
124    # Start bookmark
125    def start_a(self, attrs):
126       last_visit = None
127       last_modified = None
128
129       for attrname, value in attrs:
130          value = value.strip()
131          if attrname == 'href':
132             href = value
133          if attrname == 'add_date':
134             add_date = value
135          if attrname == 'last_visit':
136             last_visit = value
137          if attrname == 'last_modified':
138             last_modified = value
139
140       debug("Bookmark points to: `%s'" % href)
141       bookmark = Bookmark(href, add_date, last_visit, last_modified)
142       self.current_object = bookmark
143       self.current_folder.append(bookmark)
144       self.urls += 1
145       self.objects += 1
146
147    def end_a(self):
148       accumulator = self.accumulator
149       self.accumulator = ''
150
151       debug("Bookmark name: `%s'" % accumulator)
152       bookmark = self.current_folder[-1]
153       bookmark.name = accumulator
154
155
156    def flush(self):
157       accumulator = self.accumulator
158
159       if accumulator:
160          self.accumulator = ''
161
162          current_object = self.current_object
163          if current_object:
164             current_object.comment += accumulator.strip()
165             debug("Comment: `%s'" % current_object.comment)
166
167
168    def start_dl(self, attrs):
169       self.flush()
170
171    do_dt = start_dl
172
173
174    # End of folder
175    def end_dl(self):
176       self.flush()
177       debug("End folder")
178       debug("Folder stack: %s" % dump_names(self.folder_stack))
179       if self.folder_stack:
180          del self.folder_stack[-1] # pop last folder
181          if self.folder_stack:
182             self.current_folder = self.folder_stack[-1]
183          else:
184             debug("FOLDER STACK is EMPTY!!! (1)")
185       else:
186          debug("FOLDER STACK is EMPTY!!! (2)")
187       self.current_object = None
188
189
190    def close(self):
191       HTMLParser.close(self)
192       if self.folder_stack:
193          raise ValueError, "wrong folder stack: %s" % self.folder_stack
194
195
196    def do_dd(self, attrs):
197       pass
198
199    do_p = do_dd
200
201
202    # Start ruler
203    def do_hr(self, attrs):
204       self.flush()
205       debug("Ruler")
206       self.current_folder.append(Ruler())
207       self.current_object = None
208       self.objects += 1
209
210
211    # BR in comment
212    def do_br(self, attrs):
213       self.accumulator += "<BR>"
214
215
216    # Allow < in the text
217    def unknown_starttag(self, tag, attrs):
218       self.accumulator += "<%s>" % tag
219
220
221    # Do not allow unknow end tags
222    def unknown_endtag(self, tag):
223       raise NotImplementedError("Unknow end tag `%s'" % tag)