From e00d77c234dfece7a61f4029e6661543a518f358 Mon Sep 17 00:00:00 2001 From: Lars Lindqvist Date: Mon, 20 Aug 2018 08:43:53 +0200 Subject: [PATCH] Basic CLI support for tagged posts. Squashed commit of the following (pr #154): commit 8fd56c379ff89ff634b510df8abde5a9c50218f0 Merge: 08f0ee7 a3777ca Author: Lars Lindqvist Date: Wed Aug 15 20:23:23 2018 +0200 Merge branch 'master' into master commit 08f0ee795c2273b09056031253781776c5c93bf4 Merge: 700b3a8 dcea0e9 Author: Lars Lindqvist Date: Sun Aug 5 15:25:55 2018 +0200 Merge branch 'master' into master commit 700b3a8d094f552caa638a9d91f9221392a8e3f0 Author: Lars Lindqvist Date: Sat Aug 4 16:26:59 2018 +0200 Basic CLI support for tagged posts. commit 5e3cd10cbcbec6d29abd6a56ab9c39294a8d44b3 Merge: af564f5 92653dc Author: Lars Lindqvist Date: Fri Aug 3 19:33:24 2018 +0200 Merge branch 'master' into master commit af564f5174d1ffd3af3f7e635b650651e1f7411a Author: Lars Lindqvist Date: Fri Aug 3 19:25:57 2018 +0200 Fix owner_profile for Profile.get_tagged_posts() commit 3cde1f7db4860edaca970c70543ed5bca0f97853 Author: Lars Lindqvist Date: Thu Jul 26 19:51:33 2018 +0200 Add meth:get_tagged_posts to Profile --- instaloader/__main__.py | 13 +++++++++++-- instaloader/instaloader.py | 25 +++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/instaloader/__main__.py b/instaloader/__main__.py index 9f9c54e..a8f5aae 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.""" @@ -171,7 +172,8 @@ def _main(instaloader: Instaloader, targetlist: List[str], for target in profiles: with instaloader.context.error_catcher(target): instaloader.download_profile(target, download_profile_pic, not download_profile_posts, - fast_update, post_filter=post_filter) + fast_update, download_tagged=tagged, + download_tagged_only=tagged_only, post_filter=post_filter) if anonymous_retry_profiles: instaloader.context.log("Downloading anonymously: {}" .format(' '.join([p.username for p in anonymous_retry_profiles]))) @@ -179,7 +181,8 @@ def _main(instaloader: Instaloader, targetlist: List[str], for target in anonymous_retry_profiles: with instaloader.context.error_catcher(target): anonymous_loader.download_profile(target, download_profile_pic, not download_profile_posts, - fast_update, post_filter=post_filter) + fast_update, download_tagged=tagged, + download_tagged_only=tagged_only, post_filter=post_filter) if download_profile_stories and profiles: with instaloader.context.error_catcher("Download stories"): instaloader.context.log("Downloading stories") @@ -254,6 +257,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 ' @@ -360,6 +367,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 d8e5ec6..8d171ed 100644 --- a/instaloader/instaloader.py +++ b/instaloader/instaloader.py @@ -619,6 +619,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'))): @@ -686,6 +703,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""" @@ -739,6 +757,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