Ejemplo n.º 1
0
    def user_short_gql(self,
                       user_id: int,
                       use_cache: bool = True) -> UserShort:
        """
        Get full media id

        Parameters
        ----------
        user_id: int
            User ID
        use_cache: bool, optional
            Whether or not to use information from cache, default value is True

        Returns
        -------
        UserShort
            An object of UserShort type
        """
        if use_cache:
            cache = self._userhorts_cache.get(user_id)
            if cache:
                return cache
        variables = {
            "user_id": int(user_id),
            "include_reel": True,
        }
        data = self.public_graphql_request(
            variables, query_hash="ad99dd9d3646cc3c0dda65debcd266a7")
        if not data["user"]:
            raise UserNotFound(user_id=user_id, **data)
        user = extract_user_short(data["user"]["reel"]["user"])
        self._userhorts_cache[user_id] = user
        return user
Ejemplo n.º 2
0
    def search_following_v1(self, user_id: str, query: str) -> List[UserShort]:
        """
        Search following users (Private Mobile API)

        Parameters
        ----------
        user_id: str
            User id of an instagram account
        query: str
            Query to search

        Returns
        -------
        List[UserShort]
            List of users
        """
        results = self.private_request(f"friendships/{user_id}/following/",
                                       params={
                                           "includes_hashtags": "false",
                                           "search_surface":
                                           "follow_list_page",
                                           "query": query,
                                           "enable_groups": "true"
                                       })
        users = results.get("users", [])
        return [extract_user_short(user) for user in users]
Ejemplo n.º 3
0
    def user_followers_v1(self, user_id: int, amount: int = 0) -> List[User]:
        """
        Get user's followers information

        Parameters
        ----------
        user_id: int
            User id of an instagram account
        amount: int, optional
            Maximum number of media to return, default is 0

        Returns
        -------
        List[User]
            List of objects of User type
        """
        user_id = int(user_id)
        max_id = ""
        users = []
        while True:
            result = self.private_request(
                f"friendships/{user_id}/followers/",
                params={
                    "max_id": max_id,
                    "rank_token": self.rank_token
                },
            )
            for user in result["users"]:
                users.append(extract_user_short(user))
            max_id = result.get("next_max_id")
            if not max_id or (amount and len(users) >= amount):
                break
        return users
Ejemplo n.º 4
0
 def search_users(self, query: str) -> List[UserShort]:
     params = {
         "search_surface": "user_search_page",
         "timezone_offset": self.timezone_offset,
         "count": 30,
         "q": query,
     }
     result = self.private_request("users/search/", params=params)
     return [extract_user_short(item) for item in result["users"]]
Ejemplo n.º 5
0
    def user_followers_gql_chunk(
            self,
            user_id: str,
            max_amount: int = 0,
            end_cursor: str = None) -> Tuple[List[UserShort], str]:
        """
        Get user's followers information by Public Graphql API and end_cursor

        Parameters
        ----------
        user_id: str
            User id of an instagram account
        max_amount: int, optional
            Maximum number of media to return, default is 0 - Inf
        end_cursor: str, optional
            The cursor from which it is worth continuing to receive the list of followers

        Returns
        -------
        Tuple[List[UserShort], str]
            List of objects of User type with cursor
        """
        user_id = str(user_id)
        users = []
        variables = {
            "id": user_id,
            "include_reel": True,
            "fetch_mutual": False,
            "first": 12
        }
        self.inject_sessionid_to_public()
        while True:
            if end_cursor:
                variables["after"] = end_cursor
            data = self.public_graphql_request(
                variables, query_hash="5aefa9893005572d237da5068082d8d5")
            if not data["user"] and not users:
                raise UserNotFound(user_id=user_id, **data)
            page_info = json_value(data,
                                   "user",
                                   "edge_followed_by",
                                   "page_info",
                                   default={})
            edges = json_value(data,
                               "user",
                               "edge_followed_by",
                               "edges",
                               default=[])
            for edge in edges:
                users.append(extract_user_short(edge["node"]))
            end_cursor = page_info.get("end_cursor")
            if not page_info.get("has_next_page") or not end_cursor:
                break
            if max_amount and len(users) >= max_amount:
                break
        return users, end_cursor
Ejemplo n.º 6
0
    def user_following_gql(self,
                           user_id: str,
                           amount: int = 0) -> List[UserShort]:
        """
        Get user's following information by Public Graphql API

        Parameters
        ----------
        user_id: str
            User id of an instagram account
        amount: int, optional
            Maximum number of media to return, default is 0

        Returns
        -------
        List[UserShort]
            List of objects of User type
        """
        user_id = str(user_id)
        end_cursor = None
        users = []
        variables = {
            "id": user_id,
            "include_reel": True,
            "fetch_mutual": False,
            "first": 24,
        }
        self.inject_sessionid_to_public()
        while True:
            if end_cursor:
                variables["after"] = end_cursor
            data = self.public_graphql_request(
                variables, query_hash="e7e2f4da4b02303f74f0841279e52d76")
            if not data["user"] and not users:
                raise UserNotFound(user_id=user_id, **data)
            page_info = json_value(data,
                                   "user",
                                   "edge_follow",
                                   "page_info",
                                   default={})
            edges = json_value(data,
                               "user",
                               "edge_follow",
                               "edges",
                               default=[])
            for edge in edges:
                users.append(extract_user_short(edge["node"]))
            end_cursor = page_info.get("end_cursor")
            if not page_info.get("has_next_page") or not end_cursor:
                break
            if amount and len(users) >= amount:
                break
            # time.sleep(sleep)
        if amount:
            users = users[:amount]
        return users
Ejemplo n.º 7
0
    def media_likers(self, media_id: str) -> List[UserShort]:
        """
        Get user's likers

        Parameters
        ----------
        media_id: str

        Returns
        -------
        List[UserShort]
            List of objects of User type
        """
        media_id = self.media_id(media_id)
        result = self.private_request(f"media/{media_id}/likers/")
        return [extract_user_short(u) for u in result['users']]
Ejemplo n.º 8
0
    def user_followers_v1_chunk(
            self,
            user_id: str,
            max_amount: int = 0,
            max_id: str = "") -> Tuple[List[UserShort], str]:
        """
        Get user's followers information by Private Mobile API and max_id (cursor)

        Parameters
        ----------
        user_id: str
            User id of an instagram account
        max_amount: int, optional
            Maximum number of media to return, default is 0 - Inf
        max_id: str, optional
            Max ID, default value is empty String

        Returns
        -------
        Tuple[List[UserShort], str]
            Tuple of List of users and max_id
        """
        unique_set = set()
        users = []
        while True:
            result = self.private_request(f"friendships/{user_id}/followers/",
                                          params={
                                              "max_id": max_id,
                                              "count": 10000,
                                              "rank_token": self.rank_token,
                                              "search_surface":
                                              "follow_list_page",
                                              "query": "",
                                              "enable_groups": "true"
                                          })
            for user in result["users"]:
                user = extract_user_short(user)
                if user.pk in unique_set:
                    continue
                unique_set.add(user.pk)
                users.append(user)
            max_id = result.get("next_max_id")
            if not max_id or (max_amount and len(users) >= max_amount):
                break
        return users, max_id
Ejemplo n.º 9
0
    def user_following_v1(self,
                          user_id: str,
                          amount: int = 0) -> List[UserShort]:
        """
        Get user's following users information by Private Mobile API

        Parameters
        ----------
        user_id: str
            User id of an instagram account
        amount: int, optional
            Maximum number of media to return, default is 0

        Returns
        -------
        List[UserShort]
            List of objects of User type
        """
        user_id = str(user_id)
        max_id = ""
        users = []
        while True:
            if amount and len(users) >= amount:
                break
            params = {
                "rank_token": self.rank_token,
                "search_surface": "follow_list_page",
                "includes_hashtags": "true",
                "enable_groups": "true",
                "query": "",
                "count": 10000
            }
            if max_id:
                params["max_id"] = max_id
            result = self.private_request(f"friendships/{user_id}/following/",
                                          params=params)
            for user in result["users"]:
                users.append(extract_user_short(user))
            max_id = result.get("next_max_id")
            if not max_id:
                break
        if amount:
            users = users[:amount]
        return users
Ejemplo n.º 10
0
    def account_change_picture(self, path: Path) -> UserShort:
        """
        Change photo for your profile (authorized account)

        Parameters
        ----------
        path: Path
            Path to the image you want to update as your profile picture

        Returns
        -------
        UserShort
            An object of UserShort class
        """
        upload_id, _, _ = self.photo_rupload(Path(path))
        result = self.private_request(
            "accounts/change_profile_picture/",
            self.with_default_data({'use_fbuploader': True, 'upload_id': upload_id})
        )
        return extract_user_short(result["user"])
Ejemplo n.º 11
0
    def users_stories_gql(self, user_ids: List[int], amount: int = 0) -> List[UserShort]:
        """
        Get a user's stories (Public API)

        Parameters
        ----------
        user_ids: List[int]
            List of users
        amount: int
            Max amount of stories

        Returns
        -------
        List[UserShort]
            A list of objects of UserShort for each user_id
        """
        assert isinstance(user_ids, list), "user_ids should be a list of user_id"
        self.inject_sessionid_to_public()

        def _userid_chunks():
            assert user_ids is not None
            user_ids_per_query = 50
            for i in range(0, len(user_ids), user_ids_per_query):
                yield user_ids[i:i + user_ids_per_query]

        stories_un = {}
        for userid_chunk in _userid_chunks():
            res = self.public_graphql_request(
                query_hash="303a4ae99711322310f25250d988f3b7",
                variables={"reel_ids": userid_chunk, "precomposed_overlay": False}
            )
            stories_un.update(res)
        users = []
        for media in stories_un['reels_media']:
            user = extract_user_short(media['owner'])
            items = media['items']
            if amount:
                items = items[:amount]
            user.stories = [extract_story_gql(m) for m in items]
            users.append(user)
        return users
Ejemplo n.º 12
0
 def search_users_v1(self, query: str, count: int) -> List[UserShort]:
     """
     Search users by a query (Private Mobile API)
     Parameters
     ----------
     query: str
         Query to search
     count: int
         The count of search results
     Returns
     -------
     List[UserShort]
         List of users
     """
     results = self.private_request("users/search/",
                                    params={
                                        "query": query,
                                        "count": count
                                    })
     users = results.get("users", [])
     return [extract_user_short(user) for user in users]
Ejemplo n.º 13
0
    def user_following_v1(self,
                          user_id: int,
                          amount: int = 0) -> List[UserShort]:
        """
        Get user's following users information by Private Mobile API

        Parameters
        ----------
        user_id: int
            User id of an instagram account
        amount: int, optional
            Maximum number of media to return, default is 0

        Returns
        -------
        List[UserShort]
            List of objects of User type
        """
        user_id = int(user_id)
        max_id = ""
        users = []
        while True:
            if amount and len(users) >= amount:
                break
            result = self.private_request(
                f"friendships/{user_id}/following/",
                params={
                    "max_id": max_id,
                    "rank_token": self.rank_token,
                    "ig_sig_key_version": config.SIG_KEY_VERSION,
                },
            )
            for user in result["users"]:
                users.append(extract_user_short(user))
            max_id = result.get("next_max_id")
            if not max_id:
                break
        if amount:
            users = users[:amount]
        return users
Ejemplo n.º 14
0
    def story_viewers(self, story_pk: int, amount: int = 0) -> List[UserShort]:
        """
        List of story viewers (Private API)

        Parameters
        ----------
        story_pk: int
        amount: int, optional
            Maximum number of story viewers

        Returns
        -------
        List[UserShort]
            A list of objects of UserShort
        """
        users = []
        next_max_id = None
        story_pk = self.media_pk(story_pk)
        params = {"supported_capabilities_new": json.dumps(config.SUPPORTED_CAPABILITIES)}
        while True:
            try:
                if next_max_id:
                    params["max_id"] = next_max_id
                result = self.private_request(f"media/{story_pk}/list_reel_media_viewer/", params=params)
                for item in result['users']:
                    users.append(extract_user_short(item))
                if amount and len(users) >= amount:
                    break
                next_max_id = result.get('next_max_id')
                if not next_max_id:
                    break
            except Exception as e:
                self.logger.exception(e)
                break
        if amount:
            users = users[:int(amount)]
        return users
Ejemplo n.º 15
0
 def media_likers(self, media_id: str) -> List[UserShort]:
     media_id = self.media_id(media_id)
     result = self.private_request(f"media/{media_id}/likers/")
     return [extract_user_short(u) for u in result['users']]