forked from LBRYCommunity/lbry-sdk
command fixes
This commit is contained in:
parent
cc2837c021
commit
1a4a2db1b1
9 changed files with 85 additions and 68 deletions
|
@ -262,7 +262,11 @@ def main(argv=None):
|
||||||
if args.help:
|
if args.help:
|
||||||
print(doc)
|
print(doc)
|
||||||
else:
|
else:
|
||||||
parsed = docopt(doc, command_args)
|
parsed = docopt(
|
||||||
|
# TODO: ugly hack because docopt doesn't support commands with spaces in them
|
||||||
|
doc.replace(api_method_name.replace('_', ' '), api_method_name, 1),
|
||||||
|
command_args
|
||||||
|
)
|
||||||
params = set_kwargs(parsed)
|
params = set_kwargs(parsed)
|
||||||
asyncio.get_event_loop().run_until_complete(execute_command(conf, api_method_name, params))
|
asyncio.get_event_loop().run_until_complete(execute_command(conf, api_method_name, params))
|
||||||
elif args.group is not None:
|
elif args.group is not None:
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
DEFAULT_PAGE_SIZE = 20
|
||||||
|
|
||||||
NULL_HASH32 = b'\x00'*32
|
NULL_HASH32 = b'\x00'*32
|
||||||
|
|
||||||
CENT = 1000000
|
CENT = 1000000
|
||||||
|
|
|
@ -19,40 +19,12 @@ from lbry.blockchain import Transaction, Output, dewies_to_lbc, dict_values_to_l
|
||||||
from lbry.stream.managed_stream import ManagedStream
|
from lbry.stream.managed_stream import ManagedStream
|
||||||
from lbry.event import EventController, EventStream
|
from lbry.event import EventController, EventStream
|
||||||
from lbry.crypto.hash import hex_str_to_hash
|
from lbry.crypto.hash import hex_str_to_hash
|
||||||
|
from lbry.constants import DEFAULT_PAGE_SIZE
|
||||||
|
|
||||||
from .base import Service
|
from .base import Service
|
||||||
from .json_encoder import Paginated
|
from .json_encoder import Paginated
|
||||||
|
|
||||||
|
|
||||||
DEFAULT_PAGE_SIZE = 20
|
|
||||||
|
|
||||||
|
|
||||||
async def paginate_rows(get_records: Callable, page: Optional[int], page_size: Optional[int], **constraints):
|
|
||||||
page = max(1, page or 1)
|
|
||||||
page_size = max(1, page_size or DEFAULT_PAGE_SIZE)
|
|
||||||
constraints.update({
|
|
||||||
"offset": page_size * (page - 1),
|
|
||||||
"limit": page_size
|
|
||||||
})
|
|
||||||
return Paginated(await get_records(**constraints), page, page_size)
|
|
||||||
|
|
||||||
|
|
||||||
def paginate_list(items: List, page: Optional[int], page_size: Optional[int]):
|
|
||||||
page = max(1, page or 1)
|
|
||||||
page_size = max(1, page_size or DEFAULT_PAGE_SIZE)
|
|
||||||
total_items = len(items)
|
|
||||||
offset = page_size * (page - 1)
|
|
||||||
subitems = []
|
|
||||||
if offset <= total_items:
|
|
||||||
subitems = items[offset:offset+page_size]
|
|
||||||
return {
|
|
||||||
"items": subitems,
|
|
||||||
"total_pages": int((total_items + (page_size - 1)) / page_size),
|
|
||||||
"total_items": total_items,
|
|
||||||
"page": page, "page_size": page_size
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
StrOrList = Union[str, list]
|
StrOrList = Union[str, list]
|
||||||
Address = Dict
|
Address = Dict
|
||||||
|
|
||||||
|
@ -723,8 +695,8 @@ class API:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if wallet_id:
|
if wallet_id:
|
||||||
return paginate_list([self.wallets.get_wallet_or_error(wallet_id)], 1, 1)
|
return Paginated.from_list([self.wallets[wallet_id]], 1, 1)
|
||||||
return paginate_list(self.wallets.wallets, **pagination_kwargs)
|
return Paginated.from_list(list(self.wallets.wallets.values()), **pagination_kwargs)
|
||||||
|
|
||||||
async def wallet_reconnect(self):
|
async def wallet_reconnect(self):
|
||||||
""" Reconnects ledger network client, applying new configurations. """
|
""" Reconnects ledger network client, applying new configurations. """
|
||||||
|
@ -733,6 +705,7 @@ class API:
|
||||||
async def wallet_create(
|
async def wallet_create(
|
||||||
self,
|
self,
|
||||||
wallet_id: str, # wallet file name
|
wallet_id: str, # wallet file name
|
||||||
|
name: str = "", #
|
||||||
skip_on_startup=False, # don't add wallet to daemon_settings.yml
|
skip_on_startup=False, # don't add wallet to daemon_settings.yml
|
||||||
create_account=False, # generates the default account
|
create_account=False, # generates the default account
|
||||||
single_key=False # used with --create_account, creates single-key account
|
single_key=False # used with --create_account, creates single-key account
|
||||||
|
@ -741,12 +714,12 @@ class API:
|
||||||
Create a new wallet.
|
Create a new wallet.
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
wallet create (<wallet_id> | --wallet_id=<wallet_id>) [--skip_on_startup]
|
wallet create (<wallet_id> | --wallet_id=<wallet_id>) [--name=<name>]
|
||||||
[--create_account] [--single_key]
|
[--skip_on_startup] [--create_account] [--single_key]
|
||||||
|
|
||||||
"""
|
"""
|
||||||
wallet = await self.wallets.create(
|
wallet = await self.wallets.create(
|
||||||
wallet_id, create_account=create_account, single_key=single_key
|
wallet_id, name=name, create_account=create_account, single_key=single_key
|
||||||
)
|
)
|
||||||
if not skip_on_startup:
|
if not skip_on_startup:
|
||||||
with self.service.conf.update_config() as c:
|
with self.service.conf.update_config() as c:
|
||||||
|
@ -764,17 +737,7 @@ class API:
|
||||||
wallet add (<wallet_id> | --wallet_id=<wallet_id>)
|
wallet add (<wallet_id> | --wallet_id=<wallet_id>)
|
||||||
|
|
||||||
"""
|
"""
|
||||||
wallet_path = os.path.join(self.conf.wallet_dir, 'wallets', wallet_id)
|
return await self.wallets.load(wallet_id)
|
||||||
for wallet in self.wallets.wallets:
|
|
||||||
if wallet.id == wallet_id:
|
|
||||||
raise Exception(f"Wallet at path '{wallet_path}' is already loaded.")
|
|
||||||
if not os.path.exists(wallet_path):
|
|
||||||
raise Exception(f"Wallet at path '{wallet_path}' was not found.")
|
|
||||||
wallet = self.wallets.import_wallet(wallet_path)
|
|
||||||
if self.ledger.sync.network.is_connected:
|
|
||||||
for account in wallet.accounts:
|
|
||||||
await self.ledger.subscribe_account(account)
|
|
||||||
return wallet
|
|
||||||
|
|
||||||
async def wallet_remove(
|
async def wallet_remove(
|
||||||
self,
|
self,
|
||||||
|
@ -787,11 +750,7 @@ class API:
|
||||||
wallet remove (<wallet_id> | --wallet_id=<wallet_id>)
|
wallet remove (<wallet_id> | --wallet_id=<wallet_id>)
|
||||||
|
|
||||||
"""
|
"""
|
||||||
wallet = self.wallets.get_wallet_or_error(wallet_id)
|
return self.wallets.remove(wallet_id)
|
||||||
self.wallets.wallets.remove(wallet)
|
|
||||||
for account in wallet.accounts:
|
|
||||||
await self.ledger.unsubscribe_account(account)
|
|
||||||
return wallet
|
|
||||||
|
|
||||||
async def wallet_balance(
|
async def wallet_balance(
|
||||||
self,
|
self,
|
||||||
|
@ -945,9 +904,8 @@ class API:
|
||||||
kwargs = {'confirmations': confirmations, 'show_seed': include_seed}
|
kwargs = {'confirmations': confirmations, 'show_seed': include_seed}
|
||||||
wallet = self.wallets.get_or_default(wallet_id)
|
wallet = self.wallets.get_or_default(wallet_id)
|
||||||
if account_id:
|
if account_id:
|
||||||
return paginate_list([await wallet.get_account_or_error(account_id).get_details(**kwargs)], 1, 1)
|
return Paginated.from_list([wallet.accounts[account_id]], 1, 1)
|
||||||
else:
|
return Paginated.from_list(list(wallet.accounts), **pagination_kwargs)
|
||||||
return paginate_list(await wallet.get_detailed_accounts(**kwargs), **pagination_kwargs)
|
|
||||||
|
|
||||||
async def account_balance(
|
async def account_balance(
|
||||||
self,
|
self,
|
||||||
|
@ -1018,14 +976,9 @@ class API:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
wallet = self.wallets.get_or_default(wallet_id)
|
wallet = self.wallets.get_or_default(wallet_id)
|
||||||
account = await wallet.accounts.generate(account_name, language, {
|
return await wallet.accounts.generate(account_name, language, {
|
||||||
'name': SingleKey.name if single_key else HierarchicalDeterministic.name
|
'name': SingleKey.name if single_key else HierarchicalDeterministic.name
|
||||||
})
|
})
|
||||||
await wallet.save()
|
|
||||||
# TODO: fix
|
|
||||||
#if self.ledger.sync.network.is_connected:
|
|
||||||
# await self.ledger.sync.subscribe_account(account)
|
|
||||||
return account
|
|
||||||
|
|
||||||
async def account_remove(
|
async def account_remove(
|
||||||
self,
|
self,
|
||||||
|
@ -1064,7 +1017,7 @@ class API:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
wallet = self.wallets.get_or_default(wallet_id)
|
wallet = self.wallets.get_or_default(wallet_id)
|
||||||
account = wallet.get_account_or_error(account_id)
|
account = wallet.accounts[account_id]
|
||||||
change_made = False
|
change_made = False
|
||||||
|
|
||||||
if account.receiving.name == HierarchicalDeterministic.name:
|
if account.receiving.name == HierarchicalDeterministic.name:
|
||||||
|
@ -1083,14 +1036,13 @@ class API:
|
||||||
account.name = new_name
|
account.name = new_name
|
||||||
change_made = True
|
change_made = True
|
||||||
|
|
||||||
if default and wallet.default_account != account:
|
if default and wallet.accounts.default != account:
|
||||||
wallet.accounts.remove(account)
|
wallet.accounts.set_default(account)
|
||||||
wallet.accounts.insert(0, account)
|
|
||||||
change_made = True
|
change_made = True
|
||||||
|
|
||||||
if change_made:
|
if change_made:
|
||||||
account.modified_on = time.time()
|
account.modified_on = time.time()
|
||||||
await wallet.save()
|
await wallet.notify_change('account.updated')
|
||||||
|
|
||||||
return account
|
return account
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ from decimal import Decimal
|
||||||
from binascii import hexlify, unhexlify
|
from binascii import hexlify, unhexlify
|
||||||
from datetime import datetime, date
|
from datetime import datetime, date
|
||||||
from json import JSONEncoder
|
from json import JSONEncoder
|
||||||
from typing import Iterator, Generic
|
from typing import Iterator, Generic, Callable, Awaitable
|
||||||
|
|
||||||
from google.protobuf.message import DecodeError
|
from google.protobuf.message import DecodeError
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@ from lbry.crypto.bip32 import PubKey
|
||||||
from lbry.blockchain.dewies import dewies_to_lbc
|
from lbry.blockchain.dewies import dewies_to_lbc
|
||||||
from lbry.stream.managed_stream import ManagedStream
|
from lbry.stream.managed_stream import ManagedStream
|
||||||
from lbry.db.database import Result, ResultType
|
from lbry.db.database import Result, ResultType
|
||||||
|
from lbry.constants import DEFAULT_PAGE_SIZE
|
||||||
|
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
@ -135,6 +136,30 @@ class Paginated(Generic[ResultType]):
|
||||||
self.page = page
|
self.page = page
|
||||||
self.page_size = page_size
|
self.page_size = page_size
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_list(cls, items: list, page: int = None, page_size: int = None):
|
||||||
|
page = max(1, page or 1)
|
||||||
|
page_size = max(1, page_size or DEFAULT_PAGE_SIZE)
|
||||||
|
total_items = len(items)
|
||||||
|
offset = page_size * (page - 1)
|
||||||
|
subitems = []
|
||||||
|
if offset <= total_items:
|
||||||
|
subitems = items[offset:offset + page_size]
|
||||||
|
return cls(Result(subitems, total_items), page, page_size)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
async def from_getter(
|
||||||
|
cls, get_records: Callable[..., Awaitable[Result]],
|
||||||
|
page: int = None, page_size: int = None, **constraints
|
||||||
|
):
|
||||||
|
page = max(1, page or 1)
|
||||||
|
page_size = max(1, page_size or DEFAULT_PAGE_SIZE)
|
||||||
|
constraints.update({
|
||||||
|
"offset": page_size * (page - 1),
|
||||||
|
"limit": page_size
|
||||||
|
})
|
||||||
|
return cls(await get_records(**constraints), page, page_size)
|
||||||
|
|
||||||
def __getitem__(self, item: int) -> ResultType:
|
def __getitem__(self, item: int) -> ResultType:
|
||||||
return self.result[item]
|
return self.result[item]
|
||||||
|
|
||||||
|
|
|
@ -582,12 +582,12 @@ class CommandTestCase(IntegrationTestCase):
|
||||||
|
|
||||||
self.wallet = self.service.wallets.default
|
self.wallet = self.service.wallets.default
|
||||||
self.account = self.wallet.accounts.default
|
self.account = self.wallet.accounts.default
|
||||||
addresses = await self.account.ensure_address_gap()
|
address = await self.account.receiving.get_or_create_usable_address()
|
||||||
|
|
||||||
self.ledger.conf.upload_dir = os.path.join(self.ledger.conf.data_dir, 'uploads')
|
self.ledger.conf.upload_dir = os.path.join(self.ledger.conf.data_dir, 'uploads')
|
||||||
os.mkdir(self.ledger.conf.upload_dir)
|
os.mkdir(self.ledger.conf.upload_dir)
|
||||||
|
|
||||||
await self.chain.send_to_address(addresses[0], '10.0')
|
await self.chain.send_to_address(address, '10.0')
|
||||||
await self.generate(5)
|
await self.generate(5)
|
||||||
|
|
||||||
async def asyncTearDown(self):
|
async def asyncTearDown(self):
|
||||||
|
@ -642,6 +642,33 @@ class CommandTestCase(IntegrationTestCase):
|
||||||
await self.service.wait(tx)
|
await self.service.wait(tx)
|
||||||
return self.sout(tx)
|
return self.sout(tx)
|
||||||
|
|
||||||
|
async def wallet_list(self, *args, **kwargs):
|
||||||
|
return (await self.out(self.api.wallet_list(*args, **kwargs)))['items']
|
||||||
|
|
||||||
|
async def wallet_create(self, *args, **kwargs):
|
||||||
|
return await self.out(self.api.wallet_create(*args, **kwargs))
|
||||||
|
|
||||||
|
async def wallet_add(self, *args, **kwargs):
|
||||||
|
return await self.out(self.api.wallet_add(*args, **kwargs))
|
||||||
|
|
||||||
|
async def wallet_remove(self, *args, **kwargs):
|
||||||
|
return await self.out(self.api.wallet_remove(*args, **kwargs))
|
||||||
|
|
||||||
|
async def account_list(self, *args, **kwargs):
|
||||||
|
return (await self.out(self.api.account_list(*args, **kwargs)))['items']
|
||||||
|
|
||||||
|
async def account_create(self, *args, **kwargs):
|
||||||
|
return await self.out(self.api.account_create(*args, **kwargs))
|
||||||
|
|
||||||
|
async def account_add(self, *args, **kwargs):
|
||||||
|
return await self.out(self.api.account_add(*args, **kwargs))
|
||||||
|
|
||||||
|
async def account_set(self, *args, **kwargs):
|
||||||
|
return await self.out(self.api.account_set(*args, **kwargs))
|
||||||
|
|
||||||
|
async def account_remove(self, *args, **kwargs):
|
||||||
|
return await self.out(self.api.account_remove(*args, **kwargs))
|
||||||
|
|
||||||
def create_upload_file(self, data, prefix=None, suffix=None):
|
def create_upload_file(self, data, prefix=None, suffix=None):
|
||||||
file_path = tempfile.mktemp(
|
file_path = tempfile.mktemp(
|
||||||
prefix=prefix or "tmp", suffix=suffix or "", dir=self.ledger.conf.upload_dir
|
prefix=prefix or "tmp", suffix=suffix or "", dir=self.ledger.conf.upload_dir
|
||||||
|
|
|
@ -101,6 +101,9 @@ class WalletManager:
|
||||||
wallet.on_change.listen(lambda _: self.storage.save(wallet))
|
wallet.on_change.listen(lambda _: self.storage.save(wallet))
|
||||||
return wallet
|
return wallet
|
||||||
|
|
||||||
|
def remove(self, wallet_id: str) -> Wallet:
|
||||||
|
return self.wallets.pop(wallet_id)
|
||||||
|
|
||||||
async def _report_state(self):
|
async def _report_state(self):
|
||||||
try:
|
try:
|
||||||
for account in self.accounts:
|
for account in self.accounts:
|
||||||
|
|
|
@ -438,6 +438,10 @@ class AccountListManager:
|
||||||
await self.wallet.notify_change('account.removed')
|
await self.wallet.notify_change('account.removed')
|
||||||
return account
|
return account
|
||||||
|
|
||||||
|
def set_default(self, account):
|
||||||
|
self._accounts.remove(account)
|
||||||
|
self._accounts.insert(0, account)
|
||||||
|
|
||||||
def get_or_none(self, account_id: str) -> Optional[Account]:
|
def get_or_none(self, account_id: str) -> Optional[Account]:
|
||||||
if account_id is not None:
|
if account_id is not None:
|
||||||
return self[account_id]
|
return self[account_id]
|
||||||
|
|
Loading…
Reference in a new issue