From 700b3a8d094f552caa638a9d91f9221392a8e3f0 Mon Sep 17 00:00:00 2001 From: Lars Lindqvist Date: Sat, 4 Aug 2018 16:26:59 +0200 Subject: [PATCH] Basic CLI support for tagged posts. --- instaloader/__main__.py | 14 ++++++++++++-- instaloader/instaloader.py | 25 +++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/instaloader/__main__.py b/instaloader/__main__.py index 8de51a5..db78b59 100644 --- a/instaloader/__main__.py +++ b/instaloader/__main__.py @@ -62,6 +62,7 @@ def _main(instaloader: Instaloader, targetlist: List[str], profile_pic: bool = True, profile_pic_only: bool = False, fast_update: bool = False, stories: bool = False, stories_only: bool = False, + tagged: bool = False, tagged_only: bool = False, post_filter_str: Optional[str] = None, storyitem_filter_str: Optional[str] = None) -> None: """Download set of profiles, hashtags etc. and handle logging in and session files if desired.""" @@ -146,7 +147,8 @@ def _main(instaloader: Instaloader, targetlist: List[str], with instaloader.context.error_catcher(target): try: instaloader.download_profile(target, profile_pic, profile_pic_only, - fast_update, post_filter=post_filter) + fast_update, download_tagged=tagged, + download_tagged_only=tagged_only, post_filter=post_filter) except ProfileNotExistsException as err: if instaloader.context.is_logged_in and not stories_only: instaloader.context.log(err) @@ -154,7 +156,9 @@ def _main(instaloader: Instaloader, targetlist: List[str], with instaloader.anonymous_copy() as anonymous_loader: with instaloader.context.error_catcher(): anonymous_loader.download_profile(target, profile_pic, profile_pic_only, - fast_update, post_filter=post_filter) + fast_update, download_tagged=tagged, + download_tagged_only=tagged_only, + post_filter=post_filter) else: raise if stories or stories_only: @@ -231,6 +235,10 @@ def main(): g_what.add_argument('--stories-only', action='store_true', help='Rather than downloading regular posts of each specified profile, only download ' 'stories. Requires --login. Does not imply --no-profile-pic.') + g_what.add_argument('--tagged', action='store_true', + help='Also download posts where each profile is tagged.') + g_what.add_argument('--tagged-only', action='store_true', + help='Download only post where each profile is tagged, not their regular posts.') g_what.add_argument('--post-filter', '--only-if', metavar='filter', help='Expression that, if given, must evaluate to True for each post to be downloaded. Must be ' 'a syntactically valid python expression. Variables are evaluated to ' @@ -337,6 +345,8 @@ def main(): fast_update=args.fast_update, stories=args.stories, stories_only=args.stories_only, + tagged=args.tagged, + tagged_only=args.tagged_only, post_filter_str=args.post_filter, storyitem_filter_str=args.storyitem_filter) loader.close() diff --git a/instaloader/instaloader.py b/instaloader/instaloader.py index 41d819f..87d46e6 100644 --- a/instaloader/instaloader.py +++ b/instaloader/instaloader.py @@ -612,6 +612,23 @@ class Instaloader: if fast_update and not downloaded: break + def download_tagged(self, profile: Profile, fast_update: bool = False, + target: Optional[str] = None, + post_filter: Optional[Callable[[Post], bool]] = None) -> None: + if target is None: + target = profile.username + ':tagged' + self.context.log("Retrieving tagged posts for profile {}.".format(profile.username)) + count = 1 + for post in profile.get_tagged_posts(): + self.context.log("[%3i/???] " % (count), end="", flush=True) + count += 1 + if post_filter is not None and not post_filter(post): + self.context.log('<{} skipped>'.format(post)) + with self.context.error_catcher('Download tagged {}'.format(profile.username)): + downloaded = self.download_post(post, target) + if fast_update and not downloaded: + break + def _get_id_filename(self, profile_name: str) -> str: if ((format_string_contains_key(self.dirname_pattern, 'profile') or format_string_contains_key(self.dirname_pattern, 'target'))): @@ -679,6 +696,7 @@ class Instaloader: profile_pic: bool = True, profile_pic_only: bool = False, fast_update: bool = False, download_stories: bool = False, download_stories_only: bool = False, + download_tagged: bool = False, download_tagged_only: bool = False, post_filter: Optional[Callable[[Post], bool]] = None, storyitem_filter: Optional[Callable[[StoryItem], bool]] = None) -> None: """Download one profile""" @@ -732,6 +750,13 @@ class Instaloader: if download_stories_only: return + # Download tagged, if requested + if download_tagged or download_tagged_only: + with self.context.error_catcher('Download tagged of {}'.format(profile_name)): + self.download_tagged(profile, fast_update=fast_update, post_filter=post_filter) + if download_tagged_only: + return + # Iterate over pictures and download them self.context.log("Retrieving posts from profile {}.".format(profile_name)) totalcount = profile.mediacount