Skip to content

Commit

Permalink
show search error
Browse files Browse the repository at this point in the history
  • Loading branch information
cosven committed Feb 4, 2025
1 parent c6ec633 commit 1c1d094
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 19 deletions.
22 changes: 18 additions & 4 deletions feeluown/gui/components/search.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ def __init__(self, app, **kwargs):
self._layout.addStretch(0)

async def search_and_render(self, q, search_type, source_in):
# pylint: disable=too-many-locals
# pylint: disable=too-many-locals,too-many-statements
view = self
app = self._app

Expand All @@ -88,9 +88,19 @@ async def search_and_render(self, q, search_type, source_in):
succeed = 0
start = datetime.now()
is_first = True # Is first search result.
view.hint.show_msg('正在搜索...')
if source_in is not None:
source_count = len(source_in)
else:
source_count = len(app.library.list())
hint_msgs = [f'正在搜索 {source_count} 个资源提供方...']
view.hint.show_msg('\n'.join(hint_msgs))
async for result in app.library.a_search(
q, type_in=search_type, source_in=source_in):
q, type_in=search_type, source_in=source_in, return_err=True):
if result.err_msg:
hint_msgs.append(f'搜索 {result.source} 的资源出错:{result.err_msg}')
view.hint.show_msg('\n'.join(hint_msgs))
continue

table_container = TableContainer(app, view.accordion)
table_container.layout().setContentsMargins(0, 0, 0, 0)

Expand All @@ -112,6 +122,8 @@ async def search_and_render(self, q, search_type, source_in):
_, search_type, attrname, show_handler = renderer.tabs[tab_index]
objects = getattr(result, attrname) or []
if not objects: # Result is empty.
hint_msgs.append(f'搜索 {result.source} 资源,提供方返回空')
view.hint.show_msg('\n'.join(hint_msgs))
continue

succeed += 1
Expand All @@ -130,7 +142,9 @@ async def search_and_render(self, q, search_type, source_in):
renderer.toolbar.hide()
is_first = False
time_cost = (datetime.now() - start).total_seconds()
view.hint.show_msg(f'搜索完成,共有 {succeed} 个有效的结果,花费 {time_cost:.2f}s')
hint_msgs.pop(0)
hint_msgs.insert(0, f'搜索完成,共有 {succeed} 个有效的结果,花费 {time_cost:.2f}s')
view.hint.show_msg('\n'.join(hint_msgs))


class SearchResultRenderer(Renderer, TabBarRendererMixin):
Expand Down
9 changes: 7 additions & 2 deletions feeluown/gui/widgets/labels.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from PyQt5.QtCore import QTime, Qt
from PyQt5.QtGui import QPalette, QColor
from PyQt5.QtWidgets import QLabel, QSizePolicy

from feeluown.utils.utils import parse_ms
Expand Down Expand Up @@ -83,7 +84,7 @@ class MessageLabel(QLabel):
def __init__(self, text='', level=None, *args, **kwargs):
super().__init__(*args, **kwargs)

self.setTextFormat(Qt.RichText)
self.setWordWrap(True)
self.show_msg(text, level)

def show_msg(self, text, level=None):
Expand All @@ -96,4 +97,8 @@ def show_msg(self, text, level=None):
else:
hint = '️'
color = SOLARIZED_COLORS['blue']
self.setText(f"<span style='color: {color};'>{hint}{text}<span>")
palette = self.palette()
palette.setColor(QPalette.Text, QColor(color))
palette.setColor(QPalette.WindowText, QColor(color))
self.setPalette(palette)
self.setText(f"{hint}{text}")
48 changes: 35 additions & 13 deletions feeluown/library/library.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import logging
import warnings
from collections import Counter
from functools import partial
from typing import Optional, TypeVar, List, TYPE_CHECKING

from feeluown.media import Media
Expand All @@ -16,7 +15,7 @@
)
from feeluown.library.flags import Flags as PF
from feeluown.library.models import (
ModelFlags as MF, BaseModel,
ModelFlags as MF, BaseModel, SimpleSearchResult,
BriefVideoModel, BriefSongModel, SongModel,
LyricModel, VideoModel, BriefAlbumModel, BriefArtistModel
)
Expand Down Expand Up @@ -135,30 +134,53 @@ def search(self, keyword, type_in=None, source_in=None, **kwargs):
yield result

async def a_search(self, keyword, source_in=None, timeout=None,
type_in=None,
type_in=None, return_err=False,
**_):
"""async version of search
.. versionchanged:: 4.1.9
Add `return_err` parameter.
TODO: add Happy Eyeballs requesting strategy if needed
"""
type_in = SearchType.batch_parse(type_in) if type_in else [SearchType.so]

# Wrap the search function to associate the result with source.
def wrap_search(pvd, kw, t):
def search():
try:
res = pvd.search(kw, type_=t)
except Exception as e: # noqa
if return_err:
logger.exception('One provider search failed')
return SimpleSearchResult(
q=keyword,
source=pvd.identifier, # noqa
err_msg=f'{type(e)}',
)
raise e
# When a provider does not implement search method, it returns None.
if res is not None and (
res.songs or res.albums or
res.artists or res.videos or res.playlists
):
return res
return SimpleSearchResult(
q=keyword, source=pvd.identifier, err_msg='结果为空')
return search

fs = [] # future list
for provider in self._filter(identifier_in=source_in):
for type_ in type_in:
future = run_fn(partial(provider.search, keyword, type_=type_))
future = run_fn(wrap_search(provider, keyword, type_))
fs.append(future)

for future in as_completed(fs, timeout=timeout):
for task_ in as_completed(fs, timeout=timeout):
try:
result = await future
except: # noqa
logger.exception('search task failed')
continue
result = await task_
except Exception as e: # noqa
logger.exception('One search task failed due to asyncio')
else:
# When a provider does not implement search method, it returns None.
if result is not None:
yield result
yield result

async def a_song_prepare_media_no_exc(self, standby, policy):
media = None
Expand Down
2 changes: 2 additions & 0 deletions feeluown/library/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,8 @@ class SimpleSearchResult(_BaseModel):
artists: List[TArtist] = []
playlists: List[TPlaylist] = []
videos: List[TVideo] = []
source: str = ''
err_msg: str = ''


_type_modelcls_mapping = {
Expand Down

0 comments on commit 1c1d094

Please sign in to comment.