From 4702bea9f029a2f1ca461b9c7a63ccf19c179b11 Mon Sep 17 00:00:00 2001 From: Lex Berezhny Date: Mon, 6 May 2019 16:37:17 -0400 Subject: [PATCH] claim_search --not_tags feature + integration tests --- lbrynet/extras/daemon/Daemon.py | 7 ++++++- lbrynet/wallet/server/db.py | 15 ++++++++++++--- tests/integration/test_claim_commands.py | 13 +++++++++++++ 3 files changed, 31 insertions(+), 4 deletions(-) diff --git a/lbrynet/extras/daemon/Daemon.py b/lbrynet/extras/daemon/Daemon.py index 360e3e605..d1d2d8b08 100644 --- a/lbrynet/extras/daemon/Daemon.py +++ b/lbrynet/extras/daemon/Daemon.py @@ -1674,9 +1674,11 @@ class Daemon(metaclass=JSONRPCServerType): Usage: claim_search [ | --name=] [--claim_id=] [--txid= --nout=] [--channel_id=] [--channel_name=] [--is_controlling] - [--any_tags=...] [--all_tags=...] + [--any_tags=...] [--all_tags=...] [--not_tags=...] [--any_languages=...] [--all_languages=...] + [--not_languages=...] [--any_locations=...] [--all_locations=...] + [--not_locations=...] [--page=] [--page_size=] Options: @@ -1689,10 +1691,13 @@ class Daemon(metaclass=JSONRPCServerType): --is_controlling : (bool) limit to controlling claims for their respective name --any_tags= : (list) find claims containing any of the tags --all_tags= : (list) find claims containing every tag + --not_tags= : (list) find claims not containing any of these tags --any_languages= : (list) find claims containing any of the languages --all_languages= : (list) find claims containing every language + --not_languages= : (list) find claims not containing any of these languages --any_locations= : (list) find claims containing any of the locations --all_locations= : (list) find claims containing every location + --not_locations= : (list) find claims not containing any of these locations --page= : (int) page to return during paginating --page_size= : (int) number of items on page during pagination diff --git a/lbrynet/wallet/server/db.py b/lbrynet/wallet/server/db.py index ba1ab3659..08cd9b2dc 100644 --- a/lbrynet/wallet/server/db.py +++ b/lbrynet/wallet/server/db.py @@ -378,6 +378,15 @@ class SQLDB: SELECT txo_hash FROM tag WHERE tag IN ({}) GROUP BY txo_hash HAVING COUNT(tag) = :$all_tags_count """.format(', '.join(f':$all_tags{i}' for i in range(len(all_tags)))) + not_tags = constraints.pop('not_tags', [])[:100] + if not_tags: + constraints.update({ + f'$not_tags{i}': tag for i, tag in enumerate(not_tags) + }) + constraints['claim.txo_hash__not_in'] = """ + SELECT DISTINCT txo_hash FROM tag WHERE tag IN ({}) + """.format(', '.join(f':$not_tags{i}' for i in range(len(not_tags)))) + return self.db.execute(*query( f""" SELECT {cols} FROM claim @@ -413,9 +422,9 @@ class SQLDB: SEARCH_PARAMS = { 'name', 'claim_id', 'txid', 'nout', 'channel', 'channel_id', 'channel_name', - 'any_tags', 'all_tags', - 'any_locations', 'all_locations', - 'any_languages', 'all_languages', + 'any_tags', 'all_tags', 'not_tags', + 'any_locations', 'all_locations', 'not_locations', + 'any_languages', 'all_languages', 'not_languages', 'is_controlling', 'limit', 'offset' } diff --git a/tests/integration/test_claim_commands.py b/tests/integration/test_claim_commands.py index 55fa6003d..424c056b8 100644 --- a/tests/integration/test_claim_commands.py +++ b/tests/integration/test_claim_commands.py @@ -135,6 +135,19 @@ class ClaimSearchCommand(CommandTestCase): await self.assertFindsClaims([], all_tags=['ghi', 'xyz']) await self.assertFindsClaims([], all_tags=['xyz']) + # not_tags + await self.assertFindsClaims([], not_tags=['abc', 'pqr']) + await self.assertFindsClaims([claim5], not_tags=['abc']) + await self.assertFindsClaims([claim5], not_tags=['abc', 'ghi']) + await self.assertFindsClaims([claim5, claim2, claim1], not_tags=['ghi']) + await self.assertFindsClaims([claim5, claim2, claim1], not_tags=['ghi', 'xyz']) + await self.assertFindsClaims([claim5, claim4, claim3, claim2, claim1], not_tags=['xyz']) + + # combinations + await self.assertFindsClaims([claim3], all_tags=['abc', 'ghi'], not_tags=['mno']) + await self.assertFindsClaims([claim3], all_tags=['abc', 'ghi'], any_tags=['jkl'], not_tags=['mno']) + await self.assertFindsClaims([claim4, claim3, claim2], all_tags=['abc'], any_tags=['def', 'ghi']) + class ChannelCommands(CommandTestCase):