diff --git a/docs/as-module.rst b/docs/as-module.rst index 5790946..ed868c6 100644 --- a/docs/as-module.rst +++ b/docs/as-module.rst @@ -39,11 +39,55 @@ certain source:: # post is an instance of instaloader.Post L.download_post(post, target='#cat') -Besides :func:`Instaloader.get_hashtag_posts`, there is -:func:`Instaloader.get_feed_posts`, :func:`Profile.get_posts` and -:func:`Profile.get_saved_posts`. -Also, :class:`Post` instances can be created with :func:`Post.from_shortcode` -and :func:`Post.from_mediaid`. +:class:`Post` instances can be created with: + +- :func:`Post.from_shortcode` + Use a Post shortcode (part of the Post URL, + ``https://www.instagram.com/p/SHORTCODE/``) to create a Post + object:: + + post = Post.from_shortcode(L.context, SHORTCODE) + +- :meth:`Profile.get_posts` + All media of a :class:`Profile`. + +- :meth:`Profile.get_saved_posts` + Media that the user marked as saved (:class:`Profile` must be own profile + for this to work) + +- :meth:`Instaloader.get_feed_posts` + Media in the user's feed. + +- :meth:`Instaloader.get_explore_posts` + Media that is suggested by Instagram to explore. + +- :meth:`Instaloader.get_hashtag_posts` + Media associated with given hashtag. + +With the :class:`Profile` class, Instaloader also makes it easy to access +metadata of a Profile. :class:`Profile` instances can be created with: + +- :meth:`Profile.from_username`:: + + profile = Profile.from_username(L.context, USERNAME) + +- :meth:`Profile_from_userid` + given its User ID (currently requires to be logged in). + +- :meth:`Profile.get_followees` + Profiles that are followed by given user. + +- :meth:`Profile.get_followers` + Profiles that follow given user. + +- :attr:`Post.owner_profile`, :attr:`Story.owner_profile` and :attr:`StoryItem.owner_profile` + Owner profile of particular object. + +- :meth:`Post.get_likes` + Profiles that liked a given :class:`Post` + +- :attr:`PostComment.owner` attribute for comment in :meth:`Post.get_comments` + Profile of a Post comment. A reference of the many methods provided by the :mod:`instaloader` module is provided in the remainder of this document. diff --git a/docs/basic-usage.rst b/docs/basic-usage.rst index 9175929..f8799a9 100644 --- a/docs/basic-usage.rst +++ b/docs/basic-usage.rst @@ -85,9 +85,6 @@ downloads the pictures and videos and their captions. You can specify - :option:`--geotags`, to **download geotags** of each post and save them as Google Maps link, -- :option:`--metadata-json`, to store further post metadata in a separate JSON - file. - .. _filename-specification: Filename Specification @@ -103,60 +100,102 @@ pattern, the token ``{target}`` is replaced by the target name, and ``{profile}`` is replaced by the owner of the post which is downloaded. :option:`--filename-pattern` configures the path of the post's files relative -to the target directory. The default is ``--filename-pattern={date}``. +to the target directory that is specified with :option:`--dirname-pattern`. +The default is ``--filename-pattern={date_utc}_UTC``. The tokens ``{target}`` and ``{profile}`` are replaced like in the -dirname pattern. Further, the tokens ``{date}``, ``{date_utc}`` and ``{shortcode}`` are -defined. Additionally, in case of not downloading stories, the attributes of -:class:`.Post` can be used, e.g. ``{post.owner_id}`` or ``{post.mediaid}``. +dirname pattern. The following tokens are defined for usage with +:option:`--filename-pattern`: -For example, encode the poster's profile name in the filenames with: +- ``{target}`` + Target name (as given in Instaloader command line) -:: +- ``{profile}`` (same as ``{owner_username}``) + Owner of the Post / StoryItem. - instaloader --filename-pattern={date}_{profile} "#hashtag" +- ``{owner_id}`` + Unique integer ID of owner profile. -The pattern string is formatted with Python's string formatter. This -gives additional flexibilty for pattern specification. For example, -`strftime-style formatting options `__ -are supported for the post's -timestamp. The default for ``{date}`` is ``{date:%Y-%m-%d_%H-%M-%S}``. +- ``{shortcode}`` + Shortcode (identifier string). + +- ``{mediaid}`` + Integer representation of shortcode. + +- ``{date_utc}`` (same as ``{date}``) + Creation time in UTC timezone. + `strftime()-style formatting options `__ + are supported as format specifier. The default date format specifier used by + Instaloader is:: + + {date_utc:%Y-%m-%d_%H-%M-%S} + +For example, encode the poster's profile name in the filenames with:: + + instaloader --filename-pattern={date_utc}_UTC_{profile} "#hashtag" + +As another example, you may instruct Instaloader to store posts in a +``PROFILE/YEAR/SHORTCODE.jpg`` directory structure:: + + instaloader --dirname-pattern={profile} --filename-pattern={date_utc:%Y}/{shortcode} ... .. _filter-posts: Filter Posts ^^^^^^^^^^^^ -The :option:`--only-if` option allows to specify criterias that posts have to -meet to be downloaded. If not given, all posts are downloaded. It must be a -boolean Python expression where the variables :attr:`.likes`, :attr:`.comments`, -:attr:`.viewer_has_liked`, :attr:`.is_video`, and many more are defined. +.. py:currentmodule:: instaloader -A few examples: +The options :option:`--post-filter` and :option:`--storyitem-filter` +allows to specify criterias that posts or story items have to +meet to be downloaded. If not given, all posts are downloaded. -To **download the pictures from your feed that you have liked**: +The filter string must be a +`Python boolean expression `__ +where the attributes from :class:`Post` or +:class:`StoryItem` respectively are defined. -:: +Id est, the following attributes can be used with both +:option:`--post-filter` and :option:`--storyitem-filter`: - instaloader --login=your_username --only-if=viewer_has_liked :feed +- :attr:`~Post.is_video` (bool) + Post/StoryItem is a video. For example, you may skip videos:: -Or you might only want to download **posts that either you liked or were -liked by many others**: + instaloader --post-filter="not is_video" target -:: +- :attr:`~Post.owner_username` (str), :attr:`~Post.owner_id` (int) + Owner profile username / userid. - instaloader --login=your_username --only-if="likes>100 or viewer_has_liked" profile +- :attr:`~Post.date_utc` (datetime), :attr:`~Post.date_local` (datetime) + Creation timestamp. Since :class:`~datetime.datetime` objects can be created + inside filter strings, this easily allows filtering by creation date. E.g.:: -Or you may **skip videos**: + instaloader --post-filter="date_utc <= datetime(2018, 5, 31)" target -:: +As :option:`--post-filter`, the following attributes can be used additionally: - instaloader --only-if="not is_video" target +- :attr:`~Post.viewer_has_liked` (bool) + Whether user (with :option:`--login`) has liked given post. To download the + pictures from your feed that you have liked:: -Or you may filter by hashtags that occur in the Post's caption. For -example, to download posts of kittens that are cute: :: + instaloader --login=your_username --post-filter=viewer_has_liked :feed - instaloader --only-if="'cute' in caption_hashtags" "#kitten" +- :attr:`~Post.likes` (int), :attr:`~Post.comments` (int) + Likes count / Comments count. You might only want to download posts that + either you liked or were liked by many others**:: -The given string is evaluated as a -`Python boolean expression `__, -where all occuring variables are attributes of the :class:`.Post` class. + instaloader --login=your_username --post-filter="likes>100 or viewer_has_liked" profile + +- :attr:`~Post.caption_hashtags` (list of str) / :attr:`~Post.caption_mentions` (list of str) + ``#hashtags`` or ``@mentions`` (lowercased) in the Post's caption. For example, to + download posts of kittens that are cute:: + + instaloader --post-filter="'cute' in caption_hashtags" "#kitten" + +- :attr:`~Post.tagged_users` (list of str) + Lowercased usernames that are tagged in the Post. + +For :option:`--storyitem-filter`, the following additional attributes are +defined: + +- :attr:`~StoryItem.expiring_utc` (datetime) / :attr:`~StoryItem.expiring_local` (datetime) + Timestamp when StoryItem will get unavailable. diff --git a/docs/cli-options.rst b/docs/cli-options.rst index b5eddd7..12bdafa 100644 --- a/docs/cli-options.rst +++ b/docs/cli-options.rst @@ -153,15 +153,11 @@ How to Download .. option:: --filename-pattern FILENAME_PATTERN - Prefix of filenames. Posts are stored in the directory whose pattern is given - with ``--dirname-pattern``. ``{profile}`` is replaced by the profile name, + Prefix of filenames, relative to the directory given with + :option:`--dirname-pattern`. ``{profile}`` is replaced by the profile name, ``{target}`` is replaced by the target you specified, i.e. either ``:feed``, - ``#hashtag`` or the profile name. Also, the fields ``{date}``, ``{date_utc}`` and - ``{shortcode}`` can be specified. In case of not downloading stories, the - attributes of the :class:`.Post` class can be used in addition, e.g. - ``{post.owner_id}`` or ``{post.mediaid}``. - Defaults to - ``{date:%Y-%m-%d_%H-%M-%S}``. See :ref:`filename-specification`. + ``#hashtag`` or the profile name. Defaults to ``{date_utc}_UTC``. + See :ref:`filename-specification` for a list of supported tokens. .. option:: --user-agent USER_AGENT diff --git a/instaloader/__main__.py b/instaloader/__main__.py index 911f255..95d8c98 100644 --- a/instaloader/__main__.py +++ b/instaloader/__main__.py @@ -264,12 +264,10 @@ def main(): '{target} is replaced by the target you specified, i.e. either :feed, #hashtag or the ' 'profile name. Defaults to \'{target}\'.') g_how.add_argument('--filename-pattern', - help='Prefix of filenames. Posts are stored in the directory whose pattern is given with ' - '--dirname-pattern. {profile} is replaced by the profile name, ' - '{target} is replaced by the target you specified, i.e. either :feed, #hashtag or the ' - 'profile name. Also, the fields {date} and {shortcode} can be specified. In case of not ' - 'downloading stories, the attributes of the Post class can be used in addition, e.g. ' - '{post.owner_id} or {post.mediaid}. Defaults to \'{date:%%Y-%%m-%%d_%%H-%%M-%%S}\'.') + help='Prefix of filenames, relative to the directory given with ' + '--dirname-pattern. {profile} is replaced by the profile name,' + '{target} is replaced by the target you specified, i.e. either :feed' + '#hashtag or the profile name. Defaults to \'{date_utc}_UTC\'') g_how.add_argument('--user-agent', help='User Agent to use for HTTP requests. Defaults to \'{}\'.'.format(default_user_agent())) g_how.add_argument('-S', '--no-sleep', action='store_true', help=SUPPRESS) diff --git a/instaloader/structures.py b/instaloader/structures.py index 9ec74a3..10b6a59 100644 --- a/instaloader/structures.py +++ b/instaloader/structures.py @@ -177,12 +177,12 @@ class Post: @property def date(self) -> datetime: - """Synonym to :meth:`.date_utc`""" + """Synonym to :attr:`~Post.date_utc`""" return self.date_utc @property def profile(self) -> str: - """Synonym to :meth:`.owner_username`""" + """Synonym to :attr:`~Post.owner_username`""" return self.owner_username @property @@ -593,6 +593,12 @@ class StoryItem: """The mediaid is a decimal representation of the media shortcode.""" return int(self._node['id']) + @property + def shortcode(self) -> str: + """Convert :attr:`~StoryItem.mediaid` to a shortcode-like string, allowing ``{shortcode}`` to be used with + :option:`--filename-pattern`.""" + return Post.mediaid_to_shortcode(self.mediaid) + def __repr__(self): return ''.format(self.mediaid) @@ -633,12 +639,12 @@ class StoryItem: @property def date(self) -> datetime: - """Synonym to :meth:`.date_utc`""" + """Synonym to :attr:`~StoryItem.date_utc`""" return self.date_utc @property def profile(self) -> str: - """Synonym to :meth:`.owner_username`""" + """Synonym to :attr:`~StoryItem.owner_username`""" return self.owner_username @property