class Instagram(source.Source): """Implements the ActivityStreams API for Instagram.""" DOMAIN = 'instagram.com' NAME = 'Instagram' FRONT_PAGE_TEMPLATE = 'templates/instagram_index.html' def __init__(self, access_token=None): """Constructor. If an OAuth access token is provided, it will be passed on to Instagram. This will be necessary for some people and contact details, based on their privacy settings. Args: access_token: string, optional OAuth access token """ self.access_token = access_token self.api = InstagramAPI(access_token=access_token) def user_url(self, username): return 'http://instagram.com/' + username def get_actor(self, user_id=None): """Returns a user as a JSON ActivityStreams actor dict. Args: user_id: string id or username. Defaults to 'self', ie the current user. Raises: InstagramAPIError """ if user_id is None: user_id = 'self' return self.user_to_actor(self.api.user(user_id)) def get_activities_response(self, user_id=None, group_id=None, app_id=None, activity_id=None, start_index=0, count=0, etag=None, min_id=None, cache=None, fetch_replies=False, fetch_likes=False, fetch_shares=False, fetch_events=False): """Fetches posts and converts them to ActivityStreams activities. See method docstring in source.py for details. app_id is ignored. Supports min_id, but not ETag, since Instagram doesn't support it. http://instagram.com/developer/endpoints/users/#get_users_feed http://instagram.com/developer/endpoints/users/#get_users_media_recent Likes are always included, regardless of the fetch_likes kwarg. They come bundled in the 'likes' field of the API Media object: http://instagram.com/developer/endpoints/media/# Instagram doesn't have a reshare feature, so shares are never included since they don't exist. :P Raises: InstagramAPIError """ if user_id is None: user_id = 'self' if group_id is None: group_id = source.FRIENDS # TODO: paging media = [] kwargs = {} if min_id is not None: kwargs['min_id'] = min_id try: if activity_id: media = [self.api.media(activity_id, **kwargs)] elif group_id == source.SELF: media, _ = self.api.user_recent_media(user_id, **kwargs) elif group_id == source.ALL: media, _ = self.api.media_popular(**kwargs) elif group_id == source.FRIENDS: media, _ = self.api.user_media_feed(**kwargs) except InstagramAPIError, e: if e.error_type == 'APINotFoundError': logging.exception(e.error_message) media = [] else: raise activities = [self.media_to_activity(m) for m in media] response = self._make_activities_base_response(activities) return response
class Instagram(source.Source): """Implements the ActivityStreams API for Instagram.""" DOMAIN = "instagram.com" FRONT_PAGE_TEMPLATE = "templates/instagram_index.html" AUTH_URL = "&".join( ( "https://api.instagram.com/oauth/authorize?", "client_id=%s" % appengine_config.INSTAGRAM_CLIENT_ID, # firefox and chrome preserve the URL fragment on redirects (e.g. from # http to https), but IE (6 and 8) don't, so i can't just hard-code http # as the scheme here, i need to actually specify the right scheme. "redirect_uri=%s://%s/" % (appengine_config.SCHEME, appengine_config.HOST), "response_type=token", ) ) def __init__(self, access_token=None): """Constructor. If an OAuth access token is provided, it will be passed on to Instagram. This will be necessary for some people and contact details, based on their privacy settings. Args: access_token: string, optional OAuth access token """ self.access_token = access_token self.api = InstagramAPI( client_id=appengine_config.INSTAGRAM_CLIENT_ID, client_secret=appengine_config.INSTAGRAM_CLIENT_SECRET, access_token=access_token, ) def get_actor(self, user_id=None): """Returns a user as a JSON ActivityStreams actor dict. Args: user_id: string id or username. Defaults to 'self', ie the current user. """ if user_id is None: user_id = "self" return self.user_to_actor(self.api.user(user_id)) def get_activities(self, user_id=None, group_id=None, app_id=None, activity_id=None, start_index=0, count=0): """Returns a (Python) list of ActivityStreams activities to be JSON-encoded. See method docstring in source.py for details. app_id is ignored. http://instagram.com/developer/endpoints/users/#get_users_feed http://instagram.com/developer/endpoints/users/#get_users_media_recent """ if user_id is None: user_id = "self" if group_id is None: group_id = source.FRIENDS # TODO: paging media = [] try: if activity_id: media = [self.api.media(activity_id)] elif group_id == source.SELF: media, _ = self.api.user_recent_media(user_id) elif group_id == source.ALL: media, _ = self.api.media_popular() elif group_id == source.FRIENDS: media, _ = self.api.user_media_feed() except InstagramAPIError, e: if e.status_code == 400: logging.exception(e.error_message) media = [] else: raise return len(media), [self.media_to_activity(m) for m in media]