def on_action_hovered(self, action): """ Fetch song.artists when artists_action is hovered. If it is already fetched, ignore. """ data = action.data() if data is None: # submenu action return def artists_fetched_cb(future): self._fetching_artists = False artists = future.result() # ignore the potential exception if artists: for artist in artists: artist_action = action.menu().addAction(artist.name) # create a closure to bind variable artist artist_action.triggered.connect( (lambda x: lambda: self._app.browser.goto(model=x) )(artist)) data['artists'] = artists or [] action.setData(data) # the action is artists_action if 'artists' in data: # artists value has not been fetched if data['artists'] is None and self._fetching_artists is False: logger.debug('fetch song.artists for actions') song = data['song'] self._fetching_artists = True task = aio.run_in_executor(None, lambda: song.artists) task.add_done_callback(artists_fetched_cb)
async def a_search(self, keyword, source_in=None, timeout=None, type_in=None, **kwargs): """async version of search TODO: add Happy Eyeballs requesting strategy if needed """ type_in = SearchType.batch_parse(type_in) if type_in else [ SearchType.so ] fs = [] # future list for provider in self._filter(identifier_in=source_in): for type_ in type_in: future = aio.run_in_executor( None, partial(provider.search, keyword, type_=type_)) fs.append(future) results = [] # TODO: use async generator when we only support Python 3.6 or above for future in aio.as_completed(fs, timeout=timeout): try: result = await future except Exception as e: logger.exception(str(e)) else: if result is not None: results.append(result) return results
def on_song_changed(self, song): """bind song changed signal with this""" if song is None: self._set_lyric(None) return def cb(future): try: lyric = future.result() except: # noqa logger.exception('get lyric failed') lyric = None self._set_lyric(lyric) # TODO: use app.task_mgr instead future = aio.run_in_executor(None, lambda: song.lyric) future.add_done_callback(cb)
async def a_search(self, keyword, source_in=None, timeout=None, **kwargs): """async version of search TODO: add Happy Eyeballs requesting strategy if needed """ fs = [] # future list for provider in self._filter(identifier_in=source_in): future = aio.run_in_executor(None, provider.search, keyword) fs.append(future) result = [] # TODO: use async generator when we only support Python 3.6 or above for future in aio.as_completed(fs, timeout=timeout): try: result.append(await future) except Exception as e: logger.exception(str(e)) return result