def buy(user, *products): """ Takes a user id (sci login name) and a list of products (db id, may still require casting) and adds the bill to the intranet. In case of a communication error this method blocks and retries to add the bill to the intranet. If the bill was added successfully True is returned. Otherwise, if the given user is not allowed to purchase things or a products is unknown, False is returned. """ logger = logging.getLogger("remote:buy") beverages = encode_buy(products) payload = {'buy': {'beverages': beverages, 'user': user}} headers = {'content-type': 'application/json'} # HTTP-200 -> ok # HTTP-422 -> scanned user is not allowed to buy stuff # HTTP-otherwise -> something went wrong, retry logger.info("init buy sequence") try_sync = True while True: try: r = requests.put(URL_BUY, data=json.dumps(payload), headers=headers, auth=(AUTH_USER, AUTH_PASSWORD)) if r.status_code == 200: logger.info("...everything worked fine") return True elif r.status_code == 422: # sync if not try_sync: logger.critical( "...did not work (user or product unknown by FSIntra)") return False else: logger.error( "...did not work (user or product unknown by FSIntra) -> syncing" ) try_sync = True from product_list import PRODUCT_LIST PRODUCT_LIST.update() else: # something went terribly wrong, retry logger.critical("...worked perfectly wrong") LCD.message_on(**MSG_BUY_RETRY) time.sleep(MSG_BUY_RETRY_WAIT) except requests.ConnectionError: logger.critical("connection refused. Are you online") LCD.message_on(**MSG_BUY_RETRY) time.sleep(MSG_BUY_RETRY_WAIT)
def update_display(): global user_json logger = logging.getLogger("actions:update_display") logger.info("updating with...") drinks = [(PRODUCT_LIST.get_name(pid), PRODUCT_LIST.get_price(pid)) for pid in products] logger.info("...drinks: %s" % str(drinks)) total = sum([PRODUCT_LIST.get_price(pid) for pid in products]) logger.info("...total: %.2f" % total) if user_json != None: _gui.update(user, drinks, total, (float(user_json['running_debts']), float(user_json['debts']))) else: _gui.update(user, drinks, total)
def update_display(): global user_json logger = logging.getLogger("actions:update_display") logger.info("updating with...") drinks = [(PRODUCT_LIST.get_name(pid), PRODUCT_LIST.get_price(pid)) for pid in products] logger.info("...drinks: %s" % str(drinks)) total = sum([PRODUCT_LIST.get_price(pid) for pid in products]) logger.info("...total: %.2f" % total) if user_json != None: _gui.update( user, drinks, total, (float(user_json['running_debts']), float(user_json['debts']))) else: _gui.update(user, drinks, total)
def buy(user, *products): """ Takes a user id (sci login name) and a list of products (db id, may still require casting) and adds the bill to the intranet. In case of a communication error this method blocks and retries to add the bill to the intranet. If the bill was added successfully True is returned. Otherwise, if the given user is not allowed to purchase things or a products is unknown, False is returned. """ logger = logging.getLogger("remote:buy") beverages = encode_buy(products) payload = {'buy': {'beverages': beverages, 'user': user}} headers = {'content-type': 'application/json'} # HTTP-200 -> ok # HTTP-422 -> scanned user is not allowed to buy stuff # HTTP-otherwise -> something went wrong, retry logger.info("init buy sequence") try_sync = True while True: try: r = requests.put(URL_BUY, data=json.dumps(payload), headers=headers, auth=(AUTH_USER, AUTH_PASSWORD)) if r.status_code == 200: logger.info("...everything worked fine") return True elif r.status_code == 422: # sync if not try_sync: logger.critical("...did not work (user or product unknown by FSIntra)") return False else: logger.error("...did not work (user or product unknown by FSIntra) -> syncing") try_sync = True from product_list import PRODUCT_LIST PRODUCT_LIST.update() else: # something went terribly wrong, retry logger.critical("...worked perfectly wrong") LCD.message_on(**MSG_BUY_RETRY) time.sleep(MSG_BUY_RETRY_WAIT) except requests.ConnectionError: logger.critical("connection refused. Are you online") LCD.message_on(**MSG_BUY_RETRY) time.sleep(MSG_BUY_RETRY_WAIT)
def sync(): logger = logging.getLogger("actions:sync") logger.info("syncing...") _gui.message_on(**MSG_SYNC_ON) success = PRODUCT_LIST.update() time.sleep(MSG_SYNC_DELAY) if success: _gui.message(**MSG_SYNC_SUCCESS) logger.info("sync successful") else: _gui.message(**MSG_SYNC_FAILED) logger.error("sync failed")
def product_code(product_id): logger = logging.getLogger("actions:product_code") global products stop_timer() PRODUCT_LIST.idle.clear() logger.info("scanned product: %s" % product_id) try: # don't let fools run the system into malicious states -> check cast product_id = int(product_id) except ValueError: product_id = None logger.critical("product code invalid (no int)") if not product_id or not PRODUCT_LIST.contains(product_id): logger.error("product code unknown") _gui.message(**MSG_UNKNOWN_PRODUCT) else: products.append(product_id) logger.info("product accepted, new list: %s" % str(products)) _gui.set_drink_image(PRODUCT_LIST.get_url(product_id)) start_timer() update_display()
def auto_sync(): logger = logging.getLogger("actions:auto_sync") logger.info("cowardly syncing...") # this is harpooning automagically during idle time - do not display anything PRODUCT_LIST.update()