Skip to content

Commit

Permalink
Frontend for the search by tags
Browse files Browse the repository at this point in the history
  • Loading branch information
drew2a committed Dec 14, 2021
1 parent c52a04a commit 9be215b
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 47 deletions.
13 changes: 7 additions & 6 deletions src/tribler-gui/tribler_gui/tribler_window.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@

from tribler_common.network_utils import NetworkUtils
from tribler_common.process_checker import ProcessChecker
from tribler_common.utilities import uri_to_path
from tribler_common.utilities import parse_query, uri_to_path
from tribler_common.version_manager import VersionHistory

from tribler_core.utilities.unicode import hexlify
Expand Down Expand Up @@ -95,7 +95,6 @@

fc_loading_list_item, _ = uic.loadUiType(get_ui_file_path('loading_list_item.ui'))


CHECKBOX_STYLESHEET = """
QCheckBox::indicator { width: 16px; height: 16px;}
QCheckBox::indicator:checked { image: url("%s"); }
Expand Down Expand Up @@ -1027,10 +1026,12 @@ def clicked_search_bar(self, checked=False):
self.stackedWidget.setCurrentIndex(PAGE_SEARCH_RESULTS)

def on_top_search_bar_return_pressed(self):
# Initiate a new search query and switch to search loading/results page
query = self.top_search_bar.text()
if query:
self.search_results_page.search(query)
query = parse_query(self.top_search_bar.text())
if not query.original_query:
return

if self.search_results_page.search(query):
self._logger.info(f'Do search for query: {query}')
self.deselect_all_menu_buttons()
self.stackedWidget.setCurrentIndex(PAGE_SEARCH_RESULTS)

Expand Down
48 changes: 27 additions & 21 deletions src/tribler-gui/tribler_gui/widgets/searchresultswidget.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,8 @@
from PyQt5 import uic

from tribler_common.sentry_reporter.sentry_mixin import AddBreadcrumbOnShowMixin
from tribler_common.utilities import to_fts_query

from tribler_common.utilities import Query, to_fts_query
from tribler_core.components.metadata_store.db.serialization import CHANNEL_TORRENT, COLLECTION_NODE, REGULAR_TORRENT

from tribler_gui.tribler_request_manager import TriblerNetworkRequest
from tribler_gui.utilities import connect, get_ui_file_path, tr
from tribler_gui.widgets.tablecontentmodel import SearchResultsModel
Expand All @@ -25,18 +23,18 @@ def format_search_loading_label(search_request):
}

return (
tr(
"Remote responses: %(num_complete_peers)i / %(total_peers)i"
"\nNew remote results received: %(num_remote_results)i"
)
% data
tr(
"Remote responses: %(num_complete_peers)i / %(total_peers)i"
"\nNew remote results received: %(num_remote_results)i"
)
% data
)


@dataclass
class SearchRequest:
uuid: uuid
query: str
query: Query
peers: set
peers_complete: set = field(default_factory=set)
remote_results: list = field(default_factory=list)
Expand All @@ -49,6 +47,7 @@ def complete(self):
class SearchResultsWidget(AddBreadcrumbOnShowMixin, widget_form, widget_class):
def __init__(self, parent=None):
widget_class.__init__(self, parent=parent)
self._logger = logging.getLogger(self.__class__.__name__)

try:
self.setupUi(self)
Expand Down Expand Up @@ -80,42 +79,49 @@ def show_results(self, *_):
query = self.search_request.query
self.results_page.initialize_root_model(
SearchResultsModel(
channel_info={"name": (tr("Search results for %s") % query) if len(query) < 50 else f"{query[:50]}..."},
channel_info={"name": (tr("Search results for %s") % query.original_query) if len(
query.original_query) < 50 else f"{query.original_query[:50]}..."},
endpoint_url="search",
hide_xxx=self.results_page.hide_xxx,
text_filter=to_fts_query(query),
text_filter=to_fts_query(query.fts_text),
tags=list(query.tags),
type_filter=[REGULAR_TORRENT, CHANNEL_TORRENT, COLLECTION_NODE],
)
)
self.setCurrentWidget(self.results_page)

def check_can_show(self, query):
if (
self.last_search_query == query
and self.last_search_time is not None
and time.time() - self.last_search_time < 1
self.last_search_query == query
and self.last_search_time is not None
and time.time() - self.last_search_time < 1
):
logging.info("Same search query already sent within 500ms so dropping this one")
self._logger.info("Same search query already sent within 500ms so dropping this one")
return False
return True

def search(self, query):
if not self.check_can_show(query):
return
def search(self, query: Query) -> bool:
if not self.check_can_show(query.original_query):
return False

fts_query = to_fts_query(query.original_query)
if not fts_query:
return False

self.last_search_query = query
self.last_search_query = query.original_query
self.last_search_time = time.time()

# Trigger remote search
def register_request(response):
self._logger.info(f'Request registered: {response}')
self.search_request = SearchRequest(response["request_uuid"], query, set(response["peers"]))
self.state_label.setText(format_search_loading_label(self.search_request))
self.timeout_progress_bar.start()
self.setCurrentWidget(self.loading_page)

params = {'txt_filter': to_fts_query(query), 'hide_xxx': self.hide_xxx}

params = {'txt_filter': fts_query, 'hide_xxx': self.hide_xxx}
TriblerNetworkRequest('remote_query', register_request, method="PUT", url_params=params)
return True

def reset(self):
if self.currentWidget() == self.results_page:
Expand Down
46 changes: 26 additions & 20 deletions src/tribler-gui/tribler_gui/widgets/tablecontentmodel.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import json
import logging
import uuid
from dataclasses import dataclass, field
from enum import Enum, auto
Expand All @@ -14,14 +15,7 @@

from tribler_gui.defs import BITTORRENT_BIRTHDAY, COMMIT_STATUS_TODELETE, HEALTH_CHECKING
from tribler_gui.tribler_request_manager import TriblerNetworkRequest
from tribler_gui.utilities import (
connect,
format_size,
format_votes,
get_votes_rating_description,
pretty_date,
tr,
)
from tribler_gui.utilities import connect, format_size, format_votes, get_votes_rating_description, pretty_date, tr

EXPANDING = 0

Expand Down Expand Up @@ -56,16 +50,20 @@ def define_columns():
# fmt:off
# pylint: disable=line-too-long
columns_dict = {
Column.ACTIONS: d('', "", width=60, sortable=False),
Column.CATEGORY: d('category', "", width=30, tooltip_filter=lambda data: data),
Column.NAME: d('', tr("Name"), width=EXPANDING),
Column.SIZE: d('size', tr("Size"), width=90, display_filter=lambda data: (format_size(float(data)) if data != "" else "")),
Column.HEALTH: d('health', tr("Health"), width=120, tooltip_filter=lambda data: f"{data}" + ('' if data == HEALTH_CHECKING else '\n(Click to recheck)'),),
Column.UPDATED: d('updated', tr("Updated"), width=120, display_filter=lambda timestamp: pretty_date(timestamp) if timestamp and timestamp > BITTORRENT_BIRTHDAY else 'N/A',),
Column.VOTES: d('votes', tr("Popularity"), width=120, display_filter=format_votes, tooltip_filter=lambda data: get_votes_rating_description(data) if data is not None else None,),
Column.STATUS: d('status', "", sortable=False),
Column.STATE: d('state', "", width=80, tooltip_filter=lambda data: data, sortable=False),
Column.TORRENTS: d('torrents', tr("Torrents"), width=90),
Column.ACTIONS: d('', "", width=60, sortable=False),
Column.CATEGORY: d('category', "", width=30, tooltip_filter=lambda data: data),
Column.NAME: d('', tr("Name"), width=EXPANDING),
Column.SIZE: d('size', tr("Size"), width=90,
display_filter=lambda data: (format_size(float(data)) if data != "" else "")),
Column.HEALTH: d('health', tr("Health"), width=120, tooltip_filter=lambda data: f"{data}" + (
'' if data == HEALTH_CHECKING else '\n(Click to recheck)'), ),
Column.UPDATED: d('updated', tr("Updated"), width=120, display_filter=lambda timestamp: pretty_date(
timestamp) if timestamp and timestamp > BITTORRENT_BIRTHDAY else 'N/A', ),
Column.VOTES: d('votes', tr("Popularity"), width=120, display_filter=format_votes,
tooltip_filter=lambda data: get_votes_rating_description(data) if data is not None else None, ),
Column.STATUS: d('status', "", sortable=False),
Column.STATE: d('state', "", width=80, tooltip_filter=lambda data: data, sortable=False),
Column.TORRENTS: d('torrents', tr("Torrents"), width=90),
Column.SUBSCRIBED: d('subscribed', tr("Subscribed"), width=95),
}
# pylint: enable=line-too-long
Expand Down Expand Up @@ -93,6 +91,8 @@ class RemoteTableModel(QAbstractTableModel):
def __init__(self, parent=None):

super().__init__(parent)
self._logger = logging.getLogger(self.__class__.__name__)

# Unique identifier mapping for items. For torrents, it is infohash and for channels, it is concatenated value
# of public key and channel id
self.item_uid_map = {}
Expand Down Expand Up @@ -283,7 +283,7 @@ def perform_query(self, **kwargs):
if self.hide_xxx is not None:
kwargs.update({"hide_xxx": self.hide_xxx})
rest_endpoint_url = kwargs.pop("rest_endpoint_url") if "rest_endpoint_url" in kwargs else self.endpoint_url

self._logger.info(f'Request to "{rest_endpoint_url}":{kwargs}')
TriblerNetworkRequest(rest_endpoint_url, self.on_query_results, url_params=kwargs)

def on_query_results(self, response, remote=False, on_top=False):
Expand All @@ -296,6 +296,8 @@ def on_query_results(self, response, remote=False, on_top=False):
"""
if not response or self.qt_object_destroyed:
return False
self._logger.info(f'Response. Remote: {remote}, results: {len(response.get("results"))}, '
f'uuid: {response.get("uuid")}')

# Trigger labels update on the initial table load
update_labels = len(self.data_items) == 0
Expand Down Expand Up @@ -323,7 +325,6 @@ def on_query_results(self, response, remote=False, on_top=False):


class ChannelContentModel(RemoteTableModel):

columns_shown = (Column.ACTIONS, Column.CATEGORY, Column.NAME, Column.SIZE, Column.HEALTH, Column.UPDATED)

def __init__(
Expand All @@ -334,6 +335,7 @@ def __init__(
subscribed_only=None,
endpoint_url=None,
text_filter='',
tags=None,
type_filter=None,
):
RemoteTableModel.__init__(self, parent=None)
Expand All @@ -344,6 +346,7 @@ def __init__(
# Remote query (model) parameters
self.hide_xxx = hide_xxx
self.text_filter = text_filter
self.tags = tags
self.subscribed_only = subscribed_only
self.exclude_deleted = exclude_deleted
self.type_filter = type_filter
Expand Down Expand Up @@ -491,6 +494,9 @@ def perform_query(self, **kwargs):
# Only include total for the first query to the endpoint
kwargs.update({"include_total": 1})

if self.tags:
kwargs['tags'] = self.tags

super().perform_query(**kwargs)

def setData(self, index, new_value, role=None):
Expand Down

0 comments on commit 9be215b

Please sign in to comment.