Skip to content

Commit

Permalink
[instagram] add 'avatar' extractor (#929, #1097, #2992)
Browse files Browse the repository at this point in the history
  • Loading branch information
mikf committed Oct 19, 2022
1 parent ea8113f commit cf86f68
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 6 deletions.
7 changes: 6 additions & 1 deletion docs/configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1517,7 +1517,12 @@ Description
when processing a user profile.

Possible values are
``"posts"``, ``"reels"``, ``"tagged"``, ``"stories"``, ``"highlights"``.
``"posts"``,
``"reels"``,
``"tagged"``,
``"stories"``,
``"highlights"``,
``"avatar"``.

You can use ``"all"`` instead of listing all values separately.

Expand Down
2 changes: 1 addition & 1 deletion docs/supportedsites.md
Original file line number Diff line number Diff line change
Expand Up @@ -400,7 +400,7 @@ Consider all sites to be NSFW unless otherwise known.
<tr>
<td>Instagram</td>
<td>https://www.instagram.com/</td>
<td>Collections, Highlights, Posts, Reels, Saved Posts, Stories, Tag Searches, Tagged Posts, User Profiles</td>
<td>Avatars, Collections, Highlights, Posts, Reels, Saved Posts, Stories, Tag Searches, Tagged Posts, User Profiles</td>
<td>Supported</td>
</tr>
<tr>
Expand Down
56 changes: 52 additions & 4 deletions gallery_dl/extractor/instagram.py
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,7 @@ def items(self):
base = "{}/{}/".format(self.root, self.item)
stories = "{}/stories/{}/".format(self.root, self.item)
return self._dispatch_extractors((
(InstagramAvatarExtractor , base + "avatar/"),
(InstagramStoriesExtractor , stories),
(InstagramHighlightsExtractor, base + "highlights/"),
(InstagramPostsExtractor , base + "posts/"),
Expand Down Expand Up @@ -417,7 +418,7 @@ def metadata(self):
return {"tagged_owner_id": self.user_id}

self.user_id = self.api.user_id(self.item)
user = self.api.user(self.item)
user = self.api.user_by_name(self.item)

return {
"tagged_owner_id" : user["id"],
Expand Down Expand Up @@ -529,6 +530,48 @@ def posts(self):
return self.api.tags_media(self.item)


class InstagramAvatarExtractor(InstagramExtractor):
"""Extractor for an Instagram user's avatar"""
subcategory = "avatar"
pattern = USER_PATTERN + r"/avatar"
test = ("https://www.instagram.com/instagram/avatar", {
"pattern": r"https://instagram\.[\w.-]+\.fbcdn\.net/v/t51\.2885-19"
r"/281440578_1088265838702675_6233856337905829714_n\.jpg",
})

def posts(self):
if self._logged_in:
user_id = self.api.user_id(self.item)
user = self.api.user_by_id(user_id)
avatar = (user.get("hd_profile_pic_url_info") or
user["hd_profile_pic_versions"][-1])
else:
user = self.item
if user.startswith("id:"):
user = self.api.user_by_id(user[3:])
else:
user = self.api.user_by_name(user)
user["pk"] = user["id"]
url = user.get("profile_pic_url_hd") or user["profile_pic_url"]
avatar = {"url": url, "width": 0, "height": 0}

pk = user.get("profile_pic_id")
if pk:
pk = pk.partition("_")[0]
code = shortcode_from_id(pk)
else:
pk = code = "avatar:" + str(user["pk"])

return ({
"pk" : pk,
"code" : code,
"user" : user,
"caption" : None,
"like_count": 0,
"image_versions2": {"candidates": (avatar,)},
},)


class InstagramPostExtractor(InstagramExtractor):
"""Extractor for an Instagram post"""
subcategory = "post"
Expand Down Expand Up @@ -678,15 +721,19 @@ def tags_sections(self, tag):
return self._pagination_sections(endpoint, data)

@memcache(keyarg=1)
def user(self, screen_name):
def user_by_name(self, screen_name):
endpoint = "/v1/users/web_profile_info/"
params = {"username": screen_name}
return self._call(endpoint, params=params)["data"]["user"]

def user_by_id(self, user_id):
endpoint = "/v1/users/{}/info/".format(user_id)
return self._call(endpoint)["user"]

def user_id(self, screen_name):
if screen_name.startswith("id:"):
return screen_name[3:]
user = self.user(screen_name)
user = self.user_by_name(screen_name)
if user is None:
raise exception.AuthorizationError(
"Login required to access this profile")
Expand Down Expand Up @@ -797,7 +844,8 @@ def __init__(self, extractor):
self._json_dumps = json.JSONEncoder(separators=(",", ":")).encode

api = InstagramRestAPI(extractor)
self.user = api.user
self.user_by_name = api.user_by_name
self.user_by_id = api.user_by_id
self.user_id = api.user_id

@staticmethod
Expand Down

0 comments on commit cf86f68

Please sign in to comment.