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) for future in aio.as_completed(fs, timeout=timeout): try: result = await future except: # noqa logger.exception('search task failed') continue else: yield result
def search(self, keyword, type_in=None, source_in=None, **kwargs): """search song/artist/album/playlist by keyword please use a_search method if you can. :param keyword: search keyword :param type_in: search type :param source_in: None or provider identifier list - TODO: support search with filters(by artist or by source) """ type_in = SearchType.batch_parse(type_in) if type_in else [ SearchType.so ] for provider in self._filter(identifier_in=source_in): for type_ in type_in: try: result = provider.search(keyword=keyword, type_=type_, **kwargs) except Exception: # pylint: disable=broad-except logger.exception('Search %s in %s failed.', keyword, provider) else: if result is not None: yield result
async def render(req, **kwargs): """/search handler :type app: feeluown.app.App """ q = req.query.get('q', '') if not q: return type_ = req.query.get('type', None) type_ = SearchType.parse(type_) if type_ else SearchType.so source_in = req.query.get('source_in', None) if source_in is not None: source_in = source_in.split(',') else: source_in = None app = req.ctx['app'] ui = app.ui right_panel = ui.right_panel table_container = right_panel.table_container right_panel.collection_container.hide() right_panel.scrollarea.show() reader = wrap(app.library.a_search(q, type_in=type_, source_in=source_in)) renderer = SearchResultRenderer(q, type_, reader, source_in=source_in) await table_container.set_renderer(renderer)
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 search(keyword, **kwargs): type_ = SearchType.parse(kwargs['type_']) if type_ == SearchType.pl: data = provider.api.search_playlists(keyword) playlists = [ _deserialize(playlist, _BriefPlaylistSchema, False) for playlist in data ] return QQSearchModel(playlists=playlists) else: type_type_map = { SearchType.so: 0, SearchType.al: 8, SearchType.ar: 9, } data = provider.api.search(keyword, type_=type_type_map[type_]) if type_ == SearchType.so: songs = [_deserialize(song, QQSongSchema) for song in data] return QQSearchModel(songs=songs) elif type_ == SearchType.al: albums = [ _deserialize(album, _BriefAlbumSchema, False) for album in data ] return QQSearchModel(albums=albums) else: artists = [ _deserialize(artist, _BriefArtistSchema, False) for artist in data ] return QQSearchModel(artists=artists)
def search(self, keyword, type_, **kwargs): type_ = SearchType.parse(type_) type_type_map = { SearchType.so: 1, SearchType.al: 10, SearchType.ar: 100, SearchType.pl: 1000, } data = provider.api.search(keyword, stype=type_type_map[type_]) result = _deserialize(data, NeteaseSearchSchema) result.q = keyword return result