1
0
mirror of https://github.com/instaloader/instaloader.git synced 2024-10-03 22:07:11 +02:00

Make iPhone endpoint query optional (#1076)

This commit is contained in:
A Bored Pervert 2021-04-22 14:06:35 -04:00 committed by GitHub
parent e67b9e6c37
commit 3837b642b0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 35 additions and 12 deletions

View File

@ -100,7 +100,6 @@ What to Download of each Post
Do not xz compress JSON files, rather create pretty formatted JSONs.
What to Download of each Profile
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -274,6 +273,12 @@ How to Download
.. versionadded:: 4.7
.. option:: --no-iphone
Do not attempt to download iPhone version of images and videos.
.. versionadded:: 4.8
Miscellaneous Options
^^^^^^^^^^^^^^^^^^^^^

View File

@ -206,7 +206,8 @@ def _main(instaloader: Instaloader, targetlist: List[str],
if len(profiles) > 1:
instaloader.context.log("Downloading {} profiles: {}".format(len(profiles),
' '.join([p.username for p in profiles])))
if profiles and (download_profile_pic or download_posts) and not instaloader.context.is_logged_in:
if instaloader.context.iphone_support and profiles and (download_profile_pic or download_posts) and \
not instaloader.context.is_logged_in:
instaloader.context.log("Hint: Use --login to download higher-quality versions of pictures.")
instaloader.download_profiles(profiles,
download_profile_pic, download_posts, download_tagged, download_igtv,
@ -382,6 +383,8 @@ def main():
g_how.add_argument('--abort-on', type=http_status_code_list, metavar="STATUS_CODES",
help='Comma-separated list of HTTP status codes that cause Instaloader to abort, bypassing all '
'retry logic.')
g_how.add_argument('--no-iphone', action='store_true',
help='Do not attempt to download iPhone version of images and videos.')
g_misc = parser.add_argument_group('Miscellaneous Options')
g_misc.add_argument('-q', '--quiet', action='store_true',
@ -441,7 +444,8 @@ def main():
resume_prefix=resume_prefix,
check_resume_bbd=not args.use_aged_resume_files,
slide=args.slide,
fatal_status_codes=args.abort_on)
fatal_status_codes=args.abort_on,
iphone_support=not args.no_iphone)
_main(loader,
args.profile,
username=args.login.lower() if args.login is not None else None,

View File

@ -65,6 +65,8 @@ class QueryReturnedNotFoundException(ConnectionException):
class TooManyRequestsException(ConnectionException):
pass
class IPhoneSupportDisabledException(InstaloaderException):
pass
class AbortDownloadException(Exception):
"""

View File

@ -162,6 +162,7 @@ class Instaloader:
:param check_resume_bbd: Whether to check the date of expiry of resume files and reject them if expired.
:param slide: :option:`--slide`
:param fatal_status_codes: :option:`--abort-on`
:param iphone_support: not :option:`--no-iphone`
.. attribute:: context
@ -189,10 +190,12 @@ class Instaloader:
resume_prefix: Optional[str] = "iterator",
check_resume_bbd: bool = True,
slide: Optional[str] = None,
fatal_status_codes: Optional[List[int]] = None):
fatal_status_codes: Optional[List[int]] = None,
iphone_support: bool = True):
self.context = InstaloaderContext(sleep, quiet, user_agent, max_connection_attempts,
request_timeout, rate_controller, fatal_status_codes)
request_timeout, rate_controller, fatal_status_codes,
iphone_support)
# configuration parameters
self.dirname_pattern = dirname_pattern or "{target}"
@ -259,7 +262,8 @@ class Instaloader:
resume_prefix=self.resume_prefix,
check_resume_bbd=self.check_resume_bbd,
slide=self.slide,
fatal_status_codes=self.context.fatal_status_codes)
fatal_status_codes=self.context.fatal_status_codes,
iphone_support=self.context.iphone_support)
yield new_loader
self.context.error_log.extend(new_loader.context.error_log)
new_loader.context.error_log = [] # avoid double-printing of errors

View File

@ -54,7 +54,8 @@ class InstaloaderContext:
def __init__(self, sleep: bool = True, quiet: bool = False, user_agent: Optional[str] = None,
max_connection_attempts: int = 3, request_timeout: float = 300.0,
rate_controller: Optional[Callable[["InstaloaderContext"], "RateController"]] = None,
fatal_status_codes: Optional[List[int]] = None):
fatal_status_codes: Optional[List[int]] = None,
iphone_support: bool = True):
self.user_agent = user_agent if user_agent is not None else default_user_agent()
self.request_timeout = request_timeout
@ -66,6 +67,7 @@ class InstaloaderContext:
self._graphql_page_length = 50
self._root_rhx_gis = None
self.two_factor_auth_pending = None
self.iphone_support = iphone_support
# error log, filled with error() and printed at the end of Instaloader.main()
self.error_log = [] # type: List[str]

View File

@ -168,6 +168,8 @@ class Post:
@property
def _iphone_struct(self) -> Dict[str, Any]:
if not self._context.iphone_support:
raise IPhoneSupportDisabledException("iPhone support is disabled.")
if not self._context.is_logged_in:
raise LoginRequiredException("--login required to access iPhone media info endpoint.")
if not self._iphone_struct_:
@ -246,7 +248,7 @@ class Post:
@property
def url(self) -> str:
"""URL of the picture / video thumbnail of the post"""
if self.typename == "GraphImage" and self._context.is_logged_in:
if self.typename == "GraphImage" and self._context.iphone_support and self._context.is_logged_in:
try:
orig_url = self._iphone_struct['image_versions2']['candidates'][0]['url']
url = re.sub(r'([?&])se=\d+&?', r'\1', orig_url).rstrip('&')
@ -304,7 +306,7 @@ class Post:
node = edge['node']
is_video = node['is_video']
display_url = node['display_url']
if not is_video and self._context.is_logged_in:
if not is_video and self._context.iphone_support and self._context.is_logged_in:
try:
carousel_media = self._iphone_struct['carousel_media']
orig_url = carousel_media[idx]['image_versions2']['candidates'][0]['url']
@ -372,7 +374,7 @@ class Post:
def video_url(self) -> Optional[str]:
"""URL of the video, or None."""
if self.is_video:
if self._context.is_logged_in:
if self._context.iphone_support and self._context.is_logged_in:
try:
url = self._iphone_struct['video_versions'][0]['url']
return url
@ -691,6 +693,8 @@ class Profile:
@property
def _iphone_struct(self) -> Dict[str, Any]:
if not self._context.iphone_support:
raise IPhoneSupportDisabledException("iPhone support is disabled.")
if not self._context.is_logged_in:
raise LoginRequiredException("--login required to access iPhone profile info endpoint.")
if not self._iphone_struct_:
@ -834,7 +838,7 @@ class Profile:
.. versionchanged:: 4.2.1
Require being logged in for HD version (as required by Instagram)."""
if self._context.is_logged_in:
if self._context.iphone_support and self._context.is_logged_in:
try:
return self._iphone_struct['hd_profile_pic_url_info']['url']
except (InstaloaderException, KeyError) as err:
@ -1021,6 +1025,8 @@ class StoryItem:
@property
def _iphone_struct(self) -> Dict[str, Any]:
if not self._context.iphone_support:
raise IPhoneSupportDisabledException("iPhone support is disabled.")
if not self._context.is_logged_in:
raise LoginRequiredException("--login required to access iPhone media info endpoint.")
if not self._iphone_struct_:
@ -1079,7 +1085,7 @@ class StoryItem:
@property
def url(self) -> str:
"""URL of the picture / video thumbnail of the StoryItem"""
if self.typename == "GraphStoryImage" and self._context.is_logged_in:
if self.typename == "GraphStoryImage" and self._context.iphone_support and self._context.is_logged_in:
try:
orig_url = self._iphone_struct['image_versions2']['candidates'][0]['url']
url = re.sub(r'([?&])se=\d+&?', r'\1', orig_url).rstrip('&')