home *** CD-ROM | disk | FTP | other *** search
/ PC Welt 2006 November (DVD) / PCWELT_11_2006.ISO / casper / filesystem.squashfs / usr / lib / deskbar-applet / handlers / mozilla.py < prev    next >
Encoding:
Python Source  |  2006-08-29  |  18.9 KB  |  587 lines

  1. import os, re, HTMLParser, base64, glob
  2. from os.path import join, expanduser, exists, basename
  3. from gettext import gettext as _
  4. from ConfigParser import RawConfigParser
  5. from deskbar.defs import VERSION
  6. import gtk
  7. from deskbar.Watcher import FileWatcher, DirWatcher
  8. import deskbar, deskbar.Indexer, deskbar.Handler
  9.  
  10. # Check for presence of set to be compatible with python 2.3
  11. try:
  12.     set
  13. except NameError:
  14.     from sets import Set as set
  15.  
  16. from deskbar.BrowserMatch import is_preferred_browser
  17. from deskbar.BrowserMatch import BrowserSmartMatch, BrowserMatch
  18.  
  19. # Whether we will index firefox or mozilla bookmarks
  20. USING_FIREFOX = False
  21. if is_preferred_browser("firefox"):
  22.     USING_FIREFOX = True
  23.         
  24. # File returned here should be checked for existence
  25. def get_mozilla_home_file(needed_file):    
  26.     default_profile_dir = expanduser("~/.mozilla/default")
  27.     if exists(default_profile_dir):
  28.         for d in os.listdir(default_profile_dir):
  29.             return join(default_profile_dir, d, needed_file)
  30.     
  31.     return ""
  32.     
  33. def get_firefox_home_file(needed_file):
  34.     firefox_dir = expanduser("~/.mozilla/firefox/")
  35.     config = RawConfigParser({"Default" : 0})
  36.     config.read(expanduser(join(firefox_dir, "profiles.ini")))
  37.     path = None
  38.  
  39.     for section in config.sections():
  40.         if config.has_option(section, "Default") and config.get(section, "Default") == "1":
  41.             path = config.get (section, "Path")
  42.             break
  43.         elif path == None and config.has_option(section, "Path"):
  44.             path = config.get (section, "Path")
  45.         
  46.     if path == None:
  47.         return ""
  48.  
  49.     if path.startswith("/"):
  50.         return join(path, needed_file)
  51.  
  52.     return join(firefox_dir, path, needed_file)
  53.  
  54. # Whether we offer all of the browser's search engines, or only the primary
  55. # one (since by default Firefox seems to come with at least half a dozen)            
  56. GCONF_SHOW_ONLY_PRIMARY_KEY = deskbar.GCONF_DIR + "/mozilla/show_only_primary_search"
  57. SHOW_ONLY_PRIMARY = deskbar.GCONF_CLIENT.get_bool(GCONF_SHOW_ONLY_PRIMARY_KEY)
  58. if SHOW_ONLY_PRIMARY == None:
  59.     SHOW_ONLY_PRIMARY = False
  60. def _on_gconf_show_only_primary(value):
  61.     global SHOW_ONLY_PRIMARY
  62.     SHOW_ONLY_PRIMARY = value
  63. deskbar.GCONF_CLIENT.notify_add(GCONF_SHOW_ONLY_PRIMARY_KEY, lambda x, y, z, a: _on_gconf_show_only_primary(z.value.get_bool()))
  64.  
  65. # TODO re-load PRIMARY_SEARCH_ENGINE everytime it changes (which should happen
  66. # only rarely).  One (unavoidable) problem may be that firefox doesn't actually
  67. # save the change to disk until you quit firefox.
  68. PRIMARY_SEARCH_ENGINE = None
  69. try:
  70.     if USING_FIREFOX:
  71.         prefs_file = file(get_firefox_home_file("prefs.js"))
  72.     else:
  73.         # TODO - similar functionality for old-school mozilla (not firefox)
  74.         prefs_file = None
  75.     for line in prefs_file:
  76.         if line.startswith('user_pref("browser.search.selectedEngine", "'):
  77.             line = line.strip()
  78.             PRIMARY_SEARCH_ENGINE = line[len('user_pref("browser.search.selectedEngine", "'):-len('");')]
  79.             break
  80. except:
  81.     pass
  82.  
  83. def _on_handler_preferences(dialog):
  84.     def toggled_cb(sender, show_all_radio, show_primary_radio):
  85.         deskbar.GCONF_CLIENT.set_bool(GCONF_SHOW_ONLY_PRIMARY_KEY, show_primary_radio.get_active())
  86.         
  87.     def sync_ui(new_show_only_primary, show_all_radio, show_primary_radio):
  88.         show_all_radio.set_active(not new_show_only_primary)
  89.         show_primary_radio.set_active(new_show_only_primary)
  90.     
  91.     glade = gtk.glade.XML(os.path.join(deskbar.SHARED_DATA_DIR, "mozilla-search.glade"))
  92.     dialog = glade.get_widget("prefs-dialog")
  93.     show_all_radio = glade.get_widget("show_all_radio")
  94.     show_primary_radio = glade.get_widget("show_primary_radio")
  95.     
  96.     show_primary_radio.set_active(SHOW_ONLY_PRIMARY)
  97.     show_all_radio.set_active(not SHOW_ONLY_PRIMARY)
  98.     
  99.     show_all_radio.connect ("toggled", toggled_cb, show_all_radio, show_primary_radio)
  100.     show_primary_radio.connect ("toggled", toggled_cb, show_all_radio, show_primary_radio)
  101.     
  102.     notify_id = deskbar.GCONF_CLIENT.notify_add(GCONF_SHOW_ONLY_PRIMARY_KEY, lambda x, y, z, a: sync_ui(z.value.get_bool(), show_all_radio, show_primary_radio))
  103.     dialog.set_icon_name("deskbar-applet")
  104.     dialog.show_all()
  105.     dialog.run()
  106.     dialog.destroy()
  107.     deskbar.GCONF_CLIENT.notify_remove(notify_id)
  108.     
  109. def _check_requirements_bookmarks():
  110. #    if deskbar.UNINSTALLED_DESKBAR:
  111. #        return (deskbar.Handler.HANDLER_IS_HAPPY, None, None)
  112.     
  113.     if is_preferred_browser("firefox") or is_preferred_browser("mozilla"):
  114.         return (deskbar.Handler.HANDLER_IS_HAPPY, None, None)
  115.     else:
  116.         return (deskbar.Handler.HANDLER_IS_NOT_APPLICABLE, "Mozilla/Firefox is not your preferred browser, not using it.", None)
  117.         
  118. def _check_requirements_search():
  119.     if is_preferred_browser("firefox"):
  120.         return (deskbar.Handler.HANDLER_IS_CONFIGURABLE, _("You can customize which search engines are offered."), _on_handler_preferences)
  121.     elif is_preferred_browser("mozilla"):
  122.         # TODO - similar functionality for old-school mozilla (not firefox)
  123.         return (deskbar.Handler.HANDLER_IS_HAPPY, None, None)
  124.     else:
  125.         return (deskbar.Handler.HANDLER_IS_NOT_APPLICABLE, "Mozilla/Firefox is not your preferred browser, not using it.", None)
  126.         
  127. HANDLERS = {
  128.     "MozillaBookmarksHandler" : {
  129.         "name": _("Web Bookmarks"),
  130.         "description": _("Open your web bookmarks by name"),
  131.         "requirements": _check_requirements_bookmarks,
  132.         "version": VERSION,
  133.     },
  134.     "MozillaSearchHandler" : {
  135.         "name": _("Web Searches"),
  136.         "description": _("Search the web via your browser's search settings"),
  137.         "requirements": _check_requirements_search,
  138.         "version": VERSION,
  139.     },
  140.     "MozillaHistoryHandler" : {
  141.         "name": _("Web History"),
  142.         "description": _("Open your web history by name"),
  143.         "requirements": _check_requirements_bookmarks,
  144.         "version": VERSION,
  145.     }
  146. }
  147.  
  148. class MozillaBookmarksHandler(deskbar.Handler.Handler):
  149.     def __init__(self):
  150.         deskbar.Handler.Handler.__init__(self, "stock_bookmark")
  151.         self._bookmarks = None
  152.     
  153.     def initialize(self):
  154.         if not hasattr(self, 'watcher'):
  155.             self.watcher = FileWatcher()
  156.             self.watcher.connect('changed', lambda watcher, f: self._parse_bookmarks())
  157.         
  158.         # We do some gym to get the effectively parsed files
  159.         parsed_file = self._parse_bookmarks()
  160.         if parsed_file != None:
  161.             self.watcher.add(parsed_file)
  162.         
  163.     def _parse_bookmarks(self):
  164.         self._bookmarks, parsed_file, self._shortcuts_to_smart_bookmarks_map = MozillaBookmarksParser(self).get_indexer()
  165.         return parsed_file
  166.     
  167.     def stop(self):
  168.         self.watcher.remove_all()
  169.         
  170.     def query(self, query):
  171.         # First, check the smart bookmarks, or "keywords", where
  172.         # "wp Foo" takes you to the wikipedia entry for Foo.
  173.         x = self.query_smart_bookmarks(query, deskbar.DEFAULT_RESULTS_PER_HANDLER)
  174.         if x != None:
  175.             return x
  176.         else:
  177.             # If none of the smart bookmarks matched as a prefix,
  178.             # then we'll just look up all bookmarks.
  179.             return self._bookmarks.look_up(query)[:deskbar.DEFAULT_RESULTS_PER_HANDLER]
  180.     
  181.     def query_smart_bookmarks(self, query, max):
  182.         # if one of the smart bookmarks' shortcuts matches as a prefix,
  183.         # then only return that bookmark
  184.         x = query.find(" ")
  185.         if x != -1:
  186.             prefix = query[:x]
  187.             try:
  188.                 b = self._shortcuts_to_smart_bookmarks_map[prefix]
  189.                 text = query[x+1:]
  190.                 return [BrowserSmartMatch(b.get_handler(), b.name, b.url, prefix, b, icon=b.icon)]
  191.             except KeyError:
  192.                 # Probably from the b = ... line.  Getting here
  193.                 # means that there is no such shortcut.
  194.                 pass
  195.         return None
  196.  
  197. class MozillaSearchHandler(deskbar.Handler.Handler):
  198.     def __init__(self):
  199.         deskbar.Handler.Handler.__init__(self, "stock_bookmark")
  200.         self._smart_bookmarks = None
  201.     
  202.     def initialize(self):
  203.         smart_dirs = None
  204.         if USING_FIREFOX:
  205.             smart_dirs = [
  206.                 get_firefox_home_file("searchplugins"),
  207.                 get_firefox_home_file("search"),
  208.                 expanduser("~/.mozilla/searchplugins"),
  209.                 "/usr/lib/firefox/searchplugins",
  210.                 "/usr/local/lib/firefox/searchplugins",
  211.                 "/usr/lib/mozilla-firefox/searchplugins",
  212.                 "/usr/local/lib/mozilla-firefox/searchplugins"]
  213.         else:
  214.             smart_dirs = [
  215.                 get_mozilla_home_file("search"),
  216.                 expanduser("~/.mozilla/searchplugins"),
  217.                 "/usr/lib/mozilla/searchplugins",
  218.                 "/usr/local/lib/mozilla/searchplugins"]
  219.         
  220.         if not hasattr(self, 'watcher'):
  221.             self.watcher = DirWatcher()
  222.             self.watcher.connect('changed', lambda watcher, f: self._parse_search_engines(smart_dirs))
  223.         
  224.         self.watcher.add(smart_dirs)
  225.         self._parse_search_engines(smart_dirs)
  226.         
  227.     def _parse_search_engines(self, smart_dirs):
  228.         self._smart_bookmarks = MozillaSmartBookmarksDirParser(self, smart_dirs).get_smart_bookmarks()
  229.  
  230.     def stop(self):
  231.         self.watcher.remove_all()
  232.         
  233.     def query(self, query):
  234.         if SHOW_ONLY_PRIMARY and PRIMARY_SEARCH_ENGINE != None:
  235.             for s in self._smart_bookmarks:
  236.                 if s.name == PRIMARY_SEARCH_ENGINE:
  237.                     return [s]
  238.             return self._smart_bookmarks
  239.         else:
  240.             return self._smart_bookmarks
  241.         
  242. class MozillaBookmarksParser(HTMLParser.HTMLParser):
  243.     def __init__(self, handler):
  244.         HTMLParser.HTMLParser.__init__(self)
  245.         
  246.         self.handler = handler
  247.         
  248.         self.chars = ""
  249.         self.href = None
  250.         self.icon_data = None
  251.         self.bookmarks = set()
  252.         self._shortcuts_to_smart_bookmarks_map = {}
  253.         
  254.         self._indexer = deskbar.Indexer.Indexer()
  255.         
  256.         if USING_FIREFOX:
  257.             self.indexed_file = self._index_firefox()
  258.         else:
  259.             self.indexed_file = self._index_mozilla()
  260.         self.close()
  261.         
  262.     def get_indexer(self):
  263.         """
  264.         Returns a completed indexer with the contents of bookmark file,
  265.         the name of the indexed file, and a map from shortcuts (or
  266.         prefixes) to smart bookmarks - those bookmarks with %s in the
  267.         URL.
  268.         """
  269.         return (self._indexer, self.indexed_file, self._shortcuts_to_smart_bookmarks_map)
  270.         
  271.     def _index_mozilla(self):
  272.         try:
  273.             bookmarks_file = get_mozilla_home_file("bookmarks.html")
  274.             if exists(bookmarks_file):
  275.                 self.feed(file(bookmarks_file).read())
  276.                 return bookmarks_file
  277.         except Exception, msg:
  278.             print 'Error retreiving Mozilla Bookmarks:', msg
  279.         
  280.     def _index_firefox(self):
  281.         try:
  282.             bookmarks_file = get_firefox_home_file("bookmarks.html")
  283.             if exists(bookmarks_file):
  284.                 self.feed(file(bookmarks_file).read())
  285.                 return bookmarks_file
  286.         except Exception, msg:
  287.             print 'Error retreiving Mozilla Bookmarks:', msg
  288.     
  289.     def handle_starttag(self, tag, attrs):
  290.         tag = tag.lower()
  291.         if tag == "a":
  292.             self.chars = ""
  293.             self.shortcuturl = None
  294.             for tag, value in attrs:
  295.                 if tag.lower() == 'href':
  296.                     self.href = value
  297.                 if tag.lower() == 'icon' and value != "data:" and value.startswith("data:"):
  298.                     self.icon_data = value
  299.                 if tag.lower() == 'shortcuturl':
  300.                     self.shortcuturl = value
  301.  
  302.     def handle_endtag(self, tag):
  303.         tag = tag.lower()
  304.         if tag == "a":
  305.             if self.href == None or self.href.startswith("javascript:"):
  306.                 return
  307.             
  308.             pixbuf = None
  309.             if self.icon_data != None:
  310.                 try:
  311.                     # data:text/html;base64 should be the Header
  312.                     header, content = self.icon_data.split(",", 2)
  313.                     loader = gtk.gdk.PixbufLoader()
  314.                     loader.set_size(deskbar.ICON_HEIGHT, deskbar.ICON_HEIGHT)
  315.                     try:
  316.                         # Python 2.4
  317.                         loader.write(base64.b64decode(content))
  318.                     except AttributeError:
  319.                         # Python 2.3 and earlier
  320.                         loader.write(base64.decodestring(content))
  321.                     loader.close()
  322.                     pixbuf = loader.get_pixbuf()
  323.                 except Exception, msg:
  324.                     print 'Error:mozilla.py:handle_endtag:', msg
  325.                 # Reset icon data for the following icon
  326.                 self.icon_data = None
  327.                 
  328.             bookmark = BrowserMatch(self.handler, self.chars, self.href, icon=pixbuf)
  329.             if self.shortcuturl != None:
  330.                 bookmark = BrowserSmartMatch(self.handler, self.chars, self.href, self.shortcuturl, bookmark, icon=pixbuf)
  331.                 self._shortcuts_to_smart_bookmarks_map[self.shortcuturl] = bookmark
  332.             else:
  333.                 self._indexer.add("%s %s" % (self.chars, self.href), bookmark)
  334.  
  335.     def handle_data(self, chars):
  336.         self.chars = self.chars + chars
  337.  
  338.  
  339.                         
  340. class MozillaSmartBookmarksParser:
  341.     def __init__(self, f):
  342.         """
  343.         Init the parse, no exception here
  344.         """
  345.         self.f = f
  346.         self.infos = {
  347.             "search": {},
  348.             "input": {},
  349.         }
  350.     
  351.     def get_infos(self):
  352.         infos = {}
  353.         
  354.         args = "?"
  355.         for key, arg in self.infos["input"].items():
  356.             args += '%s=%s&' % (key, arg)
  357.         
  358.         if args.endswith("&"):
  359.             args = args[:-1]
  360.         
  361.         infos["name"] = self.infos["search"]["name"]
  362.         infos["description"] = self.infos["search"]["description"]
  363.  
  364.         # FIXME: If we don't have a real fallback url, doing this will most probably
  365.         # result in some error. Ideally, we should use gnomevfs to extract the
  366.         # simple hostname, for example: https://www.amazon.com/obidos/blah/q=%s&ie=7753829
  367.         # should be trimmed to https://www.amazon.com
  368.         if not "url" in self.infos["search"]:
  369.             infos["url"] = self.infos["search"]["action"]
  370.         else:
  371.             infos["url"] = self.infos["search"]["url"]
  372.             
  373.         infos["action"] = self.infos["search"]["action"] + args
  374.         return infos
  375.         
  376.     def parse(self):
  377.         """
  378.         """
  379.         tokenizer = Tokenizer(self.f)
  380.         n = state = None
  381.         
  382.         # We load the two first tokens, whch should be ["<", "search"]
  383.         tokens = [tokenizer.get_next_token(), tokenizer.get_next_token()]
  384.         while tokens[0] != None:
  385.             # Retreive the next state, the number of tokens to read next, and any discarded tokens
  386.             # by the handler, which should be handled on next iteration
  387.             state, n, rest = self._handle_token(state, tokens)
  388.             # If n == None, we finished parsing
  389.             if n == None:
  390.                 break
  391.             
  392.             # Read the requested number of tokens, but count the ones that were rejected first
  393.             tokens = rest
  394.             for i in range(n - len(rest)):
  395.                 tokens.append(tokenizer.get_next_token())
  396.     
  397.     def _handle_token(self, state, tokens):
  398.         if state == None and (tokens == ["<", "search"] or tokens == ["<", "SEARCH"]):
  399.             return "search", 3, []
  400.         elif state == None:
  401.             raise ParseException("File %s does not begin with <search" % self.f)
  402.         
  403.         # Read key=value pairs and store them in the infos["search"] dict
  404.         if state == "search" and tokens[1] == "=":
  405.             self.infos["search"][tokens[0]] = tokens[2]
  406.             return "search", 3, []
  407.         
  408.         # We reached the end of <Search tag, now in theory come the <input> tags
  409.         if state == "search" or state == "anotherinput" and tokens == [">", "<", "input"]:
  410.             return "input", 6, []
  411.         elif state == "search":
  412.             raise ParseException("Expecting <input after <search section in file %s" % self.f)
  413.         
  414.         # This parses the <input fields, taking each time 6 tokens
  415.         # First triplet is name=value, second triplet is value=val
  416.         # Special case for lone "user" second triplets, and store that in infos["input"] dict
  417.         if state == "input" and tokens[1] == "=":
  418.             if tokens[3] == "user":
  419.                 self.infos["input"][tokens[2]] = "%s"
  420.                 if tokens[4] != "=":
  421.                     return "anotherinput", 3, tokens[4:]
  422.             else:
  423.                 self.infos["input"][tokens[2]] = tokens[5]
  424.             return "anotherinput", 3, []
  425.         
  426.         # Here we stop processing, cause we are no longer in <input sections, and what comes after isn't interesting
  427.         return None, None, None
  428.  
  429. class TokenException(Exception):
  430.     pass
  431. class ParseException(Exception):
  432.     pass
  433.     
  434. class Tokenizer:
  435.     def __init__(self, f):
  436.         """
  437.         Init the tokenizer on the given file, may throw an exception.
  438.         """
  439.         self.i = 0
  440.         # Read the file, coud be streamed as well
  441.         self.f = f
  442.         self.data = file(f).read()
  443.         
  444.         self.state = "linestart"
  445.         
  446.     def get_next_token(self):
  447.         """
  448.         Returns the next token in the file.
  449.         A token is one of:
  450.         < = > name
  451.         
  452.         Returns None when the end of file is reached and beyond
  453.         """
  454.         while self.i < len(self.data):
  455.             char = self.data[self.i]
  456.             # Skip leading spaces (which are really trailing spaces after a token
  457.             # Newline is important so special case it
  458.             if char.isspace() and not char == "\n":
  459.                 self.i += 1
  460.                 continue
  461.             
  462.             if self.state == "linestart" and char == "#":
  463.                 # Eat all the comment line
  464.                 while self.i < len(self.data) and self.data[self.i] != "\n":
  465.                     self.i += 1
  466.                 self.i += 1 #position on first char after newline
  467.                 continue
  468.             
  469.             # At this point, we can only have a token, read it, and return it
  470.             # The method updates the self.i to point to the new char to read next
  471.             next_token = self.read_token()
  472.             # Wait ! We got a newline here, so back to start again..
  473.             if next_token == "\n":
  474.                 self.state = "linestart"
  475.                 continue
  476.                 
  477.             return next_token
  478.     
  479.     def read_token(self):
  480.         """
  481.         Return the token, self.i must point to the first char in this token.
  482.         self.i is updated to point just after the returned token
  483.         Returned token is one of:
  484.         < = > \n name
  485.         """
  486.         char = self.data[self.i]
  487.         
  488.         if char == "<" or char == "=" or char == ">" or char == "\n":
  489.             self.i += 1
  490.             return char
  491.         
  492.         elif char == "\"":
  493.             # Here we assume proper quoting
  494.             closing = self.data[self.i+1:].find("\"")
  495.             if closing == -1:
  496.                 raise TokenException("Couldn't find a proper closing quote in %s" % self.f)
  497.             
  498.             token = self.data[self.i+1:self.i+1+closing]
  499.             self.i += closing+2 #Next char is just *after* the closing "
  500.             return token
  501.         
  502.         else:
  503.             # Token can just be a string now..
  504.             token = ""
  505.             # We eat all chars until one of "=<>" or whitespace is found
  506.             while self.i < len(self.data) and not self.data[self.i].isspace() and not self.data[self.i] in "=><":
  507.                 token += self.data[self.i]
  508.                 self.i += 1
  509.                 
  510.             return token
  511.             
  512. class MozillaSmartBookmarksDirParser:
  513.     def __init__(self, handler, dirs):
  514.         self._smart_bookmarks = []
  515.         
  516.         # Avoid getting duplicate search engines
  517.         foundbookmarks = []
  518.         
  519.         for bookmarks_dir in dirs:
  520.             if not exists(bookmarks_dir):
  521.                 continue
  522.                 
  523.             for f in glob.glob(join(bookmarks_dir, '*.src')):
  524.                 # Check if we already parsed the file
  525.                 bmname = basename(f)
  526.                 if bmname in foundbookmarks:
  527.                     continue
  528.                 else:
  529.                     foundbookmarks.append(bmname)
  530.                 
  531.                 img = None
  532.                 try:
  533.                     img = [img for img in glob.glob(join(bookmarks_dir, '%s.*' % f[:-4])) if not img.endswith(".src")][0]
  534.                 except:
  535.                     pass
  536.                 
  537.                 parser = MozillaSmartBookmarksParser(f)
  538.                 try:
  539.                     parser.parse()
  540.                     infos = parser.get_infos()
  541.                     bookmark = BrowserMatch(handler, infos["name"], infos["url"], icon=img)
  542.                     bookmark = BrowserSmartMatch(handler, infos["name"], infos["action"], icon=img, bookmark=bookmark)
  543.                     self._smart_bookmarks.append(bookmark)
  544.                 except Exception, msg:
  545.                     print 'Error:MozillaSmartBookmarksDirParser:cannot parse smrt bookmark:%s:bookmark %s' % (msg, f)
  546.                     
  547.     
  548.     def get_smart_bookmarks(self):
  549.         """
  550.         Return a list of MozillaSmartMatch instances representing smart bookmarks
  551.         """
  552.         return self._smart_bookmarks
  553.  
  554. MOZILLA_HISTORY_REGEX = re.compile("\=http[0-9a-zA-Z\-\&\%\=\?\:\/\.]*\)")
  555. class MozillaHistoryHandler(deskbar.Handler.Handler):
  556.     def __init__(self):
  557.         deskbar.Handler.Handler.__init__(self, "epiphany-history.png")
  558.         self._history = None
  559.     
  560.     def initialize(self):
  561.         self._indexer = deskbar.Indexer.Indexer()
  562.         self._history = self._parse_history()
  563.         for history_url in self._history:
  564.             history_wo_http = history_url[history_url.find('//')+2:]
  565.             if history_wo_http.find('www.') == -1:
  566.                 history_wo_www = history_wo_http
  567.             else:
  568.                 history_wo_www = history_wo_http[history_wo_http.find('www.')+4:]
  569.             self._indexer.add("%s %s %s" % (history_wo_www, history_wo_http, history_url), BrowserMatch(self, history_wo_www, history_url, True))
  570.         
  571.     def _parse_history(self):
  572.         if USING_FIREFOX:
  573.             historydat = get_firefox_home_file("history.dat")
  574.         else:
  575.             historydat = get_mozilla_home_file("history.dat")
  576.         try:
  577.             historycontents = file(historydat).read()
  578.             historycontents = re.findall(MOZILLA_HISTORY_REGEX, historycontents)
  579.             historycontents = [x[1:-1] for x in historycontents]
  580.             return historycontents
  581.         except:
  582.             return ""
  583.     
  584.     def query(self, query):
  585.         return self._indexer.look_up(query)[:deskbar.DEFAULT_RESULTS_PER_HANDLER]
  586.  
  587.