Fix anon username from id (find renamed profile)
maybe related to #95, #104, 67ac8f3397
.
This commit is contained in:
parent
1469064176
commit
2722da6ae4
@ -74,7 +74,10 @@ metadata of a Profile. :class:`Profile` instances can be created with:
|
||||
profile = Profile.from_username(L.context, USERNAME)
|
||||
|
||||
- :meth:`Profile_from_userid`
|
||||
given its User ID (currently requires to be logged in).
|
||||
given its User ID. This allows to easily lookup a Profile's username given
|
||||
its ID::
|
||||
|
||||
Profile.from_id(L.context, USERID).username
|
||||
|
||||
- :meth:`Profile.get_followees`
|
||||
Profiles that are followed by given user.
|
||||
|
@ -629,10 +629,6 @@ class Instaloader:
|
||||
else:
|
||||
self.context.log("Trying to find profile {0} using its unique ID {1}.".format(profile_name,
|
||||
profile_id))
|
||||
if not self.context.is_logged_in:
|
||||
self.context.error("Profile {} changed its name. "
|
||||
"If you use --login=USERNAME, I can find out the new name.")
|
||||
raise LoginRequiredException("--login=USERNAME required to obtain profile name from its ID number")
|
||||
profile_from_id = Profile.from_id(self.context, profile_id)
|
||||
newname = profile_from_id.username
|
||||
self.context.log("Profile {0} has changed its name to {1}.".format(profile_name, newname))
|
||||
|
@ -56,6 +56,7 @@ class InstaloaderContext:
|
||||
self.quiet = quiet
|
||||
self.max_connection_attempts = max_connection_attempts
|
||||
self._graphql_page_length = 50
|
||||
self._root_rhx_gis = None
|
||||
|
||||
# error log, filled with error() and printed at the end of Instaloader.main()
|
||||
self.error_log = []
|
||||
@ -376,3 +377,14 @@ class InstaloaderContext:
|
||||
except KeyboardInterrupt:
|
||||
self.error("[skipped by user]", repeat_at_end=False)
|
||||
raise ConnectionException(error_string) from err
|
||||
|
||||
@property
|
||||
def root_rhx_gis(self) -> Optional[str]:
|
||||
"""rhx_gis string returned in the / query."""
|
||||
if self.is_logged_in:
|
||||
# At the moment, rhx_gis seems to be required for anonymous requests only. By returning None when logged
|
||||
# in, we can save the root_rhx_gis lookup query.
|
||||
return None
|
||||
if not self._root_rhx_gis:
|
||||
self._root_rhx_gis = self.get_json('', {})['rhx_gis']
|
||||
return self._root_rhx_gis
|
||||
|
@ -145,8 +145,8 @@ class Post:
|
||||
else:
|
||||
# Sometimes, the 'owner' structure does not contain the username, only the user's ID. In that case,
|
||||
# this call triggers downloading of the complete Post metadata struct, where the owner username
|
||||
# is contained. This is better than to get the username by user ID, since it is possible anonymously
|
||||
# and gives us other information that is more likely to be usable.
|
||||
# is contained. This is better than to get the username by user ID, since it
|
||||
# gives us other information that is more likely to be usable.
|
||||
owner_struct = self._full_metadata['owner']
|
||||
if 'username' in owner_struct:
|
||||
self._owner_profile = Profile(self._context, owner_struct)
|
||||
@ -379,17 +379,16 @@ class Profile:
|
||||
|
||||
@classmethod
|
||||
def from_id(cls, context: InstaloaderContext, profile_id: int):
|
||||
"""If logged in, create a Profile instance from a given userid. If possible, use :meth:`Profile.from_username`
|
||||
or constructor directly rather than this method, since does many requests.
|
||||
"""Create a Profile instance from a given userid. If possible, use :meth:`Profile.from_username`
|
||||
or constructor directly rather than this method, since it does many requests.
|
||||
|
||||
:param context: :attr:`Instaloader.context`
|
||||
:param profile_id: userid
|
||||
:raises: :class:`ProfileNotExistsException`, :class:`LoginRequiredException`, :class:`ProfileHasNoPicsException`
|
||||
:raises: :class:`ProfileNotExistsException`, :class:`ProfileHasNoPicsException`
|
||||
"""
|
||||
if not context.is_logged_in:
|
||||
raise LoginRequiredException("--login=USERNAME required to obtain profile metadata from its ID number.")
|
||||
data = context.graphql_query("472f257a40c653c64c666ce877d59d2b",
|
||||
{'id': str(profile_id), 'first': 1})['data']['user']
|
||||
{'id': str(profile_id), 'first': 1},
|
||||
rhx_gis=context.root_rhx_gis)['data']['user']
|
||||
if data:
|
||||
data = data["edge_owner_to_timeline_media"]
|
||||
else:
|
||||
@ -400,7 +399,7 @@ class Profile:
|
||||
raise ProfileHasNoPicsException("Profile with ID {0}: no pics found.".format(str(profile_id)))
|
||||
else:
|
||||
raise LoginRequiredException("Login required to determine username (ID: " + str(profile_id) + ").")
|
||||
username = Post.from_mediaid(context, int(data['edges'][0]["node"]["id"])).owner_username
|
||||
username = Post.from_shortcode(context, data['edges'][0]["node"]["shortcode"]).owner_username
|
||||
return cls(context, {'username': username.lower(), 'id': profile_id})
|
||||
|
||||
def _asdict(self):
|
||||
|
@ -54,6 +54,10 @@ class TestInstaloaderAnonymously(unittest.TestCase):
|
||||
self.assertEqual(PUBLIC_PROFILE_ID,
|
||||
instaloader.Profile.from_username(self.L.context, PUBLIC_PROFILE).userid)
|
||||
|
||||
def test_get_username_by_id(self):
|
||||
self.assertEqual(PUBLIC_PROFILE.lower(),
|
||||
instaloader.Profile.from_id(self.L.context, PUBLIC_PROFILE_ID).username)
|
||||
|
||||
def test_post_from_mediaid(self):
|
||||
for post in instaloader.Profile.from_username(self.L.context, PUBLIC_PROFILE).get_posts():
|
||||
post2 = instaloader.Post.from_mediaid(self.L.context, post.mediaid)
|
||||
|
Loading…
Reference in New Issue
Block a user