From 7cb530c33495531a608a95ee9b44306725e7f61e Mon Sep 17 00:00:00 2001 From: Lex Berezhny Date: Fri, 20 Mar 2020 23:19:26 -0400 Subject: [PATCH] added --channel_id and --order_by to txo_list --- lbry/extras/daemon/daemon.py | 25 ++++++++++++++----- lbry/wallet/database.py | 6 ++++- .../blockchain/test_claim_commands.py | 16 ++++++++++++ 3 files changed, 40 insertions(+), 7 deletions(-) diff --git a/lbry/extras/daemon/daemon.py b/lbry/extras/daemon/daemon.py index 0d3359494..7645024f4 100644 --- a/lbry/extras/daemon/daemon.py +++ b/lbry/extras/daemon/daemon.py @@ -2176,19 +2176,21 @@ class Daemon(metaclass=JSONRPCServerType): Usage: claim_list [--claim_type=...] [--claim_id=...] [--name=...] - [--account_id=] [--wallet_id=] + [--channel_id=...] [--account_id=] [--wallet_id=] [--page=] [--page_size=] - [--resolve] + [--resolve] [--order_by=] Options: --claim_type= : (str or list) claim type: channel, stream, repost, collection --claim_id= : (str or list) claim id + --channel_id= : (str or list) streams in this channel --name= : (str or list) claim name --account_id= : (str) id of the account to query --wallet_id= : (str) restrict results to specific wallet --page= : (int) page to return during paginating --page_size= : (int) number of items on page during pagination --resolve : (bool) resolves each claim to provide additional metadata + --order_by= : (str) field to order by: 'name', 'height', 'amount' Returns: {Paginated[Output]} """ @@ -4112,7 +4114,7 @@ class Daemon(metaclass=JSONRPCServerType): @staticmethod def _constrain_txo_from_kwargs( constraints, type=None, txid=None, # pylint: disable=redefined-builtin - claim_id=None, name=None, unspent=False, reposted_claim_id=None, + claim_id=None, channel_id=None, name=None, unspent=False, reposted_claim_id=None, is_my_input_or_output=None, exclude_internal_transfers=False, is_my_output=None, is_not_my_output=None, is_my_input=None, is_not_my_input=None): @@ -4130,6 +4132,7 @@ class Daemon(metaclass=JSONRPCServerType): elif is_not_my_output is True: constraints['is_my_output'] = False database.constrain_single_or_list(constraints, 'txo_type', type, lambda x: TXO_TYPES[x]) + database.constrain_single_or_list(constraints, 'channel_id', channel_id) database.constrain_single_or_list(constraints, 'claim_id', claim_id) database.constrain_single_or_list(constraints, 'claim_name', name) database.constrain_single_or_list(constraints, 'txid', txid) @@ -4137,13 +4140,14 @@ class Daemon(metaclass=JSONRPCServerType): return constraints @requires(WALLET_COMPONENT) - def jsonrpc_txo_list(self, account_id=None, wallet_id=None, page=None, page_size=None, resolve=False, **kwargs): + def jsonrpc_txo_list( + self, account_id=None, wallet_id=None, page=None, page_size=None, resolve=False, order_by=None, **kwargs): """ List my transaction outputs. Usage: - txo_list [--account_id=] [--type=...] [--txid=...] - [--claim_id=...] [--name=...] [--unspent] + txo_list [--account_id=] [--type=...] [--txid=...] [--unspent] + [--claim_id=...] [--channel_id=...] [--name=...] [--is_my_input_or_output | [[--is_my_output | --is_not_my_output] [--is_my_input | --is_not_my_input]] ] @@ -4156,6 +4160,7 @@ class Daemon(metaclass=JSONRPCServerType): purchase, collection, repost, other --txid= : (str or list) transaction id of outputs --claim_id= : (str or list) claim id + --channel_id= : (str or list) claims in this channel --name= : (str or list) claim name --unspent : (bool) hide spent outputs, show only unspent ones --is_my_input_or_output : (bool) txos which have your inputs or your outputs, @@ -4174,6 +4179,7 @@ class Daemon(metaclass=JSONRPCServerType): --page= : (int) page to return during paginating --page_size= : (int) number of items on page during pagination --resolve : (bool) resolves each claim to provide additional metadata + --order_by= : (str) field to order by: 'name', 'height', 'amount' Returns: {Paginated[Output]} """ @@ -4191,6 +4197,13 @@ class Daemon(metaclass=JSONRPCServerType): 'include_is_my_input': True, 'include_is_my_output': True, } + if order_by is not None: + if order_by == 'name': + constraints['order_by'] = 'txo.claim_name' + elif order_by in ('height', 'amount'): + constraints['order_by'] = order_by + else: + raise ValueError(f"'{order_by}' is not a valid --order_by value.") self._constrain_txo_from_kwargs(constraints, **kwargs) return paginate_rows(claims, claim_count, page, page_size, **constraints) diff --git a/lbry/wallet/database.py b/lbry/wallet/database.py index 5c707be9f..571335fee 100644 --- a/lbry/wallet/database.py +++ b/lbry/wallet/database.py @@ -441,6 +441,7 @@ class Database(SQLiteMixin): claim_id text, claim_name text, + channel_id text, reposted_claim_id text ); create index if not exists txo_txid_idx on txo (txid); @@ -448,6 +449,7 @@ class Database(SQLiteMixin): create index if not exists txo_claim_id_idx on txo (claim_id); create index if not exists txo_claim_name_idx on txo (claim_name); create index if not exists txo_txo_type_idx on txo (txo_type); + create index if not exists txo_channel_id_idx on txo (channel_id); create index if not exists txo_reposted_claim_idx on txo (reposted_claim_id); """ @@ -490,6 +492,8 @@ class Database(SQLiteMixin): row['txo_type'] = TXO_TYPES.get(claim.claim_type, TXO_TYPES['stream']) if claim.is_repost: row['reposted_claim_id'] = claim.repost.reference.claim_id + if claim.is_signed: + row['channel_id'] = claim.signing_channel_id else: row['txo_type'] = TXO_TYPES['stream'] elif txo.is_support: @@ -779,7 +783,7 @@ class Database(SQLiteMixin): if include_is_spent: select_columns.append("spent.txoid IS NOT NULL AS is_spent") - if 'order_by' not in constraints: + if 'order_by' not in constraints or constraints['order_by'] == 'height': constraints['order_by'] = [ "tx.height=0 DESC", "tx.height DESC", "tx.position DESC", "txo.position" ] diff --git a/tests/integration/blockchain/test_claim_commands.py b/tests/integration/blockchain/test_claim_commands.py index d7e32301b..7e3729cbc 100644 --- a/tests/integration/blockchain/test_claim_commands.py +++ b/tests/integration/blockchain/test_claim_commands.py @@ -674,6 +674,22 @@ class ClaimCommands(ClaimTestCase): # check that metadata is transfered self.assertTrue(r[0]['is_my_output']) + async def assertClaimList(self, claim_ids, **kwargs): + self.assertEqual(claim_ids, [c['claim_id'] for c in await self.claim_list(**kwargs)]) + + async def test_list_streams_in_channel_and_order_by(self): + channel1_id = self.get_claim_id(await self.channel_create('@chan-one')) + channel2_id = self.get_claim_id(await self.channel_create('@chan-two')) + stream1_id = self.get_claim_id(await self.stream_create('stream-a', bid='0.3', channel_id=channel1_id)) + stream2_id = self.get_claim_id(await self.stream_create('stream-b', bid='0.9', channel_id=channel1_id)) + stream3_id = self.get_claim_id(await self.stream_create('stream-c', bid='0.6', channel_id=channel2_id)) + await self.assertClaimList([stream2_id, stream1_id], channel_id=channel1_id) + await self.assertClaimList([stream3_id], channel_id=channel2_id) + await self.assertClaimList([stream3_id, stream2_id, stream1_id], channel_id=[channel1_id, channel2_id]) + await self.assertClaimList([stream1_id, stream2_id, stream3_id], claim_type='stream', order_by='name') + await self.assertClaimList([stream1_id, stream3_id, stream2_id], claim_type='stream', order_by='amount') + await self.assertClaimList([stream3_id, stream2_id, stream1_id], claim_type='stream', order_by='height') + class ChannelCommands(CommandTestCase):