Source

find-gift / controllers / gift.py

Full commit
import logging
import settings

from models import Gift, UserGift
from tornado.web import authenticated

from sqlalchemy.sql import and_, between
from controllers import BaseHandler, Memcached, Session
from controllers.user import window_authorize_location

AGES = (
    ('13-17', '13-17'),
    ('18-24', '18-24'),
    ('25-34', '25-34'),
    ('35-44', '35-44'),
    ('45-54', '45-54'),
    ('55-0', '+55'),
)

GENDERS = (
    ('male', 'Masculino'),
    ('female', 'Femenino')
)

PRICES = (
    ('0-50', 'S/.0-50'),
    ('50-100', 'S/.50-100'),
    ('100-150', 'S/.100-150'),
    ('150-200', 'S/.150-200'),
    ('200-250', 'S/.200-250'),
    ('250-300', 'S/.250-300'),
    ('300-0', 'S/.300+')
)

CATEGORIES = (
    ('perfumeria-maquillaje', 'Perfumeria y Maquillaje'),
    ('mujer', 'Mujer'),
    ('juvenil', 'Juvenil'),
    ('hombre', 'Hombre'),
    ('ninos', 'Ninos'),
    ('oportunidades', 'Oportunidades unicas')
)


def search_btw(field, value):

    left, right = [int(x) for x in value.split('-')]

    if left == 0 and right > 0:
        return (field <= right)
    elif left > 0 and right == 0:
        return (field >= left)
    else:
        return (between(field, left, right))


def sql_multiquery_kwords(friend_id, items):

    tmp_queries = []

    for x in items:

        sku = x.sku
        keywords = x.keywords.split(',')

        kwors = ''
        tmp_keywords_sql = []

        for k in keywords:

            tmp_keywords_sql.append(
                "strpos(lower(message), '%s') >= 0" % k.lower())

        if tmp_keywords_sql:
            kwors = ' or '.join(tmp_keywords_sql)
            kwors = ' and (%s)' % kwors

        tmp_queries.append(
            '"%s": "select uid from status where uid=%s %s"' % (
                sku, friend_id, kwors))

    url = ','.join(tmp_queries)
    q = '{%s}' % url

    return q


class Add(BaseHandler):

    @authenticated
    def post(self):

        user = self.current_user
        friend_id = self.get_argument('friend_id', None)
        gift_id = self.get_argument('gift_id', None)

        if not friend_id or not gift_id:
            logging.error('no data')

        else:

            gift = Session.query(Gift).filter(Gift.id == gift_id).first()

            if not gift:
                logging.error('not gift')

            else:

                item = Session.query(UserGift).filter(and_(
                            UserGift.user_id == user.id,
                            UserGift.gift_id == gift.id,
                            UserGift.friend_id == friend_id
                        )).first()

                if not item:

                    try:

                        user_gift = UserGift()
                        user_gift.friend_id = friend_id
                        user_gift.gift = gift
                        user_gift.user = user
                        user.gifts.append(user_gift)
                        Session.add(user)
                        Session.commit()

                    except Exception as exc:
                        Session.rollback()
                        logging.error(exc)
                    else:
                        logging.info('save gift')

                else:
                    logging.info('exists')


class Find(BaseHandler):

    @authenticated
    def get(self, friend_id, **kwargs):

        user = self.current_user
        skus = Memcached.get(str(friend_id))

        if not skus:

            q = sql_multiquery_kwords(
                friend_id,
                Session.query(Gift.sku, Gift.keywords).filter_by(
                    enabled=True).all()
            )

            params = dict(
                q=q,
                access_token=user.access_token
            )

            data = self.load_data_url(
                url='%s/fql' % settings.FACEBOOK_GRAPH,
                params=params,
                json=True
            )

            if 'error' in data:
                if data.get('error').get('type') == 'OAuthException':
                    self.finish(window_authorize_location('friends'))

            skus = [str(x.get('name')) for x in data.get('data') \
                if x.get('fql_result_set')]

            Memcached.set(str(friend_id), ','.join(skus))

        self.render('detail.html',
            user=user,
            ages=AGES,
            prices=PRICES,
            genders=GENDERS,
            categories=CATEGORIES,
            friend_id=friend_id,
            **kwargs
        )

    @authenticated
    def post(self, friend_id):

        user = self.current_user

        price = self.get_argument('price', None)
        category = self.get_argument('category', None)
        age = self.get_argument('age', None)
        gender = self.get_argument('gender', None)

        logging.info('price: %s' % price)
        logging.info('gender: %s' % gender)
        logging.info('category: %s' % category)
        logging.info('age: %s' % age)
        logging.info('user_age: %s' % user.age)
        logging.info('user_gender: %s' % user.gender)

        skus = Memcached.get(str(friend_id)).split(',')

        filters = [Gift.enabled == True, Gift.sku.in_(skus)]

        if user.age:
            filters.append(Gift.age == user.age)
        else:
            if age:
                filters.append(search_btw(Gift.age, age))

        if price:
            filters.append(search_btw(Gift.price, price))

        if category:
            filters.append(Gift.category == category)

        if user.gender:
            filters.append(Gift.gender == user.gender)
        else:
            if gender:
                filters.append(Gift.gender == gender)

        items = Session.query(
            Gift.id,
            Gift.title,
            Gift.price,
            Gift.stores,
            Gift.category
        ).filter(*filters).all()

        data_post = dict(
            price=price,
            category=category,
            age=age,
            gender=gender
        )

        self.get(friend_id, items=items, **data_post)


class List(BaseHandler):

    def check_xsrf_cookie(self):
        pass

    @authenticated
    def post(self):

        data = {}
        gifts = []
        user = self.current_user

        for x in user.gifts:

            friend_data = self.load_data_url(
                url='%s/%s' % (settings.FACEBOOK_GRAPH, x.friend_id),
                params={'access_token': user.access_token,
                    'fields': 'name'},
                json=True
            )

            gifts.append({x.friend_id: x.gift})

            data[x.friend_id] = dict(
                friend=dict(
                    id=friend_data.get('id'),
                    name=friend_data.get('name'),
                    image='%s%s/picture?type=large' % (
                        settings.FACEBOOK_GRAPH,
                        x.friend_id)
                ),
                gifts=[y.values()[0] for y in gifts if x.friend_id in y]
            )

        self.render('list.html', data=data.values())


class Delete(BaseHandler):

    @authenticated
    def post(self):

        user = self.current_user
        friend_id = self.get_argument('friend_id', None)
        gift_id = self.get_argument('gift_id', None)

        if not friend_id:
            logging.error('not data')
        else:
            filters = []
            filters.append(UserGift.user_id == user.id)
            filters.append(UserGift.friend_id == friend_id)

            if gift_id:
                if Session.query(Gift).filter(Gift.id == gift_id).first():
                    filters.append(UserGift.gift_id == gift_id)

            item = Session.query(UserGift).filter(*filters)

            if not item.first():
                logging.error('not item')

            else:

                try:
                    item.delete()
                except Exception as exc:
                    logging.error(exc)
                else:
                    logging.info('item deleted')