From 5a38c19531445297e457c8520dc9c2679dfdebd0 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Chibon Date: Dec 07 2018 15:19:15 +0000 Subject: Allow searching the content of the comments on an issue tracker Using ``content:`` one can now search all the comments on the issue tracker for that keyword. This works but it slow and thus should not be abused, so it's in purpose not being proposed prominently to the users. Fixes https://pagure.io/pagure/issue/1749 Signed-off-by: Pierre-Yves Chibon --- diff --git a/doc/usage/tips_tricks.rst b/doc/usage/tips_tricks.rst index fdfcf35..ecada60 100644 --- a/doc/usage/tips_tricks.rst +++ b/doc/usage/tips_tricks.rst @@ -105,3 +105,16 @@ Examples: ~~~~~~~~~ https://pagure.io/SSSD/sssd/issues?status=Open&search_pattern=review%3ATrue https://pagure.io/pagure/issues?status=Open&search_pattern=tags%3Aeasyfix + + +Search the comments of issues +----------------------------- + +One can search all the comments made on an issue tracker using +``content:`` in the search field. This is going to search all the +comments (including the descriptions) of all the tickets and thus can be quite +slow on large project. This is why this feature isn't being pushed much forward. + +Examples: +~~~~~~~~~ +https://pagure.io/pagure/issues?status=Open&search_pattern=content%3Aeasyfix diff --git a/pagure/lib/query.py b/pagure/lib/query.py index 529e5ef..eec9a55 100644 --- a/pagure/lib/query.py +++ b/pagure/lib/query.py @@ -2766,6 +2766,7 @@ def search_issues( offset=None, limit=None, search_pattern=None, + search_content=None, custom_search=None, updated_after=None, no_milestones=None, @@ -2820,6 +2821,8 @@ def search_issues( :type count: boolean :kwarg search_pattern: a string to search in issues title :type search_pattern: str or None + :kwarg search_content: a string to search in the issues comments + :type search_content: str or None :kwarg custom_search: a dictionary of key/values to be used when searching issues with a custom key constraint :type custom_search: dict or None @@ -3009,6 +3012,19 @@ def search_issues( sqlalchemy.or_((const for const in constraints)) ) + if search_content is not None: + query = query.filter( + sqlalchemy.or_( + model.Issue.content.ilike("%%%s%%" % search_content), + sqlalchemy.and_( + model.Issue.uid == model.IssueComment.issue_uid, + model.IssueComment.comment.ilike( + "%%%s%%" % search_content + ), + ), + ) + ) + query = session.query(model.Issue).filter( model.Issue.uid.in_(query.subquery()) ) diff --git a/pagure/ui/issues.py b/pagure/ui/issues.py index 93857c1..63de12b 100644 --- a/pagure/ui/issues.py +++ b/pagure/ui/issues.py @@ -492,9 +492,7 @@ def view_issues(repo, username=None, namespace=None): tags = [tag.strip() for tag in tags if tag.strip()] assignee = flask.request.args.get("assignee", None) author = flask.request.args.get("author", None) - search_pattern = flask.request.args.get("search_pattern", None) - if search_pattern == "": - search_pattern = None + search_pattern = flask.request.args.get("search_pattern") or None milestones = flask.request.args.getlist("milestone", None) order = flask.request.args.get("order", "desc") order_key = flask.request.args.get("order_key", "date_created") @@ -519,6 +517,7 @@ def view_issues(repo, username=None, namespace=None): "assignee": assignee, "author": author, "milestones": milestones, + "search_content": None, } no_stone = None @@ -531,6 +530,10 @@ def view_issues(repo, username=None, namespace=None): search_pattern ) + if "content" in extra_fields: + extra_fields["search_content"] = extra_fields["content"] + del (extra_fields["content"]) + for field in fields: if field in extra_fields: fields[field] = extra_fields[field]