def save_user_credentials_in_db(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: dict - This overrides the SocialNetworkBase class method save_user_credentials_in_db() because in case of user credentials related to Eventbrite, we also need to create webhook. - It first saves the credentials in db, gets the webhook id by calling create_webhook()using Eventbrite's API and updates the record in db. - This method is called from POST method of end point ProcessAccessToken() defined in social network Rest API inside social_network_service/app/restful/social_network.py. **See Also** .. seealso:: save_user_credentials_in_db() function defined in SocialNetworkBase class inside social_network_service/base.py. .. seealso::POST method of end point ProcessAccessToken() defined in social network Rest API inside social_network_service/app/restful/social_network.py. """ user_credentials_in_db = super( Eventbrite, Eventbrite).save_user_credentials_in_db(user_credentials) try: Eventbrite.create_webhook(user_credentials_in_db) except Exception: UserSocialNetworkCredential.delete(user_credentials_in_db) raise return user_credentials_in_db
def is_subscribed_test_data(user_first): """ This fixture creates two social networks and add credentials for first social network. We actually want to test 'is_subscribed' field in social networks data from API. """ old_records = SocialNetwork.query.filter( SocialNetwork.name.in_(['SN1', 'SN2'])).all() for sn in old_records: if sn.id is not None: try: SocialNetwork.delete(sn.id) except Exception: db.session.rollback() test_social_network1 = SocialNetwork(name='SN1', url='www.SN1.com') SocialNetwork.save(test_social_network1) test_social_network2 = SocialNetwork(name='SN2', url='www.SN1.com') SocialNetwork.save(test_social_network2) test_social_network1_credentials = UserSocialNetworkCredential( user_id=user_first['id'], social_network_id=test_social_network1.id, access_token='lorel ipsum', refresh_token='lorel ipsum') UserSocialNetworkCredential.save(test_social_network1_credentials) return test_social_network1, test_social_network2, test_social_network1_credentials
def save_user_credentials_in_db(cls, user_credentials): """ :param user_credentials: User's social network credentials for Meetup. :type user_credentials: dict - This overrides the SocialNetworkBase class method save_user_credentials_in_db() because in case of user credentials related to Eventbrite, we also need to create webhook. - It first saves the credentials in db, gets the Meetup Groups by calling import_meetup_groups()using Meetup's API and updates the record in db. **See Also** .. seealso:: save_user_credentials_in_db() function defined in SocialNetworkBase class inside social_network_service/base.py. .. seealso::POST method of end point ProcessAccessToken() defined in social network Rest API inside social_network_service/app/restful/social_network.py. """ user_credentials_in_db = super( cls, cls).save_user_credentials_in_db(user_credentials) try: meetup = cls( user_id=user_credentials_in_db.user_id, social_network_id=user_credentials_in_db.social_network_id) meetup.import_meetup_groups() except Exception as e: UserSocialNetworkCredential.delete(user_credentials_in_db) raise return user_credentials_in_db
def post(self): """ This endpoint triggers an event synchronizer(Celery task) against a post request with valid data Example: { "social_network_id": 1 } :return: { "message": "Your events are being updated } """ data = get_valid_json_data(request) social_network_id = data.get('social_network_id') # Required if not social_network_id: raise InvalidUsage('Please provide social_network_id') if not isinstance(social_network_id, (int, long)): raise InvalidUsage("Invalid social_network_id type") user_credentials = UserSocialNetworkCredential.get_by_user_and_social_network_id( request.user.id, social_network_id) if user_credentials: sync_events.delay(user_credentials) return ApiResponse({'message': 'Your events are being updated'}) raise ResourceNotFound( "User credentials not found for user_id: %d and social_network_id: %d" % (request.user.id, social_network_id))
def mark_vendor_deleted(self, events): """ There can be some events in db those exist in getTalent databse but not in vendor db. So we need to mark such events as `is_deleted_from_vendor = True` :param list events: list of events (dict) retrieved from Meetup / Eventbrite """ member_users = UserSocialNetworkCredential.filter_by_keywords( member_id=self.member_id, social_network_id=self.social_network.id) members_events = [] social_network_event_ids = [event['id'] for event in events] member_user_ids = [member.user_id for member in member_users] events_to_mark_deleted = Event.query.filter( Event.user_id.in_(member_user_ids), Event.is_deleted_from_vendor == 0, Event.social_network_id == self.social_network.id, ~Event.social_network_event_id.in_(social_network_event_ids)) events_marked_deleted = events_to_mark_deleted.update( {'is_deleted_from_vendor': 1}, synchronize_session=False) db.session.commit() # TODO: This commented code will be required for a future feature. Entirely delete unused events from db # deleted_event_ids = [] # for event_obj in missing_events: # try: # event = self.fetch_event(event_obj.social_network_event_id) # except Exception as e: # event = None # if not event or (event and event.get('status') in self.cancelled_status): # deleted_event_ids.append(event_obj.id) logger.info( '%s events have been marked as vendor deleted. SocialNetwork: %s, UserId: %s' % (events_marked_deleted, self.social_network.name, self.user.id))
def callback(self, oauth_verifier): """ This method is called from endpoint http://127.0.0.1:8007/v1/twitter-callback/<int:user_id> defined in app.py. Here we use "oauth_verifier" to get access token for the user. If we get any error in getting access token, we log the error and raise InternalServerError. Once we have the access_token, we get the member_id (id of getTalent user on Twitter's website) of user from Twitter API and save its credentials in database table "UserSocialNetworkCredential". :param string oauth_verifier: Token received from Twitter when user successfully connected to its account. """ self.auth.request_token = json.loads( redis_store.get('twitter_request_token_%s' % self.user.id)) redis_store.delete('twitter_request_token_%s' % self.user.id) try: self.auth.get_access_token(oauth_verifier) except tweepy.TweepError as error: logger.exception( 'Failed to get access token from Twitter for User(id:%s). \nError: %s' % (self.user.id, error.message)) raise InternalServerError( 'Failed to get access token from Twitter') access_token = self.auth.access_token # This may be used later # access_token_secret = self.auth.access_token_secret api = tweepy.API(self.auth) twitter_user = api.me() user_credentials = UserSocialNetworkCredential.get_by_user_and_social_network_id( self.user.id, self.social_network.id) if not user_credentials: user_credentials_obj = UserSocialNetworkCredential( user_id=self.user.id, social_network_id=self.social_network.id, member_id=twitter_user.id, access_token=access_token) UserSocialNetworkCredential.save(user_credentials_obj) logger.info( 'User(id:%s) is now connected with Twitter. Member id on twitter is %s' % (self.user.id, twitter_user.id)) return redirect(get_web_app_url())
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
def process_rsvps(self, rsvps): """ :param rsvps: rsvps contains rsvps of all events of a particular meetup account :type rsvps: list - This method picks an rsvp from "rsvps" and pass it to post_process_rsvp() - This method is called from process_events_rsvps() defined in EventBase class inside social_network_service/event/base.py. - We use this method while importing RSVPs via social network manager. :Example: - sn_rsvp_obj = sn_rsvp_class(social_network=self.social_network, headers=self.headers, user_credentials=user_credentials) - self.rsvps = sn_rsvp_obj.get_all_rsvps(self.events) - sn_rsvp_obj.process_rsvps(self.rsvps) **See Also** .. seealso:: process_events_rsvps() method in EventBase class social_network_service/event/base.py """ processed_rsvps = [] user_ids = [] for rsvp in rsvps: # Here we pick one RSVP from rsvps and start doing processing on it. If we get an error while processing # an RSVP, we simply log the error and move to process next RSVP. groups = MeetupGroup.get_all_records_by_group_id(rsvp['group']['id']) for group_user in groups: user_credentials = UserSocialNetworkCredential.get_by_user_and_social_network_id(group_user.user.id, self.social_network.id) sn_rsvp_obj = Meetup(user_credentials=user_credentials, headers=self.headers, social_network=self.social_network) processed_rsvps.append(sn_rsvp_obj.post_process_rsvp(rsvp)) user_ids.append(sn_rsvp_obj.user.id) saved_rsvps_count = len(filter(None, processed_rsvps)) total_rsvps_count = len(rsvps) * len(groups) failed_rsvps_count = total_rsvps_count - saved_rsvps_count user_ids = list(set(user_ids)) if total_rsvps_count: logger.info(''' process_rsvps: RSVPs for events of (UserIds:%s) have been processed. Successfully saved:%d, Failed:%d. Social network:%s ''' % (user_ids, saved_rsvps_count, failed_rsvps_count, self.social_network.name))
def _get_user_credentials(self): """ This method get user_credentials for given user and returns a tuple containing member_id, access_token and refresh_token for user. :return: member_id, access_token, refresh_token, webhook :rtype: tuple """ user_credentials = UserSocialNetworkCredential.get_by_user_and_social_network_id( self.user.id, self.social_network.id) assert user_credentials is not None member_id = user_credentials.member_id access_token = user_credentials.access_token refresh_token = user_credentials.refresh_token webhook = user_credentials.webhook return member_id, access_token, refresh_token, webhook
def save_user_credentials_in_db(cls, user_credentials): """ :param user_credentials: user's social network credentials :type user_credentials: dict - It checks if user_credentials are already in database. If a record is found, it updates the record otherwise it saves as new record. - It is called e.g. from refresh_access_token() inside social_network_service/meetup.py :Example: from social_network_service.meetup import Meetup sn = Meetup(user_id=1) sn.save_user_credentials_in_db(data) **See Also** .. seealso:: refresh_access_token() method of Meetup class inside social_network_service/meetup.py :return user's social network credentials :rtype: common.models.user.UserCredentials """ user_credentials_in_db = UserSocialNetworkCredential.get_by_user_and_social_network_id( user_credentials['user_id'], user_credentials['social_network_id']) try: if user_credentials_in_db: user_credentials_in_db.update(**user_credentials) else: user_credentials_in_db = UserSocialNetworkCredential(**user_credentials) UserSocialNetworkCredential.save(user_credentials_in_db) return user_credentials_in_db except: logger.exception('save_user_credentials_in_db: user_id: %s', user_credentials['user_id']) raise SNServerException('APIError: Unable to create user credentials')
def is_token_valid(social_network_id, user_id): # Get social network specified by social_network_id social_network = SocialNetwork.get_by_id(social_network_id) if social_network: user_social_network_credential = UserSocialNetworkCredential.get_by_user_and_social_network_id( user_id, social_network_id) if user_social_network_credential: # Get social network specific Social Network class social_network_class = get_class(social_network.name, 'social_network') # create social network object which will validate # and refresh access token (if possible) sn = social_network_class(user_id=user_id, social_network_id=social_network.id) return sn.access_token_status, social_network.name return False, social_network.name else: raise ResourceNotFound("Invalid social network id given")
def process_eventbrite_rsvp(rsvp): """ This celery task is for an individual RSVP received from Eventbrite to be processed. Response from Eventbrite API looks like { u'config': {u'action': u'order.placed', u'user_id': u'149011448333', u'endpoint_url': u'https://emails.ngrok.io/webhook/1', u'webhook_id': u'274022'}, u'api_url': u'https://www.eventbriteapi.com/v3/orders/573384540/' } :param dict rsvp: rsvp dictionary from Eventbrite """ with app.app_context(): logger = app.config[TalentConfigKeys.LOGGER] logger.info('Going to process Eventbrite RSVP: %s' % rsvp) try: eventbrite = SocialNetwork.get_by_name(EVENTBRITE) webhook_id = rsvp['config']['webhook_id'] user_credentials = UserSocialNetworkCredential.get_by_webhook_id_and_social_network_id( webhook_id, eventbrite.id) if not user_credentials: raise NoUserFound( "No User found in database that corresponds to webhook_id:%s" % webhook_id) # we make social network object here to check the validity of access token. # If access token is valid, we proceed to do the processing to save in getTalent db tables otherwise # we raise exception AccessTokenHasExpired. sn_obj = EventbriteSocialNetwork(user_id=user_credentials.user_id, social_network_id=eventbrite.id) eventbrite_rsvp_object = EventbriteRsvp( user_credentials=user_credentials, social_network=eventbrite, headers=sn_obj.headers) attendee = eventbrite_rsvp_object.process_rsvp_via_webhook(rsvp) if attendee and attendee.rsvp_id: logger.info('RSVP imported successfully. rsvp:%s' % rsvp) elif attendee: logger.info('RSVP already present in database. rsvp:%s' % rsvp) except Exception: logger.exception('Failed to save rsvp: %s' % rsvp) rollback()
def connect(self, code): """ This connects user with social-network's account. e.g. on Meetup or Eventbrite etc. This gets access token and refresh tokens for user and it also updates these tokens for previously connected users. It also gets member_id of getTalent user for requested social-network website. :param string code: code to exchange for access token and refresh token. """ access_token, refresh_token = self.get_access_and_refresh_token(self.user.id, self.social_network, code_to_get_access_token=code) self.headers = {'Authorization': 'Bearer ' + access_token} # GET member_id of getTalent user member_id = self.get_member_id() if not member_id: raise InternalServerError('Could not get member id from social-network:%s' % self.social_network.name) # Check all user_social_network_credentials in database against this member_id records_in_db = UserSocialNetworkCredential.filter_by_keywords(social_network_id=self.social_network.id, member_id=member_id) user_credentials_dict = dict(user_id=self.user.id, social_network_id=self.social_network.id, access_token=access_token, refresh_token=refresh_token, member_id=member_id) if not records_in_db: # No record found in database return self.save_user_credentials_in_db(user_credentials_dict) if len(records_in_db) >= 1: for record in records_in_db: if record.user.id == self.user.id: error_message = 'You are already connected to this account.' logger.error(error_message) raise InvalidUsage(error_message) elif record.user.domain_id == self.user.domain_id: error_message = 'Some other user is already in your domain with this account. user_id:%s, ' \ 'social_network:%s , member_id:%s.' % (self.user.id, self.social_network.name.title(), member_id) logger.error(error_message) raise InvalidUsage(error_message) else: # updating new access and refresh tokens for all user connected with same meetup account. record.access_token = access_token record.refresh_token = refresh_token db.session.commit() return self.save_user_credentials_in_db(user_credentials_dict)
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
def rsvp_events_importer(social_network_name, mode, user_credentials_id, datetime_range): """ Imports RSVPs or events of a user, create candidates store them in db and also upload them on Cloud search :param str social_network_name: Facebook, Eventbrite, Meetup :param str mode: rsvp or event :param int user_credentials_id: user credentials entry :param dict datetime_range: """ with app.app_context(): logger = app.config[TalentConfigKeys.LOGGER] user_credentials = UserSocialNetworkCredential.get_by_id( user_credentials_id) user_id = user_credentials.user_id try: social_network = SocialNetwork.get_by_name( social_network_name.lower()) 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 token8 sn = social_network_class(user_id) logger.info( '%s Importer has started for %s(UserId: %s). Social Network is %s.' % (mode.title(), sn.user.name, sn.user.id, social_network.name)) # Call social network process method to start importing rsvps/event sn.process(mode, user_credentials=user_credentials, **datetime_range) # Update last_updated of each user_credentials. user_credentials.update( updated_datetime=datetime.datetime.utcnow()) except Exception as e: logger.exception( 'start: running %s importer, user_id: %s failed. %s', mode, user_id, e.message)
def get(self): """ This action returns a list of user social networks. :Example: headers = {'Authorization': 'Bearer <access_token>'} response = requests.get(API_URL + '/venues/', headers=headers) .. Response:: { "count": 3, "social_networks": [ { "api_url": "https://api.meetup.com/2", "auth_url": "https://secure.meetup.com/oauth2", "client_key": "jgjvi3gsvrgjcp2mu9r6nb3kb0", "id": 13, "is_subscribed": true, "name": "Meetup", "redirect_uri": "http://127.0.0.1:8000/web/user/get_token", "updated_time": "", "url": "www.meetup.com/" }, { "api_url": "https://www.eventbriteapi.com/v3", "auth_url": "https://www.eventbrite.com/oauth", "client_key": "MSF5F2NUE35NQTLRLB", "id": 18, "is_subscribed": true, "name": "Eventbrite", "redirect_uri": "http://127.0.0.1:8000/web/user/get_token", "updated_time": "", "url": "www.eventbrite.com" }, { "api_url": "https://graph.facebook.com/v2.4", "auth_url": "https://graph.facebook.com/oauth", "client_key": "1709873329233611", "id": 2, "is_subscribed": false, "name": "Facebook", "redirect_uri": "", "updated_time": "", "url": "www.facebook.com/" } ] } .. HTTP Status:: 200 (OK) 500 (Internal Server Error) """ user_id = request.user.id connected_networks = request.args.get('connected_networks', '0') if connected_networks == '1': user_credentials = UserSocialNetworkCredential.get_connected_networks( request.user.id) social_networks = [ user_credential.social_network.to_json() for user_credential in user_credentials ] return dict(social_networks=social_networks) # Get list of networks user is subscribed to from UserSocialNetworkCredential table subscribed_networks = None subscribed_data = UserSocialNetworkCredential.get_by_user_id( user_id=user_id) if subscribed_data: # Get list of social networks user is subscribed to subscribed_networks = SocialNetwork.get_by_ids( [data.social_network_id for data in subscribed_data]) # Convert it to JSON subscribed_networks[0].to_json() subscribed_networks = map(lambda sn: sn.to_json(), subscribed_networks) # Add 'is_subscribed' key in each object and set it to True because # these are the social networks user is subscribed to subscribed_networks = self.set_is_subscribed(subscribed_networks, value=True) # Get list of social networks user is not subscribed to unsubscribed_networks = SocialNetwork.get_all_except_ids( [data.social_network_id for data in subscribed_data]) if unsubscribed_networks: unsubscribed_networks = map(lambda sn: sn.to_json(), unsubscribed_networks) # Add 'is_subscribed' key in each object and set it to False unsubscribed_networks = self.set_is_subscribed( unsubscribed_networks, value=False) # Now merge both subscribed and unsubscribed networks all_networks = [] if subscribed_networks: all_networks.extend(subscribed_networks) if unsubscribed_networks: all_networks.extend(unsubscribed_networks) if all_networks: for sn in all_networks: del sn['secret_key'] return dict(social_networks=all_networks, count=len(all_networks)) else: return dict(social_networks=[], count=0)
def test_eventbrite_rsvp_importer_endpoint(self, token_first, user_first, talent_pool_session_scope, user_same_domain, token_same_domain): """ Test eventbrite rsvps importer. A pre-existing rsvp is on eventbrite. - Run rsvp importer for eventbrite. - Then check if already created rsvp is imported correctly or not - Then again run rsvp importer and assert there should be only 1 rsvp - Remove user talent pool and run tests and rsvp should not be imported """ rsvp_id = '672393772' social_network_event_id = '26557579435' user_id = user_first['id'] headers = dict(Authorization='Bearer %s' % token_first) headers['Content-Type'] = 'application/json' eventbrite_obj = SocialNetwork.get_by_name('Eventbrite') usercredentials = UserSocialNetworkCredential.get_all_credentials( eventbrite_obj.id) for usercredential in usercredentials: usercredential.update(updated_datetime=None) rsvps = RSVP.filter_by_keywords( **{ 'social_network_rsvp_id': rsvp_id, 'social_network_id': eventbrite_obj.id }) for rsvp in rsvps: RSVP.delete(rsvp.id) """---------------------------Get or Import event for eventbrite-------------------------------""" event = Event.get_by_user_and_social_network_event_id( user_id=user_id, social_network_event_id=social_network_event_id) # If event is not imported then run event importer and import events first if not event: # Import events first then import RSVPs response = requests.post(url=SocialNetworkApiUrl.IMPORTER % ('event', 'eventbrite'), headers=headers) assert response.status_code == codes.OK retry(assert_event, args=(user_id, social_network_event_id), sleeptime=15, attempts=15, sleepscale=1, retry_exceptions=(AssertionError, )) eventbrite_event = Event.get_by_user_and_social_network_event_id( user_id, social_network_event_id) assert eventbrite_event """------------------------------------------------------------------------------------------------ -----------------------------SECTION: Import RSVPs for User 1-------------------------------------- """ response = requests.post(url=SocialNetworkApiUrl.IMPORTER % ('rsvp', 'eventbrite'), data=json.dumps({}), headers=headers) assert response.status_code == codes.OK # Check if rsvp is imported for user 1 def f(_rsvp_id, _eventbrite_id, event_id, count=1): db.db.session.commit() _rsvp = RSVP.filter_by_keywords( **{ 'social_network_rsvp_id': _rsvp_id, 'social_network_id': _eventbrite_id, 'event_id': event_id }) assert len(_rsvp) == count retry(f, sleeptime=15, attempts=15, sleepscale=1, retry_exceptions=(AssertionError, ), args=(rsvp_id, eventbrite_obj.id, eventbrite_event.id)) """------------------------------------------------------------------------------------------------ Get RSVP for user id 2, which shouldn't be imported due to talent pool attached """ db.db.session.commit() eventbrite_event_user_second = Event.get_by_user_and_social_network_event_id( user_same_domain['id'], social_network_event_id) assert eventbrite_event_user_second retry(f, sleeptime=15, attempts=15, sleepscale=1, retry_exceptions=(AssertionError, ), args=(rsvp_id, eventbrite_obj.id, eventbrite_event_user_second.id, 0)) """------------------------------------------------------------------------------------------------ ----------------SECTION: Import RSVPs again and rsvps shouldn't be redundant------------------------ """ # Run rsvp importer again and data should not be redundant. response = requests.post(url=SocialNetworkApiUrl.IMPORTER % ('rsvp', 'eventbrite'), data=json.dumps({}), headers=headers) assert response.status_code == codes.OK retry(f, sleeptime=15, attempts=15, sleepscale=1, retry_exceptions=(AssertionError, ), args=(rsvp_id, eventbrite_obj.id, eventbrite_event.id)) rsvp = RSVP.get_by_social_network_rsvp_id_and_social_network_id( rsvp_id, eventbrite_obj.id) RSVP.delete(rsvp.id)
def disconnect(cls, user_id, social_network): user_credentials = UserSocialNetworkCredential.get_by_user_and_social_network_id(user_id, social_network.id) if user_credentials: UserSocialNetworkCredential.delete(user_credentials) return user_credentials
def __init__(self, user_id, social_network_id=None, validate_credentials=True, validate_token=True, exclude_fields=()): """ - This sets the user's credentials as base class property so that it can be used in other classes. - We also check the validity of access token and try to refresh it in case it has expired. :param int|long user_id: Id of User :param int|long|None social_network_id: Social Network Id :param bool validate_credentials: If True, this will validate the credentials of user for given social network. :param bool validate_token: If True, this will validate auth token of user for given social network. """ self.events = [] self.api_relative_url = None self.user, self.social_network = self.get_user_and_social_network(user_id, social_network_id) self.api_url = self.social_network.api_url self.user_credentials = UserSocialNetworkCredential.get_by_user_and_social_network_id(self.user.id, self.social_network.id) if validate_credentials: if not self.user_credentials: raise UserCredentialsNotFound('UserSocialNetworkCredential for social network ' '%s and User Id %s not found in db.' % (self.__class__.__name__, self.user.id)) data = { "access_token": self.user_credentials.access_token, "gt_user_id": self.user_credentials.user_id, "social_network_id": self.social_network.id, "auth_url": self.social_network.auth_url } # checks if any field is missing for given user credentials items = [value for key, value in data.iteritems() if key not in exclude_fields] if all(items): self.auth_url = data['auth_url'] self.gt_user_id = data['gt_user_id'] self.social_network_id = data['social_network_id'] self.access_token = data['access_token'] else: # gets fields which are missing items = [key for key, value in data.iteritems() if key not in exclude_fields and not value] data_to_log = {'user_id': self.user.id, 'missing_items': items} # Log those fields in error which are not present in Database error_message = "User id: %(user_id)s\n Missing Item(s) in user's " \ "credential: %(missing_items)s\n" % data_to_log raise MissingFieldsInUserCredentials('API Error: %s' % error_message) # Eventbrite and meetup social networks take access token in header # so here we generate authorization header to be used by both of them self.headers = {'Authorization': 'Bearer ' + self.access_token} # token validity is checked here. If token is expired, we refresh it # here and save new access token in database. if validate_token: self.access_token_status = self.validate_and_refresh_access_token() else: self.access_token_status = True if not self.access_token_status: # Access token has expired. Couldn't refresh it for given # social network. logger.info('__init__: Access token has expired. Please connect with %s again from "Profile" page. ' 'user_id: %s' % (self.social_network.name, self.user.id)) raise AccessTokenHasExpired('Access token has expired for %s' % self.social_network.name) self.start_date_dt = None self.webhook_id = None if not self.user_credentials.member_id and validate_token: # gets and save the member id of gt-user self.get_member_id()