def parse_admin_create_recurring_transfer(message): """Parses an admin-create-recurring-transfer message.""" body = message.split() if len(body) != 5: return None _, amount_text, sender, destination, tick_count_text = body try: amount = int(amount_text) tick_count = int(tick_count_text) except ValueError: return None return (amount, parse_account_id(sender), parse_account_id(destination), tick_count)
def cli(fp, acc): with LedgerServer(fp) as server: print(f"{_name} ver {_ver}") print("run help for a list of commands") print("or exit to leave the cli") while True: try: cmd = input(ps1(acc)) except KeyboardInterrupt: print() cmd = '' except EOFError: print('exit') cmd = 'exit' if cmd == '': continue if cmd.split()[0] in cant_run: print(f"Can't execute {cmd.split()[0]} from cli") elif cmd.startswith('login'): split = cmd.split() acc_id = parse_account_id(split[1]) acc = acc_id elif cmd.startswith('exit'): break else: print(run_command(acc, cmd, server))
def _get_account(account_id: Union[AccountId, str], server: Server) -> Account: """Get account from server, unless it doesn't exist, in which case raise""" account_id = parse_account_id(account_id) if not server.has_account(account_id): raise AccountCommandException(account_id) return server.get_account(account_id)
def process_request_alias(author: AccountId, message: str, server: Server, **kwargs): """Processes a request for an alias code.""" account = assert_is_account(author, server) split_msg = message.split() if len(split_msg) != 2: raise CommandException('Incorrect formatting. Expected `request-alias ALIAS_ACCOUNT_NAME`.') _, alias_name = split_msg alias_id = parse_account_id(alias_name) if server.has_account(alias_id): raise CommandException( 'An account has already been associated with %s, so it cannot be an alias for this account.' % alias_id.readable()) # To generate an alias code, we generate an ECC public/private key pair, use the # private key to generate a signed version of the aliased account name and associate # the public key with the account. key = ECC.generate(curve='P-256') signature = sign_message(str(alias_id), key) server.add_public_key(account, key.public_key()) # At this point we will allow the private key to be forgotten. # Compose a helpful message for as to how the bot can be contacted to link accounts. if isinstance(alias_id, RedditAccountId): contact_message = 'Send me that exact command as a Reddit Private Message (not a direct chat) from %s.' % alias_id.readable() elif isinstance(alias_id, DiscordAccountId): contact_message = 'Send me that exact command prefixed with a mention of my name via Discord from account %s.' % alias_id else: contact_message = '' return ('I created an alias request code for you. ' 'Make {0} an alias for this account ({2}) by sending me the following message from {3}.\n\n```\nadd-alias {4} {1}\n```\n\n{5}').format( str(alias_id), signature, author.readable(), alias_id.readable(), str(author), contact_message)
def _farm_balance(author, rest, server): account = author if rest != "": account = parse_account_id(rest.split()[0]) balance = commands.get_farm_balance(author, account, server) return f"Your inventory contains ".join( f"{farm.type.name}, " for farm in balance) if len(balance) > 0 else f"Your inventory is empty"
def process_proxy_command(author: AccountId, message: str, server: Server, **kwargs): """Processes a command by proxy.""" account_name, signature, command = parse_proxy_command(message) account = assert_is_account(account_name, server) if is_signed_by(account, command, signature): return process_command(parse_account_id(account_name), command, server) else: raise CommandException('Cannot execute command by proxy because the signature is invalid.')
def _vest_balance(author: Union[AccountId, str], rest, server): account = author if rest != "": account = parse_account_id(rest.split()[0]) has_vest = commands.vest_balance(author, account, server) if has_vest: return f"{account} has a vest" else: return f"{account} does not have a vest"
def _gun_balance(author: Union[AccountId, str], rest, server): account = author if rest != "": account = parse_account_id(rest.split()[0]) bal = commands.gun_balance(author, account, server) if account == author: return f"your gun-balance is {bal}" else: return f"{account} 's gun-balance is {bal}"
def assert_is_account(account_name: Union[str, AccountId], server: Server) -> Account: """Asserts that a particular account exists. Returns the account.""" if isinstance(account_name, str): account_name = parse_account_id(account_name) if not server.has_account(account_name): raise CommandException( ('Sorry, I can\'t process your request because %s does not have an account yet. ' 'Accounts can be opened using the `open` command.') % account_name.readable()) return server.get_account(account_name)
def parse_remove_funds(message): body = message.split() if len(body) != 3: return None _, amount_text, account = body try: amount = Fraction(amount_text) except ValueError: return None return amount, parse_account_id(account)
def parse(cmd, account, fp): acc = parse_account_id(account) if cmd is not None: server = LedgerServer(fp) cmds = cmd.split(';') for cmd in cmds: print(run_command(acc, cmd, server)) server.close() elif cmd is None: cli(fp, account)
def assert_authorized(account_name: Union[str, AccountId], server: Server, auth_level: Authorization) -> Account: """Asserts that a particular account exists and has an authorization level that is at least `auth_level`. Returns the account.""" if isinstance(account_name, str): account_name = parse_account_id(account_name) account = assert_is_account(account_name, server) if account.get_authorization().value < auth_level.value: raise CommandException('Sorry, I can\'t process your request because %s does not have the required authorization.' % account_name.readable()) return account
def parse_impl(): split_message = message.split('\n', 1) if len(split_message) != 2: return None proxy_line, command = split_message command = command.strip('\n\r') proxy_elems = proxy_line.split() if len(proxy_elems) == 2: _, account_name = proxy_elems return (parse_account_id(account_name), None, command) elif len(proxy_elems) == 4: _, protocol, account_name, enc_signature = proxy_elems if protocol != 'dsa': return None return (parse_account_id(account_name), enc_signature, command) else: return None
def parse_print_money(message): """Parses a money printing request.""" body = message.split() if len(body) != 3: return None _, amount_text, beneficiary = body try: amount = int(amount_text) except ValueError: return None return (amount, parse_account_id(beneficiary))
def parse(cmd, account, fp): acc = parse_account_id(account) if cmd is not None: server = LedgerServer(fp) cmds = cmd.split(';') for cmd in cmds: if cmd.startswith("shoot"): print("Can't execute shoot from cli") else: print(run_command(acc, cmd, server)) server.close() elif cmd is None: cli(fp, account)
def perform_transfer(author_name, sender_name, destination_name, amount, server): """Helper function that performs a transfer.""" author_id = parse_account_id(author_name) assert_is_account(author_name, server) sender = assert_is_account(sender_name, server) dest = assert_is_account(destination_name, server) # TODO: check for common reasons for why a transfer might not be able to go through (e.g., insufficient # balance) and provide a helpful error message for each of those cases. if not server.can_transfer(sender, dest, amount): return 'Sorry, but I can\'t perform that transfer.' proof = server.transfer(author_id, sender, dest, amount) proof_string = ' Proof: %s.' % proof if proof is not None else '' return 'Transfer performed successfully.%s' % proof_string