Esempio n. 1
0
def add_allergen(request):
    """
    Adds an allergen to a user's allergen list
    """
    try:
        session_id = request.get_signed_cookie('session_id', default=None)
        euid = request.COOKIES.get('euid')
        user = User.get_by_id(crypto.decrypt(euid))
        allergen_name = request.POST.get('allergen', '')
        allergen = Label.query(Label.user_id == user.key.id(),
                               Label.name == allergen_name).get(keys_only=True)

        if session_id and not allergen:
            profile = user.get_profile()

            for a in profile['allergens']:
                if a['name'] == allergen_name: a['value'] = 'true'

            response = label_api.set_profile(session_id, profile)

            if response.get('result') == 'success':
                Label(user_id=user.key.id(), name=allergen_name).put_async()
                return HttpResponse('{"result": "success"}',
                                    content_type='application/json')
    except:
        pass

    return HttpResponse('{"result": "failure"}',
                        content_type='application/json')
Esempio n. 2
0
def remove_nutrient(request):
    """
    Removes a nutrient from a user's nutrient list
    """
    try:
        session_id = request.get_signed_cookie('session_id', default=None)
        euid = request.COOKIES.get('euid')
        user = User.get_by_id(crypto.decrypt(euid))
        nutrient_name = request.POST.get('nutrient', '')
        nutrient = Label.query(Label.user_id == user.key.id(),
                               Label.name == nutrient_name).get(keys_only=True)

        if session_id and nutrient:
            profile = user.get_profile()

            for n in profile['nutrients']:
                if n['name'] == nutrient_name: n['value'] = 'false'

            response = label_api.set_profile(session_id, profile)

            if response.get('result') == 'success':
                nutrient.delete_async()
                return HttpResponse('{"result": "success"}',
                                    content_type='application/json')
    except:
        pass

    return HttpResponse('{"result": "failure"}',
                        content_type='application/json')
Esempio n. 3
0
def add_allergen(request):
    """
    Adds an allergen to a user's allergen list
    """
    try:
        session_id = request.get_signed_cookie('session_id', default=None)
        euid = request.COOKIES.get('euid')
        user = User.get_by_id(crypto.decrypt(euid))
        allergen_name = request.POST.get('allergen', '')
        allergen = Label.query(
            Label.user_id == user.key.id(),
            Label.name == allergen_name).get(keys_only=True)

        if session_id and not allergen:
            profile = user.get_profile()

            for a in profile['allergens']:
                if a['name'] == allergen_name: a['value'] = 'true'

            response = label_api.set_profile(session_id, profile)

            if response.get('result')  == 'success':
                Label(user_id = user.key.id(), name = allergen_name).put_async()
                return HttpResponse('{"result": "success"}', content_type='application/json')
    except:
        pass

    return HttpResponse('{"result": "failure"}', content_type='application/json')
Esempio n. 4
0
def remove_nutrient(request):
    """
    Removes a nutrient from a user's nutrient list
    """
    try:
        session_id = request.get_signed_cookie('session_id', default=None)
        euid = request.COOKIES.get('euid')
        user = User.get_by_id(crypto.decrypt(euid))
        nutrient_name = request.POST.get('nutrient', '')
        nutrient = Label.query(
            Label.user_id == user.key.id(),
            Label.name == nutrient_name).get(keys_only=True)

        if session_id and nutrient:
            profile = user.get_profile()

            for n in profile['nutrients']:
                if n['name'] == nutrient_name: n['value'] = 'false'

            response = label_api.set_profile(session_id, profile)

            if response.get('result')  == 'success':
                nutrient.delete_async()
                return HttpResponse('{"result": "success"}', content_type='application/json')
    except:
        pass

    return HttpResponse('{"result": "failure"}', content_type='application/json')
Esempio n. 5
0
def authenticate(request):
    """
    Get credentials from Google using code from client,
    and then check if the user already exists in ndb.
    """
    try:
        oauth_flow = OAuth2WebServerFlow(
            client_id=settings.GOOGLE_CLIENT['web']['client_id'],
            client_secret=settings.GOOGLE_CLIENT['web']['client_secret'],
            auth_uri=settings.GOOGLE_CLIENT['web']['auth_uri'],
            token_uri=settings.GOOGLE_CLIENT['web']['token_uri'],    
            redirect_uri='postmessage',
            scope='openid email',
        )
        credentials = json.loads(oauth_flow.step2_exchange(request.body).to_json())
    except FlowExchangeError:
        return HttpResponse('{"result":"failure"}', content_type='application/json')
    else:
        user = User.get_by_id(credentials['id_token']['sub'])

        if not user:
            user = User(
                id = credentials['id_token']['sub'],
                email = credentials['id_token']['email'],
                refresh_token = credentials.get('refresh_token'))
            user.put()

        try:
            uid = user.key.id()
            session = label_api.create_session(user_id=uid, app_id=uid, device_id=uid)
            session_id = session.get('session_id')

            if not session_id:
                raise Exception

            # Must set profile before adding ingredients
            response = label_api.set_profile(session_id, user.get_profile())

            if response.get('result') != 'success':
                raise Exception

            for label in Label.query(Label.user_id == uid, Label.sub_id != '').fetch():
                label_api.add_ingredient(session_id, label.sub_id)

            response = HttpResponse(json.dumps({
                "success": True,
                "euid": crypto.encrypt(uid)
            }), content_type='application/json')

            response.set_signed_cookie('session_id', session_id)

            return response
        except:
            pass

    return HttpResponse('{"success": false}', content_type='application/json')
Esempio n. 6
0
 def set_profile(self, session_id, profile=None):
     if profile:
         label_api.set_profile(session_id, profile)
     else:
         label_api.set_profile(session_id, self.get_profile())
Esempio n. 7
0
 def set_profile(self, session_id, profile=None):
     if profile:
         label_api.set_profile(session_id, profile)
     else:
         label_api.set_profile(session_id, self.get_profile())
Esempio n. 8
0
def search(request):
    """
    Returns a list of search results.
    """
    search_term = request.GET.get('q').lower()
    start = request.GET.get('start', '0')
    mobile = request.GET.get('mobile')
    user = User.get_by_id(crypto.decrypt(
        request.COOKIES['euid'])) if 'euid' in request.COOKIES else None
    session_id = request.get_signed_cookie('session_id', default=None)

    if not session_id:
        session = {}
        while 'session_id' not in session:
            session = label_api.create_session()
        session_id = session['session_id']
        label_api.set_profile(session_id)

    products = []  # list of product info dictionaries
    pages = []  # list of (page_start, page_label) tuples
    total_found = 0

    # If start is not an integer, set start to 0
    try:
        start = int(start)
    except ValueError:
        start = 0

    if user:
        profile_hash = crypto.get_hmac_sha256_hash(
            json.dumps(user.get_profile(), sort_keys=True))
    else:
        profile_hash = crypto.get_hmac_sha256_hash(
            json.dumps(
                {
                    "nutrients": [{
                        "name": "Calories",
                        "value": "true"
                    }, {
                        "name": "Total Fat",
                        "value": "true"
                    }, {
                        "name": "Cholesterol",
                        "value": "true"
                    }, {
                        "name": "Sodium",
                        "value": "true"
                    }, {
                        "name": "Total Carbohydrate",
                        "value": "true"
                    }, {
                        "name": "Dietary Fiber",
                        "value": "true"
                    }, {
                        "name": "Sugars",
                        "value": "true"
                    }, {
                        "name": "Protein",
                        "value": "true"
                    }],
                    "allergens": [{
                        "name": "Gluten",
                        "value": "true"
                    }],
                    "additives": [{
                        "name": "Preservatives",
                        "value": "true"
                    }],
                    "myingredients": [],
                    "mysort": [{
                        "sort_variable": "Calories",
                        "sort_order": 1,
                        "variable_type": 1
                    }],
                },
                sort_keys=True))

    cached = Search_Cache.query(Search_Cache.profile_hash == profile_hash,
                                Search_Cache.search_term == search_term,
                                Search_Cache.start == start).get()

    # Data in cache and less than 5 days old
    if cached and (datetime.utcnow() - cached.updated_on).days < 5:
        products = cached.products
        pages = cached.pages
        total_found = cached.nfound

    else:
        if cached: cached.key.delete()

        search_result = {}

        while 'numFound' not in search_result:
            search_result = label_api.search_products(session_id,
                                                      search_term,
                                                      start=start)

        total_found = search_result['numFound']

        if total_found > 0:
            products = search_result['productsArray']
            pages = get_pages(start, total_found)

        # Get product details
        for product in products:
            if product['product_size'].strip() == 'none':
                product['product_size'] = ''

            prod_details = label_api.label_array(session_id, product['upc'])

            if 'productsArray' in prod_details:
                product['details'] = prod_details['productsArray'][0]
                product['contains'] = []
                product['may_contain'] = []

                # Get nutrient percentage value
                for nutrient in product['details']['nutrients']:
                    if nutrient[
                            'nutrient_name'] in constants.DAILY_VALUES and nutrient[
                                'nutrient_uom'] in constants.UNIT_MULTIPLIER:
                        try:
                            nutrient['percentage_value'] = '{:.0%}'.format(
                                float(nutrient['nutrient_value']) *
                                constants.UNIT_MULTIPLIER[
                                    nutrient['nutrient_uom']] /
                                constants.DAILY_VALUES[
                                    nutrient['nutrient_name']][1])
                        except ValueError:
                            nutrient['percentage_value'] = ''

                for allergen in product['details']['allergens']:
                    if allergen['allergen_value'] == '2':
                        product['contains'].append(allergen['allergen_name'])
                    elif allergen['allergen_value'] == '1':
                        product['may_contain'].append(
                            allergen['allergen_name'])

                for additive in product['details']['additives']:
                    if additive['additive_value'] == '2':
                        product['contains'].append(additive['additive_name'])
                    elif additive['additive_value'] == '1':
                        product['may_contain'].append(
                            additive['additive_name'])

                for ingredient in product['details']['procingredients']:
                    if ingredient['value'] == 2:
                        product['contains'].append(ingredient['name'])
                    elif ingredient['value'] == 1:
                        product['may_contain'].append(ingredient['name'])

        # Add to cache
        Search_Cache(profile_hash=profile_hash,
                     search_term=search_term,
                     start=start,
                     products=products,
                     pages=pages,
                     nfound=total_found).put()

    for product in products:
        # Check if product is on user shopping list
        if user and Shopping_List_Product.query(
                Shopping_List_Product.user_id == user.key.id(),
                Shopping_List_Product.barcode
                == product['upc']).get(keys_only=True):
            product['on_shopping_list'] = 'true'

        # Check if product is on user shopping list
        if user and Pantry_Product.query(
                Pantry_Product.user_id == user.key.id(), Pantry_Product.barcode
                == product['upc']).get(keys_only=True):
            product['in_pantry'] = 'true'

    response = render_to_response(
        'search.html', {
            'search_term': search_term,
            'products': products,
            'products_len': len(products),
            'pages': pages,
            'start': start,
            'total_found': total_found,
        }, RequestContext(request))

    response.set_signed_cookie('session_id', session_id)

    return response
Esempio n. 9
0
def authenticate(request):
    """
    Get credentials from Google using code from client,
    and then check if the user already exists in ndb.
    """
    try:
        oauth_flow = OAuth2WebServerFlow(
            client_id=settings.GOOGLE_CLIENT['web']['client_id'],
            client_secret=settings.GOOGLE_CLIENT['web']['client_secret'],
            auth_uri=settings.GOOGLE_CLIENT['web']['auth_uri'],
            token_uri=settings.GOOGLE_CLIENT['web']['token_uri'],
            redirect_uri='postmessage',
            scope='openid email',
        )
        credentials = json.loads(
            oauth_flow.step2_exchange(request.body).to_json())
    except FlowExchangeError:
        return HttpResponse('{"result":"failure"}',
                            content_type='application/json')
    else:
        user = User.get_by_id(credentials['id_token']['sub'])

        if not user:
            user = User(id=credentials['id_token']['sub'],
                        email=credentials['id_token']['email'],
                        refresh_token=credentials.get('refresh_token'))
            user.put()

        try:
            uid = user.key.id()
            session = label_api.create_session(user_id=uid,
                                               app_id=uid,
                                               device_id=uid)
            session_id = session.get('session_id')

            if not session_id:
                raise Exception

            # Must set profile before adding ingredients
            response = label_api.set_profile(session_id, user.get_profile())

            if response.get('result') != 'success':
                raise Exception

            for label in Label.query(Label.user_id == uid,
                                     Label.sub_id != '').fetch():
                label_api.add_ingredient(session_id, label.sub_id)

            response = HttpResponse(json.dumps({
                "success": True,
                "euid": crypto.encrypt(uid)
            }),
                                    content_type='application/json')

            response.set_signed_cookie('session_id', session_id)

            return response
        except:
            pass

    return HttpResponse('{"success": false}', content_type='application/json')
Esempio n. 10
0
def search(request):
    """
    Returns a list of search results.
    """
    search_term = request.GET.get('q').lower()
    start = request.GET.get('start', '0')
    mobile = request.GET.get('mobile')
    user = User.get_by_id(crypto.decrypt(request.COOKIES['euid'])) if 'euid' in request.COOKIES else None
    session_id = request.get_signed_cookie('session_id', default=None)

    if not session_id:
        session = {}
        while 'session_id' not in session:
            session = label_api.create_session()
        session_id = session['session_id']
        label_api.set_profile(session_id)

    products = [] # list of product info dictionaries
    pages = [] # list of (page_start, page_label) tuples
    total_found = 0

    # If start is not an integer, set start to 0
    try:
        start = int(start)
    except ValueError:
        start = 0

    if user:
        profile_hash = crypto.get_hmac_sha256_hash(json.dumps(user.get_profile(), sort_keys=True))
    else:
        profile_hash = crypto.get_hmac_sha256_hash(json.dumps({
            "nutrients": [
                {"name": "Calories", "value": "true"},
                {"name": "Total Fat", "value": "true"},
                {"name": "Cholesterol", "value": "true"},
                {"name": "Sodium", "value": "true"},
                {"name": "Total Carbohydrate", "value": "true"},
                {"name": "Dietary Fiber", "value": "true"},
                {"name": "Sugars", "value": "true"},
                {"name": "Protein", "value": "true"}
            ],
            "allergens": [
                {"name": "Gluten", "value": "true"}
            ],
            "additives": [
                {"name": "Preservatives", "value": "true"}
            ],
            "myingredients": [],
            "mysort": [
                {
                    "sort_variable": "Calories",
                    "sort_order": 1,
                    "variable_type": 1
                }
            ],
        }, sort_keys=True))

    cached = Search_Cache.query(
        Search_Cache.profile_hash == profile_hash,
        Search_Cache.search_term == search_term,
        Search_Cache.start == start).get()

    # Data in cache and less than 5 days old
    if cached and (datetime.utcnow() - cached.updated_on).days < 5:
        products = cached.products
        pages = cached.pages
        total_found = cached.nfound

    else:
        if cached: cached.key.delete()

        search_result = {}

        while 'numFound' not in search_result:
            search_result = label_api.search_products(session_id, search_term, start=start)

        total_found = search_result['numFound']

        if total_found > 0:
            products = search_result['productsArray']
            pages = get_pages(start, total_found)

        # Get product details
        for product in products:
            if product['product_size'].strip() == 'none':
                product['product_size'] = ''

            prod_details = label_api.label_array(session_id, product['upc'])

            if 'productsArray' in prod_details:
                product['details'] = prod_details['productsArray'][0]
                product['contains'] = []
                product['may_contain'] = []

                # Get nutrient percentage value
                for nutrient in product['details']['nutrients']:
                    if nutrient['nutrient_name'] in constants.DAILY_VALUES and nutrient['nutrient_uom'] in constants.UNIT_MULTIPLIER:
                        try:
                            nutrient['percentage_value'] = '{:.0%}'.format(float(nutrient['nutrient_value']) * constants.UNIT_MULTIPLIER[nutrient['nutrient_uom']] / constants.DAILY_VALUES[nutrient['nutrient_name']][1])
                        except ValueError:
                            nutrient['percentage_value'] = ''

                for allergen in product['details']['allergens']:
                    if allergen['allergen_value'] == '2':
                        product['contains'].append(allergen['allergen_name'])
                    elif allergen['allergen_value'] == '1':
                        product['may_contain'].append(allergen['allergen_name'])

                for additive in product['details']['additives']:
                    if additive['additive_value'] == '2':
                        product['contains'].append(additive['additive_name'])
                    elif additive['additive_value'] == '1':
                        product['may_contain'].append(additive['additive_name'])

                for ingredient in product['details']['procingredients']:
                    if ingredient['value'] == 2:
                        product['contains'].append(ingredient['name'])
                    elif ingredient['value'] == 1:
                        product['may_contain'].append(ingredient['name'])

        # Add to cache
        Search_Cache(profile_hash = profile_hash,
               search_term = search_term,
               start = start,
               products = products,
               pages = pages,
               nfound = total_found).put()

    for product in products:
        # Check if product is on user shopping list
        if user and Shopping_List_Product.query(
                Shopping_List_Product.user_id == user.key.id(),
                Shopping_List_Product.barcode == product['upc']
        ).get(keys_only=True):
            product['on_shopping_list'] = 'true'

        # Check if product is on user shopping list
        if user and Pantry_Product.query(
                Pantry_Product.user_id == user.key.id(),
                Pantry_Product.barcode == product['upc']
        ).get(keys_only=True):
            product['in_pantry'] = 'true'

    response = render_to_response(
        'search.html', 
        {
            'search_term': search_term,
            'products': products,
            'products_len': len(products),
            'pages': pages,
            'start': start,
            'total_found': total_found,
        },
        RequestContext(request))

    response.set_signed_cookie('session_id', session_id)

    return response