Exemple #1
0
 def get(self):
     self.response.headers['Content-Type'] = 'text/plain'
     access_token = None
     real_key = self.request.get('key')
     if not real_key:
         fb_uid = self.request.get('fb_uid')
         fbl = fb_api.FBLookup(fb_uid, access_token)
         fbtype_lookup = {
             'OBJ_PROFILE': fb_api.LookupProfile,
             'OBJ_USER': fb_api.LookupUser,
             'OBJ_USER_EVENTS': fb_api.LookupUserEvents,
             'OBJ_EVENT': fb_api.LookupEvent,
             'OBJ_EVENT_MEMBERS': fb_api.LookupEventMembers,
             'OBJ_THING_FEED': fb_api.LookupThingCommon,
             'OBJ_THING_USER': fb_api.LookupThingUser,
             'OBJ_THING_GROUP': fb_api.LookupThingGroup,
             'OBJ_THING_PAGE': fb_api.LookupThingPage,
         }
         req_type = self.request.get('type')
         if req_type in fbtype_lookup:
             fbtype = fbtype_lookup[req_type]
         else:
             self.response.out.write('type %s  must be one of %s' %
                                     (req_type, fbtype_lookup.keys()))
             return
         key = fb_api.generate_key(fbtype, self.request.get('arg'))
         real_key = fbl.key_to_cache_key(key)
     memcache_result = memcache.get(real_key)
     db_result = fb_api.FacebookCachedObject.get_by_key_name(real_key)
     if not db_result:
         self.response.set_status(404)
         return
     self.response.out.write('Database Date:\n%s\n\n' %
                             db_result.date_cached)
     self.response.out.write('Memcache:\n%s\n\n' %
                             pprint.pformat(memcache_result, width=200))
     self.response.out.write('Database:\n%s\n\n' % pprint.pformat(
         db_result and db_result.decode_data() or None, width=200))
     self.response.out.write('MemcacheJSON:\n%s\n\n' %
                             json.dumps(memcache_result))
     self.response.out.write(
         'DatabaseJSON:\n%s\n\n' %
         json.dumps(db_result and db_result.decode_data() or None))
def _facebook_weekly_post(db_auth_token, city_data):
    city_key = city_data['city']

    city = cities.City.get_by_key_name(city_key)
    page_id = db_auth_token.token_nickname
    fbl = fb_api.FBLookup(None, db_auth_token.oauth_token)

    d = datetime.date.today()
    week_start = d - datetime.timedelta(
        days=d.weekday())  # round down to last monday

    search_results = _generate_results_for(city, week_start)
    if len(search_results) < 2:
        return {}

    # Generate image on GCS
    image_url = weekly_images.build_and_cache_image(city, week_start,
                                                    search_results)

    # Generate the weekly text post
    message = _generate_post_for(city, week_start, search_results)

    # Can't upload image to FB Page...as the uploaded photo then becomes un-animated
    # So instead lets link to the image from our FB post

    # Now post to FB Feed about it
    post_values = {
        'message': message,
        'link': image_url,
    }
    feed_targeting = get_city_targeting_data(fbl, city)
    if feed_targeting:
        # Ideally we'd do this as 'feed_targeting', but Facebook appears to return errors with that due to:
        # {u'error': {u'message': u'Invalid parameter', u'code': 100, u'is_transient': False,
        #  u'error_user_title': u'Invalid Connection', u'error_subcode': 1487124, u'type': u'FacebookApiException',
        #  u'error_user_msg': u'You can only specify connections to objects you are an administrator or developer of.',
        #  u'error_data': {u'blame_field': u'targeting'}}}
        post_values['targeting'] = json.dumps(feed_targeting)
    logging.info("FB Feed Post Values: %s", post_values)
    endpoint = 'v2.9/%s/feed' % page_id
    result = fbl.fb.post(endpoint, None, post_values)
    logging.info('Post Result for %s: %s', city.display_name(), result)
    return result
    def post(self):
        if self.json_body['scrapinghub_key'] != keys.get('scrapinghub_key'):
            self.response.status = 403
            return

        fb_uid = '701004'
        user = users.User.get_by_id(fb_uid)
        fbl = fb_api.FBLookup(fb_uid, user.fb_access_token)

        for event_url in self.json_body['events']:
            logging.info('Adding %s', event_url)
            event_id = urls.get_event_id_from_url(event_url)
            if not event_id:
                logging.warning('Not a valid fb event for adding: %s', event_url)
                continue
            fb_event = fbl.get(fb_api.LookupEvent, event_id, allow_cache=False)
            try:
                add_entities.add_update_event(fb_event, fbl, creating_method=eventdata.CM_AUTO_WEB)
            except add_entities.AddEventException:
                logging.exception('Error adding event %s', event_id)
def create_user(user_id='701004',
                access_token='Access Token',
                access_token_expires=None,
                location='NYC'):
    fields_str = '%2C'.join(fb_api.OBJ_USER_FIELDS)
    base_url = '/v2.2/%s' % user_id
    url = '%s?fields=%s' % (base_url, fields_str)

    fb_api.FBAPI.results.update({
        url: (200, {
            'id': user_id,
            'name': 'Test User',
            'email': '*****@*****.**'
        }),
        '%s/events?since=yesterday&fields=id,rsvp_status' % base_url: (200, {
            "data": {},
        }),
        '%s/friends' % base_url: (200, {}),
        '%s/permissions' % base_url: (200, {}),
    })

    existing_user = users.User.get_by_id(user_id)
    assert not existing_user, "Found user: %s" % existing_user

    if not access_token_expires:
        access_token_expires = datetime.datetime.now() + datetime.timedelta(
            days=60)

    client = 'test'

    fbl = fb_api.FBLookup(None, None)
    fb_user = fbl.get(fb_api.LookupUser, user_id)

    user = user_creation.create_user_with_fbuser(user_id,
                                                 fb_user,
                                                 access_token,
                                                 access_token_expires,
                                                 location,
                                                 send_email=True,
                                                 client=client)
    return user
Exemple #5
0
def function_migrate_thing_to_new_id(fbapi_obj, old_source_id, new_source_id):
    old_source = thing_db.Source.get_by_key_name(old_source_id)

    # Maybe we got two of these and it already ran in parallel, so ignore this one
    if not old_source:
        return

    fbl = fb_api.FBLookup(None, fbapi_obj.access_token_list)

    fbl.fb.raise_on_page_redirect = True
    try:
        results = fbl.get(fb_api.LookupThingCommon, new_source_id)
    except fb_api.PageRedirectException as e:
        # If our forwarding address in turn has its own forwarding address,
        # repoint the old thing further down the chain
        deferred.defer(function_migrate_thing_to_new_id, fbl.fb, old_source_id,
                       e.to_id)
        return

    new_source = thing_db.create_source_from_id(fbl, new_source_id)
    new_source.creating_fb_uid = new_source.creating_fb_uid or old_source.creating_fb_uid
    new_source.creation_time = new_source.creation_time or old_source.creation_time
    new_source.last_scrape_time = new_source.last_scrape_time or old_source.last_scrape_time

    new_source.num_all_events = (new_source.num_all_events
                                 or 0) + (old_source.num_all_events or 0)
    new_source.num_potential_events = (new_source.num_potential_events
                                       or 0) + (old_source.num_potential_events
                                                or 0)
    new_source.num_real_events = (new_source.num_real_events
                                  or 0) + (old_source.num_real_events or 0)
    new_source.num_false_negatives = (new_source.num_false_negatives or 0) + (
        old_source.num_false_negatives or 0)

    # Who has pointers to sources??
    migrate_potential_events(old_source_id, new_source_id)

    new_source.put()
    old_source.delete()
    def handle_alternate_login(self, request):
        # If the mobile app sent the user to a /....?uid=XX&access_token_md5=YY URL,
        # then let's verify the parameters, and log the user in as that user
        if request.get('uid'):
            if request.get('access_token'):
                fbl = fb_api.FBLookup(request.get('uid'),
                                      request.get('access_token'))
                fb_user = fbl.get(fb_api.LookupUser, 'me')
                logging.info("Requested /me with given access_token, got %s",
                             fb_user)

                if fb_user['profile']['id'] == request.get('uid'):
                    user = users.User.get_by_id(request.get('uid'))
                    access_token_md5 = hashlib.md5(
                        user.fb_access_token).hexdigest()
                    self.set_login_cookie(request.get('uid'),
                                          access_token_md5=access_token_md5)
            if request.get('access_token_md5'):
                user = users.User.get_by_id(request.get('uid'))
                if user and request.get('access_token_md5') == hashlib.md5(
                        user.fb_access_token).hexdigest():
                    # Authenticated! Now save cookie so subsequent requests can trust that this user is authenticated.
                    # The subsequent request will see a valid user_login param (though without an fb_cookie_uid)
                    self.set_login_cookie(
                        request.get('uid'),
                        access_token_md5=self.request.get('access_token_md5'))
            # But regardless of whether the token was correct, let's redirect and get rid of these url params.
            current_url_args = {}
            for arg in sorted(self.request.GET):
                if arg in ['uid', 'access_token', 'access_token_md5']:
                    continue
                current_url_args[arg] = self.request.GET.getall(arg)
            final_url = self.request.path + '?' + urls.urlencode(
                current_url_args, doseq=True)
            # Make sure we immediately stop running the initialize() code if we return a URL here
            return final_url
        else:
            return False
Exemple #7
0
    def setup_login_state(self, request):
        #TODO(lambert): change fb api to not request access token, and instead pull it from the user
        # only request the access token from FB when it's been longer than a day, and do it out-of-band to fetch-and-update-db-and-memcache

        self.fb_uid = None
        self.user = None
        self.access_token = None

        if len(request.get_all('nt')) > 1:
            logging.error('Have too many nt= parameters, something is Very Wrong!')
            for k, v in request.cookies.iteritems():
                logging.info("DEBUG: cookie %r = %r", k, v)
        # Load Facebook cookie
        try:
            response = facebook.parse_signed_request_cookie(request.cookies)
        except Cookie.CookieError:
            logging.exception("Error processing cookie: %s")
            return
        fb_cookie_uid = None
        if response:
            fb_cookie_uid = response['user_id']
        logging.info("fb cookie id is %s", fb_cookie_uid)

        # Normally, our trusted source of login id is the FB cookie,
        # though we may override it below in the case of access_token_md5
        trusted_cookie_uid = fb_cookie_uid

        # for k, v in self.request.cookies.iteritems():
        #     logging.info('cookie %s = %s', k, v)

        # Load our dancedeets logged-in user/state
        our_cookie_uid = None
        user_login_string = self.get_login_cookie()
        if user_login_string:
            user_login_cookie = json.loads(urllib.unquote(user_login_string))
            logging.info("Got login cookie: %s", user_login_cookie)
            if validate_hashed_userlogin(user_login_cookie):
                our_cookie_uid = user_login_cookie['uid']
                # If we have a browser cookie that's verified via access_token_md5,
                # so let's trust it as authoritative here and ignore the fb cookie
                if not trusted_cookie_uid and user_login_cookie.get('access_token_md5'):
                    trusted_cookie_uid = our_cookie_uid
                    logging.info("Validated cookie, logging in as %s", our_cookie_uid)

        if self.request.cookies.get('user_login', ''):
            logging.info("Deleting old-style user_login cookie")
            self.response.set_cookie('user_login', '', max_age=0, path='/', domain=self._get_login_cookie_domain())

        # If the user has changed facebook users, let's automatically re-login at dancedeets
        if trusted_cookie_uid and trusted_cookie_uid != our_cookie_uid:
            self.set_login_cookie(trusted_cookie_uid)
            our_cookie_uid = trusted_cookie_uid

        # Don't force-logout the user if there is a our_cookie_uid but not a trusted_cookie_uid
        # The fb cookie probably expired after a couple hours, and we'd prefer to keep our users logged-in

        # Logged-out view, just return without setting anything up
        if not our_cookie_uid:
            return

        self.fb_uid = our_cookie_uid
        self.user = users.User.get_by_id(self.fb_uid)

        # If we have a user, grab the access token
        if self.user:
            if trusted_cookie_uid:
                # Long-lived tokens should last "around" 60 days, so let's refresh-renew if there's only 40 days left
                if self.user.fb_access_token_expires:
                    token_expires_soon = (self.user.fb_access_token_expires - datetime.datetime.now()) < datetime.timedelta(days=40)
                else:
                    # These are either infinite-access tokens (which won't expire soon)
                    # or they are ancient tokens (in which case, our User reload mapreduce has already set user.expired_oauth_token)
                    token_expires_soon = False
                # Update the access token if necessary
                if self.user.expired_oauth_token or token_expires_soon or self.request.get('update_fb_access_token'):
                    try:
                        access_token, access_token_expires = self.get_long_lived_token_and_expires(request)
                    except TypeError:
                        logging.info("Could not access cookie ")
                    except facebook.AlreadyHasLongLivedToken:
                        logging.info("Already have long-lived token, FB wouldn't give us a new one, so no need to refresh anything.")
                    else:
                        logging.info("New access token from cookie: %s, expires %s", access_token, access_token_expires)
                        if access_token:
                            self.user = users.User.get_by_id(self.fb_uid)
                            self.user.fb_access_token = access_token
                            self.user.fb_access_token_expires = access_token_expires
                            self.user.expired_oauth_token = False
                            self.user.expired_oauth_token_reason = None
                            # this also sets to memcache
                            self.user.put()
                            logging.info("Stored the new access_token to the User db")
                        else:
                            logging.error("Got a cookie, but no access_token. Using the one from the existing user. Strange!")
                if 'web' not in self.user.clients:
                    self.user = users.User.get_by_id(self.fb_uid)
                    self.user.clients.append('web')
                    self.user.put()
                    logging.info("Added the web client to the User db")
                self.access_token = self.user.fb_access_token
            else:
                self.access_token = self.user.fb_access_token
                logging.info("Have dd login cookie but no fb login cookie")
                if self.user.expired_oauth_token:
                    self.fb_uid = None
                    self.user = None
                    self.access_token = None
                    return
        elif trusted_cookie_uid:
            # if we don't have a user but do have a token, the user has granted us permissions, so let's construct the user now
            try:
                access_token, access_token_expires = self.get_long_lived_token_and_expires(request)
            except facebook.AlreadyHasLongLivedToken:
                logging.warning(
                    "Don't have user, just trusted_cookie_uid. And unable to get long lived token for the incoming request. Giving up and doing logged-out"
                )
                self.fb_uid = None
                self.access_token = None
                self.user = None
                return
            self.access_token = access_token
            # Fix this ugly import hack:
            fbl = fb_api.FBLookup(self.fb_uid, self.access_token)
            fbl.debug = 'fbl' in self.debug_list
            fb_user = fbl.get(fb_api.LookupUser, self.fb_uid)

            referer = self.get_cookie('User-Referer')
            city = self.request.get('city') or self.get_location_from_headers() or get_location(fb_user)
            logging.info("User passed in a city of %r, facebook city is %s", self.request.get('city'), get_location(fb_user))
            ip = ips.get_remote_ip(self.request)
            user_creation.create_user_with_fbuser(
                self.fb_uid, fb_user, self.access_token, access_token_expires, city, ip, send_email=True, referer=referer, client='web'
            )
            # TODO(lambert): handle this MUUUCH better
            logging.info("Not a /login request and there is no user object, constructed one realllly-quick, and continuing on.")
            self.user = users.User.get_by_id(self.fb_uid)
            # Should not happen:
            if not self.user:
                logging.error("We still don't have a user!")
                self.fb_uid = None
                self.access_token = None
                self.user = None
                return
        else:
            # no user, no trusted_cookie_uid, but we have fb_uid from the user_login cookie
            logging.error("We have a user_login cookie, but no user, and no trusted_cookie_uid. Acting as logged-out")
            self.fb_uid = None
            self.access_token = None
            self.user = None
            return

        logging.info("Logged in uid %s with name %s and token %s", self.fb_uid, self.user.full_name, self.access_token)

        # Track last-logged-in state
        hour_ago = datetime.datetime.now() - datetime.timedelta(hours=1)
        if not getattr(self.user, 'last_login_time', None) or self.user.last_login_time < hour_ago:
            # Do this in a separate request so we don't increase latency on this call
            deferred.defer(update_last_login_time, self.user.fb_uid, datetime.datetime.now(), _queue='slow-queue')
            backgrounder.load_users([self.fb_uid], allow_cache=False)
Exemple #8
0
    def runTest(self):
        fbl = fb_api.FBLookup('uid', 'access_token')
        fbl.allow_cache = False

        # Set up our facebook backend
        fb_api.FBAPI.results = {
            URL_111: (200, {
                'id': '111',
                'name': 'page 1',
                'likes': 1
            }),
            '/v2.2/111/feed': (200, {
                'data': []
            }),
            '/v2.2/111/events': (200, {
                'data': []
            }),
            URL_222: (200, {
                'id': '222',
                'name': 'page 2',
                'likes': 1
            }),
            '/v2.2/222/feed': (200, {
                'data': []
            }),
            '/v2.2/222/events': (200, {
                'data': []
            }),
        }

        # Fetch it and construct a source
        result = fbl.get(fb_api.LookupThingFeed, '111')
        source = thing_db.create_source_for_id('111', result)
        source.num_all_events = 5
        source.put()

        source = thing_db.Source.get_by_key_name('111')
        self.assertEquals(source.name, 'page 1')

        self.mark_as_error_and_reload(fbl)

        # Let's verify id 111 no longer exists
        source = thing_db.Source.get_by_key_name('111')

        # Now let's load id 222 and verify it exists
        source = thing_db.Source.get_by_key_name('222')
        # And verify that our data from the first one got carried over
        self.assertEquals(source.num_all_events, 5)
        # But the the remaining data comes from the latest FB values for this page id
        self.assertEquals(source.name, 'page 2')

        # Now let's create 111 again, to verify merge works
        fb_api.FBAPI.results.update({
            URL_111: (200, {
                'id': '111',
                'name': 'page 1',
                'likes': 1
            }),
            '/v2.2/111/feed': (200, {
                'data': []
            }),
        })
        source = thing_db.create_source_for_id('111', result)
        source.num_all_events = 5
        source.put()

        pe = potential_events.PotentialEvent(key_name="333")
        #STR_ID_MIGRATE
        pe.source_ids = [111, 222]
        pe.source_fields = [
            thing_db.GRAPH_TYPE_PROFILE, thing_db.GRAPH_TYPE_PROFILE
        ]
        pe.put()

        self.mark_as_error_and_reload(fbl)

        pe = potential_events.PotentialEvent.get_by_key_name("333")
        #STR_ID_MIGRATE
        self.assertEqual(pe.source_ids, [222])
        self.assertEqual(pe.source_fields, [thing_db.GRAPH_TYPE_PROFILE])
    def initialize(self, request, response):
        super(BaseRequestHandler, self).initialize(request, response)
        self.run_handler = True

        # Redirect from the bare 'dancedeets.com' to the full 'www.dancedeets.com'
        url = urlparse.urlsplit(self.request.url)
        if url.netloc != self._get_full_hostname():
            logging.info("Redirecting from %s to %s: %s", url.netloc,
                         self._get_full_hostname(), self.request.url)
            new_url = urlparse.urlunsplit([
                url.scheme,
                self._get_full_hostname(),
                url.path,
                url.query,
                url.fragment,
            ])
            self.run_handler = False
            self.redirect(new_url, abort=True)
            return
        login_url = self.get_login_url()
        redirect_url = self.handle_alternate_login(request)
        if redirect_url:
            self.run_handler = False
            # We need to run with abort=False here, or otherwise our set_cookie calls don't work. :(
            # Reported in https://github.com/GoogleCloudPlatform/webapp2/issues/111
            self.redirect(redirect_url, abort=False)
            return

        self.setup_login_state(request)

        self.display['attempt_autologin'] = 1
        # If they've expired, and not already on the login page, then be sure we redirect them to there...
        redirect_for_new_oauth_token = (self.user
                                        and self.user.expired_oauth_token)
        if redirect_for_new_oauth_token:
            logging.error(
                "We have a logged in user, but an expired access token. How?!?!"
            )
        # TODO(lambert): delete redirect_for_new_oauth_token codepaths
        # TODO(lambert): delete codepaths that handle user-id but no self.user. assume this entire thing relates to no-user.
        if redirect_for_new_oauth_token or (
                self.requires_login() and (not self.fb_uid or not self.user)):
            # If we're getting a referer id and not signed up, save off a cookie until they sign up
            if not self.fb_uid:
                logging.info("No facebook cookie.")
            if not self.user:
                logging.info("No database user object.")
            if self.user and self.user.expired_oauth_token:
                logging.info("User's OAuth token expired")
                #self.set_cookie('fbsr_' + FACEBOOK_CONFIG['app_id'], '', 'Thu, 01 Jan 1970 00:00:01 GMT')
                #logging.info("clearing cookie %s", 'fbsr_' + FACEBOOK_CONFIG['app_id'])
                self.set_cookie(
                    'User-Message',
                    "You changed your facebook password, so will need to click login again."
                )
            if self.request.get('referer'):
                self.set_cookie('User-Referer', self.request.get('referer'))
            if not self.is_login_page():
                logging.info("Login required, redirecting to login page: %s",
                             login_url)
                self.run_handler = False
                return self.redirect(login_url)
            else:
                self.display[
                    'attempt_autologin'] = 0  # do not attempt auto-login. wait for them to re-login
                self.fb_uid = None
                self.access_token = None
                self.user = None
        # If they have a fb_uid, let's do lookups on that behalf (does not require a user)
        if self.fb_uid:
            allow_cache = bool(int(self.request.get('allow_cache', 1)))
            self.fbl = fb_api.FBLookup(self.fb_uid, self.access_token)
            self.fbl.allow_cache = allow_cache
            # Always look up the user's information for every page view...?
            self.fbl.request(fb_api.LookupUser, self.fb_uid)
        else:
            self.fbl = fb_api.FBLookup(None, None)
        self.fbl.debug = 'fbl' in self.debug_list
        if self.user:
            self.jinja_env.filters[
                'date_only_human_format'] = self.user.date_only_human_format
            self.jinja_env.filters[
                'date_human_format'] = self.user.date_human_format
            self.jinja_env.filters[
                'time_human_format'] = self.user.time_human_format
            self.jinja_env.globals[
                'duration_human_format'] = self.user.duration_human_format
            self.display['messages'] = self.user.get_and_purge_messages()
        else:
            self.jinja_env.filters[
                'date_only_human_format'] = dates.date_only_human_format
            self.jinja_env.filters[
                'date_human_format'] = dates.date_human_format
            self.jinja_env.filters[
                'time_human_format'] = dates.time_human_format
            self.jinja_env.globals[
                'duration_human_format'] = dates.duration_human_format
            self.display['login_url'] = login_url
        self.jinja_env.filters['datetime_format'] = dates.datetime_format

        self.jinja_env.globals['dd_event_url'] = urls.dd_event_url
        self.jinja_env.globals['raw_fb_event_url'] = urls.raw_fb_event_url
        self.jinja_env.globals['dd_admin_event_url'] = urls.dd_admin_event_url
        self.jinja_env.globals[
            'dd_admin_source_url'] = urls.dd_admin_source_url

        self.display['request'] = request
        self.display['app_id'] = facebook.FACEBOOK_CONFIG['app_id']
        self.display['prod_mode'] = self.request.app.prod_mode

        self.display[
            'base_hostname'] = 'dancedeets.com' if self.request.app.prod_mode else 'dev.dancedeets.com'
        self.display['full_hostname'] = self._get_full_hostname()

        self.display['email_suffix'] = ''

        self.display['keyword_tokens'] = [{
            'value': x.public_name
        } for x in event_types.STYLES]
        fb_permissions = 'rsvp_event,email,user_events'
        if self.request.get('all_access'):
            fb_permissions += ',read_friendlists,manage_pages'
        self.display['fb_permissions'] = fb_permissions

        already_used_mobile = self.user and (
            'react-android' in self.user.clients or 'react-ios'
            in self.user.clients or 'android' in self.user.clients
            or 'ios' in self.user.clients or False)
        mobile_platform = mobile.get_mobile_platform(self.request.user_agent)
        show_mobile_promo = not mobile_platform and not already_used_mobile
        self.display['show_mobile_promo'] = show_mobile_promo
        self.display['mobile_platform'] = mobile_platform
        if mobile_platform == mobile.MOBILE_ANDROID:
            self.display['mobile_app_url'] = mobile.ANDROID_URL
        elif mobile_platform == mobile.MOBILE_IOS:
            self.display['mobile_app_url'] = mobile.IOS_URL
        self.display['mobile'] = mobile
        self.display['mobile_show_smartbanner'] = True

        self.display['ip_location'] = self.get_location_from_headers()

        self.display['styles'] = event_types.STYLES
        self.display['us_cities'] = [
            'New York, NY',
            'Los Angeles, CA',
            'San Francisco, CA',
            '',
            'Anaheim, CA',
            'Boston, MA',
            'Chicago, IL',
            'Detroit, MI',
            'Las Vegas, CA',
            'Montreal, Canada',
            'Ottawa, Canada',
            'Philadelphia, PA',
            'Phoenix, AZ',
            'Portland, OR',
            'Sacramento, CA',
            'San Diego, CA',
            'Seattle, WA',
            'Toronto, Canada',
            'Vancouver, Canada',
            'Washington, DC',
        ]
        self.display['eu_cities'] = [
            'Amsterdam, Netherlands',
            'Barcelona, Spain',
            'Berlin, Germany',
            'Bratislava, Slovakia',
            'Brno, Czech Republic',
            'Brussels, Belgium',
            'Copenhagen, Denmark',
            'Frankfurt, Germany',
            'Geneva, Switzerland',
            'Helsinki, Finland',
            'London, UK',
            'Lyon, France',
            'Manchester, United Kingdom',
            'Marseille, France',
            'Milan, Italy',
            'Oslo, Norway',
            'Paris, France',
            'Rome, Italy',
            'Stockholm, Sweden',
            'Vienna, Austria',
            'Warsaw, Poland',
            'Zurich, Switzerland',
        ]
        self.display['other'] = [
            'Argentina',
            'Australia',
            'Brasil: Minas Gerais',
            'Colombia',
            'Hong Kong',
            'India',
            'Japan: Osaka',
            'Japan: Tokyo',
            'Malaysia',
            'New Zealand',
            'Peru',
            'Philippines',
            'Singapore',
            'Taiwan',
        ]

        self.display['deb'] = self.request.get('deb')
        self.display['debug_list'] = self.debug_list
        self.display['user'] = self.user

        webview = bool(request.get('webview'))
        self.display['webview'] = webview
        if webview:
            if bool(request.get('nd', 1)):
                self.display['class_base_template'] = '_new_base_webview.html'
            else:
                self.display['class_base_template'] = '_base_webview.html'
        else:
            if bool(request.get('nd', 1)):
                self.display['class_base_template'] = '_new_base.html'
            else:
                self.display['class_base_template'] = '_base.html'

        self.display.update(rankings.retrieve_summary())
 def setUp(self):
     super(TestClassifier, self).setUp()
     self.fbl = fb_api.FBLookup("dummyid", None)
def facebook_post(auth_token, db_event):
    link = campaign_url(db_event.id, 'fb_feed')
    datetime_string = db_event.start_time.strftime('%s @ %s' % (DATE_FORMAT, TIME_FORMAT))

    page_id = auth_token.token_nickname
    endpoint = 'v2.5/%s/feed' % page_id
    fbl = fb_api.FBLookup(None, auth_token.oauth_token)

    post_values = {}
    # post_values['message'] = db_event.name
    post_values['link'] = link
    post_values['name'] = db_event.name
    post_values['caption'] = datetime_string
    name = _get_posting_user(db_event)

    human_date = db_event.start_time.strftime('%B %-d')
    # TODO: Sometimes we definitely know the City (from a lat/long), but FB doesn't give us a city.
    # Hopefully in the Great Event Location Cleanup, can take care of this...
    if db_event.city:
        location = '%s ' % db_event.city
    else:
        location = ''

    host = ''
    admins = db_event.admins
    if admins:
        admin_ids = [x['id'] for x in admins]
        page_admin_ids = fb_api_util.filter_by_type(fbl, admin_ids, 'page')
        host = text.human_list('@[%s]' % x for x in page_admin_ids)

    # Tag it if we can
    if db_event.venue.get('id'):
        venue = '@[%s]' % db_event.venue.get('id')
    else:
        venue = db_event.location_name

    message = "Hey %sdancers, time to dance! New dance event on %s at %s." % (location, human_date, venue)
    if host and host != venue:
        message += ' Hosted by our friends at %s.' % host
    if name:
        message += ' Thanks to %s for adding it to DanceDeets!' % name
    post_values['message'] = message

    description = db_event.description
    if len(description) > 10000:
        post_values['description'] = description[:9999] + u"…"
    else:
        post_values['description'] = description
    post_values['description'] = post_values['description']
    cover = db_event.largest_cover
    if cover:
        post_values['picture'] = cover['source']
    venue_id = db_event.venue.get('id')
    if venue_id:
        post_values['place'] = venue_id

    feed_targeting = get_targeting_data(fbl, db_event)
    if feed_targeting:
        # Ideally we'd do this as 'feed_targeting', but Facebook appears to return errors with that due to:
        # {u'error': {u'message': u'Invalid parameter', u'code': 100, u'is_transient': False,
        #  u'error_user_title': u'Invalid Connection', u'error_subcode': 1487124, u'type': u'FacebookApiException',
        #  u'error_user_msg': u'You can only specify connections to objects you are an administrator or developer of.',
        #  u'error_data': {u'blame_field': u'targeting'}}}
        post_values['targeting'] = json.dumps(feed_targeting)

    logging.info("FB Feed Post Values: %s", post_values)
    return fbl.fb.post(endpoint, None, post_values)
Exemple #12
0
def facebook_post(auth_token, db_event):
    link = common.campaign_url(db_event, 'fb_feed')
    datetime_string = db_event.start_time.strftime(
        '%s @ %s' % (common.DATE_FORMAT, common.TIME_FORMAT))

    page_id = auth_token.token_nickname
    endpoint = 'v2.9/%s/feed' % page_id
    fbl = fb_api.FBLookup(None, auth_token.oauth_token)

    post_values = {}
    # post_values['message'] = db_event.name
    post_values['link'] = link
    post_values['name'] = db_event.name
    post_values['caption'] = datetime_string
    name = _get_posting_user(db_event)

    human_date = db_event.start_time.strftime('%B %-d')
    # TODO: Sometimes we definitely know the City (from a lat/long), but FB doesn't give us a city.
    # Hopefully in the Great Event Location Cleanup, can take care of this...
    if db_event.city:
        location = db_event.city
    else:
        location = ''

    host = ''
    admins = db_event.admins
    if admins:
        admin_ids = [x['id'] for x in admins]
        page_admin_ids = fb_api_util.filter_by_type(fbl, admin_ids, 'page')
        # TODO: Can I @mention the people here too, like I do as a human? Or does it only work with pages?
        host = text.human_list('@[%s]' % x for x in page_admin_ids)

    # Tag it if we can
    if db_event.venue_id:
        venue = '@[%s]' % db_event.venue_id
    else:
        venue = db_event.location_name

    if not location:
        # Don't want to post events globally...too noisy
        return {}

    params = {
        'location': location,
        'date': human_date,
        'venue': venue,
    }
    messages = [
        'Dancers, are you ready? %(venue)s has an event on %(date)s in %(location)s.',
        'Hello %(location)s dancers, mark your calendars! We just found a new dance event on %(date)s at %(venue)s.',
        'Hey %(location)s dancers, save the date! Look what we found coming up on %(date)s at %(venue)s.',
        'Just posted! We have an upcoming dance event on %(date)s at %(venue)s in %(location)s.',
        'What\'s up %(location)s, there\'s a dance event at %(venue)s on %(date)s.',
    ]
    message = random.choice(messages) % params
    if host and host != venue:
        message += random.choice([
            ' Hosted by our friends at %(host)s.',
            ' Thanks to our buddies at %(host)s for hosting!',
            ' Hitup the awesome %(host)s with any questions you\'ve got!',
        ]) % {
            'host': host
        }
    if name:
        message += random.choice([
            ' Thanks to %(name)s for adding it to DanceDeets!',
            ' And a special thanks to %(name)s, for sharing it with you all on DanceDeets!',
            ' This event brought to you on DanceDeets courtesy of %(name)s!',
        ]) % {
            'name': name
        }
    post_values['message'] = message

    description = db_event.description
    if len(description) > 10000:
        post_values['description'] = description[:9999] + u"…"
    else:
        post_values['description'] = description
    post_values['description'] = post_values['description']
    cover = db_event.largest_cover
    if cover:
        post_values['picture'] = cover['source']
    venue_id = db_event.venue_id
    if venue_id:
        post_values['place'] = venue_id

    feed_targeting = get_targeting_data(fbl, db_event)
    if feed_targeting:
        # Ideally we'd do this as 'feed_targeting', but Facebook appears to return errors with that due to:
        # {u'error': {u'message': u'Invalid parameter', u'code': 100, u'is_transient': False,
        #  u'error_user_title': u'Invalid Connection', u'error_subcode': 1487124, u'type': u'FacebookApiException',
        #  u'error_user_msg': u'You can only specify connections to objects you are an administrator or developer of.',
        #  u'error_data': {u'blame_field': u'targeting'}}}
        post_values['targeting'] = json.dumps(feed_targeting)

    logging.info("FB Feed Post Values: %s", post_values)
    return fbl.fb.post(endpoint, None, post_values)
Exemple #13
0
    def runTest(self):
        fbl = fb_api.FBLookup('uid', 'access_token')

        fields_str = '%2C'.join(fb_api.OBJ_USER_FIELDS)
        url = '/v2.9/uid?fields=%s' % fields_str
        event_url = '/v2.9/uid/events?since=yesterday&fields=id,rsvp_status&limit=3000'

        # Set up our facebook backend
        fb_api.FBAPI.results = {
            url: (200, {}),
            event_url: (200, {}),
            '/v2.9/uid/friends': (200, {}),
            '/v2.9/uid/permissions': (200, {}),
        }
        # And fetching it then populates our memcache and db
        result = fbl.get(fb_api.LookupUser, 'uid')
        self.assertEqual(
            result, {
                'empty': None,
                'friends': {},
                'permissions': {},
                'profile': {},
                'rsvp_for_future_events': {},
            })

        # Now remove our facebook backend, and test all our caches

        fb_api.FBAPI.results = {}
        fbl.clear_local_cache()

        # Check that if allow_cache=False, we cannot fetch anything
        fbl.allow_cache = False
        self.assertRaises(fb_api.NoFetchedDataException, fbl.get,
                          fb_api.LookupUser, 'uid')
        fbl.allow_cache = True

        # Rely on memcache/dbcache to fulfill this request now
        fbl.clear_local_cache()
        result = fbl.get(fb_api.LookupUser, 'uid')
        self.assertEqual(
            result, {
                'empty': None,
                'friends': {},
                'permissions': {},
                'profile': {},
                'rsvp_for_future_events': {},
            })

        # Clear memcache...
        user_key = (fb_api.LookupUser, '"uid"')
        fbl.m.invalidate_keys([user_key])
        fbl.clear_local_cache()

        # Check that fetching with allow_db_cache=False, fails
        fbl.allow_dbcache = False
        self.assertRaises(fb_api.NoFetchedDataException, fbl.get,
                          fb_api.LookupUser, 'uid')
        fbl.allow_dbcache = True

        # But allowing db cache still works (and repopulates memcache)
        result = fbl.get(fb_api.LookupUser, 'uid')
        self.assertEqual(
            result, {
                'empty': None,
                'friends': {},
                'permissions': {},
                'profile': {},
                'rsvp_for_future_events': {},
            })

        # Clear dbcache, but still can work (because of memcache)
        fbl.db.invalidate_keys([user_key])
        fbl.clear_local_cache()

        # Without allowing memcache read, it fails
        fbl.allow_memcache_read = False
        self.assertRaises(fb_api.NoFetchedDataException, fbl.get,
                          fb_api.LookupUser, 'uid')
        fbl.allow_memcache_read = True

        # But with memcache read, it works fine
        result = fbl.get(fb_api.LookupUser, 'uid')
        self.assertEqual(
            result, {
                'empty': None,
                'friends': {},
                'permissions': {},
                'profile': {},
                'rsvp_for_future_events': {},
            })

        # Clear memcache, now that db is empty, data is entirely gone, and it no longer works
        fbl.m.invalidate_keys([user_key])
        fbl.clear_local_cache()
        self.assertRaises(fb_api.NoFetchedDataException, fbl.get,
                          fb_api.LookupUser, 'uid')
Exemple #14
0
    def runTest(self):
        fbl = fb_api.FBLookup('uid', 'access_token')
        fbl.allow_cache = False

        # Set up our facebook backend
        fields_str = '%2C'.join(fb_api.OBJ_EVENT_FIELDS)
        url = '/v2.9/eid?fields=%s' % fields_str

        picture_url = '/v2.9/eid/picture?redirect=false&type=large'
        # Inaccessible event
        fb_api.FBAPI.results = {
            url: (400, {
                "error": {
                    "message": "Unsupported get request.",
                    "type": "GraphMethodException",
                    "code": 100
                }
            }),
            picture_url: (400, {
                "error": {
                    "message": "Unsupported get request.",
                    "type": "GraphMethodException",
                    "code": 100
                }
            }),
        }

        result = fbl.get(fb_api.LookupEvent, 'eid')
        self.assertEqual(result['empty'],
                         fb_api.EMPTY_CAUSE_INSUFFICIENT_PERMISSIONS)
        fbl.clear_local_cache()

        # Partial timeout of optional field
        fb_api.FBAPI.results = {
            url: (200, {
                'id': 'eid'
            }),
            '/?fields=images&ids=%7Bresult%3Dinfo%3A%24.cover.id%7D':
            fb_api_stub.RESULT_TIMEOUT,
            picture_url: (200, {}),
        }

        result = fbl.get(fb_api.LookupEvent, 'eid')
        self.assertEqual(result['info']['id'], 'eid')
        fbl.clear_local_cache()

        # Partial timeout of required field
        fb_api.FBAPI.results = {
            url: (200, {
                'id': 'eid'
            }),
            '/?fields=images&ids=%7Bresult%3Dinfo%3A%24.cover.id%7D':
            fb_api_stub.RESULT_TIMEOUT,
            picture_url: fb_api_stub.RESULT_TIMEOUT,
        }

        self.assertRaises(fb_api.NoFetchedDataException, fbl.get,
                          fb_api.LookupEvent, 'eid')
        fbl.clear_local_cache()

        # Event without a Cover field
        fb_api.FBAPI.results = {
            url: (200, {
                "name": "Event Title",
                "start_time": "2014-07-12T17:00:00-0400",
                "id": "eid"
            }),
            '/?fields=images&ids=%7Bresult%3Dinfo%3A%24.cover.id%7D': (400, {
                'error': {
                    'message': 'Cannot specify an empty identifier',
                    'code': 2500,
                    'type': 'OAuthException'
                }
            }),
            picture_url: (200, {
                "data": [{
                    "pic": "",
                    "all_members_count": 437,
                }]
            }),
        }

        result = fbl.get(fb_api.LookupEvent, 'eid')
        self.assertEqual(result['empty'], None)
        self.assertEqual(result['info']['id'], 'eid')
        fbl.clear_local_cache()

        fb_api.FBAPI.do_timeout = True
        self.assertRaises(fb_api.NoFetchedDataException, fbl.get,
                          fb_api.LookupEvent, 'eid')
        fb_api.FBAPI.do_timeout = False
        fbl.clear_local_cache()
Exemple #15
0
    def initialize(self, request, response):
        super(BaseRequestHandler, self).initialize(request, response)
        self.run_handler = True

        if abuse.is_abuse(self.request):
            self.run_handler = False
            self.response.out.write(
                'You are destroying our server with your request rate. Please implement rate-limiting, respect robots.txt, and/or email [email protected]'
            )
            return

        # Redirect from the bare 'dancedeets.com' to the full 'www.dancedeets.com'
        url = urlparse.urlsplit(self.request.url)
        # We technically don't need dd.events in here, since its handler is a BareBonesRequestHandler...but it include it to be safe.
        allowed_passthrough_domains = [r'dev\.dancedeets\.com$', r'img\.dancedeets\.com$', r'dd\.events$', r'dancer?\.bio$']
        matches_passthrough_domain = [x for x in allowed_passthrough_domains if re.search(x, url.netloc)]
        if not os.environ.get('DEBUG_MEMORY_LEAKS') and url.netloc != self._get_full_hostname() and not matches_passthrough_domain:
            logging.info("Redirecting from %s to %s: %s", url.netloc, self._get_full_hostname(), self.request.url)
            new_url = urlparse.urlunsplit([
                url.scheme,
                self._get_full_hostname(),
                url.path,
                url.query,
                url.fragment,
            ])
            self.run_handler = False
            self.redirect(new_url, abort=True)
            return

        # Always turn https on! For now, let's use a short expiry
        # This only 'takes effect' when it is returned on an https domain,
        # so we still need to make sure to add an https redirect.
        https_redirect_duration = 60 * 60 * 24 * 7
        if url.netloc != 'dev.dancedeets.com':
            self.response.headers.add_header('Strict-Transport-Security', 'max-age=%s' % https_redirect_duration)
        # This is how we detect if the incoming url is on https in GAE Flex (we cannot trust request.url)
        if request.method == 'GET' and request.environ.get('HTTP_X_FORWARDED_PROTO') == 'http':
            new_url = urlparse.urlunsplit([
                'https',
                url.netloc,
                url.path,
                url.query,
                url.fragment,
            ])
            self.run_handler = False
            self.redirect(new_url, abort=True)

        login_url = self.get_login_url()
        redirect_url = self.handle_alternate_login(request)
        if redirect_url:
            self.run_handler = False
            # We need to run with abort=False here, or otherwise our set_cookie calls don't work. :(
            # Reported in https://github.com/GoogleCloudPlatform/webapp2/issues/111
            self.redirect(redirect_url, abort=False)
            return

        self.setup_login_state(request)

        self.display['attempt_autologin'] = 1
        # If they've expired, and not already on the login page, then be sure we redirect them to there...
        redirect_for_new_oauth_token = (self.user and self.user.expired_oauth_token)
        if redirect_for_new_oauth_token:
            logging.error("We have a logged in user, but an expired access token. How?!?!")
        # TODO(lambert): delete redirect_for_new_oauth_token codepaths
        # TODO(lambert): delete codepaths that handle user-id but no self.user. assume this entire thing relates to no-user.
        if redirect_for_new_oauth_token or (self.requires_login() and (not self.fb_uid or not self.user)):
            # If we're getting a referer id and not signed up, save off a cookie until they sign up
            if not self.fb_uid:
                logging.info("No facebook cookie.")
            if not self.user:
                logging.info("No database user object.")
            if self.user and self.user.expired_oauth_token:
                logging.info("User's OAuth token expired")
                #self.set_cookie('fbsr_' + FACEBOOK_CONFIG['app_id'], '', 'Thu, 01 Jan 1970 00:00:01 GMT')
                #logging.info("clearing cookie %s", 'fbsr_' + FACEBOOK_CONFIG['app_id'])
                self.set_cookie('User-Message', "You changed your facebook password, so will need to click login again.")
            if self.request.get('referer'):
                self.set_cookie('User-Referer', self.request.get('referer'))
            if not self.is_login_page():
                logging.info("Login required, redirecting to login page: %s", login_url)
                self.run_handler = False
                return self.redirect(login_url)
            else:
                self.display['attempt_autologin'] = 0  # do not attempt auto-login. wait for them to re-login
                self.fb_uid = None
                self.access_token = None
                self.user = None
        # If they have a fb_uid, let's do lookups on that behalf (does not require a user)
        if self.fb_uid:
            self.setup_fbl()
            # Always look up the user's information for every page view...?
            self.fbl.request(fb_api.LookupUser, self.fb_uid)
        else:
            self.fbl = fb_api.FBLookup(None, None)
        self.fbl.debug = 'fbl' in self.debug_list
        if self.user:
            self.jinja_env.filters['date_only_human_format'] = self.user.date_only_human_format
            self.jinja_env.filters['date_human_format'] = self.user.date_human_format
            self.jinja_env.filters['time_human_format'] = self.user.time_human_format
            self.jinja_env.globals['duration_human_format'] = self.user.duration_human_format
            self.display['messages'] = self.user.get_and_purge_messages()
        else:
            self.jinja_env.filters['date_only_human_format'] = dates.date_only_human_format
            self.jinja_env.filters['date_human_format'] = dates.date_human_format
            self.jinja_env.filters['time_human_format'] = dates.time_human_format
            self.jinja_env.globals['duration_human_format'] = dates.duration_human_format
            self.display['login_url'] = login_url
        self.jinja_env.filters['datetime_format'] = dates.datetime_format

        self.jinja_env.globals['dd_event_url'] = urls.dd_event_url
        self.jinja_env.globals['raw_fb_event_url'] = urls.raw_fb_event_url
        self.jinja_env.globals['dd_admin_event_url'] = urls.dd_admin_event_url
        self.jinja_env.globals['dd_admin_source_url'] = urls.dd_admin_source_url

        locales = self.request.headers.get('Accept-Language', '').split(',')
        self.locales = [x.split(';')[0] for x in locales]
        if self.request.get('hl'):
            self.locales = self.request.get('hl').split(',')
        logging.info('Accept-Language is %s, final locales are %s', self.request.headers.get('Accept-Language', ''), self.locales)
        self.display['request'] = request
        self.display['app_id'] = facebook.FACEBOOK_CONFIG['app_id']
        self.display['prod_mode'] = self.request.app.prod_mode

        self.display['base_hostname'] = 'dancedeets.com' if self.request.app.prod_mode else 'dev.dancedeets.com'
        self.display['full_hostname'] = self._get_full_hostname()

        self.display['email_suffix'] = ''

        self.display['keyword_tokens'] = [{'value': x.public_name} for x in event_types.STYLES]
        fb_permissions = 'rsvp_event,email,user_events'
        if self.request.get('all_access'):
            fb_permissions += ',read_friendlists,manage_pages'
        self.display['fb_permissions'] = fb_permissions

        already_used_mobile = self.user and (
            'react-android' in self.user.clients or 'react-ios' in self.user.clients or 'android' in self.user.clients or
            'ios' in self.user.clients or False
        )
        mobile_platform = mobile.get_mobile_platform(self.request.user_agent)
        show_mobile_promo = not mobile_platform and not already_used_mobile
        self.display['show_mobile_promo'] = show_mobile_promo
        self.display['mobile_platform'] = mobile_platform
        if mobile_platform == mobile.MOBILE_ANDROID:
            self.display['mobile_app_url'] = mobile.ANDROID_URL
        elif mobile_platform == mobile.MOBILE_IOS:
            self.display['mobile_app_url'] = mobile.IOS_URL
        self.display['mobile'] = mobile
        self.display['mobile_show_smartbanner'] = True

        import time
        start = time.time()
        self.display['ip_location'] = self.get_location_from_headers()
        timelog.log_time_since('Getting City from IP', start)

        self.display['styles'] = event_types.STYLES
        self.display['cities'] = [(
            'North America', [
                'Albuquerque',
                'Austin',
                'Baltimore',
                'Boston',
                'Chicago',
                'Detroit',
                'Houston',
                'Las Vegas',
                'Los Angeles',
                'Miami',
                'New York City',
                'Orlando',
                'Philadelphia',
                'Portland',
                'San Francisco',
                'San Jose',
                'San Diego',
                'Seattle',
                'Washington DC',
                '',
                'Calgary',
                'Edmonton',
                'Montreal',
                'Ottawa',
                'Toronto',
                'Vancouver',
                ''
                'Mexico: Mexico City',
            ]
        ), (
            'Latin/South America', [
                'Argentina: Buenos Aires',
                'Argentina: Neuquen',
                'Brazil: Belo Horizonte',
                'Brazil: Brasilia',
                'Brazil: Cruitiba',
                'Brazil: Porto Alegre',
                'Brazil: Rio de Janeiro',
                'Brazil: Sao Paulo',
                'Colombia',
                'Chile: Santiago',
                'Peru: Lima',
            ]
        ), (
            'Europe', [
                'Austria: Vienna',
                'Belgium: Brussels',
                'Czech: Prague Republic',
                'Denmark: Copenhagen',
                'Estonia: Tallinn',
                'Finland: Helsinki',
                'France: Nantes',
                'France: Paris',
                'France: Perpignan',
                'Germany: Berlin',
                'Germany: Hamburg',
                u'Germany: Köln/Cologne',
                'Germany: Leipzig',
                u'Germany: München/Munich',
                'Italy: Milan',
                'Italy: Rome',
                'Netherlands: Amsterdam',
                'Norway: Oslo',
                'Poland: Warsaw',
                'Poland: Wroclaw',
                'Russia: Moscow',
                'Slovakia: Bratislava',
                'Spain: Barcelona',
                'Sweden: Malmoe',
                'Sweden: Stockholm',
                'Switzerland: Basel',
                'Switzerland: Geneve',
                'Switzerland: Zurich',
                'United Kingdom: Leeds',
                'United Kingdom: London',
            ]
        ), (
            'Asia', [
                'Hong Kong',
                'India',
                u'Japan: Tokyo (日本東京)',
                u'Japan: Osaka (日本大阪)',
                'Korea',
                u'Taiwan: Kaohsiung (台灣高雄市)',
                u'Taiwan: Taipei (台灣台北市)',
                u'Taiwan: Taichung (台灣臺中市)',
                'Philippines',
                'Singapore',
                'Australia: Melbourne',
                'Australia: Perth',
                'Australia: Sydney',
            ]
        )]

        self.display['deb'] = self.request.get('deb')
        self.display['debug_list'] = self.debug_list
        self.display['user'] = self.user

        webview = bool(request.get('webview'))
        self.display['webview'] = webview
        if webview:
            self.display['class_base_template'] = '_new_base_webview.html'
        else:
            self.display['class_base_template'] = '_new_base.html'

        totals = rankings.retrieve_summary()
        totals['total_events'] = humanize.intcomma(totals['total_events'])
        totals['total_users'] = humanize.intcomma(totals['total_users'])
        self.display.update(totals)
Exemple #16
0
 def get_fblookup(self):
     fbl = fb_api.FBLookup(self.fb_uid, self.fb_access_token)
     return fbl
Exemple #17
0
    def runTest(self):
        fbl = fb_api.FBLookup('uid', 'access_token')
        fbl.allow_cache = False

        # Set up our facebook backend
        fb_api.FBAPI.results = {
            URL_111: (200, {
                'id': '111',
                'name': 'page 1'
            }),
            URL_111_FEED: (200, {
                'data': []
            }),
            URL_111_EVENTS: (200, {
                'data': []
            }),
            URL_111_INFO2: (200, {}),
            URL_222: (200, {
                'id': '222',
                'name': 'page 2'
            }),
            URL_222_FEED: (200, {
                'data': []
            }),
            URL_222_EVENTS: (200, {
                'data': []
            }),
            URL_222_INFO2: (200, {}),
            '/%s/111?metadata=1' % fb_api.LookupThingCommon.version: (200, {
                'metadata': {
                    'type': 'page'
                }
            }),
            '/%s/222?metadata=1' % fb_api.LookupThingCommon.version: (200, {
                'metadata': {
                    'type': 'page'
                }
            }),
        }

        # Fetch it and construct a source
        source = thing_db.create_source_from_id(fbl, '111')
        source.num_all_events = 5
        source.put()

        source = thing_db.Source.get_by_key_name('111')
        self.assertEquals(source.name, 'page 1')

        self.mark_as_error_and_reload(fbl)

        # Let's verify id 111 no longer exists
        source = thing_db.Source.get_by_key_name('111')

        # Now let's load id 222 and verify it exists
        source = thing_db.Source.get_by_key_name('222')
        # And verify that our data from the first one got carried over
        self.assertEquals(source.num_all_events, 5)
        # But the the remaining data comes from the latest FB values for this page id
        self.assertEquals(source.name, 'page 2')

        # Now let's create 111 again, to verify merge works
        fb_api.FBAPI.results.update({
            URL_111: (200, {
                'id': '111',
                'name': 'page 1'
            }),
            URL_111_FEED: (200, {
                'data': []
            }),
        })
        source = thing_db.create_source_from_id(fbl, '111')
        source.num_all_events = 5
        source.put()

        pe = potential_events.PotentialEvent(key_name="333")
        pe.set_sources([potential_events.PESource("111", thing_db.FIELD_FEED), potential_events.PESource("222", thing_db.FIELD_FEED)])
        pe.put()

        self.mark_as_error_and_reload(fbl)

        pe = potential_events.PotentialEvent.get_by_key_name("333")
        #STR_ID_MIGRATE
        self.assertEqual(pe.sources(), [potential_events.PESource("222", thing_db.FIELD_FEED)])
Exemple #18
0
    def get(self, name):
        topics = topic_db.Topic.query(topic_db.Topic.url_path == name).fetch(1)
        if not topics:
            self.response.set_status(404)
            return

        topic = topics[0]

        if topic.graph_id:
            # We shouldn't need any tokens to access pages
            fbl = fb_api.FBLookup(None, None)
            fb_source = fbl.get(topic_db.LookupTopicPage, topic.graph_id)
        else:
            fb_source = None

        def prefilter(doc_event):
            """Function for fitlering doc results, before we spend the energy to load the corresponding DBEvents.

            We only want on-topic events here:
            - Must contain keyword in the title
            - Must contain keyword on a line where it makes up >10% of the text (for judges, workshops, etc). We want to hide the resume-includes-classes-from-X people
            """
            logging.info("Prefiltering event %s", doc_event.doc_id)
            name = doc_event.field('name').value.lower()
            description = doc_event.field('description').value.lower()

            description_lines = description.split('\n')

            for keyword in topic.search_keywords:
                keyword_word_re = re.compile(r'\b%s\b' % keyword)
                if keyword_word_re.search(name):
                    return True
                for line in description_lines:
                    result = keyword_word_re.search(line)
                    # If the keyword is more than 10% of the text in the line:
                    # Examples:
                    #   "- HOUSE - KAPELA (Serial Stepperz/Wanted Posse)"
                    #   "5th November : EVENT Judged by HIRO :"
                    if result:
                        if 1.0 * len(keyword) / len(line) > 0.1:
                            return True
                        else:
                            logging.info(
                                "Found keyword %r on line, but not long enough: %r",
                                keyword, line)

            logging.info("Prefilter dropping event %s with name: %r" %
                         (doc_event.doc_id, name))
            return False

        keywords = ' OR '.join('"%s"' % x for x in topic.search_keywords)
        search_query = search_base.SearchQuery(keywords=keywords)
        # Need these fields for the prefilter
        search_query.extra_fields = ['name', 'description']
        search_results = search.Search(search_query).get_search_results(
            prefilter=prefilter)

        self.display['topic_title'] = topic.override_title or (
            fb_source and fb_source['info']['name'])
        self.display['topic_image'] = topic.override_image or (
            fb_source and fb_source['picture']['data']['url'])
        self.display['topic_description'] = topic.override_description or (
            fb_source and fb_source['info'].get('about')) or ''

        self.display['all_results'] = search_results

        by_year = []
        for year, month_events in sorted(
                grouping.group_results_by_date(search_results).items()):
            by_year.append((year, sorted(month_events.items())))
        self.display['group_by_date'] = by_year
        by_country = sorted(
            grouping.group_results_by_location(search_results).items(),
            key=lambda x: (-len(x[1]), x[0]))
        self.display['group_by_location'] = by_country

        # TODO:
        # show points on map (future and past?)
        # show future events
        # show past events
        # show high quality and low quality events (most viable with 'past')
        # have an ajax filter on the page that lets me filter by location?
        self.display['fb_page'] = fb_source

        self.render_template('topic')
def load_potential_events_for_user(user):
    fbl = fb_api.FBLookup(user.fb_uid, user.fb_access_token)
    fbl.allow_cache = False
    load_potential_events_for_user_ids(fbl, [user.fb_uid])
Exemple #20
0
 def runTest(self):
     ids = ['110312662362915']
     fbl = fb_api.FBLookup(None, None)
     page_ids = fb_api_util.filter_by_type(fbl, ids, 'page')
     self.assertEqual(page_ids, ids)
Exemple #21
0
 def setUp(self):
     super(TestEventLocations, self).setUp()
     self.fbl = fb_api.FBLookup("dummyid", None)