Source

find-gift / controllers / __init__.py

Full commit
import cPickle
import settings
import memcache
import logging
import urllib
import simplejson
import hmac
import base64
import hashlib
import datetime

from models import User
from tornado.web import RequestHandler
from sqlalchemy import orm, create_engine

engine = create_engine(settings.DATABASE_DSN)
Session = orm.sessionmaker(bind=engine)()

Memcached = memcache.Client(
    settings.MEMCACHED_SERVERS,
    debug=settings.MEMCACHED_DEBUG
)


def get_age(date_of_birth):

    logging.info('date_of_birth: %s' % date_of_birth)
    tmp = None

    try:

        date_of_birth = datetime.datetime.strptime(
            date_of_birth, '%d/%m/%Y').date()

        if date_of_birth > datetime.date.today().replace(
                year=date_of_birth.year):
            tmp = datetime.date.today().year - date_of_birth.year - 1
        else:
            tmp = datetime.date.today().year - date_of_birth.year

    except Exception as exc:
        logging.error(exc)

    return tmp


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


class BaseHandler(RequestHandler):

    def __init__(self, *args, **kwargs):
        super(BaseHandler, self).__init__(*args, **kwargs)

    @property
    def user_data_facebook(self):

        cookie = self.get_secure_cookie('user')

        if not cookie:
            return None
        else:
            return cPickle.loads(cookie)

    def get_current_user(self):

        cookie = self.get_secure_cookie('user')

        if not cookie:
            return None
        else:

            try:
                cookie_user = cPickle.loads(cookie)
            except Exception as exc:
                logging.error(exc)
                return None
            else:

                return Session.query(User).filter_by(
                    fbid=cookie_user.get('user_id')).first()

    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 Facebook(object):

    def window_location(self, redirect):

        url = '%s%s' % (
            settings.FACEBOOK_CANVAS_PAGE,
            redirect
        )

        return "<script>window.top.location='%s'</script>" % url

    def window_authorize_location(self, redirect=None):

        url = '%s%s%s' % (
            settings.FACEBOOK_CANVAS_PAGE,
            'authorize/',
            redirect
        )

        return "<script>window.top.location='%s'</script>" % url

    def authorize_permission(self, redirect, state):

        permissions = (
            'email',
            'friends_likes',
            'friends_activities',
            'friends_interests',
            'friends_birthday',
            'read_stream',
            'user_birthday'
        )

        params = dict(
            client_id=settings.FACEBOOK_API_KEY,
            redirect_uri='%sauthorize/%s' % (
                settings.FACEBOOK_CANVAS_PAGE, redirect),
            scope=','.join(permissions),
            state=state
        )

        url = '%s?%s' % (settings.FACEBOOK_OAUTH, urllib.urlencode(params))
        return "<script>window.top.location='%s'</script>" % url

    def parse_signed_request(self, 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 get_access_token_code(self, code, redirect):

        params = dict(
            client_id=settings.FACEBOOK_API_KEY,
            client_secret=settings.FACEBOOK_API_SECRET,
            code=code,
            redirect_uri='%sauthorize/%s' % (
                settings.FACEBOOK_CANVAS_PAGE, redirect)
        )

        try:
            data = urllib.urlopen('%s?%s' % (
                settings.FACEBOOK_ACCESS_TOKEN,
                urllib.urlencode(params))
            ).read()

            return data.split('&')[0][len('access_token') + 1:]

        except Exception as exc:
            logging.error(exc)
            return None

    def get_access_token(self, access_token):

        params = dict(
            client_id=settings.FACEBOOK_API_KEY,
            client_secret=settings.FACEBOOK_API_SECRET,
            grant_type='fb_exchange_token',
            fb_exchange_token=access_token
        )

        try:
            data = urllib.urlopen('%s?%s' % (
                settings.FACEBOOK_ACCESS_TOKEN,
                urllib.urlencode(params))
            ).read()

            return data.split('&')[0][len('access_token') + 1:]

        except Exception as exc:
            logging.error(exc)
            return None

    def get_info(self, access_token, user_id):

        params = dict(
            access_token=access_token,
            fields='email,birthday,gender,name'
        )

        url = '%s/%s' % (settings.FACEBOOK_GRAPH, user_id)

        try:
            data = urllib.urlopen('%s?%s' % (
                url, urllib.urlencode(params))).read()
            return simplejson.loads(data)

        except Exception as exc:
            logging.error(exc)
            return None

    def get_friends(self, access_token, user_id, limit, page):

        def pagination(limit, page):

            if page.isdigit():
                page = int(page)
            else:
                page = 1

            offset = ((page - 1) * limit)

            return (limit, offset)

        limit, offset = pagination(limit, page)

        print offset

        params = dict(
            access_token=access_token,
            fields='name',
            limit=limit,
            offset=offset
        )

        url = '%s/%s/friends' % (settings.FACEBOOK_GRAPH, user_id)

        try:
            data = urllib.urlopen('%s?%s' % (
                url, urllib.urlencode(params))).read()
            return simplejson.loads(data)

        except Exception as exc:
            logging.error(exc)
            return None

    def search_in_wall_keys(self, access_token, friend_id, search_items):

        def sql_multiquery_kwords(friend_id, search_items):

            q = None
            tmp_queries = []

            for x in search_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))

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

                logging.info('q: %s' % q)

            return {'q': q, 'tmp_queries': tmp_queries}

        q = sql_multiquery_kwords(friend_id, search_items)

        if not q.get('tmp_queries'):
            return None
        else:
            params = dict(
                q=q.get('q'),
                access_token=access_token
            )

            url = '%s/fql' % settings.FACEBOOK_GRAPH

            logging.info('%s?%s' % (
                    url, urllib.urlencode(params)))

            try:
                data = urllib.urlopen('%s?%s' % (
                    url, urllib.urlencode(params))).read()
                return simplejson.loads(data)

            except Exception as exc:
                logging.error(exc)
                return None

    def search_im_profile(self, access_token, friend_id, search_items=None):

        keywords = []

        def tags(connector, access_token, url=None):

            if not url:

                params = dict(
                    access_token=access_token,
                    fields='name',
                    limit=50
                )

                url = '%s/%s/%s?%s' % (
                    settings.FACEBOOK_GRAPH,
                    friend_id,
                    connector,
                    urllib.urlencode(params)
                )

            logging.info('url: %s' % url)

            try:
                data = simplejson.loads(urllib.urlopen(url).read())
            except IOError as exc:
                logging.info(exc)
                #tags(connector, friend_id, access_token)
            else:

                items = data.get('data')

                if items:

                    for x in items:
                        keywords.append(x['name'].lower().split(' '))

                    paging = data.get('paging')

                    if 'next' in paging:
                        tags(
                            connector,
                            access_token,
                            paging.get('next')
                        )

        connectors = (
            'books',
            'games',
            'likes',
            'music',
            'movies',
            'interests',
            'television',
            'activities'
        )

        for connector in connectors:
            tags(connector, access_token)

        data3 = []
        for x in keywords:
            for y in x:
                if not y in data3 or y != '':
                    data3.append(y)

        return data3