コード例 #1
0
    def get_rsvps(self, event):
        """
        :param event: event in getTalent database
        :type event: common.models.event.Event
        :return: rsvps of given event
        :rtype: list

        - We get RSVPs of given event by API of Meetup.

        - We use this method while importing RSVPs through social network
            manager.

        :Example:

        - Create RSVP class object as

        sn_rsvp_obj = sn_rsvp_class(social_network=self.social_network,
                                    headers=self.headers,
                                    user_credentials=user_credentials)

        - Then call get_all_rsvps() on sn_rsvp_obj by passing events in
        parameters as follow

            self.rsvps = sn_rsvp_obj.get_all_rsvps(self.events)

        - Inside get_all_rsvps(), we call get_rsvps() on class object.

        - It appends rsvps of an events in a list and returns it

        **See Also**
            .. seealso:: get_all_rsvps() method in RSVPBase class
            inside social_network_service/rsvp/base.py for more insight.

        :return: list of RSVPs
        """
        rsvps = []
        social_network_id = event.social_network_id
        assert social_network_id is not None
        rsvps_url = get_url(self, Urls.RSVPS)
        params = {'event_id': event.social_network_event_id}
        response = http_request('GET', rsvps_url, params=params, headers=self.headers, user_id=self.user.id)
        if response.ok:
            data = response.json()
            rsvps.extend(data['results'])
            # next_url determines the pagination, this variable keeps appearing in response if there are more pages
            # and stops showing when there are no more. We have almost the same code for events' pagination,
            # might consolidate it.
            next_url = data['meta']['next'] or None
            while next_url:
                # Sleep for 10 / 30 seconds to avoid throttling
                time.sleep(0.34)
                # attach the key before sending the request
                response = http_request('GET', next_url, headers=self.headers, user_id=self.user.id)
                if response.ok:
                    data = response.json()
                    rsvps.extend(data['results'])
                    next_url = data['meta']['next'] or None
                    if not next_url:
                        break
            return rsvps
コード例 #2
0
    def get_rsvps(self, event):
        """
        This method is used to get all attendees of an event
        :param event: Eventbrite event
        :type event: Event
        :return: List of RSVPs
        :rtype: list
        """
        rsvps_url = get_url(self,
                            Urls.RSVPS).format(event.social_network_event_id)
        response = http_request('GET',
                                url=rsvps_url,
                                headers=self.headers,
                                user_id=self.user.id)
        all_rsvps = []
        data = response.json()
        page_size = data['pagination']['page_size']
        total_records = data['pagination']['object_count']
        all_rsvps.extend(data['attendees'])
        current_page = 1
        total_pages = total_records / page_size
        for page in xrange(1, total_pages):
            params = {'page': current_page}
            current_page += 1
            # get data for every page
            response = http_request('GET',
                                    rsvps_url,
                                    params=params,
                                    headers=self.headers,
                                    user_id=self.user.id)
            if response.ok:
                data = response.json()
                all_rsvps.extend(data['attendees'])

        return all_rsvps
コード例 #3
0
 def get_events(self):
     """
     We send GET requests to API URL and get data. We also
     have to handle pagination because Meetup's API
     does that too.
     :return: all_events: Events of getTalent user on Meetup.com
     :rtype all_events: list
     """
     all_events = []  # contains all events of gt-users
     # page size is 100 so if we have 500 records we will make
     # 5 requests (using pagination where each response will contain
     # 100 records).
     events_url = get_url(self, Urls.EVENTS)
     # we can specify status=upcoming,past,draft,cancelled etc. By default we
     # have status=upcoming, so we are not explicitly specifying in fields.
     meetup_groups = MeetupGroup.filter_by_keywords(user_id=self.user.id)
     if not meetup_groups:
         logger.warn(
             '''No MeetupGroup is associated with this user subscription for Meetup.
                        UserId: %s
                        MemberId: %s
                        ''' %
             (self.user.id, self.user_credentials.member_id))
         return all_events
     params = {
         'group_id':
         ','.join([str(group.group_id) for group in meetup_groups]),
         'status': "upcoming,proposed,suggested",
         'fields': 'timezone'
     }
     response = http_request('GET',
                             events_url,
                             params=params,
                             headers=self.headers,
                             user_id=self.user.id)
     if response.ok:
         data = response.json()
         all_events = []
         all_events.extend(data['results'])
         # next_url determines the pagination, this variable keeps
         # appearing in response if there are more pages and stops
         # showing up when there are no more.
         next_url = data['meta']['next'] or None
         while next_url:
             url = next_url
             # Sleep for 10 / 30 seconds to avoid throttling
             time.sleep(0.34)
             response = http_request('GET',
                                     url,
                                     headers=self.headers,
                                     user_id=self.user.id)
             if response.ok:
                 data = response.json()
                 all_events.extend(data['results'])
                 next_url = data['meta']['next'] or None
                 if not next_url:
                     break
     return all_events
コード例 #4
0
    def get_events(self, status='live', order_by='start_asc'):
        """
        We send GET requests to Eventbrite API and get already created events
        by this user on eventbrite.com.
        We also have to handle pagination because Eventbrite's API does that
        too.
        :return all_events: a collection of eventbrite events for specific user
        :rtype all_events: list
        """
        # create url to fetch events from eventbrite.com
        search = str(self.member_id) + '/owned_events'
        events_url = get_url(self, Urls.USER).format(search)
        params = {'status': status}
        # initialize event list to empty
        all_events = []
        try:
            # send a GET request to eventbrite's api to get events for given
            # user and after start_date
            response = http_request('GET',
                                    events_url,
                                    params=params,
                                    headers=self.headers,
                                    user_id=self.user.id)
        except:
            logger.exception('get_events: user_id: %s' % self.user.id)
            raise

        if response.ok:
            # if response is ok, get json data
            data = response.json()
            all_events.extend(data['events'])
            current_page = 1
            total_pages = data['pagination']['page_count']
            for page in range(1, total_pages):
                params_copy = params.copy()
                current_page += 1
                params_copy['page'] = current_page
                try:
                    # get data for every page
                    response = http_request('GET',
                                            events_url,
                                            params=params_copy,
                                            headers=self.headers,
                                            user_id=self.user.id)
                except Exception as e:
                    logger.exception('get_events: user_id: %s' % self.user.id)

                if response.ok:
                    data = response.json()
                all_events.extend(data['events'])
        return all_events
コード例 #5
0
    def get_groups(self):
        """
        - This function fetches the groups of user from Meetup website for
            which the user is an organizer. These groups are shown
            in drop down while creating event on Meetup through Event Creation
            Form.

        - This function is called from GET method of class MeetupGroups() inside
            social_network_service/app/restful/social_network.py

        :Example:
                from social_network_service.meetup import Meetup
                sn = Meetup(user_id=1)
                sn.get_groups()
        :return: Meetup groups for which gt-user is an organizer
        :rtype: list (list of dicts where each dict is likely the response from
                    Meetup API)
        **See Also**
        .. seealso:: GET method of class MeetupGroups() inside
            social_network_service/app/restful/social_network.py
        """
        url = get_url(self, SocialNetworkUrls.GROUPS)
        params = {'organizer_id': self.user_credentials.member_id}
        # Sleep for 10 / 30 seconds to avoid throttling
        time.sleep(0.34)
        response = http_request('GET',
                                url,
                                params=params,
                                headers=self.headers,
                                user_id=self.user.id)
        if response.ok:
            return response.json()['results']
        else:
            return []
コード例 #6
0
 def unpublish_event(self, event_id, method=HttpMethods.DELETE):
     """
     This function is used while running unit tests. It deletes the Event from database that were created
     during the lifetime of a unit test.
     :param int | long event_id: id of newly created event
     :param string method: http standard method , default is DELETE
     :return: True if event is deleted from vendor, False otherwise.
     :rtype: bool
     """
     # create url to unpublish event
     url = get_url(self, Urls.EVENT).format(event_id)
     # Sleep for 10 / 30 seconds to avoid throttling
     time.sleep(0.34)
     # params are None. Access token is present in self.headers
     response = http_request(method,
                             url,
                             headers=self.headers,
                             user_id=self.user.id)
     if response.ok:
         logger.info('|  Event has been unpublished (deleted)  |')
     else:
         error_message = "Event was not unpublished (deleted):%s" % response.text
         log_error({'user_id': self.user.id, 'error': error_message})
         raise EventNotUnpublished(
             'ApiError: Unable to remove event from %s' %
             self.social_network.name)
コード例 #7
0
 def application_based_auth(self):
     """
     This function does application based authentication with Twitter. This do not need any user interaction
     to connect with Twitter account because it makes request on behalf of App.
     It raises InternalServerError in case authentication fails.
     Here are the detailed docs https://dev.twitter.com/oauth/application-only.
     :return: Access token for getTalent app to access Twitter's API.
     :rtype: str
     """
     combined_key = self.consumer_key + ':' + self.consumer_secret
     combined_key = base64.b64encode(combined_key)
     headers = {
         'Authorization': 'Basic %s' % combined_key,
         'Content-Type': 'application/x-www-form-urlencoded'
     }
     data = {'grant_type': 'client_credentials'}
     result = http_request('post',
                           APPLICATION_BASED_AUTH_URL,
                           headers=headers,
                           data=data,
                           app=app)
     if result.ok:
         logger.info(
             'Successfully authenticated from Twitter API. User(id:%s).',
             self.user.id)
         access_token = result.json()['access_token']
         return access_token
     raise InternalServerError(
         'Error Occurred while authenticating from Twitter')
コード例 #8
0
 def publish_event(self, social_network_event_id):
     """
     This function publishes the Event on Eventbrite.
     This event is public.
     :param social_network_event_id: id for event on eventbrite.com
     :type social_network_event_id: int
     :exception EventNotPublished: raises this exception when unable to
         publish event on Eventbrite.com
     """
     # create url to publish event
     url = get_url(self,
                   Urls.PUBLISH_EVENT).format(str(social_network_event_id))
     # params are None. Access token is present in self.headers
     response = http_request('POST',
                             url,
                             headers=self.headers,
                             user_id=self.user.id)
     if response.ok:
         logger.info('|  Event has been published  |')
     else:
         error_message = "Event was not Published. There are some " \
                         "errors: Details: %s  |" % response.text
         log_error({
             'user_id': self.user.id,
             'error': error_message,
         })
         raise EventNotPublished('ApiError: Unable to publish event '
                                 'on Eventbrite')
コード例 #9
0
    def add_venue_to_sn(self, venue_data):
        """
        This function sends a POST request to Eventbrite api to create a venue for event.
        :param dict venue_data: a dictionary containing data required to create a venue
        """

        payload = {
            'venue.name': venue_data['address_line_1'],
            'venue.address.address_1': venue_data['address_line_1'],
            'venue.address.address_2': venue_data.get('address_line_2'),
            'venue.address.region': venue_data['state'],
            'venue.address.city': venue_data['city'],
            'venue.address.postal_code': venue_data.get('zip_code'),
            'venue.address.latitude': venue_data.get('latitude'),
            'venue.address.longitude': venue_data.get('longitude')
        }
        # create url to send post request to create venue
        url = get_url(self, Urls.VENUES)
        response = http_request('POST',
                                url,
                                params=payload,
                                headers=self.headers,
                                user_id=self.user.id)
        json_resp = response.json()
        if response.ok:
            logger.info('|  Venue has been created  |')
            venue_id = json_resp.get('id')
        else:
            raise InternalServerError(
                'ApiError: Unable to create venue for Eventbrite',
                additional_error_info=dict(venue_error=json_resp))

        venue_data['user_id'] = self.user.id
        venue_data['social_network_venue_id'] = venue_id
        return SocialNetworkBase.save_venue(venue_data)
コード例 #10
0
 def update_event(self):
     """
     It first creates/ updates a venue on Meetup.com and then passes that
     venue's id in event's payload to update event location along with event
     data.
     :exception EventNotCreated: raises exception if unable to update event
             on Meetup.com
     :return: id of event
     :rtype: int
     """
     # create url to update event
     url = get_url(self, Urls.EVENT).format(self.social_network_event_id)
     # create or update venue for event
     venue_id = self.add_location()
     # add venue id in event payload to update event venue on Meetup.com
     self.payload.update({'venue_id': venue_id})
     # Sleep for 10 / 30 seconds to avoid throttling
     time.sleep(0.34)
     response = http_request('POST',
                             url,
                             params=self.payload,
                             headers=self.headers,
                             user_id=self.user.id)
     if response.ok:
         event_id = response.json().get('id')
         logger.info('|  Event %s updated Successfully  |' %
                     self.payload['name'])
         self.data['social_network_event_id'] = event_id
         return self.save_event()
     else:
         error_message = 'Event was not created. Error occurred during ' \
                         'event update on Meetup'
         log_error({'user_id': self.user.id, 'error': error_message})
         raise EventNotCreated('ApiError: Unable to update event on Meetup')
コード例 #11
0
    def get_member_id(self):
        """
        - If getTalent user has an account on some social network, like Meetup.com, it will have a "member id" for
            that social network. This "member id" is used to make API subsequent calls to fetch events or RSVPs and
            relevant data for getTalent user from social network website.

        :Example:

            from social_network_service.meetup import Meetup
            sn = Meetup(user_id=1)
            sn.get_member_id()

        - We call this method from connect() of SocialNetworkBase class so that we don't need to get 'member id'
            of getTalent user while making object of some social network class at different places.
            (e.g. creating object of Meetup() in when importing events)

        **See Also**
        .. seealso:: connect() method defined in SocialNetworkBase class inside social_network_service/base.py.
        """
        logger.info('Getting "member id" of %s(user id:%s) using API of %s.' % (self.user.name, self.user.id,
                                                                                self.social_network.name))
        url = get_url(self, SocialNetworkUrls.VALIDATE_TOKEN)
        # Now we have the URL, access token, and header is set too,
        response = http_request('POST', url, headers=self.headers, user_id=self.user.id, app=app)
        if response.ok:
            return response.json().get('id')
        else:
            logger.error('get_member_id: Error:%s.' % response.text)
コード例 #12
0
 def _filter_event(self, event):
     """
     This method returns True if given event's group is owned by current user.
     :param event: event to be tested
     :type event: dict
     :return True or False
     :rtype Boolean
     """
     social_network_group_id = event['group'].get('id')
     # check if event's group id exists
     if social_network_group_id:
         if social_network_group_id in self.social_network_group_ids:
             return True
         url = get_url(self, Urls.GROUPS) + '/?sign=true'
         # Sleep for 10 / 30 seconds to avoid throttling
         time.sleep(0.34)
         response = http_request(
             'GET',
             url,
             params={'group_id': social_network_group_id},
             headers=self.headers,
             user_id=self.user.id)
         if response.ok:
             group = response.json()
             group_organizer = group['results'][0]['organizer']
             # group_organizer contains a dict that has member_id and name
             if str(group_organizer['member_id']) == self.member_id:
                 # save this group id as user's owned groups, so no need to
                 # fetch it again
                 self.social_network_group_ids.append(
                     social_network_group_id)
                 return True
     return False
コード例 #13
0
 def delete_webhooks(cls, user_credentials):
     """
     This method deletes webhook for current user from eventbrite
     :param type(t) user_credentials: user credentials for eventbrite for this user
     """
     url = user_credentials.social_network.api_url + "/webhooks/" + user_credentials.webhook
     headers = {'Authorization': 'Bearer ' + user_credentials.access_token}
     response = http_request('GET',
                             url,
                             headers=headers,
                             user_id=user_credentials.user.id)
     if response.ok:
         webhook = response.json()
         # Deleting existing webhook for this user because we don't know about their action types.
         # Need to register a webhook with `event.published` and `event.unpublished` actions and correct callback url
         http_request('DELETE',
                      webhook['resource_uri'],
                      headers=headers,
                      user_id=user_credentials.user.id)
コード例 #14
0
    def get_access_and_refresh_token(cls, user_id, social_network, code_to_get_access_token=None, method_type=None,
                                     payload=None, params=None, api_relative_url=None):
        """
        This function is used by Social Network API to save 'access_token' and 'refresh_token' for specific
        social network against a user (current user) by sending an POST call to respective social network API.
        :param user_id: current user id
        :param social_network: social_network in getTalent database
        :param code_to_get_access_token: Code which is exchanged for an access token.
        :param method_type: In case of Eventbrite, need to make a 'POST' call to get access token.
        :param payload: is set inside this method and is passed in super constructor. This is sent in body
                        of HTTP request.
        :param params: dictionary of data to send in the url params.
        :param api_relative_url: This variable is set in this function and is passed in super constructor to make
                                HTTP request.
        :type user_id: int
        :type social_network: common.models.social_network.SocialNetwork
        :type code_to_get_access_token: str
        :type method_type: str
        :type payload: dict
        :type payload: dict
        :type api_relative_url: str
        :return: returns access token and refresh token
        :rtype: tuple (str, str)
        """
        logger.info('Getting "access_token and refresh_token" of user_id:%s using API of %s.'
                    % (user_id, social_network.name))
        url = social_network.auth_url + api_relative_url
        get_token_response = http_request(method_type, url, data=payload, user_id=user_id, params=params)
        try:
            if get_token_response.ok:
                # access token is used to make API calls, this is what we need
                # to make subsequent calls
                try:
                    response = get_token_response.json()
                    access_token = response.get('access_token')
                    # refresh token is used to refresh the access token
                    refresh_token = response.get('refresh_token')
                except ValueError:
                    if 'facebook' in social_network.api_url:
                        # In case of Facebook, access_token is retrieved as follows
                        access_token = \
                            get_token_response.content.split('=')[1].split('&')[0]
                        refresh_token = ''
                    else:
                        raise
                return access_token, refresh_token
            else:
                log_error({'user_id': user_id, 'error': get_token_response.json().get('error')})
                raise SNServerException('Unable to to get access token for current user')

        except:
            logger.exception('get_access_and_refresh_token: user_id: %s, social network: %s(id: %s)'
                             % (user_id, social_network.name, social_network.id))
            raise SNServerException('Unable to create user credentials for current user')
コード例 #15
0
    def add_venue_to_sn(self, venue_data):
        """
        This function sends a POST request to Meetup api to create a venue for event.
        :param dict venue_data: a dictionary containing data required to create a venue
        """
        if not venue_data.get('group_url_name'):
            raise InvalidUsage("Mandatory Input Missing: group_url_name",
                               error_code=custom_codes.MISSING_REQUIRED_FIELDS)
        url = get_url(self, SocialNetworkUrls.VENUES,
                      custom_url=MEETUP_VENUE).format(
                          venue_data['group_url_name'])
        payload = {
            'address_1': venue_data['address_line_1'],
            'address_2': venue_data.get('address_line_2'),
            'city': venue_data['city'],
            'country': venue_data['country'],
            'state': venue_data['state'],
            'name': venue_data['address_line_1']
        }
        # Sleep for 10 / 30 seconds to avoid throttling
        time.sleep(0.34)
        response = http_request('POST',
                                url,
                                params=payload,
                                headers=self.headers,
                                user_id=self.user.id)
        json_resp = response.json()
        if response.ok:
            venue_id = json_resp['id']
            logger.info('Venue has been Added. Venue Id: %s', venue_id)
        elif response.status_code == codes.CONFLICT:
            # 409 is returned when our venue is matching existing
            # venue/venues.
            try:
                match_id = json_resp['errors'][0]['potential_matches'][0]['id']
            except:
                raise InternalServerError('Invalid response from Meetup',
                                          error_code=INVALID_MEETUP_RESPONSE)
            venue = Venue.get_by_user_id_and_social_network_venue_id(
                self.user.id, match_id)
            if venue:
                raise InvalidUsage(
                    'Venue already exists in getTalent database',
                    additional_error_info=dict(id=venue.id),
                    error_code=VENUE_EXISTS_IN_GT_DATABASE)
            venue_id = json_resp['errors'][0]['potential_matches'][0]['id']
        else:
            raise InternalServerError(
                'ApiError: Unable to create venue for Meetup',
                additional_error_info=dict(venue_error=json_resp))

        venue_data['user_id'] = self.user.id
        venue_data['social_network_venue_id'] = venue_id
        return SocialNetworkBase.save_venue(venue_data)
コード例 #16
0
 def get_event(self, event_url):
     """
     This method takes event resource uri, sends a GET call to respective social network API and then saves
     retrieved event in db.
     :param event_url: event resource rui
     :return: event model object
     :rtype type(t)
     """
     # Sleep for 10 / 30 seconds to avoid throttling
     time.sleep(0.34)
     response = http_request('get', event_url, headers=self.headers)
     if response.ok:
         event = response.json()
         return self.import_event(event)
コード例 #17
0
    def save_attendee_source(self, attendee):
        """
        :param attendee: attendees is a utility object we share in calls that
                 contains pertinent data.
        :type attendee: object of class Attendee defined in utilities.py

        - This method checks if the event is present in candidate_source db
         table. If does not exist, it adds record, otherwise updates the
         record. It then appends id of source in attendee object to be saved in
         candidate table.

        - This method is called from process_rsvps() defined in
          RSVPBase class inside social_network_service/rsvp/base.py.

        - We use this method while importing RSVPs through social network

        :Example:

            attendee = self.save_attendee_source(attendee)

        **See Also**
            .. seealso:: process_rsvps() method in EventBase class
        :return attendee:
        :rtype: Attendee
        """
        attendee.event.description = attendee.event.description[:1000].encode('utf-8') if attendee.event.description \
            else 'Not given'
        candidate_source = {
            "source": {
                "description": attendee.event.description,
                "notes": attendee.event.title
            }
        }
        access_token = User.generate_jw_token(user_id=self.user.id)
        header = {
            'Content-Type': 'application/json',
            'Authorization': access_token
        }
        response = http_request('POST', UserServiceApiUrl.DOMAIN_SOURCES, headers=header,
                                data=json.dumps(candidate_source))
        # Source already exists
        if response.status_code == requests.codes.bad:
            attendee.candidate_source_id = response.json()['error']['source_id']
        elif response.status_code != requests.codes.created:
            logger.exception(response.text)
            raise InternalServerError(error_message="Error while creating candidate source")
        else:
            attendee.candidate_source_id = response.json()['source']['id']

        return attendee
コード例 #18
0
    def test_meetup_rsvp_importer_with_valid_token(self, user_first,
                                                   talent_pool_session_scope,
                                                   token_first,
                                                   meetup_event_dict_second):
        """
        - We post an RSVP on this event. We assert on response of RSVP POST.
            If it is in 2xx, then we run rsvp importer to import RSVP
            (that we just posted) in database. After importing RSVPs, we pick
            the imported record using social_network_rsvp_id and finally assert
            on the status of RSVP. It should be same as given in POST request's
            payload.

        - We add 'id' of newly created event to delete it from social network
            website in the finalizer of meetup_event_dict.
        """
        event = meetup_event_dict_second['event']
        with app.app_context():
            social_network_event_id = event.social_network_event_id
            user_credentials = UserSocialNetworkCredential.get_by_user_and_social_network_id(
                user_first['id'], event.social_network.id)
            # create object of respective social network to run RSVP importer
            social_network = SocialNetwork.get_by_name(
                user_credentials.social_network.name)
            social_network_class = get_class(social_network.name.lower(),
                                             'social_network',
                                             user_credentials=user_credentials)
            # we call social network class here for auth purpose, If token is expired
            # access token is refreshed and we use fresh token to make HTTP calls
            sn = social_network_class(user_id=user_credentials.user_id)
            url = '{}/rsvp/'.format(sn.api_url)
            payload = {'event_id': social_network_event_id, 'rsvp': 'no'}
            response = http_request('POST',
                                    url,
                                    params=payload,
                                    headers=sn.headers)
            assert response.ok is True
            logger.info('RSVP has been posted successfully')
            social_network_rsvp_id = response.json()['rsvp_id']
            sn.process('rsvp', user_credentials=user_credentials)
            # get the imported RSVP by social_network_rsvp_id and social_network_id
            rsvp_in_db = RSVP.get_by_social_network_rsvp_id_and_social_network_id(
                social_network_rsvp_id, social_network.id)
            assert isinstance(rsvp_in_db, RSVP)
            assert rsvp_in_db.status == payload['rsvp']
            response = send_request('delete',
                                    url=SocialNetworkApiUrl.EVENT % event.id,
                                    access_token=token_first)

            assert response.status_code == codes.OK
コード例 #19
0
    def fetch_event(self, event_id):
        """
        This method creates api url to fetch an event and then sends a GET request to fetch that event.
        :param str | int | long event_id: social network event id
        :return: event dict or None
        """
        event_url = get_url(self, SocialNetworkUrls.EVENT).format(event_id)
        try:
            response = http_request('get', event_url, headers=self.headers)

            if response.ok:
                return response.json()
        except ResourceNotFound:
            logger.info('Event not found for url: %s' % event_url)
            return None
コード例 #20
0
 def create_webhook(cls, user_credentials):
     """
     :param user_credentials: User's social network credentials for which
             we need to create webhook. Webhook is created to be updated
             about any RSVP on an
             event of Eventbrite.
     :type user_credentials:  common.models.user.UserSocialNetworkCredential
     - This method creates a webhook to stream the live feed of RSVPs of
         Eventbrite events to the getTalent app. Once we have the webhook
         id for given user, we update user credentials in db.
     - It also performs a check which ensures that webhook is not generated
         every time code passes through this flow once a webhook has been
         created for a user (since webhook don't expire and are unique for
         every user).
     - This method is called from save_user_credentials_in_db() defined in
         Eventbrite class inside social_network_service/eventbrite.py.
     **See Also**
     .. seealso:: save_user_credentials_in_db() function defined in Eventbrite
         class inside social_network_service/eventbrite.py.
     .. seealso:: get_access_and_refresh_token() function defined in Eventbrite
         class inside social_network_service/eventbrite.py.
     """
     url = user_credentials.social_network.api_url + "/webhooks/"
     payload = {
         'endpoint_url':
         SocialNetworkApiUrl.WEBHOOK % user_credentials.user_id,
         'actions':
         ','.join([
             ACTIONS['published'], ACTIONS['unpublished'], ACTIONS['rsvp']
         ])
     }
     headers = {'Authorization': 'Bearer ' + user_credentials.access_token}
     response = http_request('POST',
                             url,
                             params=payload,
                             headers=headers,
                             user_id=user_credentials.user.id)
     try:
         webhook_id = response.json()['id']
         user_credentials.update(webhook=webhook_id)
     except Exception:
         logger.exception('create_webhook: user_id: %s' %
                          user_credentials.user.id)
         raise InternalServerError(
             "Eventbrite Webhook wasn't created successfully")
コード例 #21
0
 def test_meetup_rsvp_importer_with_invalid_token(self, user_first,
                                                  token_first,
                                                  meetup_event_dict_second):
     """
     - Here we post an RSVP on newly created event and assert on response
         of RSVP POST. It should be 2xx, then we run rsvp importer with
         invalid token. RSVP for this event should not be imported.
     - We add 'id' of newly created event to delete it from social network
         website in the finalizer of meetup_event_dict.
     """
     with app.app_context():
         event = meetup_event_dict_second['event']
         social_network_event_id = event.social_network_event_id
         user_credentials = UserSocialNetworkCredential.get_by_user_and_social_network_id(
             user_first['id'], event.social_network.id)
         # create object of respective social network to run RSVP importer
         social_network = SocialNetwork.get_by_name(
             user_credentials.social_network.name)
         social_network_class = get_class(social_network.name.lower(),
                                          'social_network',
                                          user_credentials=user_credentials)
         # we call social network class here for auth purpose, If token is expired
         # access token is refreshed and we use fresh token to make HTTP calls
         sn = social_network_class(user_id=user_credentials.user_id)
         url = sn.api_url + '/rsvp/'
         payload = {'event_id': social_network_event_id, 'rsvp': 'no'}
         response = http_request('POST',
                                 url,
                                 params=payload,
                                 headers=sn.headers)
         assert response.ok is True, "Response: {}".format(response.text)
         logger.info('RSVP has been posted successfully')
         social_network_rsvp_id = response.json()['rsvp_id']
         sn.headers = {'Authorization': 'Bearer invalid_token'}
         logger.info('Access Token has been malformed.')
         # Call process method of social network class to start importing RSVPs
         sn.process('rsvp', user_credentials=user_credentials)
         # get the imported RSVP by social_network_rsvp_id and social_network_id
         rsvp_in_db = RSVP.get_by_social_network_rsvp_id_and_social_network_id(
             social_network_rsvp_id, social_network.id)
         assert rsvp_in_db is None
コード例 #22
0
 def archive_email_campaigns_for_deleted_event(self, event,
                                               deleted_from_vendor):
     """
     Whenever an event is deleted from social-network, we update field `is_deleted_from_vendor` to 1.
     We then check if it was promoted via email-campaign to getTalent candidates and mark all linked email-campaigns
     as archived.
     :param Event event: Event object
     :param bool deleted_from_vendor: flag to mark 'is_deleted_from_vendor' field true or false
     """
     # if deleted_from_vendor is True, it means we are directly deleting event from our api call not from third party
     # social network that's why we need to un-publish
     # event from social network and will also mark is_hidden=1.
     if deleted_from_vendor:
         event.update(is_deleted_from_vendor=1, is_hidden=1)
     else:
         event.update(is_deleted_from_vendor=1)
     base_campaign_events = event.base_campaign_event
     for base_campaign_event in base_campaign_events:
         base_campaign = base_campaign_event.base_campaign
         email_campaigns = base_campaign.email_campaigns.all()
         for email_campaign in email_campaigns:
             data = {'is_hidden': 1}
             try:
                 response = http_request('patch',
                                         EmailCampaignApiUrl.CAMPAIGN %
                                         email_campaign.id,
                                         headers=self.gt_headers,
                                         data=json.dumps(data))
                 if response.ok:
                     logger.info(
                         'Email campaign(id:%s) has been archived successfully.'
                         % email_campaign.id)
                 else:
                     logger.info(
                         'Email campaign(id:%s) could not be archived.' %
                         email_campaign.id)
             except Exception:
                 logger.exception(
                     'Email campaign(id:%s) could not be archived.' %
                     email_campaign.id)
コード例 #23
0
 def create_event(self):
     """
     This function is used to create Meetup event using vendor's API.
     It first creates a venue for event. Then venue_id is passed to
     event_payload.
     Then a POST request to Meetup API creates event on Meetup.com
     :exception EventNotCreated: raises exception if unable to
     publish/create event on Meetup.com.
     :return: id of event in db
     :rtype: int
     """
     venue_id = self.add_location()
     url = get_url(self, Urls.EVENT).format('')
     self.payload.update({
         'venue_id': venue_id,
         'publish_status': 'published'
     })
     logger.info(
         'Creating event for %s(user id:%s) using url:%s of API of %s.' %
         (self.user.name, self.user.id, url, self.social_network.name))
     # Sleep for 10 / 30 seconds to avoid throttling
     time.sleep(0.34)
     response = http_request('POST',
                             url,
                             params=self.payload,
                             headers=self.headers,
                             user_id=self.user.id)
     if response.ok:
         event = response.json()
         event_id = event['id']
         logger.info('|  Event %s created Successfully  |' %
                     self.payload['name'])
         self.data['social_network_event_id'] = event_id
         self.data['url'] = event.get('event_url', '')
         return self.save_event()
     else:
         error_message = 'Event was not Created. Error occurred during draft creation'
         log_error({'user_id': self.user.id, 'error': error_message})
         raise EventNotCreated('ApiError: Unable to create event on Meetup')
コード例 #24
0
    def import_meetup_groups(self):
        """
        This method is to fetch user's meetup groups and save them in gt database.
        """
        url = get_url(self, SocialNetworkUrls.GROUPS)
        params = {'organizer_id': self.user_credentials.member_id}
        # Sleep for 10 / 30 seconds to avoid throttling
        time.sleep(0.34)
        response = http_request('GET',
                                url,
                                params=params,
                                headers=self.headers,
                                user_id=self.user.id)
        meetup_groups = []
        if response.ok:
            groups = response.json()['results']
            for group in groups:
                meetup_group = MeetupGroup.get_by_group_id(group['id'])

                if meetup_group:
                    if meetup_group.user_id == self.user.id:
                        meetup_groups.append(meetup_group.to_json())
                        continue
                meetup_group = MeetupGroup(
                    group_id=group['id'],
                    user_id=self.user.id,
                    name=group['name'],
                    url_name=group['urlname'],
                    description=group.get('description'),
                    created_datetime=group.get('created'),
                    visibility=group.get('visibility'),
                    country=group.get('country'),
                    state=group.get('state'),
                    city=group.get('city'),
                    timezone=group.get('timezone'))
                MeetupGroup.save(meetup_group)
                meetup_groups.append(meetup_group.to_json())
        return meetup_groups
コード例 #25
0
    def create_event_organizer(self, data):
        """
        This method sends a POST request to Eventbrite API to create an event organizer.
        :param dict[str, T] data: organizer data
        :return: organizer id on Eventbrite
        :rtype string
        """
        mandatory_input_data = ['name', 'about']
        # gets fields which are missing
        missing_items = find_missing_items(data, mandatory_input_data)
        if missing_items:
            raise InvalidUsage("Mandatory Input Missing: %s" % missing_items)

        payload = {
            'organizer.name': data['name'],
            'organizer.description.html': data['about']
        }
        # create url to send post request to create organizer
        url = get_url(self, Urls.ORGANIZERS)
        response = http_request('POST',
                                url,
                                params=payload,
                                headers=self.headers,
                                user_id=self.user.id)
        json_response = response.json()
        if response.ok:
            return json_response['id']
        elif response.status_code == requests.codes.BAD_REQUEST and json_response.get(
                'error') == "ARGUMENTS_ERROR":
            raise InvalidUsage(
                'Organizer name `{}` already exists on Eventbrite'.format(
                    data['name']),
                error_code=ORGANIZER_ALREADY_EXISTS)
        raise InternalServerError(
            'Error occurred while creating organizer.',
            additional_error_info=dict(error=json_response))
コード例 #26
0
    def manage_event_tickets(self, tickets_url):
        """
        Here tickets are created for event on Eventbrite.
        This method sends a POST request to Eventbrite.com API to create or
        update tickets. Call this method from create_tickets or update_tickets
        with respective tickets_url. It returns tickets id if successful
        otherwise raises "TicketsNotCreated" exception

        :param tickets_url  (API url to create or update event tickets)
        :type tickets_url: str
        :exception TicketsNotCreated (throws exception if unable to create or
            update tickets)
        :return: tickets_id (an id which refers to tickets for event on
            eventbrite.com)
        :rtype: str
        """
        # send POST request to create or update tickets for event
        response = http_request('POST',
                                tickets_url,
                                params=self.ticket_payload,
                                headers=self.headers,
                                user_id=self.user.id)
        if response.ok:
            logger.info(
                '|  %s Ticket(s) have been created  |' %
                str(self.ticket_payload['ticket_class.quantity_total']))
            tickets_id = response.json().get('id')
            return tickets_id
        else:
            error_message = 'Event tickets were not created successfully'
            log_error({
                'user_id': self.user.id,
                'error': error_message,
            })
            raise TicketsNotCreated('ApiError: Unable to create event tickets '
                                    'on Eventbrite')
コード例 #27
0
    def save_attendee_as_candidate(self, attendee):
        """
        :param attendee: attendees is a utility object we share in calls that
         contains pertinent data.
        :type attendee: object of class Attendee defined in utilities.py

        - This method adds the attendee as a new candidate if it is not present
         in the database already, otherwise it updates the previous record. It
         then appends the candidate_id to the attendee object and add/updates record in
         candidate_social_network db table. It then returns attendee object.

        - This method is called from process_rsvps() defined in
          RSVPBase class inside social_network_service/rsvp/base.py.

        - We use this method while importing RSVPs through social network
        :Example:

            attendee = self.save_attendee_as_candidate(attendee)

        **See Also**
            .. seealso:: process_rsvps() method in EventBase class
        :return attendee:
        :rtype: Attendee
        """
        candidate_in_db = None
        request_method = 'post'
        domain_id = User.get_domain_id(attendee.gt_user_id)
        candidate_by_email = CandidateEmail.get_email_in_users_domain(domain_id, attendee.email)
        if candidate_by_email:
            candidate_in_db = candidate_by_email.candidate
        if not candidate_in_db:
            # TODO: Need to handle multiple sources per candidate
            candidate_in_db = Candidate.filter_by_keywords(first_name=attendee.first_name,
                                                           last_name=attendee.last_name,
                                                           source_id=attendee.candidate_source_id,
                                                           source_product_id=attendee.source_product_id)

            if candidate_in_db:
                candidate_in_db = candidate_in_db[0]
                # Check if candidate's domain is same as user's domain
                if not candidate_in_db.user.domain_id == domain_id:
                    candidate_in_db = None

        # To create candidates, user must have be associated with talent_pool
        talent_pools = TalentPool.filter_by_keywords(user_id=attendee.gt_user_id)
        talent_pool_ids = map(lambda talent_pool: talent_pool.id, talent_pools)

        if not talent_pool_ids:
            raise InternalServerError("save_attendee_as_candidate: user doesn't have any talent_pool")

        # Create data dictionary
        data = {'first_name': attendee.first_name,
                'last_name': attendee.last_name,
                'source_id': attendee.candidate_source_id,
                'source_product_id': attendee.source_product_id,
                'talent_pool_ids': dict(add=talent_pool_ids)
                }
        social_network_data = {
            'name': attendee.event.social_network.name,
            'profile_url': attendee.social_profile_url
        }

        # Update if already exist
        if candidate_in_db:
            candidate_id = candidate_in_db.id
            data.update({'id': candidate_id})
            request_method = 'patch'
            # Get candidate's social network if already exist
            candidate_social_network_in_db = \
                CandidateSocialNetwork.get_by_candidate_id_and_sn_id(candidate_id, attendee.social_network_id)
            if candidate_social_network_in_db:
                social_network_data.update({'id': candidate_social_network_in_db.id})

        if attendee.email:
            data.update({'emails': [{'address': attendee.email,
                                     'label': EmailLabel.PRIMARY_DESCRIPTION,
                                     'is_default': True
                                     }]
                         })
        # Update social network data to be sent with candidate
        data.update({'social_networks': [social_network_data]})
        access_token = User.generate_jw_token(user_id=self.user.id)
        header = {
            'Content-Type': 'application/json',
            'Authorization': access_token
        }
        resp = http_request(request_method, url=CandidateApiUrl.CANDIDATES, headers=header,
                            data=json.dumps(dict(candidates=[data])), app=app)
        data_resp = resp.json()
        if resp.status_code not in [codes.CREATED, codes.OK]:
            error_message = 'save_attendee_as_candidate: candidate creation failed. Error:%s' % data_resp
            logger.error(error_message)
            raise InternalServerError(error_message)
        attendee.candidate_id = data_resp['candidates'][0]['id']
        return attendee
コード例 #28
0
    def add_location(self):
        """
        This generates a venue object for the event and returns the
        id of venue.
        :exception EventLocationNotCreated: throws exception if unable to
            create or update venue on Eventbrite
        :exception VenueNotFound: raises exception if venue does not exist
            in database
        :return venue_id: id for venue created on eventbrite.com
        :rtype venue_id: int

            :Example:

                This method is used to create venue or location for event
                on Eventbrite. It requires a venue already created in getTalent
                database otherwise it will raise VenueNotFound exception.

                Given venue id it first gets venue from database and uses its
                data to create Eventbrite object

                >> eventbrite = Eventbrite(user=gt_user,
                                           headers=authentication_headers)

                Then we call add location from create event
                To get a better understanding see *create_event()* method.


        """
        # get venue from db which will be created on Eventbrite
        venue = Venue.get_by_user_id_social_network_id_venue_id(
            self.user.id, self.social_network.id, self.venue_id)
        if venue:
            if venue.social_network_venue_id:
                # there is already a venue on Eventbrite with this info.
                return venue.social_network_venue_id
            # This dict is used to create venue
            payload = {
                'venue.name': venue.address_line_1,
                'venue.address.address_1': venue.address_line_1,
                'venue.address.address_2': venue.address_line_2,
                'venue.address.region': venue.state,
                'venue.address.city': venue.city,
                # 'venue.address.country': venue.country,
                'venue.address.postal_code': venue.zip_code,
                'venue.address.latitude': venue.latitude,
                'venue.address.longitude': venue.longitude,
            }
            # create url to send post request to create venue
            url = get_url(self, Urls.VENUES)
            response = http_request('POST',
                                    url,
                                    params=payload,
                                    headers=self.headers,
                                    user_id=self.user.id)
            if response.ok:
                logger.info('|  Venue has been created  |')
                venue_id = response.json().get('id')
                venue.update(social_network_venue_id=venue_id)
                return venue_id
            else:
                error_message = "Venue was not Created. There are some " \
                                "errors: Details: %s " % response
                message = '\nErrors from the Social Network:\n'
                message += \
                    ''.join(response.json().get('error') + ','
                            + response.json().get('error_description'))
                error_message += message
                log_error({'error': error_message, 'user_id': self.user.id})
                raise EventLocationNotCreated(
                    'ApiError: Unable to create venue for event\n %s' %
                    message)
        else:
            error_message = 'Venue with ID = %s does not exist in db.' \
                            % self.venue_id
            log_error({
                'user_id': self.user.id,
                'error': error_message,
            })
            raise VenueNotFound('Venue not found in database. Kindly create'
                                ' venue first.')
コード例 #29
0
    def get_attendee(self, rsvp):
        """
        :param rsvp: rsvp is likely the response of social network API.
        :type rsvp: dict
        :return: attendee
        :rtype: object

        - This function is used to get the data of candidate related
          to given rsvp. It attaches all the information in attendee object.
          attendees is a utility object we share in calls that contains
          pertinent data.

        - This method is called from process_rsvps() defined in RSVPBase class.

        :Example:

            attendee = self.get_attendee(rsvp)

        - RSVP data return from Meetup looks like

        In case of RSVPs importer:

        {
            'group': {
                        'group_lat': 24.860000610351562,
                        'created': 1439953915212,
                        'join_mode': 'open',
                        'group_lon': 67.01000213623047,
                        'urlname': 'Meteor-Karachi',
                        'id': 17900002
                    },
            'created': 1438040123000,
            'rsvp_id': 1562651661,
            'mtime': 1438040194000,
            'event': {
                        'name': 'Welcome to Karachi - Meteor',
                        'id': '223588917'
                        'event_url': 'http://www.meetup.com/Meteor-Karachi/events/223588917/',
                        'time': 1440252000000,
                    },
            'member': {
                        'name': 'kamran',
                        'member_id': 190405794
                    },
            'guests': 1,
            'member_photo':
                    {
                        'thumb_link': 'http://photos3.meetupstatic.com/photos/member/c/b/1/0/thumb_248211984.jpeg',
                        'photo_id': 248211984,
                        'highres_link': 'http://photos3.meetupstatic.com/photos/member/c/b/1/0/highres_248211984.jpeg',
                        'photo_link': 'http://photos3.meetupstatic.com/photos/member/c/b/1/0/member_248211984.jpeg'
                    },
            'response': 'yes'
            }

        From streaming API:

        {
            u'group': {
                    u'group_city': u'Denver',
                    u'group_lat': 39.68,
                    u'group_urlname': u'denver-metro-chadd-support',
                    u'group_name': u'Denver-Metro CHADD (Children and Adults with ADHD) Meetup',
                    u'group_lon': -104.92,
                    u'group_topics': [
                                        {u'topic_name': u'ADHD', u'urlkey': u'adhd'},
                                        {u'topic_name': u'ADHD Support', u'urlkey': u'adhd-support'},
                                        {u'topic_name': u'Adults with ADD', u'urlkey': u'adults-with-add'},
                                        {u'topic_name': u'Families of Children who have ADD/ADHD',
                                            u'urlkey': u'families-of-children-who-have-add-adhd'},
                                        {u'topic_name': u'ADHD, ADD', u'urlkey': u'adhd-add'},
                                        {u'topic_name': u'ADHD Parents with ADHD Children',
                                            u'urlkey': u'adhd-parents-with-adhd-children'},
                                        {u'topic_name': u'Resources for ADHD', u'urlkey': u'resources-for-adhd'},
                                        {u'topic_name': u'Parents of Children with ADHD',
                                            u'urlkey': u'parents-of-children-with-adhd'},
                                        {u'topic_name': u'Support Groups for Parents with ADHD Children',
                                            u'urlkey': u'support-groups-for-parents-with-adhd-children'},
                                        {u'topic_name': u'Educators Training on AD/HD',
                                            u'urlkey': u'educators-training-on-ad-hd'},
                                        {u'topic_name': u'Adults with ADHD', u'urlkey': u'adults-with-adhd'}
                                    ],
                    u'group_state': u'CO', u'group_id': 1632579, u'group_country': u'us'
                },
        u'rsvp_id': 1639776896,
        u'venue': {u'lat': 39.674759, u'venue_id': 3407262, u'lon': -104.936317,
                   u'venue_name': u'Denver Academy-Richardson Hall'},
        u'visibility': u'public',
        u'event': {
                        u'event_name': u'Manage the Impact of Technology on Your Child and Family with Lana Gollyhorn',
                        u'event_id': u'235574682',
                        u'event_url': u'https://www.meetup.com/denver-metro-chadd-support/events/235574682/',
                        u'time': 1479778200000
                   },
        u'member': {
                    u'member_name': u'Valerie Brown',
                    u'member_id': 195674019
                    },
        u'guests': 0,
        u'mtime': 1479312043215,
        u'response': u'yes'
        }


        In both cases, we get info of attendee from Meetup API and response looks like

        {
            u'status': u'active',
            u'city': u'Horsham',
            u'name': u'Katalin Nimmerfroh',
            u'other_services': {},
            u'country': u'gb',
            u'topics': [
                        {u'name': u'Musicians', u'urlkey': u'musicians', u'id': 173},
                        {u'name': u'Acting', u'urlkey': u'acting', u'id': 226}
                    ],
            u'lon': -0.33,
            u'joined': 1456995423000,
            u'id': 200820968,
            u'state': u'P6',
            u'link': u'http://www.meetup.com/members/200820968',
            u'photo': {
                    u'thumb_link': u'http://photos2.meetupstatic.com/photos/member/4/f/f/9/thumb_254420473.jpeg',
                    u'photo_id': 254420473,
                    u'highres_link': u'http://photos2.meetupstatic.com/photos/member/4/f/f/9/highres_254420473.jpeg',
                    u'base_url': u'http://photos2.meetupstatic.com',
                    u'type': u'member',
                    u'photo_link': u'http://photos4.meetupstatic.com/photos/member/4/f/f/9/member_254420473.jpeg'
                    },
            u'lat': 51.07,
            u'visited': 1472805623000,
            u'self': {u'common': {}}}


        - So we will get the member data and issue a member call to get more info about member so we can later save
            him as a candidate.

        **See Also**
            .. seealso:: process_rsvps() method in RSVPBase class inside social_network_service/rsvp/base.py
            for more insight.
        """
        if self.rsvp_via_importer:
            social_network_event_id = rsvp['event']['id']
        else:
            social_network_event_id = rsvp['event']['event_id']
        event = Event.get_by_user_id_social_network_id_vendor_event_id(self.user.id, self.social_network.id,
                                                                       social_network_event_id)
        if not event:
            raise EventNotFound('Event is not present in db, social_network_event_id is %s. '
                                'User Id: %s' % (social_network_event_id, self.user.id))

        member_url = self.api_url + '/member/' + str(rsvp['member']['member_id'])
        # Sleep for 10 / 30 seconds to avoid throttling
        time.sleep(0.34)
        response = http_request('GET', member_url, headers=self.headers, user_id=self.user.id)
        if response.ok:
            data = response.json()
            attendee = Attendee()
            attendee.first_name = data['name'].split(" ")[0]
            if len(data['name'].split(" ")) > 1:
                attendee.last_name = data['name'].split(" ")[1]
            else:
                attendee.last_name = ' '
            attendee.full_name = data['name']
            attendee.city = data['city']
            attendee.email = ''  # Meetup API does not expose this
            attendee.country = data['country']
            attendee.social_profile_url = data['link']
            # attendee.picture_url = data['photo']['photo_link']
            attendee.gt_user_id = self.user.id
            attendee.social_network_id = self.social_network.id
            attendee.rsvp_status = rsvp['response']
            attendee.vendor_rsvp_id = rsvp['rsvp_id']
            # TODO: This won't work now, need to figure out a way
            attendee.vendor_img_link = "<img class='pull-right' " \
                                       "style='width:60px;height:30px'" \
                                       " src='/web/static/images" \
                                       "/activities/meetup_logo.png'/>"
            # get event from database
            epoch_time = rsvp['mtime']
            dt = milliseconds_since_epoch_to_dt(epoch_time)
            attendee.added_time = dt
            attendee.event = event
            return attendee
コード例 #30
0
    def refresh_access_token(self):
        """
        - When user authorizes Meetup account, we get a refresh token
            and access token. Access token expires in one hour.
            Here we refresh the access_token using refresh_token without user
            involvement and save in user_credentials db table.


        - This function is called from validate_and_refresh_access_token()
            defined in SocialNetworkBase class inside
            social_network_service/base.py

        :Example:
                from social_network_service.meetup import Meetup
                sn = Meetup(user_id=1)
                sn.refresh_access_token()

        **See Also**
        .. seealso:: validate_and_refresh_token() function defined in
            SocialNetworkBase class inside social_network_service/base.py.

        :return True if token has been refreshed successfully and False
                otherwise.
        :rtype: bool
        """
        status = False
        user_refresh_token = self.user_credentials.refresh_token

        auth_url = get_url(self, SocialNetworkUrls.REFRESH_TOKEN, is_auth=True)
        client_id = self.social_network.client_key
        client_secret = self.social_network.secret_key

        payload_data = {
            'client_id': client_id,
            'client_secret': client_secret,
            'grant_type': u'refresh_token',
            'refresh_token': user_refresh_token
        }
        # Sleep for 10 / 30 seconds to avoid throttling
        time.sleep(0.34)
        response = http_request('POST',
                                url=auth_url,
                                data=payload_data,
                                user_id=self.user.id,
                                app=app)
        if response.ok:
            try:
                # access token has been refreshed successfully, need to update
                # self.access_token and self.headers
                response = response.json()
                self.access_token = response.get('access_token')
                self.headers.update(
                    {'Authorization': 'Bearer ' + self.access_token})
                refresh_token = response.get('refresh_token')
                UserSocialNetworkCredential.query.filter_by(social_network_id=self.social_network.id,
                                                            member_id=self.user_credentials.member_id).\
                    update({'access_token': self.access_token, 'refresh_token': refresh_token})
                db.session.commit()
                logger.info("Access token has been refreshed.")
                status = True
            except Exception:
                logger.exception('refresh_access_token: user_id: %s' %
                                 self.user.id)
        else:
            # Error has been logged inside http_request()
            pass
        return status