Skip to content

Commit

Permalink
added followers() and followings() to Mobile.py
Browse files Browse the repository at this point in the history
  • Loading branch information
diezo committed Mar 2, 2024
1 parent 0c1f497 commit a84fa7b
Show file tree
Hide file tree
Showing 13 changed files with 253 additions and 4 deletions.
73 changes: 72 additions & 1 deletion ensta/Mobile.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
import datetime
import json
from .parser.ProfileParser import parse_profile
from .structures import Profile, StoryLink
from .parser.FollowersParser import parse_followers
from .parser.FollowingsParser import parse_followings
from .structures import Profile, StoryLink, Followers, Followings
from .Direct import Direct
from ensta.Utils import time_id, fb_uploader

Expand Down Expand Up @@ -699,3 +701,72 @@ def unlike(self, media_id: str) -> bool:
"Unable to unlike media. Maybe try using another account, switch "
"to a different network, or use reputed proxies."
)

def followers(self, identifier: str, next_cursor: str | int | None = None) -> Followers:
"""
Get followers list of an account
:param: identifier: Username or UserID (UserID Recommended)
:return: Followers Object
"""

next_cursor: str = str(next_cursor) if next_cursor is not None else None
user_id: str = self.profile(identifier).user_id
max_id_line: str = f"&max_id={next_cursor}" if next_cursor is not None else ""

response: Response = self.session.get(
url=f"https://i.instagram.com/api/v1/friendships/{user_id}/followers/?enable_groups=true{max_id_line}"
)

try:
response_dict: dict = response.json()

if response_dict.get("status", "") != "ok":
raise NetworkError(
"Response status was not ok.\n"
f"Response Dict: {response_dict}"
)

return parse_followers(response_dict)

except JSONDecodeError:
raise NetworkError(
"Unable to get followers list. Make sure either the account is public or you're "
"already following the target user. Also, make sure the user hasn't blocked or "
"restricted you. Try using another account, switch "
"to a different network, or use reputed proxies."
)

def followings(self, identifier: str, next_cursor: str | int | None = None) -> Followings:
"""
Get followings list of an account
:param: identifier: Username or UserID (UserID Recommended)
:return: Followings Object
"""

next_cursor: str = str(next_cursor) if next_cursor is not None else None
user_id: str = self.profile(identifier).user_id
max_id_line: str = f"&max_id={next_cursor}" if next_cursor is not None else ""

response: Response = self.session.get(
url=f"https://i.instagram.com/api/v1/friendships/{user_id}/following/?enable_groups=true"
f"&includes_hashtags=true{max_id_line}"
)

try:
response_dict: dict = response.json()

if response_dict.get("status", "") != "ok":
raise NetworkError(
"Response status was not ok.\n"
f"Response Dict: {response_dict}"
)

return parse_followings(response_dict)

except JSONDecodeError:
raise NetworkError(
"Unable to get followings list. Make sure either the account is public or you're "
"already following the target user. Also, make sure the user hasn't blocked or "
"restricted you. Try using another account, switch "
"to a different network, or use reputed proxies."
)
26 changes: 26 additions & 0 deletions ensta/parser/FollowersListParser.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
from ensta.structures.Follower import Follower


def parse_followers_list(items: list[dict]) -> list[Follower]:

followers = list()

for item in items:

followers.append(
Follower(
user_id=str(item.get("pk")),
username=item.get("username"),
full_name=item.get("full_name"),
is_private=item.get("is_private"),
fbid_v2=item.get("fbid_v2"),
third_party_downloads_enabled=item.get("third_party_downloads_enabled"),
profile_picture_id=item.get("profile_pic_id"),
profile_picture_url=item.get("profile_pic_url"),
is_verified=item.get("is_verified"),
has_anonymous_profile_picture=item.get("has_anonymous_profile_picture"),
latest_reel_media=item.get("latest_reel_media")
)
)

return followers
19 changes: 19 additions & 0 deletions ensta/parser/FollowersParser.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
from ensta.structures.Followers import Followers
from ensta.structures.Follower import Follower
from .FollowersListParser import parse_followers_list


def parse_followers(information: dict) -> Followers:

followers_list: list[Follower] = parse_followers_list(information.get("users"))

return Followers(
list=followers_list,
next_cursor=information.get("next_max_id"),
big_list=information.get("big_list"),
list_length=information.get("page_size"),
has_more=information.get("has_more"),
should_limit_list_of_followers=information.get("should_limit_list_of_followers"),
use_clickable_see_more=information.get("use_clickable_see_more"),
show_spam_follow_request_tab=information.get("show_spam_follow_request_tab")
)
27 changes: 27 additions & 0 deletions ensta/parser/FollowingsListParser.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
from ensta.structures.Following import Following


def parse_followings_list(items: list[dict]) -> list[Following]:

followings = list()

for item in items:

followings.append(
Following(
user_id=str(item.get("pk")),
username=item.get("username"),
full_name=item.get("full_name"),
is_private=item.get("is_private"),
fbid_v2=item.get("fbid_v2"),
third_party_downloads_enabled=item.get("third_party_downloads_enabled"),
profile_picture_id=item.get("profile_pic_id"),
profile_picture_url=item.get("profile_pic_url"),
is_verified=item.get("is_verified"),
has_anonymous_profile_picture=item.get("has_anonymous_profile_picture"),
latest_reel_media=item.get("latest_reel_media"),
is_favorite=item.get("is_favorite")
)
)

return followings
19 changes: 19 additions & 0 deletions ensta/parser/FollowingsParser.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
from ensta.structures.Followings import Followings
from ensta.structures.Following import Following
from .FollowingsListParser import parse_followings_list


def parse_followings(information: dict) -> Followings:

followings_list: list[Following] = parse_followings_list(information.get("users"))

return Followings(
list=followings_list,
next_cursor=information.get("next_max_id"),
big_list=information.get("big_list"),
list_length=information.get("page_size"),
hashtag_count=information.get("hashtag_count"),
has_more=information.get("has_more"),
should_limit_list_of_followers=information.get("should_limit_list_of_followers"),
use_clickable_see_more=information.get("use_clickable_see_more"),
)
4 changes: 4 additions & 0 deletions ensta/parser/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,6 @@
from .BiographyLinkParser import parse_biography_link
from .ProfileParser import parse_profile
from .FollowersParser import parse_followers
from .FollowingsParser import parse_followings
from .FollowersListParser import parse_followers_list
from .FollowingsListParser import parse_followings_list
21 changes: 21 additions & 0 deletions ensta/structures/Follower.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from dataclasses import dataclass


@dataclass
class Follower:

"""
Stores single follower information e.g. - Full Name, Username, Profile Picture Url, etc.
"""

user_id: str
username: str
full_name: str
is_private: bool
fbid_v2: str
third_party_downloads_enabled: int
profile_picture_id: str
profile_picture_url: str
is_verified: bool
has_anonymous_profile_picture: bool
latest_reel_media: int
19 changes: 19 additions & 0 deletions ensta/structures/Followers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
from dataclasses import dataclass
from .Follower import Follower


@dataclass
class Followers:

"""
Stores fetched followers information e.g. - List, Next Cursor, List Length, etc.
"""

list: list[Follower]
next_cursor: int
big_list: bool
list_length: int
has_more: bool
should_limit_list_of_followers: bool
use_clickable_see_more: bool
show_spam_follow_request_tab: bool
22 changes: 22 additions & 0 deletions ensta/structures/Following.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from dataclasses import dataclass


@dataclass
class Following:

"""
Stores single following information e.g. - Full Name, Username, Profile Picture Url, etc.
"""

user_id: str
username: str
full_name: str
is_private: bool
fbid_v2: str
third_party_downloads_enabled: int
profile_picture_id: str
profile_picture_url: str
is_verified: bool
has_anonymous_profile_picture: bool
latest_reel_media: int
is_favorite: bool
19 changes: 19 additions & 0 deletions ensta/structures/Followings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
from dataclasses import dataclass
from .Following import Following


@dataclass
class Followings:

"""
Stores fetched followings information e.g. - List, Next Cursor, List Length, etc.
"""

list: list[Following]
next_cursor: int
big_list: bool
list_length: int
hashtag_count: int
has_more: bool
should_limit_list_of_followers: bool
use_clickable_see_more: bool
4 changes: 4 additions & 0 deletions ensta/structures/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
from .Profile import Profile
from .BiographyLink import BiographyLink
from .StoryLink import StoryLink
from .Followers import Followers
from .Followings import Followings
from .Follower import Follower
from .Following import Following
2 changes: 0 additions & 2 deletions mobile_migration_checklist.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
### Remaining features:

- followers
- followings
- fetch posts
- individual post data
- get post id by share url
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from distutils.core import setup
from pathlib import Path

version = "5.1.9"
version = "5.2.0"
long_description = (Path(__file__).parent / "README.md").read_text(encoding="utf-8")

setup(
Expand Down

0 comments on commit a84fa7b

Please sign in to comment.