"""Collector for instagram metrics.""" import requests from social_analytics import config from social_analytics.constants import collectors def collect_instagram_metrics(profile_id, instagram_auth_token): """ Collect instagram metrics for a given profile id. Args: profile_id (str): the id by which to query the instagram API. instagram_auth_token (str): the instagram auth token. Returns: dict: instagram API's json response dict. """ if not profile_id.strip(): return url = construct_instagram_url(profile_id, instagram_auth_token) result = requests.get(url) return result.json() def construct_instagram_url(profile_id, instagram_auth_token): """ Generate a instagram api url based on a profile id. Args: profile_id (str): the id for which to generate a instagram API url. instagram_auth_token (str): the instagram access token. Returns: url (str): a instagram API url for the given id. """ url = '{base_url}{profile_id}?access_token={access_token}'.format( base_url=collectors.INSTAGRAM_BASE_URL, profile_id=profile_id, access_token=instagram_auth_token) return url def refresh_token(): """Refresh instagram access token. Returns: dict: Until the refresh token functionality is implemented, the token stored in config. """ # TODO implement instagram token refresh. return config.INSTAGRAM_ACCESS_TOKEN def recommend_instagram_profile(profile_name, instagram_auth_token): """Recommend instagram profile. Args: profile_name (str): The profile name of the artist. instagram_auth_token (str): The instagram access token. Returns: Dict or None: A dictionary with the suggested profile or None when no profile matches the given name. """ # Get users list limited to a count of 1. # Sometimes the result has more than one items. url = ( '{base_url}search?q={profile_name}&count=1&access_token={access_token}' .format( base_url=collectors.INSTAGRAM_BASE_URL, profile_name=profile_name, access_token=instagram_auth_token)) result = requests.get(url) result_json = result.json() if 'data' not in result_json or not result_json['data']: return None profiles = result_json['data'] profile_with_most_likes = None # In the case of more than one result iterate over them. for profile in profiles: # Fetch info for profile. user_search_response = collect_instagram_metrics( profile['id'], instagram_auth_token) # In case of error, usually it's a private profile. if 'data' not in user_search_response: continue user_info = user_search_response['data'] if profile_with_most_likes is None: profile_with_most_likes = user_info continue if (user_info['counts']['followed_by'] > profile_with_most_likes['counts']['followed_by']): profile_with_most_likes = user_info if profile_with_most_likes: return { 'platform': 'instagram', 'platform_id': profile_with_most_likes['id'], 'platform_name': profile_with_most_likes['username'], 'metric_value': profile_with_most_likes['counts']['followed_by'] } def verify_instagram_profile(platform_id, instagram_auth_token): """Verify instagram profile. Args: platform_id (str): The profile id of the artist e.g. 123444453 Returns: Dict or None: A dictionary with the verified profile or None when there is not any profile for the given profile name. """ url = construct_instagram_url(platform_id, instagram_auth_token) result = requests.get(url) result_json = result.json() if 'error_message' in result_json['meta']: return None data = result_json['data'] return { 'platform': 'instagram', 'platform_id': data['id'], 'platform_name': data['username'], 'metric_value': data['counts']['followed_by'] }