示例#1
0
 def get_pixbuf(self):
     """
     Returns pixbuf that L{get_icon}
     points to
     
     @return: gtk.gdk.Pixbuf
     """
     if self.get_icon() != None:
         return load_icon(self.get_icon())
     return None
示例#2
0
 def get_pixbuf(self):
     """
     Returns pixbuf that L{get_icon}
     points to
     
     @return: gtk.gdk.Pixbuf
     """
     if self.get_icon() != None:
         return load_icon(self.get_icon())
     return None
示例#3
0
class BeagleHandler(deskbar.interfaces.Module):
    
    INFOS = {'icon': load_icon("system-search"),
            "name": _("Beagle"),
            "description": _("Search all of your documents (using Beagle)"),
            'version': VERSION,
            }
    
    def __init__(self):
        deskbar.interfaces.Module.__init__(self)
                
    def query(self, query):
        self._emit_query_ready(query, [BeagleMatch(name=query, priority=self.get_priority())] )
    
    @staticmethod
    def has_requirements():
        #FIXME: better way to detect beagle ?
        for dir in get_xdg_data_dirs():
            if glob(join(dir, "applications", "*best.desktop")) or glob(join(dir, "applications", "*beagle-search.desktop")):
                return True
        BeagleHandler.INSTRUCTIONS = _("Beagle does not seem to be installed.")
        return False
示例#4
0
class TomboyNotesModule (deskbar.interfaces.Module):

    INFOS = {'icon': load_icon("tomboy"),
        'name': _('Tomboy Notes'),
        'description': _('Search your Tomboy notes'),
        'version': VERSION,
        }
    
    tomboy = None
    
    def __init__(self):
        deskbar.interfaces.Module.__init__(self)
    
    def initialize(self):
        TomboyNotesModule.tomboy = get_tomboy_connection()
         
    def stop(self):
        TomboyNotesModule.tomboy = None
    
    # This is so when Tomboy is disabled, history items won't try to connect
    # Otherwise, we get big DBus errors
    def set_enabled(self, val):
        if val == False: TomboyNotesModule.tomboy = None
        deskbar.interfaces.Module.set_enabled(self, val)
    
    # Handles the return from the Tomboy method SearchNotes
    # This should be called from the lambda in query so that it will get
    # the extra information (the query text)
    def handle_searchnotes( self, text, notes ):
        for note in notes:
            try:
                if tomboy().NoteExists(note):
                    match = TomboyExistingNoteMatch(note)
                    match.set_priority (self.get_priority())
                    self._emit_query_ready( text, [match] )
            except (dbus.DBusException, dbus.exceptions.DBusException), e:
                LOGGER.exception(e)
                return
示例#5
0
class BeagleLiveHandler(deskbar.interfaces.Module):

    INFOS = {
        'icon':
        load_icon("system-search"),
        "name":
        _("Beagle Live"),
        "description":
        _("Search all of your documents (using Beagle), as you type"),
        'version':
        VERSION,
    }

    def __init__(self):
        deskbar.interfaces.Module.__init__(self)
        self.__counter_lock = threading.Lock()
        self.__beagle_lock = threading.Lock()
        self.__snippet_lock = threading.Lock()
        self.__finished_lock = threading.Lock()

        self.__snippet_request = {}  # Maps beagle.Hit to beagle.SnippetRequest

        # We have to store instances for each query term
        self._counter = {}  # Count hits for each hit type
        self._at_max = {
        }  # Whether we have reached the maximum for a particular hit type before
        self._beagle_query = {}
        self.__hits_added_id = {}
        self.__hits_finished_id = {}
        self.__finished = {
        }  # Whether we got all matches from beagle for query

    def initialize(self):
        self.beagle = beagle.Client()

    def stop(self):
        self.beagle = None

    def query(self, qstring):
        self.__counter_lock.acquire()
        self._counter[qstring] = {}
        self._at_max[qstring] = {}
        self.__counter_lock.release()

        self.__finished_lock.acquire()
        self.__finished[qstring] = False
        self.__finished_lock.release()

        try:
            self.__beagle_lock.acquire()

            beagle_query = beagle.Query()
            self.__hits_added_id[qstring] = beagle_query.connect(
                "hits-added", self._on_hits_added, qstring)
            self.__hits_finished_id[qstring] = beagle_query.connect(
                "finished", self._on_finished, qstring)
            beagle_query.add_text(qstring)

            self._beagle_query[qstring] = beagle_query

            LOGGER.debug("Sending beagle query (%r) for '%s'",
                         self._beagle_query[qstring], qstring)
            try:
                self.beagle.send_request_async(self._beagle_query[qstring])
            except GError, e:
                LOGGER.exception(e)
                self._cleanup_query(qstring)
        finally:
            self.__beagle_lock.release()

    def _on_hits_added(self, query, response, qstring):
        for hit in response.get_hits():
            if hit.get_type() not in TYPES:
                LOGGER.info("Beagle live seen an unknown type: %s",
                            str(hit.get_type()))
                continue

            beagle_type = self._get_beagle_type(hit)
            if beagle_type == None:
                continue

            if beagle_type.get_has_snippet():
                self._get_snippet(query, hit, qstring, beagle_type)
            else:
                self._create_match(hit, beagle_type, qstring)

    def _on_finished(self, query, response, qstring):
        LOGGER.debug("Beagle query (%r) for '%s' finished with response %r",
                     query, qstring, response)
        self.__finished_lock.acquire()
        self.__finished[qstring] = True
        self.__finished_lock.release()

    def _on_snippet_received(self, request, response, hit, qstring,
                             beagle_type):
        snippet = response.get_snippet()
        if snippet == None:
            snippet_text = None
        else:
            # Remove trailing whitespaces and escape '%'
            snippet_text = snippet.strip().replace("%", "%%")

        self._create_match(hit, beagle_type, qstring, snippet_text)

    def _on_snippet_closed(self, request, hit, qstring):
        self._cleanup_snippet(hit)

        self.__snippet_lock.acquire()
        n_snippets = len(self.__snippet_request)
        self.__snippet_lock.release()

        self.__finished_lock.acquire()
        finished = self.__finished[qstring]
        self.__finished_lock.release()

        # FIXME: This only works when at least one
        # result has a snippet, otherwise we
        # miss cleaning up
        if finished and n_snippets == 0:
            self._cleanup_query(qstring)
            self._cleanup_counter(qstring)

    def _cleanup_counter(self, qstring):
        self.__counter_lock.acquire()
        if qstring in self._counter:
            del self._counter[qstring]
            del self._at_max[qstring]
        self.__counter_lock.release()

    def _cleanup_snippet(self, hit):
        LOGGER.debug("Cleaning up hit %r", hit)
        self.__snippet_lock.acquire()
        del self.__snippet_request[hit]
        self.__snippet_lock.release()
        hit.unref()

    def _cleanup_query(self, qstring):
        LOGGER.debug("Cleaning up query for '%s'", qstring)
        # Remove counter for query
        self.__beagle_lock.acquire()
        # Disconnect signals, otherwise we receive late matches
        # when beagle found the query term in a newly indexed file
        beagle_query = self._beagle_query[qstring]
        beagle_query.disconnect(self.__hits_added_id[qstring])
        beagle_query.disconnect(self.__hits_finished_id[qstring])
        del self._beagle_query[qstring]
        del self.__hits_added_id[qstring]
        del self.__hits_finished_id[qstring]
        self.__beagle_lock.release()

        self.__finished_lock.acquire()
        del self.__finished[qstring]
        self.__finished_lock.release()

    def _get_snippet(self, query, hit, qstring, beagle_type):
        LOGGER.debug("Retrieving snippet for hit %r", hit)

        snippet_request = beagle.SnippetRequest()
        snippet_request.set_query(query)
        snippet_request.set_hit(hit)
        hit.ref()
        snippet_request.connect('response', self._on_snippet_received, hit,
                                qstring, beagle_type)
        snippet_request.connect('closed', self._on_snippet_closed, hit,
                                qstring)

        self.__snippet_lock.acquire()
        self.__snippet_request[hit] = snippet_request
        self.__snippet_lock.release()

        try:
            self.__beagle_lock.acquire()
            try:
                self.beagle.send_request_async(snippet_request)
            except GError, e:
                LOGGER.exception(e)
                self._cleanup_snippet(hit)
        finally:
            self.__beagle_lock.release()

    def _get_beagle_type(self, hit):
        """
        Returns the appropriate L{BeagleType}
        for the given hit
        
        @type hit: beagle.Hit
        @return: L{BeagleType} instance
        """
        hit_type = hit.get_type()
        snippet = None

        if hit_type in TYPES:
            beagle_type = TYPES[hit_type]
        else:
            LOGGER.warning("Unknown beagle match type found: %s",
                           result["type"])
            return None

        # Directories are Files in beagle context
        if hit_type == "File":
            filetype = hit.get_properties("beagle:FileType")
            if filetype != None \
                and filetype[0] in BEAGLE_FILE_TYPE_TO_TYPES_MAP:
                beagle_type = TYPES[BEAGLE_FILE_TYPE_TO_TYPES_MAP[filetype[0]]]

        return beagle_type

    def _create_match(self, hit, beagle_type, qstring, snippet=None):
        # Get category
        cat_type = beagle_type.get_category()

        result = {
            "uri": hit.get_uri(),
            "type": beagle_type,
            "snippet": snippet,
        }

        self.__counter_lock.acquire()
        # Create new counter for query and type
        if not cat_type in self._counter[qstring]:
            self._counter[qstring][cat_type] = 0
        # Increase counter
        self._counter[qstring][cat_type] += 1

        if self._counter[qstring][cat_type] > MAX_RESULTS:
            if cat_type in self._at_max[qstring]:
                # We already reached the maximum before
                self.__counter_lock.release()
                return
            else:
                # We reach the maximum for the first time
                self._at_max[qstring][cat_type] = True
                self._emit_query_ready(qstring, [
                    BeagleSearchMatch(qstring, cat_type,
                                      beagle_type.get_hit_type())
                ])
            self.__counter_lock.release()
            return
        self.__counter_lock.release()

        self._get_properties(hit, result)
        self._escape_pango_markup(result, qstring)

        self._emit_query_ready(qstring, [
            BeagleLiveMatch(
                result, category=cat_type, priority=self.get_priority())
        ])

    def _get_properties(self, hit, result):
        beagle_type = result["type"]

        name = None
        for prop in beagle_type.get_name_properties():
            try:
                name = hit.get_properties(
                    prop
                )[0]  # get_property_one() would be cleaner, but this works around bug #330053
            except:
                pass

            if name != None:
                result["name"] = name
                break

        if name == None:
            #translators: This is used for unknown values returned by beagle
            #translators: for example unknown email sender, or unknown note title
            result["name"] = _("?")

        for prop, keys in beagle_type.get_extra_properties().items():
            val = None
            for key in keys:
                try:
                    val = hit.get_properties(
                        key
                    )[0]  # get_property_one() would be cleaner, but this works around bug #330053
                except:
                    pass

                if val != None:
                    result[prop] = val
                    break

            if val == None:
                #translators: This is used for unknown values returned by beagle
                #translators: for example unknown email sender, or unknown note title
                result[prop] = _("?")

    def _escape_pango_markup(self, result, qstring):
        """
        Escape everything for display through pango markup, except filenames.
        Filenames are escaped in escaped_uri or escaped_identifier
        """
        for key, val in result.items():
            if key == "uri" or key == "identifier":
                result["escaped_" + key] = cgi.escape(val)
            elif key == "snippet":
                # Add the snippet, in escaped form if available
                if result["snippet"] != None and result["snippet"] != "":
                    tmp = re.sub(r"<.*?>", "", result["snippet"])
                    tmp = re.sub(r"</.*?>", "", tmp)
                    result["snippet"] = cgi.escape(tmp)

                    # FIXME: re.escape too much, we only want to escape special regex chars
                    # we should provide a convenient method for _all_ modules
                    result["snippet"] = re.sub(
                        re.escape(qstring),
                        "<span weight='bold'>" + qstring + "</span>",
                        result["snippet"], re.IGNORECASE)
                else:
                    result["snippet"] = ""
            elif isinstance(result[key], str):
                result[key] = cgi.escape(val)

    @staticmethod
    def has_requirements():
        # Check if we have python bindings for beagle
        try:
            import beagle
        except Exception, e:
            BeagleLiveHandler.INSTRUCTIONS = _(
                "Could not load beagle, libbeagle has been compiled without python bindings."
            )
            return False

        # Check if beagled is running
        if not beagle.beagle_util_daemon_is_running():
            if is_program_in_path("beagled"):
                BeagleLiveHandler.INSTRUCTIONS = _(
                    "Beagle daemon is not running.")
                return False
            else:
                BeagleLiveHandler.INSTRUCTIONS = _(
                    "Beagled could not be found in your $PATH.")
                return False
        else:
            return True
示例#6
0
from gettext import gettext as _
from deskbar.core.Utils import load_icon

CATEGORIES = {
    # Special categories
    "default"    : {    
        "name": _("Uncategorized"),
        "icon": load_icon("unknown"),
    },
    "history" : {
        "name": _("History"),
        "icon": load_icon("document-open-recent"),
    },
    
    # Standard handlers
    "documents"    : {    
        "name": _("Documents"),
        "icon": load_icon("empty"),
    },
    "emails"    : {    
        "name": _("Emails"),
        "icon": load_icon("emblem-mail"),
    },
    "conversations"    : {    
        "name": _("Conversations"),
        "icon": load_icon("system-users"),
    },
    "files"    : {    
        "name": _("Files"),
        "icon": load_icon("empty"),
    },
示例#7
0
class WikipediaSuggestHandler(deskbar.interfaces.Module):
    
    INFOS = {'icon': load_icon("wikipedia.png"),
             'name': _("Wikipedia Suggest"),
             'description': _("As you type, Wikipedia will offer suggestions."),
             'version': VERSION}
    
    DEFAULT_LANG = "en"
    
    def __init__(self):
        deskbar.interfaces.Module.__init__(self)
        self._lang = None
        self._mateconf = GconfStore.get_instance().get_client()
        self._mateconf.notify_add(MATECONF_KEY, self._on_language_changed)
        self._set_lang()
    
    def _set_lang(self):
        self._lang = self._mateconf.get_string(MATECONF_KEY)
        if self._lang == None:
            localelang = self._guess_lang()
            self._mateconf.set_string(MATECONF_KEY, localelang)
            
    def _guess_lang(self):
        """ Try to guess lang """
        localelang = get_locale_lang()
        if localelang == None:
            localelang = self.DEFAULT_LANG
        else:
            localelang = localelang.split("_")[0]
            
            # Check if the language is supported
            for name, code in LANGUAGES:
                if code == localelang:
                    return localelang
            
            # Set fallback
            localelang = self.DEFAULT_LANG
                    
        return localelang
    
    def _on_language_changed(self, client, cnxn_id, entry, data):
        if entry.value == None:
            self._set_lang()
        else:
            self._lang = entry.value.get_string()
            
    def query(self, qstring):        
        args = {'lang': self._lang, 'search': qstring}
        url = WIKIPEDIA_SUGGEST_URL + '?' + urllib.urlencode(args)
        
        try:
            result = urllib.urlopen(url, proxies=get_proxy())
        except (IOError, EOFError), msg:
            # Print error for debugging purposes and end querying
            LOGGER.error("Could not open URL %s: %s, %s" % (url, msg[0], msg[1]))
            return

        matches = []
        for line in result:
            cols = line.strip().split("\t", 2)
            if len(cols) == 2:
                title, lang = cols
                matches.append( WikipediaSuggestMatch(title, lang) )
        self._emit_query_ready( qstring, matches )