Exemplo n.º 1
0
def create_legoset_record(set_id):
    """
    Add a legoset to the database
    Presupposes check for pre-existence already done
    :param set_id: LEGO set ID
    :returns: created LegoSet object
    :rtype: LegoSet
    """
    # Query Amazon API for info about the set
    response = amazon.search(set_id)
    item = response.find('item')
    if item is not None:
        new_legoset = LegoSet({
            'id':
            set_id,
            'url':
            item.find('detailpageurl').get_text(),
            'title':
            item.find('itemattributes').find('title').get_text(),
            'image':
            item.find('mediumimage').find('url').get_text()
        })
        try:
            new_legoset.save()
            # Update stock level so we have some inital data to display
            update_stock(new_legoset)
            return new_legoset
        except:
            raise FlaskError('Unable to save new set to database',
                             status_code=500)
    raise FlaskError('Could not find set {} on Amazon'.format(set_id),
                     status_code=400)
Exemplo n.º 2
0
def login(amazon_token):
    """
    Performs the following:
    1. Asks Amazon about this access token
    2. Gets an email address
    3. Sees if that email exists in the db
    If not, creates that user
    4. Signs the user id into a JWT
    5. Returns token and the email (for display purposes) to the user
    for future requests
    The client side can then stash the JWT in localStorage

    :param amazon_token: string token returned from Login With Amazon query
    :returns: User object from database
    :rtype: dict
    """
    profile = requests.get(
        'https://api.amazon.com/user/profile?access_token={}'
            .format(amazon_token)).json()
    if 'email' in profile:
        user = User.query.filter_by(email=profile['email']).first()
        if user is not None:
            token = create_jwt(user.id)
            return {'token': token, 'email': profile['email'], 'new': False}
        else:
            new_user = User(profile['email']).save()
            token = create_jwt(new_user.id)
            return {'token': token, 'email': profile['email'], 'new': True}
    raise FlaskError('Could not authenticate user', status_code=401)
Exemplo n.º 3
0
def search(set_id):
    """
    GET /legoset/search/<id>
    Queries Amazon for info about this legoset and returns it
    :param set_id: LEGO set ID
    :returns: dict repr of found LegoSet object
    :rtype: dict
    """
    # First check in our database
    set_exists = LegoSet.query.filter_by(id=set_id).first()
    if set_exists:
        return set_exists.to_dict()
    # If not found, check amazon
    response = amazon.search(set_id)
    item = response.find('item')
    if item is not None:
        return {
            'id': int(set_id),
            'url': item.find('detailpageurl').get_text(),
            'title': item.find('itemattributes').find('title').get_text(),
            'image': item.find('mediumimage').find('url').get_text()
        }
    # If it could not be found, raise an error but also 200 status indicating no fault
    raise FlaskError('Could not find set {} on Amazon'.format(set_id),
                     status_code=200)
Exemplo n.º 4
0
def delete_watch_route(w_id):
    """
    Delete specified watch
    :param w_id: primary key identifying Watch object
    :returns: json message indicating success
    :rtype: json
    :raises: KeyError
    """
    try:
        watch_id = w_id or request.args.get('w_id')
        data = request.get_json(force=True)
        user = get_user(data['token'])
        delete_watch(watch_id, user)
        return jsonify({'result': 'Watch ' + watch_id + ' deleted'})
    except KeyError:
        error = FlaskError('Must supply a token and a set ID', status_code=400)
        return error.json_response()
    except Exception as e:
        return exception_json_response(e)
Exemplo n.º 5
0
def delete_watch(set_id, user):
    """
    Cease watching LegoSet set_id for user
    :param set_id: LEGO set id
    :param user: User object
    :returns: LEGO set id
    :rtype: string
    """
    for watch in user.watches:
        if watch.id == int(set_id):
            user.watches.remove(watch)
            user.save()
            return set_id
    raise FlaskError('Watch not found', status_code=400)
Exemplo n.º 6
0
def get_user(token):
    """
    Get a User object from a token
    Unlike authenticate() this will include the email and ID
    :param token: JWT identifying user
    :type token: string
    :returns: User object from database
    :rtype: User
    """
    user_id = authenticate(token)
    user = User.query.filter_by(id=user_id).first()
    if user is not None:
        return user
    raise FlaskError('User not found', status_code=401)
Exemplo n.º 7
0
def authenticate(token):
    """
    Decode JWT and extract user id
    :param token: JWT identifying a user
    :type token: string
    :returns: user id
    :rtype: string
    """
    try:
        decoded = jwt.decode(token, environ['JWT_SECRET'], algorithms=['HS256'])
        return decoded['user']
    except:
        ''' If token is invalid raise an error '''
        raise FlaskError('Could not authenticate user', status_code=401)
Exemplo n.º 8
0
def add_watch(legoset, user):
    """
    POST /watch/add
    Add a new watch to the database
    :param legoset: LegoSet object
    :param user: User object
    :returns: dict repr of LegoSet object
    :rtype: dict
    """
    if legoset in user.watches:
        print('watch already exists for user')
        raise FlaskError('Watch already exists for user', status_code=400)
    user.watches.append(legoset)
    user.save()
    return legoset.to_dict()
Exemplo n.º 9
0
def add_watch_route():
    """
    Add a watched set to the database, return JSON
    :returns: json repr of Watch object
    :rtype: json
    :raises: KeyError
    :raises: FlaskError
    """
    data = request.get_json(force=True)
    try:
        set_id = data['id']
        token = data['token']
        # Perform this check early to ensure authentication
        user = get_user(token)
        legoset = get_or_create_legoset(set_id)
        watch = add_watch(legoset, user)
        return jsonify({'result': watch})
    except KeyError:
        error = FlaskError('Must supply a token and a set ID', status_code=400)
        return error.json_response()
    except FlaskError as e:
        return e.json_response()
    except Exception as e:
        return exception_json_response(e)
Exemplo n.º 10
0
def find_legoset_view(id):
    """
    Return json repr of LegoSet
    :param id: LEGO set id
    :rtype: json
    :raises: ValueError
    :raises: FlaskError
    """
    try:
        # ID must be an integer between 5 and 7 digits
        test = re.match(r'^\d{5,7}$', id)
        if not test:
            raise ValueError
        token = request.args.get('token')
        authenticate(token)
        legoset = search(int(id))
        return jsonify({'result': legoset})
    except ValueError:
        error = FlaskError(
            'Please supply a valid query (a 5 to 7 digit integer)',
            status_code=400)
        return error.json_response()
    except FlaskError as e:
        return e.json_response()