import sys from getpass import getpass from inspect import signature import connection from connection import client_request from debug import debug from game import DEFAULT_ORDER_EXPIRY from run_client import allowed_commands, fake_loading_bar from util import my_tabulate, yn_dialog exiting = False def login(username=None, password=None): if connection.session_id is not None: fake_loading_bar('Signing out', duration=0.7) connection.session_id = None if username is None: username = input('Username: ') if password is None: if sys.stdin.isatty(): password = getpass('Password: ') else: password = input('Password: ') fake_loading_bar('Signing in', duration=2.3) response = client_request('login', {"username": username, "password": password}) success = 'session_id' in response if success: connection.session_id = response['session_id'] print('Login successful.') else: if 'error_message' in response: print('Login failed with message:', response['error_message']) else: print('Login failed.') def register(username=None, game_key='', password=None, retype_pw=None): if connection.session_id is not None: connection.session_id = None fake_loading_bar('Signing out', duration=0.7) if username is None: username = input('Username: ') if password is None: if sys.stdin.isatty(): password = getpass('New password: ') retype_pw = getpass('Retype password: ') else: password = input('New password: ') retype_pw = input('Retype password: ') if password != retype_pw: print('Passwords do not match.') return elif retype_pw is None: if sys.stdin.isatty(): retype_pw = getpass('Retype password: ') else: retype_pw = input('Retype password: ') if password != retype_pw: print('Passwords do not match.') return if not debug: if game_key == '': print('Entering a game key will provide you with some starting money and other useful stuff.') game_key = input('Game key (leave empty if you don\'t have one): ') fake_loading_bar('Validating Registration', duration=5.2) if game_key != '': fake_loading_bar('Validating Game Key', duration=0.4) response = client_request('register', {"username": username, "password": password, "game_key": game_key}) if 'error_message' in response: print('Registration failed with message:', response['error_message']) def cancel_order(order_no=None): if order_no is None: order_no = input('Order No.: ') fake_loading_bar('Validating Request', duration=0.6) response = client_request('cancel_order', {"session_id": connection.session_id, "order_id": order_no}) if 'error_message' in response: print('Order cancelling failed with message:', response['error_message']) def change_pw(password=None, retype_pw=None): if password != retype_pw: password = None if password is None: if sys.stdin.isatty(): password = getpass('New password: ') retype_pw = getpass('Retype password: ') else: password = input('New password: ') retype_pw = input('Retype password: ') if password != retype_pw: print('Passwords do not match.') return elif retype_pw is None: if sys.stdin.isatty(): retype_pw = getpass('Retype password: ') else: retype_pw = input('Retype password: ') if password != retype_pw: print('Passwords do not match.') return fake_loading_bar('Validating password', duration=1.2) fake_loading_bar('Changing password', duration=5.2) response = client_request('change_password', {"session_id": connection.session_id, "password": password}) if 'error_message' in response: print('Changing password failed with message:', response['error_message']) fake_loading_bar('Signing out', duration=0.7) connection.session_id = None # noinspection PyShadowingBuiltins def help(): print('Allowed commands:') command_table = [] for cmd in allowed_commands: this_module = sys.modules[__name__] method = getattr(this_module, cmd) params = signature(method).parameters command_table.append([cmd] + [p for p in params]) print(my_tabulate(command_table, tablefmt='pipe', headers=['command', 'param 1', 'param 2', 'param 3', 'param 4', 'param 5', ])) print('NOTE:') print(' All parameters for all commands are optional!') print(' Commands can be combined in one line with ; between them.') print(' Parameters are separated with whitespace.') print(' Use . as a decimal separator.') print(' Use 0/1 for boolean parameters (other strings might work).') def depot(): fake_loading_bar('Loading data', duration=1.3) response = client_request('depot', {"session_id": connection.session_id}) success = 'data' in response and 'own_wealth' in response if success: data = response['data'] for row in data: row.append(row[1] * row[2]) print(my_tabulate(data, headers=['Object', 'Amount', 'Course', 'Bid', 'Ask', 'Est. Value'], tablefmt="pipe")) print('This corresponds to a wealth of roughly', response['own_wealth']) else: if 'error_message' in response: print('Depot access failed with message:', response['error_message']) else: print('Depot access failed.') def leaderboard(): fake_loading_bar('Loading data', duration=1.3) response = client_request('leaderboard', {}) success = 'data' in response if success: print(my_tabulate(response['data'], headers=['Trader', 'Wealth'], tablefmt="pipe")) # print('Remember that the goal is to be as rich as possible, not to be richer than other traders!') else: if 'error_message' in response: print('Leaderboard access failed with message:', response['error_message']) else: print('Leaderboard access failed.') def activate_key(key=''): if key == '': print('Entering a game key may get you some money or other useful stuff.') key = input('Key: ') if key == '': print('Invalid key.') fake_loading_bar('Validating Key', duration=0.4) response = client_request('activate_key', {"session_id": connection.session_id, 'key': key}) if 'error_message' in response: print('Key activation failed with message:', response['error_message']) def _order(is_buy_order, obj_name, amount, limit, stop_loss, expiry): if stop_loss not in [None, '1', '0']: print('Invalid value for flag stop loss (only 0 or 1 allowed).') return if obj_name is None: # TODO list some available objects obj_name = input('Name of object to sell: ') if amount is None: amount = input('Amount: ') if limit is None: set_limit = yn_dialog('Do you want to place a limit?') if set_limit: limit = input('Limit: ') stop_loss = yn_dialog('Is this a stop-loss limit?') if limit is not None: try: limit = float(limit) except ValueError: print('Invalid limit.') return if stop_loss is None: stop_loss = yn_dialog('Is this a stop-loss limit?') question = 'Are you sure you want to use such a low limit (limit=' + str(limit) + ')?:' if not is_buy_order and limit <= 0 and not yn_dialog(question): print('Order was not placed.') return if expiry is None: expiry = input('Time until order expires (minutes, default ' + str(DEFAULT_ORDER_EXPIRY) + '):') if expiry == '': expiry = DEFAULT_ORDER_EXPIRY try: expiry = float(expiry) except ValueError: print('Invalid expiration time.') return fake_loading_bar('Sending Data', duration=1.3) response = client_request('order', {"buy": is_buy_order, "session_id": connection.session_id, "amount": amount, "ownable": obj_name, "limit": limit, "stop_loss": stop_loss, "time_until_expiration": expiry}) if 'error_message' in response: print('Order placement failed with message:', response['error_message']) else: print('You might want to use the `trades` or `depot` commands', 'to see if the order has been executed already.') def sell(obj_name=None, amount=None, limit=None, stop_loss=None, expiry=None): _order(is_buy_order=False, obj_name=obj_name, amount=amount, limit=limit, stop_loss=stop_loss, expiry=expiry) def buy(obj_name=None, amount=None, limit=None, stop_loss=None, expiry=None): _order(is_buy_order=True, obj_name=obj_name, amount=amount, limit=limit, stop_loss=stop_loss, expiry=expiry) def orders(): fake_loading_bar('Loading Data', duration=0.9) response = client_request('orders', {"session_id": connection.session_id}) success = 'data' in response if success: print(my_tabulate(response['data'], headers=['Buy?', 'Name', 'Size', 'Limit', 'stop-loss', 'Expires', 'No.'], tablefmt="pipe")) else: if 'error_message' in response: print('Order access failed with message:', response['error_message']) else: print('Order access failed.') def orders_on(obj_name=None): if obj_name is None: # TODO list some available objects obj_name = input('Name of object to check: ') fake_loading_bar('Loading Data', duration=2.3) response = client_request('orders_on', {"session_id": connection.session_id, "ownable": obj_name}) success = 'data' in response if success: print(my_tabulate(response['data'], headers=['My', 'Buy?', 'Name', 'Size', 'Limit', 'Expires', 'No.'], tablefmt="pipe")) else: if 'error_message' in response: print('Order access failed with message:', response['error_message']) else: print('Order access failed.') def gift(username=None, obj_name=None, amount=None): if username is None: username = input('Username of recipient: ') if obj_name is None: obj_name = input('Name of object to give: ') if amount is None: amount = input('How many?: ') fake_loading_bar('Sending Gift', duration=4.2) response = client_request('gift', {"session_id": connection.session_id, "username": username, "object_name": obj_name, "amount": amount}) if 'error_message' in response: print('Order access failed with message:', response['error_message']) elif 'message' in response: print(response['message']) def news(): fake_loading_bar('Loading Data', duration=0.76) response = client_request('news', {}) success = 'data' in response if success: print(my_tabulate(response['data'], headers=['Date', 'Title'], tablefmt="pipe")) else: if 'error_message' in response: print('News access failed with message:', response['error_message']) else: print('News access failed.') def tradables(): fake_loading_bar('Loading Data', duration=12.4) response = client_request('tradables', {}) success = 'data' in response if success: print(my_tabulate(response['data'], headers=['Name', 'Course', 'Market Cap.'], tablefmt="pipe")) world_wealth = 0 for row in response['data']: if row[2] is not None: world_wealth += row[2] print('Estimated worldwide wealth:', world_wealth) else: if 'error_message' in response: print('Data access failed with message:', response['error_message']) else: print('Data access failed.') def trades_on(obj_name=None, limit=5): limit = float(limit) if obj_name is None: # TODO list some available objects obj_name = input('Name of object to check: ') fake_loading_bar('Loading Data', duration=0.34*limit) response = client_request('trades_on', {"session_id": connection.session_id, "ownable": obj_name, "limit": limit}) success = 'data' in response if success: print(my_tabulate(response['data'], headers=['Time', 'Volume', 'Price'], tablefmt="pipe")) else: if 'error_message' in response: print('Trades access failed with message:', response['error_message']) else: print('Trades access failed.') def trades(limit=10): limit = float(limit) fake_loading_bar('Loading Data', duration=limit * 0.21) response = client_request('trades', {"session_id": connection.session_id, "limit": limit}) success = 'data' in response if success: print(my_tabulate(response['data'], headers=['Buy?', 'Name', 'Volume', 'Price', 'Time'], tablefmt="pipe")) else: if 'error_message' in response: print('Trades access failed with message:', response['error_message']) else: print('Trades access failed.') def old_orders(include_canceled=None, include_executed=None, limit=10): limit = float(limit) if include_canceled is None: include_canceled = yn_dialog('Include canceled/expired orders in list?') if include_executed is None: include_executed = yn_dialog('Include fully executed orders in list?') fake_loading_bar('Loading Data', duration=limit * 0.27) response = client_request('old_orders', {"session_id": connection.session_id, "include_canceled": include_canceled, "include_executed": include_executed, "limit": limit}) success = 'data' in response if success: print(my_tabulate(response['data'], headers=['Buy?', 'Name', 'Size', 'Limit', 'Expiry', 'No.', 'Status'], tablefmt="pipe")) else: if 'error_message' in response: print('Order access failed with message:', response['error_message']) else: print('Order access failed.') # noinspection PyShadowingBuiltins def exit(): global exiting exiting = True