Compare commits

..
Author SHA1 Message Date
Alexander Graf a9cf78655c Fix obtaining post metadata when not logged-in
Fixes #960.
2021-01-24 20:47:57 +01:00
André Koch-Kramer 3955540080 Release of version 4.6 2021-01-09 16:23:49 +01:00
André Koch-Kramer 3fe6b1e139 Merge remote-tracking branch 'origin/upcoming/v4.6' 2021-01-09 16:11:05 +01:00
Alexander Graf a2ce906fd0 Fix efficiency bug regarding {filename} in filename-pattern
Avoid evaluating 'url' when preparing the filename if the
filename-pattern does not contain the "{filename}" token. This avoids
the URL to be queried even though it is not needed (e.g. with
--no-pictures).
2021-01-04 17:37:19 +01:00
Alexander Graf 227efa7b68 Improvements to contributing.md, other minor changes 2021-01-02 17:41:19 +01:00
Alexander Graf d7f7cad4a2 docs: Link to examples in master branch 2020-12-23 19:39:18 +01:00
7 changed files with 49 additions and 20 deletions
+1
View File
@@ -0,0 +1 @@
custom: "https://instaloader.github.io/contributing.html#donations"
+2 -1
View File
@@ -1,7 +1,8 @@
<!--
Please describe:
Thanks for your willingness to contribute to Instaloader! Please briefly
describe
- A motivation for this change, e.g.
- Fixes # .
+1 -1
View File
@@ -65,7 +65,7 @@ extlinks = {
'Issue #'
),
'example': (
'https://raw.githubusercontent.com/instaloader/instaloader/v' + current_release + '/docs/codesnippets/%s',
'https://raw.githubusercontent.com/instaloader/instaloader/master/docs/codesnippets/%s',
'Example '
),
}
+11 -3
View File
@@ -11,11 +11,19 @@ Instaloader's development is organized on
`GitHub <https://github.com/instaloader/instaloader>`__, where Issues and Pull
Requests are discussed.
Contributing to an open source project is an unmatchable opportunity to improve
and manifest programming skills. For issues that are good starting points to get
involved in Instaloader development, as they do not require deep insight into
Instaloader's code base, have a look at our
`Issues labelled 'good first issue' <https://github.com/instaloader/instaloader/contribute>`__.
This document covers several ways of how you can contribute back to Instaloader.
Answering Questions
-------------------
The easiest way to help out is to answer questions. If you are interested in
answering questions regarding Instaloader, good places to start are
answering questions regarding Instaloader, good places to begin are
- `Questions tagged 'instaloader' on Stack Overflow <https://stackoverflow.com/questions/tagged/instaloader>`__,
- `Instaloader Issues labeled 'question' <https://github.com/instaloader/instaloader/issues?q=is%3Aissue+is%3Aopen+label%3Aquestion>`__.
@@ -81,8 +89,8 @@ Improvements of the Instaloader source or its documentation can be proposed as a
make -C docs html
- Feel free to create an issue to make sure someone from the Instaloader team
agrees that the change might be an improvement, and is happy with your basic
proposal, before working on a pull request.
agrees that the change might be an improvement, or if you want to discuss
your basic proposal, before working on a pull request.
Proposing Features
------------------
+1 -1
View File
@@ -1,7 +1,7 @@
"""Download pictures (or videos) along with their captions and other metadata from Instagram."""
__version__ = '4.6rc1'
__version__ = '4.6'
try:
+13 -7
View File
@@ -524,11 +524,15 @@ class Instaloader:
self.context.two_factor_login(two_factor_code)
@staticmethod
def __prepare_filename(filename_template: str, url: str) -> str:
def __prepare_filename(filename_template: str, url: Callable[[], str]) -> str:
"""Replace filename token inside filename_template with url's filename and assure the directories exist.
.. versionadded:: 4.6"""
filename = filename_template.replace("{filename}", os.path.splitext(os.path.basename(urlparse(url).path))[0])
if "{filename}" in filename_template:
filename = filename_template.replace("{filename}",
os.path.splitext(os.path.basename(urlparse(url()).path))[0])
else:
filename = filename_template
os.makedirs(os.path.dirname(filename), exist_ok=True)
return filename
@@ -549,7 +553,7 @@ class Instaloader:
dirname = _PostPathFormatter(post).format(self.dirname_pattern, target=target)
filename_template = os.path.join(dirname, self.format_filename(post, target=target))
filename = self.__prepare_filename(filename_template, post.url)
filename = self.__prepare_filename(filename_template, lambda: post.url)
# Download the image(s) / video thumbnail and videos within sidecars if desired
downloaded = True
@@ -563,7 +567,8 @@ class Instaloader:
suffix = str(edge_number)
if '{filename}' in self.filename_pattern:
suffix = ''
filename = self.__prepare_filename(filename_template, sidecar_node.display_url)
# pylint:disable=cell-var-from-loop
filename = self.__prepare_filename(filename_template, lambda: sidecar_node.display_url)
# Download sidecar picture or video thumbnail (--no-pictures implies --no-video-thumbnails)
downloaded &= self.download_pic(filename=filename, url=sidecar_node.display_url,
mtime=post.date_local, filename_suffix=suffix)
@@ -571,7 +576,8 @@ class Instaloader:
suffix = str(edge_number)
if '{filename}' in self.filename_pattern:
suffix = ''
filename = self.__prepare_filename(filename_template, sidecar_node.video_url)
# pylint:disable=cell-var-from-loop
filename = self.__prepare_filename(filename_template, lambda: sidecar_node.video_url)
# Download sidecar video if desired
downloaded &= self.download_pic(filename=filename, url=sidecar_node.video_url,
mtime=post.date_local, filename_suffix=suffix)
@@ -690,13 +696,13 @@ class Instaloader:
date_local = item.date_local
dirname = _PostPathFormatter(item).format(self.dirname_pattern, target=target)
filename_template = os.path.join(dirname, self.format_filename(item, target=target))
filename = self.__prepare_filename(filename_template, item.url)
filename = self.__prepare_filename(filename_template, lambda: item.url)
downloaded = False
if not item.is_video or self.download_video_thumbnails is True:
url = item.url
downloaded = self.download_pic(filename=filename, url=url, mtime=date_local)
if item.is_video and self.download_videos is True:
filename = self.__prepare_filename(filename_template, str(item.video_url))
filename = self.__prepare_filename(filename_template, lambda: str(item.video_url))
downloaded |= self.download_pic(filename=filename, url=item.video_url, mtime=date_local)
# Save caption if desired
metadata_string = _ArbitraryItemFormatter(item).format(self.storyitem_metadata_txt_pattern).strip()
+20 -7
View File
@@ -141,11 +141,16 @@ class Post:
def _obtain_metadata(self):
if not self._full_metadata_dict:
pic_json = self._context.graphql_query(
'2b0673e0dc4580674a88d426fe00ea90',
{'shortcode': self.shortcode}
)
self._full_metadata_dict = pic_json['data']['shortcode_media']
if self._context.is_logged_in:
pic_json = self._context.graphql_query(
'2b0673e0dc4580674a88d426fe00ea90',
{'shortcode': self.shortcode}
)
self._full_metadata_dict = pic_json['data']['shortcode_media']
else:
# if not logged in, above graphql query is responded with a redirect to login page
pic_json = self._context.get_json("p/{0}/".format(self.shortcode), params={})
self._full_metadata_dict = pic_json['entry_data']['PostPage'][0]['graphql']['shortcode_media']
if self._full_metadata_dict is None:
raise BadResponseException("Fetching Post metadata failed.")
if self.shortcode != self._full_metadata_dict['shortcode']:
@@ -449,8 +454,16 @@ class Post:
# Avoid doing additional requests if there are no comments
return
comment_edges = self._field('edge_media_to_comment', 'edges')
answers_count = sum([edge['node'].get('edge_threaded_comments', {}).get('count', 0) for edge in comment_edges])
try:
# this seems to be the structure for logged-in accesses
comment_edges = self._field('edge_media_to_comment', 'edges')
answers_count = sum([edge['node'].get('edge_threaded_comments', {}).get('count', 0)
for edge in comment_edges])
except KeyError:
# ... and this for anonymous accesses
comment_edges = self._field('edge_media_to_parent_comment', 'edges')
answers_count = sum([edge['node']['edge_threaded_comments']['count']
for edge in comment_edges])
if self.comments == len(comment_edges) + answers_count:
# If the Post's metadata already contains all parent comments, don't do GraphQL requests to obtain them