示例#1
0
 def __init__(self):
     super(LyricsWikiaSearchThread, self).__init__()
     self.daemon = True
     self._queue = Queue()
     self._stopped = False
     self._current = None
示例#2
0
class LyricsWikiaSearchThread(threading.Thread):
    TIMEOUT = 4.0

    def __init__(self):
        super(LyricsWikiaSearchThread, self).__init__()
        self.daemon = True
        self._queue = Queue()
        self._stopped = False
        self._current = None

    def search_song(self, song, done_cb):
        """Trigger a new search, old ones will be canceled"""

        assert song
        assert done_cb

        if not self.is_alive():
            self.start()

        self._current = song
        while not self._queue.empty():
            self._queue.get_nowait()
        self._queue.put((song, done_cb))

    def stop(self):
        """Stop all active searches, no callback will be called after this
           returns.
        """

        self._stopped = True
        self._queue.put((None, None))

    def __idle(self, song, func, *args, **kwargs):
        def delayed():
            if self._stopped or song is not self._current:
                return
            func(song, *args, **kwargs)

        GLib.idle_add(delayed)

    def _do_search(self, song):
        """Returns a URL or None"""

        fetch_url = create_api_search_url(song)
        try:
            response = urlopen(fetch_url, timeout=self.TIMEOUT)
        except EnvironmentError:
            return

        try:
            xml = response.read()
        except IOError:
            return

        try:
            dom = minidom.parseString(xml)
        except Exception:
            # who knows...
            return

        page_id_nodes = dom.getElementsByTagName("page_id")
        if not page_id_nodes or not page_id_nodes[0].hasChildNodes():
            return

        url_nodes = dom.getElementsByTagName("url")
        try:
            page = url_nodes[0].firstChild.data
        except (IndexError, AttributeError):
            return
        else:
            return page

    def run(self):
        while not self._stopped:
            song, cb = self._queue.get()
            if self._stopped:
                break
            result = self._do_search(song)
            self.__idle(song, cb, result)