command fixes

This commit is contained in:
Lex Berezhny 2020-10-17 09:33:44 -04:00
parent cc2837c021
commit 1a4a2db1b1
9 changed files with 85 additions and 68 deletions

View file

@ -262,7 +262,11 @@ def main(argv=None):
if args.help:
print(doc)
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)
asyncio.get_event_loop().run_until_complete(execute_command(conf, api_method_name, params))
elif args.group is not None:

View file

@ -1,3 +1,5 @@
DEFAULT_PAGE_SIZE = 20
NULL_HASH32 = b'\x00'*32
CENT = 1000000

View file

@ -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.event import EventController, EventStream
from lbry.crypto.hash import hex_str_to_hash
from lbry.constants import DEFAULT_PAGE_SIZE
from .base import Service
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]
Address = Dict
@ -723,8 +695,8 @@ class API:
"""
if wallet_id:
return paginate_list([self.wallets.get_wallet_or_error(wallet_id)], 1, 1)
return paginate_list(self.wallets.wallets, **pagination_kwargs)
return Paginated.from_list([self.wallets[wallet_id]], 1, 1)
return Paginated.from_list(list(self.wallets.wallets.values()), **pagination_kwargs)
async def wallet_reconnect(self):
""" Reconnects ledger network client, applying new configurations. """
@ -733,6 +705,7 @@ class API:
async def wallet_create(
self,
wallet_id: str, # wallet file name
name: str = "", #
skip_on_startup=False, # don't add wallet to daemon_settings.yml
create_account=False, # generates the default account
single_key=False # used with --create_account, creates single-key account
@ -741,12 +714,12 @@ class API:
Create a new wallet.
Usage:
wallet create (<wallet_id> | --wallet_id=<wallet_id>) [--skip_on_startup]
[--create_account] [--single_key]
wallet create (<wallet_id> | --wallet_id=<wallet_id>) [--name=<name>]
[--skip_on_startup] [--create_account] [--single_key]
"""
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:
with self.service.conf.update_config() as c:
@ -764,17 +737,7 @@ class API:
wallet add (<wallet_id> | --wallet_id=<wallet_id>)
"""
wallet_path = os.path.join(self.conf.wallet_dir, 'wallets', 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
return await self.wallets.load(wallet_id)
async def wallet_remove(
self,
@ -787,11 +750,7 @@ class API:
wallet remove (<wallet_id> | --wallet_id=<wallet_id>)
"""
wallet = self.wallets.get_wallet_or_error(wallet_id)
self.wallets.wallets.remove(wallet)
for account in wallet.accounts:
await self.ledger.unsubscribe_account(account)
return wallet
return self.wallets.remove(wallet_id)
async def wallet_balance(
self,
@ -945,9 +904,8 @@ class API:
kwargs = {'confirmations': confirmations, 'show_seed': include_seed}
wallet = self.wallets.get_or_default(wallet_id)
if account_id:
return paginate_list([await wallet.get_account_or_error(account_id).get_details(**kwargs)], 1, 1)
else:
return paginate_list(await wallet.get_detailed_accounts(**kwargs), **pagination_kwargs)
return Paginated.from_list([wallet.accounts[account_id]], 1, 1)
return Paginated.from_list(list(wallet.accounts), **pagination_kwargs)
async def account_balance(
self,
@ -1018,14 +976,9 @@ class API:
"""
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
})
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(
self,
@ -1064,7 +1017,7 @@ class API:
"""
wallet = self.wallets.get_or_default(wallet_id)
account = wallet.get_account_or_error(account_id)
account = wallet.accounts[account_id]
change_made = False
if account.receiving.name == HierarchicalDeterministic.name:
@ -1083,14 +1036,13 @@ class API:
account.name = new_name
change_made = True
if default and wallet.default_account != account:
wallet.accounts.remove(account)
wallet.accounts.insert(0, account)
if default and wallet.accounts.default != account:
wallet.accounts.set_default(account)
change_made = True
if change_made:
account.modified_on = time.time()
await wallet.save()
await wallet.notify_change('account.updated')
return account

View file

@ -4,7 +4,7 @@ from decimal import Decimal
from binascii import hexlify, unhexlify
from datetime import datetime, date
from json import JSONEncoder
from typing import Iterator, Generic
from typing import Iterator, Generic, Callable, Awaitable
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.stream.managed_stream import ManagedStream
from lbry.db.database import Result, ResultType
from lbry.constants import DEFAULT_PAGE_SIZE
log = logging.getLogger(__name__)
@ -135,6 +136,30 @@ class Paginated(Generic[ResultType]):
self.page = page
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:
return self.result[item]

View file

@ -582,12 +582,12 @@ class CommandTestCase(IntegrationTestCase):
self.wallet = self.service.wallets.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')
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)
async def asyncTearDown(self):
@ -642,6 +642,33 @@ class CommandTestCase(IntegrationTestCase):
await self.service.wait(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):
file_path = tempfile.mktemp(
prefix=prefix or "tmp", suffix=suffix or "", dir=self.ledger.conf.upload_dir

View file

@ -101,6 +101,9 @@ class WalletManager:
wallet.on_change.listen(lambda _: self.storage.save(wallet))
return wallet
def remove(self, wallet_id: str) -> Wallet:
return self.wallets.pop(wallet_id)
async def _report_state(self):
try:
for account in self.accounts:

View file

@ -438,6 +438,10 @@ class AccountListManager:
await self.wallet.notify_change('account.removed')
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]:
if account_id is not None:
return self[account_id]