/controller.py
Python | 477 lines | 448 code | 27 blank | 2 comment | 6 complexity | 7eb21355b5a4d8622c42adfdb9dc3863 MD5 | raw file
- import hmac
- import urllib
- import base64
- import hashlib
- import logging
- import settings
- import simplejson
- import tasks
- import cPickle
- import memcache
- from models import Gift, User, UserGift
- from tornado.web import RequestHandler, HTTPError
- from sqlalchemy import create_engine, orm
- from sqlalchemy.sql import and_, between
- engine = create_engine(settings.DATABASE_DSN)
- Session = orm.sessionmaker(bind=engine)()
- mc = memcache.Client(['127.0.0.1:11211'], debug=0)
- AGES = (
- ('13-17', '13-17'),
- ('18-24', '18-24'),
- ('25-34', '25-34'),
- ('35-44', '35-44'),
- ('45-54', '45-54'),
- ('55-0', '+55'),
- )
- GENDER = (
- ('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 pagination(limit, page):
- if not page.isdigit():
- page = int(page)
- else:
- page = 1
- offset = ((page - 1) * limit)
- return (limit, offset)
- def base64_url_decode(inp):
- padding_factor = (4 - len(inp) % 4) % 4
- inp += "=" * padding_factor
- return base64.b64decode(unicode(inp).translate(
- dict(zip(map(ord, u'-_'), u'+/'))))
- def tags(user_id, friend_id, token):
- connectors = (
- 'books',
- 'games',
- 'likes',
- 'music',
- 'movies',
- 'interests',
- 'television',
- 'activities'
- )
- for connector in connectors:
- tasks.tags.delay(user_id, connector, friend_id, token)
- def multiquery_kwords(friend_id, items):
- tmp_queries = []
- for x in items:
- #sku = x.get('sku')
- sku = x.sku
- #keywords = x.get('keywords')
- 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
- def load_data_url(url, params, json=True):
- try:
- data = urllib.urlopen('%s?%s' % (
- url, urllib.urlencode(params))).read()
- if json:
- data = simplejson.loads(data)
- except Exception as exc:
- logging.error(exc)
- data = None
- return data
- def parse_signed_request(signed_request, secret):
- l = signed_request .split('.', 2)
- encoded_sig = l[0]
- payload = l[1]
- sig = base64_url_decode(encoded_sig)
- data = simplejson.loads(base64_url_decode(payload))
- if data.get('algorithm').upper() != 'HMAC-SHA256':
- logging.error('Unknown algorithm')
- return None
- else:
- expected_sig = hmac.new(
- secret, msg=payload, digestmod=hashlib.sha256
- ).digest()
- if sig != expected_sig:
- return None
- else:
- return data
- def js_windows_location(url):
- return "<script>top.location.href='%s'</script>" % url
- class BaseHandler(RequestHandler):
- def __init__(self, *args, **kwargs):
- super(BaseHandler, self).__init__(*args, **kwargs)
- def render_string(self, template, **kwargs):
- kwargs.update({'handler': self})
- return self.settings.get('template_env')\
- .get_template(template).render(**kwargs)
- def render(self, template, **kwargs):
- self.finish(self.render_string(template, **kwargs))
- class Index(BaseHandler):
- def post(self):
- self.clear_cookie('user')
- signed_request = self.get_argument('signed_request', None)
- if signed_request:
- user = parse_signed_request(signed_request, settings.API_SECRET)
- else:
- user = None
- if not user or not 'user_id' in user:
- permissions = (
- 'email',
- 'friends_likes',
- 'friends_activities',
- 'friends_interests',
- 'friends_birthday',
- 'read_stream',
- )
- params = dict(
- client_id=settings.API_KEY,
- redirect_uri=settings.CANVAS_PAGE,
- scope=','.join(permissions)
- )
- url = '%s?%s' % (settings.FACEBOOK_OAUTH, urllib.urlencode(params))
- logging.info('url: %s' % url)
- self.write(js_windows_location(url))
- else:
- data = cPickle.dumps({
- 'user_id': user['user_id'],
- 'access_token': user['oauth_token']
- }, -1)
- self.set_secure_cookie('user', data)
- limit, offset = pagination(9, self.get_argument('page', '1'))
- params = dict(
- access_token=user['oauth_token'],
- fields='picture,name',
- limit=limit,
- offset=offset
- )
- data = load_data_url(
- url='%s/me/friends' % settings.FACEBOOK_GRAPH,
- params=params,
- json=True
- )
- user_data = load_data_url(
- url='%s/%s' % (settings.FACEBOOK_GRAPH, user.get('user_id')),
- params={'access_token': user.get('oauth_token')},
- json=True
- )
- user2 = Session.query(User).filter_by(
- email=user_data.get('email')).first()
- if not user2:
- user2 = User()
- user2.email = user_data.get('email')
- user2.fbid = user_data.get('id')
- Session.add(user2)
- Session.commit()
- self.render('index.html', data=data.get('data'))
- class ListGift(BaseHandler):
- def post(self):
- cookie = self.get_secure_cookie('user')
- if cookie:
- user = cPickle.loads(cookie)
- else:
- user = None
- if not user:
- raise HTTPError(500, "Auth failed")
- user = Session.query(User).filter_by(
- fbid=user.get('user_id')).first()
- self.render('list.html', user=user)
- class AddGift(BaseHandler):
- def post(self):
- cookie = self.get_secure_cookie('user')
- if cookie:
- user = cPickle.loads(cookie)
- else:
- user = None
- if not user:
- raise HTTPError(500, "Auth failed")
- friend_id = self.get_argument('friend_id', None)
- gift_id = self.get_argument('gift_id', None)
- user2 = Session.query(User).filter_by(fbid=user.get('user_id')).first()
- gift2 = Session.query(Gift).filter(Gift.id == gift_id).first()
- exists = Session.query(UserGift).filter(and_(
- UserGift.user_id == user2.id,
- UserGift.gift_id == gift_id,
- UserGift.friend_id == friend_id
- )).first()
- if not exists and gift2 and user2:
- try:
- user_gift = UserGift()
- user_gift.friend_id = friend_id
- user_gift.gift = gift2
- user_gift.user = user2
- user2.gifts.append(user_gift)
- Session.add(user2)
- Session.commit()
- except Exception as exc:
- Session.rollback()
- logging.error(exc)
- else:
- logging.info('exists')
- class FindGift(BaseHandler):
- def get(self, friend_id):
- cookie = self.get_secure_cookie('user')
- mc.delete(str(friend_id))
- if cookie:
- user = cPickle.loads(cookie)
- else:
- user = None
- if not user:
- raise HTTPError(500, "Auth failed")
- items = Session.query(Gift).all()
- params = dict(
- q=multiquery_kwords(friend_id, items),
- access_token=user.get('access_token')
- )
- data = load_data_url(
- url='%s/fql' % settings.FACEBOOK_GRAPH,
- params=params,
- json=True
- )
- skus = []
- for x in data.get('data'):
- if x.get('fql_result_set'):
- skus.append(x.get('name'))
- mc.set(str(friend_id), ','.join([str(x) for x in skus]))
- logging.info(data)
- friend_data = load_data_url(
- url='%s/%s' % (settings.FACEBOOK_GRAPH, friend_id),
- params={'access_token': user.get('access_token')},
- json=True
- )
- if 'birthday' in friend_data:
- has_birthday = True
- else:
- has_birthday = True
- if 'gender' in friend_data:
- has_gender = False
- else:
- has_gender = True
- logging.info(friend_data)
- self.render('detail.html',
- ages=AGES,
- prices=PRICES,
- gender=GENDER,
- categories=CATEGORIES,
- has_birthday=has_birthday,
- has_gender=has_gender,
- friend_id=friend_id
- )
- def post(self, friend_id):
- cookie = self.get_secure_cookie('user')
- if cookie:
- user = cPickle.loads(cookie)
- else:
- user = None
- if not user:
- raise HTTPError(500, "Auth failed")
- price = self.get_argument('price', None)
- gender = self.get_argument('gender', None)
- category = self.get_argument('category', None)
- age = self.get_argument('age', None)
- price = '50-100'
- gender = 'male'
- category = 'oportunidades'
- age = '13-17'
- logging.info('price: %s' % price)
- logging.info('gender: %s' % gender)
- logging.info('category: %s' % category)
- logging.info('age: %s' % age)
- has_birthday = True
- has_gender = False
- skus = mc.get(str(friend_id)).split(',')
- filters = [Gift.sku.in_(skus)]
- if age:
- left, right = [int(x) for x in age.split('-')]
- if left == 0 and right > 0:
- filters.append(Gift.age <= right)
- elif left > 0 and right == 0:
- filters.append(Gift.age >= left)
- else:
- filters.append(between(Gift.age, left, right))
- if price:
- left, right = [int(x) for x in price.split('-')]
- if left == 0 and right > 0:
- filters.append(Gift.price <= right)
- elif left > 0 and right == 0:
- filters.append(Gift.price >= left)
- else:
- filters.append(between(Gift.price, left, right))
- if category:
- filters.append(Gift.category == category)
- if gender:
- filters.append(Gift.gender == gender)
- items = Session.query(Gift).filter(*filters).all()
- logging.info(items)
- self.render('detail.html',
- ages=AGES,
- prices=PRICES,
- gender=GENDER,
- categories=CATEGORIES,
- has_birthday=has_birthday,
- has_gender=has_gender,
- items=items,
- friend_id=friend_id
- )