Beispiel #1
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')
Beispiel #2
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')
Beispiel #3
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')
Beispiel #4
0
def checkout(request):
    """
    Stripe checkout
    """
    user_id = crypto.decrypt(request.COOKIES.get('euid', ''))
    user = User.get_by_id(user_id)

    if not user:
        return redirect('/')

    try:
        stripe.api_key = settings.STRIPE_SECRET_KEY
        charge = stripe.Charge.create(
            amount=800,  # amount in cents
            currency='usd',
            source=request.POST.get('stripeToken', ''),
            description='Classifood upgrade for {0}'.format(
                request.POST.get('stripeEmail')))

        if charge.get('status') != 'succeeded':
            raise Exception
    except:
        print 'Stripe Error: Failed to charge user {0}'.format(user_id)
        return redirect('/user/profile?upgrade_status=0')
    else:
        Order(user_id=user_id,
              name=request.POST.get('name'),
              description=request.POST.get('description'),
              price=int(request.POST.get('price'))).put()
        user.group_id = 2
        user.upgrade_exp = datetime.utcnow() + timedelta(days=180)
        user.put()

    return redirect('/user/profile')
Beispiel #5
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')
Beispiel #6
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')
Beispiel #7
0
def checkout(request):
    """
    Stripe checkout
    """
    user_id = crypto.decrypt(request.COOKIES.get('euid', ''))
    user = User.get_by_id(user_id)

    if not user:
        return redirect('/')

    try:
        stripe.api_key = settings.STRIPE_SECRET_KEY
        charge = stripe.Charge.create(
            amount=800, # amount in cents
            currency='usd',
            source=request.POST.get('stripeToken', ''),
            description='Classifood upgrade for {0}'.format(request.POST.get('stripeEmail'))
        )

        if charge.get('status') != 'succeeded':
            raise Exception
    except:
        print 'Stripe Error: Failed to charge user {0}'.format(user_id)
        return redirect('/user/profile?upgrade_status=0')
    else:
        Order(user_id = user_id,
              name = request.POST.get('name'),
              description = request.POST.get('description'),
              price = int(request.POST.get('price'))).put()
        user.group_id = 2
        user.upgrade_exp = datetime.utcnow() + timedelta(days=180)
        user.put()

    return redirect('/user/profile')
Beispiel #8
0
def user_profile(request):
    """
    Returns user profile page
    """
    user_id = crypto.decrypt(request.COOKIES['euid']) if 'euid' in request.COOKIES else None
    session_id = request.get_signed_cookie('session_id', default=None)

    if user_id and session_id:
        user = User.get_by_id(user_id)
        profile = user.get_profile()
        show_expired = False
        show_failed_upgrade = False

        if user.group_id == 2: # Upgraded user
            now = datetime.utcnow()
            if user.upgrade_exp < now:
                user.group_id = 1
                user.reset_profile(session_id)
                user.put()
                if (now - user.upgrade_exp).days < 3:
                    show_expired = True

        if request.GET.get('upgrade_status') == '0':
            show_failed_upgrade = True

        def filter_list(a_list):
            result = {}
            for x in a_list:
                if x['value'] == 'true':
                    result[x['name']] = True
            return result

        user_nutrients = filter_list(profile['nutrients'])
        user_allergens = filter_list(profile['allergens'])
        user_additives = filter_list(profile['additives'])
        user_ingredients = Label.query(
            Label.user_id == user_id,
            Label.sub_id != None).fetch()

        return render_to_response(
            'user_profile.html',
            {
                'user': user,
                'user_nutrients': user_nutrients,
                'user_allergens': user_allergens,
                'user_additives': user_additives,
                'user_ingredients': user_ingredients,
                'known_nutrients': constants.known_nutrients,
                'known_allergens': constants.known_allergens,
                'known_additives': constants.known_additives,
                'show_expired': show_expired,
                'show_failed_upgrade': show_failed_upgrade,
                'stripe_public_key': settings.STRIPE_PUBLIC_KEY
            },
            RequestContext(request))

    return redirect('/signin')    
Beispiel #9
0
def user_profile(request):
    """
    Returns user profile page
    """
    user_id = crypto.decrypt(
        request.COOKIES['euid']) if 'euid' in request.COOKIES else None
    session_id = request.get_signed_cookie('session_id', default=None)

    if user_id and session_id:
        user = User.get_by_id(user_id)
        profile = user.get_profile()
        show_expired = False
        show_failed_upgrade = False

        if user.group_id == 2:  # Upgraded user
            now = datetime.utcnow()
            if user.upgrade_exp < now:
                user.group_id = 1
                user.reset_profile(session_id)
                user.put()
                if (now - user.upgrade_exp).days < 3:
                    show_expired = True

        if request.GET.get('upgrade_status') == '0':
            show_failed_upgrade = True

        def filter_list(a_list):
            result = {}
            for x in a_list:
                if x['value'] == 'true':
                    result[x['name']] = True
            return result

        user_nutrients = filter_list(profile['nutrients'])
        user_allergens = filter_list(profile['allergens'])
        user_additives = filter_list(profile['additives'])
        user_ingredients = Label.query(Label.user_id == user_id,
                                       Label.sub_id != None).fetch()

        return render_to_response(
            'user_profile.html', {
                'user': user,
                'user_nutrients': user_nutrients,
                'user_allergens': user_allergens,
                'user_additives': user_additives,
                'user_ingredients': user_ingredients,
                'known_nutrients': constants.known_nutrients,
                'known_allergens': constants.known_allergens,
                'known_additives': constants.known_additives,
                'show_expired': show_expired,
                'show_failed_upgrade': show_failed_upgrade,
                'stripe_public_key': settings.STRIPE_PUBLIC_KEY
            }, RequestContext(request))

    return redirect('/signin')
Beispiel #10
0
def add_to_shopping_list(request):
    """
    Adds a product to the Shopping_List_Product table
    """
    user_id = crypto.decrypt(request.COOKIES['euid']) if 'euid' in request.COOKIES else None
    user = User.get_by_id(user_id) if user_id else None
    barcode = request.POST.get('barcode', '')

    if user and barcode and not Shopping_List_Product.query(
            Shopping_List_Product.user_id == user_id,
            Shopping_List_Product.barcode == barcode).get(keys_only=True):
        Shopping_List_Product(user_id = user_id, barcode = barcode).put()
        return HttpResponse('{"result": "success"}', content_type='application/json')

    return HttpResponse('{"result": "failure"}', content_type='application/json')
Beispiel #11
0
def add_to_shopping_list(request):
    """
    Adds a product to the Shopping_List_Product table
    """
    user_id = crypto.decrypt(
        request.COOKIES['euid']) if 'euid' in request.COOKIES else None
    user = User.get_by_id(user_id) if user_id else None
    barcode = request.POST.get('barcode', '')

    if user and barcode and not Shopping_List_Product.query(
            Shopping_List_Product.user_id == user_id,
            Shopping_List_Product.barcode == barcode).get(keys_only=True):
        Shopping_List_Product(user_id=user_id, barcode=barcode).put()
        return HttpResponse('{"result": "success"}',
                            content_type='application/json')

    return HttpResponse('{"result": "failure"}',
                        content_type='application/json')
Beispiel #12
0
def user_shopping_list(request):
    """
    Returns the user shopping list
    """
    user_id = crypto.decrypt(
        request.COOKIES['euid']) if 'euid' in request.COOKIES else None
    session_id = request.get_signed_cookie('session_id', default=None)

    if user_id and session_id:
        user = User.get_by_id(user_id)
        start = request.GET.get('start', '0')
        label_error = False

        try:
            start = int(start)
        except ValueError:
            start = 0

        # Get shopping list products by user_id
        prod_entities = Shopping_List_Product.query(
            Shopping_List_Product.user_id == user_id).order(
                -Shopping_List_Product.added_on).fetch(limit=5, offset=start)

        # Get total number of shopping list
        total = Shopping_List_Product.query(
            Shopping_List_Product.user_id == user_id).count()

        products = []
        length = 0
        now = datetime.utcnow()

        for entity in prod_entities:
            # Get product detailed info
            prod_details = label_api.label_array(session_id, entity.barcode)

            if 'productsArray' in prod_details:
                products.append(prod_details['productsArray'][0])
                length += 1
                products[length - 1]['contains'] = []
                products[length - 1]['may_contain'] = []

                # Get nutrient percentage value
                for nutrient in products[length - 1]['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 products[length - 1]['allergens']:
                    if allergen['allergen_value'] == '2':
                        products[length - 1]['contains'].append(
                            allergen['allergen_name'])
                    elif allergen['allergen_value'] == '1':
                        products[length - 1]['may_contain'].append(
                            allergen['allergen_name'])

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

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

            else:
                label_error = True
                break

            # Check if product is on user shopping list
            if Pantry_Product.query(
                    Pantry_Product.user_id == user_id,
                    Pantry_Product.barcode == entity.barcode).get(
                        keys_only=True):
                products[length - 1]['in_pantry'] = 'true'

            # Get time between now when product was added
            products[length -
                     1]['t_delta'] = utils.get_time_delta_str(now -
                                                              entity.added_on)

        pages = get_pages(start, total)

        return render_to_response(
            'user_shopping_list.html', {
                'products': products,
                'products_len': len(products),
                'total': total,
                'start': start,
                'pages': pages,
                'label_error': label_error,
            }, RequestContext(request))

    return redirect('/signin')
Beispiel #13
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
Beispiel #14
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')
Beispiel #15
0
def user_shopping_list(request):
    """
    Returns the user shopping list
    """
    user_id = crypto.decrypt(request.COOKIES['euid']) if 'euid' in request.COOKIES else None
    session_id = request.get_signed_cookie('session_id', default=None)
    
    if user_id and session_id:
        user = User.get_by_id(user_id)
        start = request.GET.get('start', '0')
        label_error = False

        try:
            start = int(start)
        except ValueError:
            start = 0

        # Get shopping list products by user_id        
        prod_entities = Shopping_List_Product.query(
            Shopping_List_Product.user_id == user_id).order(
                -Shopping_List_Product.added_on).fetch(limit=5, offset=start)

        # Get total number of shopping list
        total = Shopping_List_Product.query(Shopping_List_Product.user_id == user_id).count()

        products = []
        length = 0
        now = datetime.utcnow()

        for entity in prod_entities:
            # Get product detailed info
            prod_details = label_api.label_array(session_id, entity.barcode)

            if 'productsArray' in prod_details:
                products.append(prod_details['productsArray'][0])
                length += 1
                products[length-1]['contains'] = []
                products[length-1]['may_contain'] = []

                # Get nutrient percentage value
                for nutrient in products[length-1]['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 products[length-1]['allergens']:
                    if allergen['allergen_value'] == '2':
                        products[length-1]['contains'].append(allergen['allergen_name'])
                    elif allergen['allergen_value'] == '1':
                        products[length-1]['may_contain'].append(allergen['allergen_name'])

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

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

            else:
                label_error=True
                break

            # Check if product is on user shopping list
            if Pantry_Product.query(
                    Pantry_Product.user_id == user_id,
                    Pantry_Product.barcode == entity.barcode
            ).get(keys_only=True):
                products[length-1]['in_pantry'] = 'true'

            # Get time between now when product was added
            products[length-1]['t_delta'] = utils.get_time_delta_str(now - entity.added_on)

        pages = get_pages(start, total)

        return render_to_response(
            'user_shopping_list.html',
            {
                'products': products,
                'products_len': len(products),
                'total': total,
                'start': start,
                'pages': pages,
                'label_error': label_error,
            },
            RequestContext(request))

    return redirect('/signin')
Beispiel #16
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