shop.py
1 from typing import Any 2 3 from .command import command, CommandError 4 from .help import print_help 5 from .morphcoin import get_wallet_from_file 6 from ..client import Client 7 from ..context import DeviceContext 8 from ..exceptions import ItemNotFoundError, NotEnoughCoinsError 9 from ..models import Wallet, ShopCategory, ShopProduct 10 from ..util import strip_float, print_tree 11 12 13 def list_shop_products(client: Client) -> dict[str, ShopProduct]: 14 out = {} 15 for category in ShopCategory.shop_list(client): 16 for subcategory in category.subcategories: 17 for item in subcategory.items: 18 out[item.name.replace(" ", "")] = item 19 for item in category.items: 20 out[item.name.replace(" ", "")] = item 21 return out 22 23 24 @command("shop", [DeviceContext]) 25 def handle_shop(context: DeviceContext, args: list[str]) -> None: 26 """ 27 Buy new hardware and more in the shop 28 """ 29 30 if args: 31 raise CommandError("Unknown subcommand.") 32 print_help(context, handle_shop) 33 34 35 @handle_shop.subcommand("list") 36 def handle_shop_list(context: DeviceContext, _: Any) -> None: 37 """ 38 List shop prodcuts 39 """ 40 41 categories: list[ShopCategory] = ShopCategory.shop_list(context.client) 42 maxlength = max( 43 *[len(item.name) + 4 for category in categories for item in category.items], 44 *[ 45 len(item.name) 46 for category in categories 47 for subcategory in category.subcategories 48 for item in subcategory.items 49 ], 50 ) 51 tree = [] 52 for category in categories: 53 category_tree = [] 54 for subcategory in category.subcategories: 55 subcategory_tree: list[tuple[str, list[Any]]] = [ 56 (item.name.ljust(maxlength) + strip_float(item.price / 1000, 3) + " MC", []) 57 for item in subcategory.items 58 ] 59 category_tree.append((subcategory.name, subcategory_tree)) 60 61 for item in category.items: 62 category_tree.append((item.name.ljust(maxlength + 4) + strip_float(item.price / 1000, 3) + " MC", [])) 63 64 tree.append((category.name, category_tree)) 65 66 print("Shop") 67 print_tree(tree) 68 69 70 @handle_shop.subcommand("buy") 71 def handle_shop_buy(context: DeviceContext, args: list[str]) -> None: 72 """ 73 Buy something in the shop 74 """ 75 76 if len(args) != 2: 77 raise CommandError("usage: shop buy <product> <wallet>") 78 79 product_name, wallet_filepath = args 80 81 wallet: Wallet = get_wallet_from_file(context, wallet_filepath) 82 83 shop_products: dict[str, ShopProduct] = list_shop_products(context.client) 84 if product_name not in shop_products: 85 raise CommandError("This product does not exist in the shop.") 86 product: ShopProduct = shop_products[product_name] 87 88 try: 89 product.buy(wallet) 90 except ItemNotFoundError: 91 raise CommandError("This product does not exist in the shop.") 92 except NotEnoughCoinsError: 93 raise CommandError("You don't have enough coins on your wallet to buy this product.") 94 95 96 @handle_shop_buy.completer() 97 def shop_completer(context: DeviceContext, args: list[str]) -> list[str]: 98 if len(args) == 1: 99 return list(list_shop_products(context.client)) 100 if len(args) == 2: 101 return context.file_path_completer(args[1]) 102 return []