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, Facebook, get_age

facebook = Facebook()

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))


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):

        #Memcached.delete('509300321')
        user = self.current_user
        data = facebook.get_info(user.access_token, friend_id)
        data2 = facebook.search_im_profile(user.access_token, friend_id)

        skus = Session.query(Gift.sku).filter(
            Gift.keywords.in_(','.join(data2))).all()

        if data:

            if 'gender' in data:
                logging.info('set gender: %s' % data.get('gender'))
                self.set_cookie('friend_gender', data.get('gender'))

            if 'birthday' in data:
                user_age = get_age(data.get('birthday'))

                if user_age:
                    logging.info('set age: %s' % user_age)
                    self.set_cookie('friend_age', user_age)

        skus = Memcached.get(str(friend_id))

        if not skus:

            data = facebook.search_in_wall_keys(
                user.access_token,
                friend_id,
                Session.query(Gift.sku, Gift.keywords).filter_by(
                    enabled=True).all()
            )

            if data:

                if 'error' in data:
                    if data.get('error').get('type') == 'OAuthException':

                        self.finish(
                            facebook.window_authorize_location('friends'))

                else:

                    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))

        filters = [Gift.enabled == True]

        if skus:
            filters.append(Gift.sku.in_(skus.split(',')))

        user_age = self.get_cookie('friend_age')
        user_gender = self.get_cookie('friend_gender')

        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

        #print user.access_token

        for x in user.gifts:

            friend_data = facebook.get_info(x.friend_id, user.access_token)

            if 'error' in friend_data:
                #logging.info(friend_data.get('error'))
                self.finish(
                    facebook.window_authorize_location('list_friends'))
            else:

                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')