예제 #1
0
파일: slots.py 프로젝트: devinmatte/mizu
def update_slot_status():
    if request.headers.get('Content-Type') != 'application/json':
        return bad_headers_content_type()

    body = request.json

    logger.debug('Handling slot update')

    unprovided = []
    if 'machine' not in body:
        unprovided.append('machine')
    if 'slot' not in body:
        unprovided.append('slot')

    if len(unprovided) > 0:
        return bad_params(
            'The following required parameters were not provided: {}'.format(
                ', '.join(unprovided)))

    if 'active' not in body and 'item_id' not in body:
        return bad_params(
            'Either the state or item within a slot must be provided for an update.'
        )

    updates = {}

    if 'active' in body:
        if not isinstance(body['active'], bool):
            return bad_params('The active parameter must be a boolean value')

        updates['active'] = body['active']

    if 'item_id' in body:
        try:
            item_id = int(body['item_id'])
            if item_id <= 0:
                raise ValueError()
        except ValueError:
            return bad_params('The item ID value must be a positive integer')

        updates['item'] = item_id

        item = db.session.query(Item).filter(Item.id == item_id).first()

        if item is None:
            return bad_params(
                'No item with ID {} is present in the system'.format(item_id))

    try:
        slot_num = int(body['slot'])

        if slot_num <= 0:
            raise ValueError()
    except ValueError:
        return bad_params('The slot number must be a positive integer')

    machine = db.session.query(Machine).filter(
        Machine.name == body['machine']).first()
    if machine is None:
        return bad_params('The machine \'{}\' is not a valid machine'.format(
            body['machine']))

    slot = db.session.query(Slot).filter(Slot.number == slot_num,
                                         Slot.machine == machine.id).first()
    if slot is None:
        return bad_params(
            'The machine \'{}\' does not have a slot number {}'.format(
                body['machine'],
                body['slot'],
            ))

    logger.debug('Slot update details validated')

    slot = db.session.query(Slot).filter(Slot.number == body['slot'], Slot.machine == machine.id).\
            update(updates, synchronize_session=False)

    if slot < 1:
        return jsonify({
            'error': 'Could not update slot',
            'errorCode': 500,
            'message': 'Contact a drink admin'
        }), 500

    db.session.commit()

    slot = db.session.query(Slot).filter(Slot.number == slot_num,
                                         Slot.machine == machine.id).first()

    success = {
        'message':
        'Successfully updated slot {} in {}'.format(slot.number,
                                                    body['machine']),
        'slot': {
            'machine': body['machine'],
            'number': slot.number,
            'active': slot.active,
            'item_id': slot.item,
        },
    }

    return jsonify(success), 200
예제 #2
0
파일: drinks.py 프로젝트: RamZallan/mizu
def drop_drink(adapter, user=None):
    if request.headers.get('Content-Type') != 'application/json':
        return bad_headers_content_type()

    logger.debug('Handing request to drop drink')

    bal_before = _get_credits(user['preferred_username'])

    body = request.json

    unprovided = []
    if 'machine' not in body:
        unprovided.append('machine')
    if 'slot' not in body:
        unprovided.append('slot')

    if len(unprovided) > 0:
        return bad_params(
            'The following required parameters were not provided: {}'.format(
                ', '.join(unprovided)))

    machine = db.session.query(Machine).filter(
        Machine.name == body['machine']).first()
    if machine is None:
        return bad_params(
            'The machine name \'{}\' is not a valid machine'.format(
                body['machine']))

    slot = db.session.query(Slot).filter(Slot.number == body['slot'],
                                         Slot.machine == machine.id).first()
    if slot is None:
        return bad_params(
            'The machine \'{}\' does not have a slot with id \'{}\''.format(
                body['machine'], body['slot']))

    logger.debug('Drop request is valid')

    slot_status = _get_machine_status(body['machine'])
    if (body['machine'] == 'snack' and slot.count < 1
        ) or slot_status[body['slot'] - 1]['empty']:  # slots are 1 indexed
        return jsonify({
            "error": "The requested slot is empty!",
            "errorCode": 400
        }), 400

    item = db.session.query(Item).filter(Item.id == slot.item).first()

    if bal_before < item.price:
        response = {
            "error": "The user \'{}\' does not have a sufficient drinkBalance",
            "errorCode": 402
        }
        return jsonify(response), 402

    logger.debug('User has sufficient balance')

    machine_hostname = '{}.csh.rit.edu'.format(machine.name)
    request_endpoint = 'https://{}/drop'.format(machine_hostname)

    body = {"slot": slot.number}

    headers = {
        'X-Auth-Token': app.config['MACHINE_API_TOKEN'],
        'Content-Type': 'application/json'
    }

    # Do the thing
    try:
        response = requests.post(request_endpoint,
                                 json=body,
                                 headers=headers,
                                 timeout=5)
    except requests.exceptions.ConnectionError:
        return jsonify({
            "error": "Could not contact drink machine for drop!",
            "errorCode": 500
        }), 500
    except requests.exceptions.Timeout:
        return jsonify({
            "error": "Connection to the drink machine timed out!",
            "errorCode": 500
        }), 500

    try:
        response.raise_for_status()
    except requests.exceptions.HTTPError:
        return jsonify({"error": "Could not access slot for drop!",
                        "message": response.json()['error'],
                        "errorCode": response.status_code}),\
                       response.status_code

    logger.debug('Dropped drink - adjusting user credits')
    new_balance = bal_before - item.price
    _manage_credits(user['preferred_username'], new_balance, adapter)
    logger.debug('Credits for {} updated'.format(user['preferred_username']))

    if machine.name == 'snack':
        slot.count = Slot.count - 1  # Decrement stock count, set inactive if empty
        if slot.count == 0:
            slot.active = False
        db.session.commit()

    return jsonify({
        "message": "Drop successful!",
        "drinkBalance": new_balance
    }), response.status_code