def save_event(self): """ This method takes dictionary containing event data. It first checks if any event is there with given info (user_id, social_network_id, social_network_event_id), then it updates the existing event otherwise creates a new event in getTalent database. Call this method after successfully publishing event on social network. :return event.id: id for event in getTalent database, that was created or updated :rtype event.id : int """ data = self.data sn_event_id = data['social_network_event_id'] social_network_id = data['social_network_id'] event = Event.get_by_user_id_social_network_id_vendor_event_id( self.user.id, social_network_id, sn_event_id) try: # if event exists in database, then update existing one. if event: del data['id'] event.update(**data) else: # event not found in database, create a new one event = Event(**data) Event.save(event) except Exception as error: logger.exception( 'save_event: Event was not updated/saved in Database. ' 'user_id: %s, event_id: %s, social network: %s(id: %s). Error:%s' % (self.user.id, event.id, self.social_network.name, self.social_network.id, error.message)) raise EventNotSaveInDb( 'Error occurred while saving event in database') return event.id
def authenticate(self): """ Here we use OAuthHandler of tweepy to give us request token. We use that request token and redirect the user to Twitter website where user can add its credentials. Once user is successfully logged-in, user is again redirected to URL as specified by callback URL of OAuthHandler which is http://127.0.0.1:8007/v1/twitter-callback/<int:user_id> (for local environment) in this case. In case of failure, we log the error and raises InternalServerError. This method is called from endpoint http://127.0.0.1:8007/v1/twitter-auth. """ try: # redirect_url takes the user to login-page of Twitter to authorize getTalent app. redirect_url = self.auth.get_authorization_url() # Once user is successfully logged-in to Twitter account, it is redirected to callback URL where # we need to exchange request token with access token. This access token is used to access Twitter API. # So, we save request_token in the redis and retrieve this in callback() method. redis_store.set('twitter_request_token_%s' % self.user.id, json.dumps(self.auth.request_token)) # redirect the user to Twitter website for authorization. return redirect_url except tweepy.TweepError as error: logger.exception( 'Error! Failed to get request token from Twitter for User(id:%s).\nError:%s' % (self.user.id, error.message)) raise InternalServerError("Couldn't connect to Twitter account.")
def delete_event(self, event_id, delete_from_vendor=True): """ Here we pass an event id, picks it from db, and try to delete it both from social network and database. If successfully deleted from both sources, returns True, otherwise returns False. :param event_id: is the 'id' of event present in our db :type event_id: int or long :param delete_from_vendor: is flag to delete event from third party :type delete_from_vendor: bool :return: True if deletion is successful, False otherwise. :rtype: bool """ event = Event.get_by_user_and_event_id(self.user.id, event_id) if event: try: if delete_from_vendor: self.unpublish_event(event.social_network_event_id) self.archive_email_campaigns_for_deleted_event( event, delete_from_vendor) return True except Exception: # some error while removing event logger.exception( 'delete_event: user_id: %s, event_id: %s, social network: %s(id: %s)' % (self.user.id, event.id, self.social_network.name, self.social_network.id)) return False # event not found in database
def process_events(self, events): """ :param list events: contains events of a particular user for a specific social network. This is the function to process events once we have the events of some social network. It first maps the social network fields to gt-db fields. Then it checks if the event is present is db or not. If event is already in db, it updates the event fields otherwise it stores the event in db. Finally we import RSVPs of all the events in method post_process_events(). """ if events: self.pre_process_events(events) if events: logger.info( 'Events of %s(UserId: %s) are being processed to save in database.' % (self.user.name, self.user.id)) for event in events: try: self.events.append(self.import_event(event)) except Exception: logger.exception( '''Error occurred while importing event. UserId: %s, SocialNetworkId: %s Event: %s ''' % (self.user.id, self.social_network.id, event)) self.mark_vendor_deleted(events) if events: self.post_process_events()
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')
def get_all_pages(self, response, target_list): """ :param response: dictionary containing data after a request is made. :param target_list: list in which items to be appended after getting from different pages/requests :type response: requests.Response :type target_list: list - This method is used to get the paginated data. To get all data about event attendees, event rsvps etc we need to send multiple request because facebook sends data in pages or we can say chunks, some specific number of records in a single request and a url to next page (resources). So to get all pages data call this method and pass first request response and target list in which data is to be appended. It will send request to get next page given in this request "next" attribute/Key and will continue until no next page is there to fetch. :Example: try: # get those attendees who have confirmed their presence expected_attendees = self.graph.get_object(url + 'confirm') except facebook.GraphAPIError as error: # handle errors here pass rsvps += expected_attendees['data'] self.get_all_pages(expected_attendees, rsvps) It will add all confirm rsvps in "rsvps" list which was passed as target. **See Also** .. seealso:: process_rsvps() method in RSVPBase class inside social_network_service/rsvp/base.py for more insight. :return: attendee object which contains data about the candidate """ while True: try: response = requests.get(response['paging']['next']) if response.ok: response = response.json() if 'data' in response: target_list.extend(response['data']) except KeyError: break except requests.HTTPError as error: error_message_dict = dict(url=response['paging']['next'], error_message=error.message) error_message = "Couldn't get data while paginating over " \ "Facebook records. URL: %(url)s, " \ "%(error_message)s" % error_message_dict logger.exception("get_all_pages: %s, user_id: %s" % (error_message, self.user.id)) raise
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
def process(self, mode, user_credentials=None, **kwargs): """ :param mode: mode is either 'event' or 'rsvp. :param user_credentials: are the credentials of user for a specific social network in db. :type mode: str :type user_credentials: common.models.user.UserSocialNetworkCredential - Depending upon the mode, here we make the objects of required classes (Event Class or RSVP class) and call required methods on those objects for importing events or rsvps. - This method is called from start() defined in social network manager inside social_network_service/manager.py. :Example: from social_network_service.meetup import Meetup sn = Meetup(user_id=1) sn.process('event', user_credentials=user_credentials) **See Also** .. seealso:: start() function defined in social network manager inside social_network_service/manager.py. """ user_id = self.user.id social_network_id = self.social_network.id social_network_name = self.social_network.name try: sn_name = self.social_network.name.strip() # get_required class under social_network_service/event/ to process events event_class = get_class(sn_name, 'event') # create object of selected event class sn_event_obj = event_class(user_credentials=user_credentials, social_network=self.social_network, headers=self.headers, **kwargs) if mode == EVENT: # gets events using respective API of Social Network logger.info('Getting event(s) of %s(UserId:%s) from %s website.' % (self.user.name, self.user.id, self.social_network.name)) self.events = sn_event_obj.get_events() logger.info('Got %s live event(s) of %s(UserId: %s) on %s within provided time range.' % (len(self.events), self.user.name, self.user.id, self.social_network.name)) # process events to save in database sn_event_obj.process_events(self.events) elif mode == RSVP: sn_event_obj.process_events_rsvps(user_credentials, headers=self.headers, social_network=self.social_network) except Exception: logger.exception('process: running %s importer, user_id: %s, social network: %s(id: %s)' % (mode, user_id, social_network_name, social_network_id))
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")
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 get_events(self): """ This method retrieves events from facebook through its Graph API and saves in database. We send GET requests to API URL and get data. We also have to handle pagination because Facebook's API sends paginated response. :return: all events of getTalent user on Facebook within specified time range :rtype: list :Example: create facebook object and call get_events on it facebook = Facebook(user=gt_user, headers=auth_headers) facebook.get_events() """ self.graph = facebook.GraphAPI(access_token=self.access_token) all_events = [] user_events = [] # https://developer.facebook.com to see detail on params try: response = self.graph.get_object( 'v2.4/me/events', fields='is_viewer_admin, description, name, category, owner, ' 'place, start_time, ticket_uri, end_time, parent_group, ' 'attending_count, maybe_count, noreply_count, timezone', since=self.start_date, until=self.end_date) except facebook.GraphAPIError: logger.exception('get_events: user_id: %s' % self.user.id) raise if 'data' in response: user_events.extend(response['data']) self.get_all_pages(response, user_events) # Need only events user is an admin of user_events = filter(lambda event: event['is_viewer_admin'] is True, user_events) all_events.extend(user_events) return all_events
def get_all_pages(self, response, target_list): """ We keep iterating over pages as long as keep finding the URL in response['paging']['next']. :param response: :param target_list: :type response: dict :type target_list: list """ while True: try: response = requests.get(response['paging']['next']) if response.ok: response = response.json() if response and response['data']: target_list.extend(response['data']) except KeyError: break except requests.HTTPError: logger.exception('get_all_pages: user_id: %s' % self.user.id) raise
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)
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 event_sn_to_gt_mapping(self, event): """ We take event's data from social network's API and map its fields to getTalent database fields. Finally we return Event's object to save/update record in getTalent database. We also issue some calls to get updated venue and organizer information. :param event: data from Facebook API. :type event: dictionary :exception Exception: It raises exception if there is an error getting data from API. :return: event: Event object :rtype event: common.models.event.Event """ venue = None location = None venue_id = None organizer = None organizer_id = None assert event is not None owner = event.get('owner') if event.get('place'): venue = event.get('place') location = venue['location'] try: organizer = self.graph.get_object('v2.4/' + owner['id']) organizer = organizer.get('data') except facebook.GraphAPIError: logger.exception( 'event_sn_to_gt_mapping: Getting data of organizer. ' 'user_id: %s, social_network_event_id: %s' % (self.user.id, event['id'])) raise if owner or organizer: organizer_data = dict( user_id=self.user.id, name=owner['name'] if owner and owner.has_key('name') else '', email=organizer['email'] if organizer and organizer.has_key('email') else '', about='') organizer_in_db = EventOrganizer.get_by_user_id_and_name( self.user.id, owner['name'] if owner and owner.has_key('name') else '') if organizer_in_db: organizer_in_db.update(**organizer_data) organizer_id = organizer_in_db.id else: organizer_instance = EventOrganizer(**organizer_data) EventOrganizer.save(organizer_instance) organizer_id = organizer_instance.id if venue: venue_data = dict( social_network_venue_id=venue['id'], user_id=self.user.id, address_line_1=location['street'] if location.has_key('street') else '', address_line_2='', city=location['city'].title() if location.has_key('city') else '', state='', zip_code=location['zip'] if location.has_key('zip') else None, country=location['country'].title() if location.has_key('country') else '', longitude=float(location['longitude']) if location.has_key('longitude') else 0, latitude=float(location['latitude']) if location.has_key('latitude') else 0, ) venue_in_db = Venue.get_by_user_id_and_social_network_venue_id( self.user.id, venue['id']) if venue_in_db: venue_in_db.update(**venue_data) venue_id = venue_in_db.id else: venue = Venue(**venue_data) Venue.save(venue) venue_id = venue.id try: event = Event(social_network_event_id=event['id'], title=event['name'], description=event.get('description', ''), social_network_id=self.social_network.id, user_id=self.user.id, organizer_id=organizer_id, venue_id=venue_id, social_network_group_id=0, start_datetime=event.get('start_time'), end_datetime=event.get('end_time'), timezone=event.get('timezone'), registration_instruction='', cost=0, currency='', max_attendees=event['attending_count'] + event['maybe_count'] + event['noreply_count'] if (event and event.has_key('attending_count') and event.has_key('maybe_count') and event.has_key('noreply_count')) else '') except: logger.exception('event_sn_to_gt_mapping: user_id: %s, ' 'social_network_event_id: %s' % (self.user.id, event['id'])) else: return event
def post_process_rsvp(self, rsvp): """ :param dict rsvp: is likely the response from social network API. ** Working ** - Here we do the following steps a)- We move on to get attendee using the given rsvp by get_attendees() call. "attendees" is a utility object we share in calls that contains pertinent data. get_attendee() should be implemented by a child. b)- We pick the source product of RSVP (e.g. meetup or eventbrite). c)- We store the source of candidate in candidate_source db table. d)- Once we have the attendees data we call save_attendee_as_candidate() which stores each attendee as a candidate. e)- Finally we save the RSVP in following tables 1- rsvp 3- Activity - 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 # TODO: Through nightly script which fetches data from different social networks :Example: - rsvp_obj = Meetup(social_network=self.social_network, headers=self.headers, user_credentials=user_credentials) - event = Event.get_by_id(1) - rsvps = rsvp_obj.get_rsvps(event) - rsvp_obj.post_process_rsvps(rsvps[0]) **See Also** .. seealso:: process_events_rsvps() method in EventBase class social_network_service/event/base.py """ self.user = db.session.merge(self.user) self.social_network = db.session.merge(self.social_network) try: attendee = self.get_attendee(rsvp) if not attendee: logger.info('Attendee object couldn\'t be created because event is not imported yet. RSVP data: %s' % rsvp) return # following picks the source product id for attendee attendee = self.pick_source_product(attendee) # following will store candidate info in attendees attendee = self.save_attendee_source(attendee) # following will store candidate info in attendees attendee = self.save_attendee_as_candidate(attendee) # following call will store rsvp info in attendees attendee = self.save_rsvp(attendee) # finally we store info in table activity attendee = self.save_rsvp_in_activity_table(attendee) return attendee except Exception: # Shouldn't raise an exception, just log it and move to process next RSVP logger.exception('post_process_rsvps: user_id: %s, RSVP data: %s, social network: %s(id:%s)' % (self.user.id, rsvp, self.social_network.name, self.social_network.id))
def get_all_rsvps(self, events): """ :param events: events contains all the events of a particular user present in database table "event". :type events: list ** Working ** - We go over each event one by one and get RSVPs of that event. This is done in the get_rsvps() method which fetches RSVPs and attach them to rsvps list of dicts. :Example: If we are importing rsvps of social network meetup, then we create RSVP class object in EventBase class method process_events_rsvps() as sn_rsvp_obj = sn_rsvp_class(social_network=self.social_network, headers=self.headers, user_credentials=user_credentials) Then we 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) :return: It appends rsvps of all events of a particular user in self.rsvps and returns it. - We use this method inside process_events_rsvps() defined in EventBase class inside social_network_service/event/base.py. - We use this method while importing RSVPs through social_network either by direct hitting endpoint or by running an hourly job scheduled by scheduler service. **See Also** .. seealso:: process_events_rsvps() method in EventBase class inside social_network_service/event/base.py """ if events: logger.info('Getting RSVPs for events of %s(UserId: %s) from %s website.' % (self.user.name, self.user.id, self.social_network.name)) for event in events: # events is a list of dicts where each dict is likely a # response return from the database. # We pick one event from events_list, and get its rsvps # from respective social network. try: rsvps = self.get_rsvps(event) # rsvps is a list of dicts, where each dict is likely a response returned from the # social network side. if rsvps: # appends RSVPs of all events in self.rsvps self.rsvps += rsvps except Exception as error: # Shouldn't raise an exception, just log it and move to get RSVPs of next event logger.exception('get_all_rsvps: user_id: %s, event_id: %s, social network: %s(id:%s)' % (self.user.id, event.id, self.social_network.name, self.social_network.id)) if hasattr(error, 'response'): if error.response.status_code == codes.UNAUTHORIZED: # Access token is Invalid, Stop the execution. break logger.info('There are %d RSVPs to process for events of %s(UserId: %s).' % (len(self.rsvps), self.user.name, self.user.id)) return self.rsvps
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) **See Also** .. seealso:: process_rsvps() method in RSVPBase class inside social_network_service/rsvp/base.py for more insight. """ try: data = self.graph.get_object('v2.4/' + rsvp['id'], fields='first_name, last_name, name, ' 'email, location, address, ' 'link, picture') except facebook.GraphAPIError: logger.exception( "get_attendee: Couldn't get Facebook's attendee info. " "user_id: %s, social_network_rsvp_id: %s" % (self.user.id, rsvp['id'])) raise if 'location' in data: try: location = self.graph.get_object('v2.4/' + data['location']['id'], fields='location') except facebook.GraphAPIError: logger.exception( "get_attendee: Couldn't get location info (Facebook). " "user_id: %s, social_network_rsvp_id: %s" % (self.user.id, rsvp['id'])) raise if 'location' in location: location = location['location'] else: location = {} if data: try: attendee = Attendee() attendee.first_name = data.get('first_name', '') attendee.last_name = data.get('last_name', '') attendee.full_name = data.get('name', '') attendee.email = data.get('email', '') attendee.city = location.get('city', '') attendee.country = location.get('country', '') attendee.latitude = location.get('latitude') attendee.longitude = location.get('longitude') attendee.zip = location.get('zip') attendee.social_profile_url = data.get('link', '') attendee.picture_url = data['picture']['data']['url'] \ if 'picture' in data and 'data' in data['picture']\ and 'url' in data['picture']['data'] else '' attendee.gt_user_id = self.user.id attendee.social_network_id = self.social_network.id # we are using profile_id here as we don't have any # rsvp_id for this vendor. attendee.vendor_rsvp_id = rsvp['id'] # We do not have 'time' of rsvp from Facebook API response. # We cannot use datetime.now() here because every time we run # importer, we will have duplicate candidates as their added # time will not be same as the added time of previous record. # So for now, we are saving it as blank. attendee.added_time = ' ' attendee.vendor_img_link = \ "<img class='pull-right' " \ "style='width:60px;height:30px' " \ "src='/web/static/images/activities/facebook_logo.png'/>" social_network_event_id = rsvp['vendor_event_id'] if rsvp['rsvp_status'].strip() == 'attending' \ or rsvp['rsvp_status'].strip() == 'maybe': attendee.rsvp_status = 'yes' else: attendee.rsvp_status = 'no' event = Event.get_by_user_id_social_network_id_vendor_event_id( self.user.id, self.social_network.id, social_network_event_id) if event: attendee.event = event return attendee else: raise EventNotFound( 'Event is not present in db, ' 'social_network_event_id is ' '%s. User Id: %s' % (social_network_event_id, self.user.id)) except Exception: raise
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 from Graph API of Facebook - 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. """ rsvps = [] try: self.graph = facebook.GraphAPI(access_token=self.access_token) url = 'v2.4/%s' % str(event.social_network_event_id) + '/' # Get list of people surely attending confirm_attendees = self.graph.get_object(url + 'attending') except facebook.GraphAPIError: logger.exception( "get_rsvps: Couldn't get 'attending' RSVPs (Facebook), " "user_id: %s, social_network_event_id: %s" % (self.user.id, event.social_network_event_id)) raise rsvps += confirm_attendees['data'] self.get_all_pages(confirm_attendees, rsvps) # Get list of people who aren't certain try: expected_attendees = self.graph.get_object(url + 'maybe') except facebook.GraphAPIError: logger.exception( "get_rsvps: Couldn't get 'maybe' RSVPs (Facebook), " "user_id: %s, social_network_event_id: %s" % (self.user.id, event.social_network_event_id)) raise rsvps += expected_attendees['data'] self.get_all_pages(expected_attendees, rsvps) # Get list of people who declined try: declined_attendees = self.graph.get_object(url + 'declined') except facebook.GraphAPIError: logger.exception( "get_rsvps: Couldn't get 'declined' RSVPs (Facebook), " "user_id: %s, social_network_event_id: %s" % (self.user.id, event.social_network_event_id)) raise rsvps += declined_attendees['data'] self.get_all_pages(declined_attendees, rsvps) for rsvp in rsvps: rsvp.update( {'vendor_event_id': str(event.social_network_event_id)}) return rsvps
def get(self, *args, **kwargs): """ This action returns a list of user events. In the response, we return fields as returned from Meetup's /groups call given at http://www.meetup.com/meetup_api/docs/2/groups/ :Example: headers = {'Authorization': 'Bearer <access_token>'} response = requests.get(API_URL + '/venues/', headers=headers) .. Response:: This response is from Meetup API which will be returned. { "count": 1, "groups": [ { "category": { "shortname": "tech", "name": "tech", "id": 34 }, "city": "Lahore", "utc_offset": 18000000, "who": "Python Lovers", "rating": 0, "description": "This group is for anyone interested in computer programming. Python is one of the top ranking programming languages. All skill levels are welcome. Basic purpose is to get exposure about python from smart people all over the world. We can also meet at some restaurant for some food and drink afterward. Let's meetup and share knowledge.", "created": 1439705650000, "country": "PK", "topics": [ { "name": "Python", "urlkey": "python", "id": 1064 }, { "name": "Web Development", "urlkey": "web-development", "id": 15582 }, { "name": "Programming Languages", "urlkey": "programming-languages", "id": 17628 }, { "name": "Computer programming", "urlkey": "computer-programming", "id": 48471 }, { "name": "Python web development", "urlkey": "python-web-development", "id": 917242 } ], "join_mode": "open", "lon": 74.3499984741211, "visibility": "public", "link": "http://www.meetup.com/QC-Python-Learning/", "members": 59, "urlname": "QC-Python-Learning", "lat": 31.559999465942383, "timezone": "Asia/Karachi", "organizer": { "name": "Waqas Younas", "member_id": 183366764 }, "id": 18837246, "name": "QC - Python Learning" } ] } .. HTTP Status:: 200 (OK) 500 (Internal Server Error) """ user_id = request.user.id try: meetup = Meetup(user_id=user_id) groups = meetup.get_groups() response = dict(groups=groups, count=len(groups)) except Exception as e: logger.exception('Could not get meetup groups') raise InternalServerError(e.message) return response