mirror of
https://github.com/instaloader/instaloader.git
synced 2024-11-20 17:22:31 +01:00
Make iPhone endpoint query optional (#1076)
This commit is contained in:
parent
e67b9e6c37
commit
3837b642b0
@ -100,7 +100,6 @@ What to Download of each Post
|
|||||||
|
|
||||||
Do not xz compress JSON files, rather create pretty formatted JSONs.
|
Do not xz compress JSON files, rather create pretty formatted JSONs.
|
||||||
|
|
||||||
|
|
||||||
What to Download of each Profile
|
What to Download of each Profile
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
@ -274,6 +273,12 @@ How to Download
|
|||||||
|
|
||||||
.. versionadded:: 4.7
|
.. versionadded:: 4.7
|
||||||
|
|
||||||
|
.. option:: --no-iphone
|
||||||
|
|
||||||
|
Do not attempt to download iPhone version of images and videos.
|
||||||
|
|
||||||
|
.. versionadded:: 4.8
|
||||||
|
|
||||||
Miscellaneous Options
|
Miscellaneous Options
|
||||||
^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
@ -206,7 +206,8 @@ def _main(instaloader: Instaloader, targetlist: List[str],
|
|||||||
if len(profiles) > 1:
|
if len(profiles) > 1:
|
||||||
instaloader.context.log("Downloading {} profiles: {}".format(len(profiles),
|
instaloader.context.log("Downloading {} profiles: {}".format(len(profiles),
|
||||||
' '.join([p.username for p in 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.context.log("Hint: Use --login to download higher-quality versions of pictures.")
|
||||||
instaloader.download_profiles(profiles,
|
instaloader.download_profiles(profiles,
|
||||||
download_profile_pic, download_posts, download_tagged, download_igtv,
|
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",
|
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 '
|
help='Comma-separated list of HTTP status codes that cause Instaloader to abort, bypassing all '
|
||||||
'retry logic.')
|
'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 = parser.add_argument_group('Miscellaneous Options')
|
||||||
g_misc.add_argument('-q', '--quiet', action='store_true',
|
g_misc.add_argument('-q', '--quiet', action='store_true',
|
||||||
@ -441,7 +444,8 @@ def main():
|
|||||||
resume_prefix=resume_prefix,
|
resume_prefix=resume_prefix,
|
||||||
check_resume_bbd=not args.use_aged_resume_files,
|
check_resume_bbd=not args.use_aged_resume_files,
|
||||||
slide=args.slide,
|
slide=args.slide,
|
||||||
fatal_status_codes=args.abort_on)
|
fatal_status_codes=args.abort_on,
|
||||||
|
iphone_support=not args.no_iphone)
|
||||||
_main(loader,
|
_main(loader,
|
||||||
args.profile,
|
args.profile,
|
||||||
username=args.login.lower() if args.login is not None else None,
|
username=args.login.lower() if args.login is not None else None,
|
||||||
|
@ -65,6 +65,8 @@ class QueryReturnedNotFoundException(ConnectionException):
|
|||||||
class TooManyRequestsException(ConnectionException):
|
class TooManyRequestsException(ConnectionException):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
class IPhoneSupportDisabledException(InstaloaderException):
|
||||||
|
pass
|
||||||
|
|
||||||
class AbortDownloadException(Exception):
|
class AbortDownloadException(Exception):
|
||||||
"""
|
"""
|
||||||
|
@ -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 check_resume_bbd: Whether to check the date of expiry of resume files and reject them if expired.
|
||||||
:param slide: :option:`--slide`
|
:param slide: :option:`--slide`
|
||||||
:param fatal_status_codes: :option:`--abort-on`
|
:param fatal_status_codes: :option:`--abort-on`
|
||||||
|
:param iphone_support: not :option:`--no-iphone`
|
||||||
|
|
||||||
.. attribute:: context
|
.. attribute:: context
|
||||||
|
|
||||||
@ -189,10 +190,12 @@ class Instaloader:
|
|||||||
resume_prefix: Optional[str] = "iterator",
|
resume_prefix: Optional[str] = "iterator",
|
||||||
check_resume_bbd: bool = True,
|
check_resume_bbd: bool = True,
|
||||||
slide: Optional[str] = None,
|
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,
|
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
|
# configuration parameters
|
||||||
self.dirname_pattern = dirname_pattern or "{target}"
|
self.dirname_pattern = dirname_pattern or "{target}"
|
||||||
@ -259,7 +262,8 @@ class Instaloader:
|
|||||||
resume_prefix=self.resume_prefix,
|
resume_prefix=self.resume_prefix,
|
||||||
check_resume_bbd=self.check_resume_bbd,
|
check_resume_bbd=self.check_resume_bbd,
|
||||||
slide=self.slide,
|
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
|
yield new_loader
|
||||||
self.context.error_log.extend(new_loader.context.error_log)
|
self.context.error_log.extend(new_loader.context.error_log)
|
||||||
new_loader.context.error_log = [] # avoid double-printing of errors
|
new_loader.context.error_log = [] # avoid double-printing of errors
|
||||||
|
@ -54,7 +54,8 @@ class InstaloaderContext:
|
|||||||
def __init__(self, sleep: bool = True, quiet: bool = False, user_agent: Optional[str] = None,
|
def __init__(self, sleep: bool = True, quiet: bool = False, user_agent: Optional[str] = None,
|
||||||
max_connection_attempts: int = 3, request_timeout: float = 300.0,
|
max_connection_attempts: int = 3, request_timeout: float = 300.0,
|
||||||
rate_controller: Optional[Callable[["InstaloaderContext"], "RateController"]] = None,
|
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.user_agent = user_agent if user_agent is not None else default_user_agent()
|
||||||
self.request_timeout = request_timeout
|
self.request_timeout = request_timeout
|
||||||
@ -66,6 +67,7 @@ class InstaloaderContext:
|
|||||||
self._graphql_page_length = 50
|
self._graphql_page_length = 50
|
||||||
self._root_rhx_gis = None
|
self._root_rhx_gis = None
|
||||||
self.two_factor_auth_pending = 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()
|
# error log, filled with error() and printed at the end of Instaloader.main()
|
||||||
self.error_log = [] # type: List[str]
|
self.error_log = [] # type: List[str]
|
||||||
|
@ -168,6 +168,8 @@ class Post:
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def _iphone_struct(self) -> Dict[str, Any]:
|
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:
|
if not self._context.is_logged_in:
|
||||||
raise LoginRequiredException("--login required to access iPhone media info endpoint.")
|
raise LoginRequiredException("--login required to access iPhone media info endpoint.")
|
||||||
if not self._iphone_struct_:
|
if not self._iphone_struct_:
|
||||||
@ -246,7 +248,7 @@ class Post:
|
|||||||
@property
|
@property
|
||||||
def url(self) -> str:
|
def url(self) -> str:
|
||||||
"""URL of the picture / video thumbnail of the post"""
|
"""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:
|
try:
|
||||||
orig_url = self._iphone_struct['image_versions2']['candidates'][0]['url']
|
orig_url = self._iphone_struct['image_versions2']['candidates'][0]['url']
|
||||||
url = re.sub(r'([?&])se=\d+&?', r'\1', orig_url).rstrip('&')
|
url = re.sub(r'([?&])se=\d+&?', r'\1', orig_url).rstrip('&')
|
||||||
@ -304,7 +306,7 @@ class Post:
|
|||||||
node = edge['node']
|
node = edge['node']
|
||||||
is_video = node['is_video']
|
is_video = node['is_video']
|
||||||
display_url = node['display_url']
|
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:
|
try:
|
||||||
carousel_media = self._iphone_struct['carousel_media']
|
carousel_media = self._iphone_struct['carousel_media']
|
||||||
orig_url = carousel_media[idx]['image_versions2']['candidates'][0]['url']
|
orig_url = carousel_media[idx]['image_versions2']['candidates'][0]['url']
|
||||||
@ -372,7 +374,7 @@ class Post:
|
|||||||
def video_url(self) -> Optional[str]:
|
def video_url(self) -> Optional[str]:
|
||||||
"""URL of the video, or None."""
|
"""URL of the video, or None."""
|
||||||
if self.is_video:
|
if self.is_video:
|
||||||
if self._context.is_logged_in:
|
if self._context.iphone_support and self._context.is_logged_in:
|
||||||
try:
|
try:
|
||||||
url = self._iphone_struct['video_versions'][0]['url']
|
url = self._iphone_struct['video_versions'][0]['url']
|
||||||
return url
|
return url
|
||||||
@ -691,6 +693,8 @@ class Profile:
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def _iphone_struct(self) -> Dict[str, Any]:
|
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:
|
if not self._context.is_logged_in:
|
||||||
raise LoginRequiredException("--login required to access iPhone profile info endpoint.")
|
raise LoginRequiredException("--login required to access iPhone profile info endpoint.")
|
||||||
if not self._iphone_struct_:
|
if not self._iphone_struct_:
|
||||||
@ -834,7 +838,7 @@ class Profile:
|
|||||||
|
|
||||||
.. versionchanged:: 4.2.1
|
.. versionchanged:: 4.2.1
|
||||||
Require being logged in for HD version (as required by Instagram)."""
|
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:
|
try:
|
||||||
return self._iphone_struct['hd_profile_pic_url_info']['url']
|
return self._iphone_struct['hd_profile_pic_url_info']['url']
|
||||||
except (InstaloaderException, KeyError) as err:
|
except (InstaloaderException, KeyError) as err:
|
||||||
@ -1021,6 +1025,8 @@ class StoryItem:
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def _iphone_struct(self) -> Dict[str, Any]:
|
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:
|
if not self._context.is_logged_in:
|
||||||
raise LoginRequiredException("--login required to access iPhone media info endpoint.")
|
raise LoginRequiredException("--login required to access iPhone media info endpoint.")
|
||||||
if not self._iphone_struct_:
|
if not self._iphone_struct_:
|
||||||
@ -1079,7 +1085,7 @@ class StoryItem:
|
|||||||
@property
|
@property
|
||||||
def url(self) -> str:
|
def url(self) -> str:
|
||||||
"""URL of the picture / video thumbnail of the StoryItem"""
|
"""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:
|
try:
|
||||||
orig_url = self._iphone_struct['image_versions2']['candidates'][0]['url']
|
orig_url = self._iphone_struct['image_versions2']['candidates'][0]['url']
|
||||||
url = re.sub(r'([?&])se=\d+&?', r'\1', orig_url).rstrip('&')
|
url = re.sub(r'([?&])se=\d+&?', r'\1', orig_url).rstrip('&')
|
||||||
|
Loading…
Reference in New Issue
Block a user