Compare commits

...
5 Commits
Author SHA1 Message Date
Alexander Graf 1f311d3e1e First Beta Release for Version 4.1 2018-08-31 12:11:43 +02:00
Alexander Graf 862c51fa81 Profile.from_id graphql query is not rate limited 2018-08-30 13:59:46 +02:00
Alexander Graf cc15cb5857 Cache and reuse profiles for Profile.from_id() 2018-08-30 13:52:16 +02:00
Alexander Graf 0e534ba519 Use username/:tagged as target for tagged posts
Subdirs in profile folders were introduced with --highlights, and moving
:tagged posts there allows to further call instaloader as

instaloader [flags] */

(#154)
2018-08-30 09:57:42 +02:00
Alexander Graf 567a04a661 format_filename method to apply filename pattern 2018-08-30 09:13:49 +02:00
4 changed files with 20 additions and 6 deletions
+1 -1
View File
@@ -1,7 +1,7 @@
"""Download pictures (or videos) along with their captions and other metadata from Instagram."""
__version__ = '4.1a1'
__version__ = '4.1b1'
try:
+9 -3
View File
@@ -338,6 +338,12 @@ class Instaloader:
:raises ConnectionException: If connection to Instagram failed."""
self.context.login(user, passwd)
def format_filename(self, item: Union[Post, StoryItem], target: Optional[str] = None):
"""Format filename of a :class:`Post` or :class:`StoryItem` according to ``filename-pattern`` parameter.
.. versionadded:: 4.1"""
return _PostPathFormatter(item).format(self.filename_pattern, target=target)
def download_post(self, post: Post, target: str) -> bool:
"""
Download everything associated with one instagram post node, i.e. picture, caption and video.
@@ -348,7 +354,7 @@ class Instaloader:
"""
dirname = _PostPathFormatter(post).format(self.dirname_pattern, target=target)
filename = dirname + '/' + _PostPathFormatter(post).format(self.filename_pattern, target=target)
filename = dirname + '/' + self.format_filename(post, target=target)
os.makedirs(os.path.dirname(filename), exist_ok=True)
# Download the image(s) / video thumbnail and videos within sidecars if desired
@@ -473,7 +479,7 @@ class Instaloader:
date_local = item.date_local
dirname = _PostPathFormatter(item).format(self.dirname_pattern, target=target)
filename = dirname + '/' + _PostPathFormatter(item).format(self.filename_pattern, target=target)
filename = dirname + '/' + self.format_filename(item, target=target)
os.makedirs(os.path.dirname(filename), exist_ok=True)
downloaded = False
if not item.is_video or self.download_video_thumbnails is True:
@@ -693,7 +699,7 @@ class Instaloader:
.. versionadded:: 4.1"""
if target is None:
target = profile.username + ':tagged'
target = profile.username + '/:tagged'
self.context.log("Retrieving tagged posts for profile {}.".format(profile.username))
count = 1
for post in profile.get_tagged_posts():
+5 -1
View File
@@ -69,6 +69,9 @@ class InstaloaderContext:
# Can be set to True for testing, disables supression of InstaloaderContext._error_catcher
self.raise_all_errors = False
# Cache profile from id (mapping from id to Profile)
self.profile_id_cache = dict()
@contextmanager
def anonymous_copy(self):
session = self._session
@@ -245,7 +248,8 @@ class InstaloaderContext:
is_graphql_query = 'query_hash' in params and 'graphql/query' in path
# some queries are not rate limited if invoked anonymously:
query_not_limited = is_graphql_query and not self.is_logged_in \
and params['query_hash'] in ['9ca88e465c3f866a76f7adee3871bdd8']
and params['query_hash'] in ['9ca88e465c3f866a76f7adee3871bdd8',
'472f257a40c653c64c666ce877d59d2b']
if is_graphql_query and not query_not_limited:
waittime = graphql_query_waittime()
if waittime > 0:
+5 -1
View File
@@ -402,6 +402,8 @@ class Profile:
:param profile_id: userid
:raises: :class:`ProfileNotExistsException`, :class:`ProfileHasNoPicsException`
"""
if profile_id in context.profile_id_cache:
return context.profile_id_cache[profile_id]
data = context.graphql_query("472f257a40c653c64c666ce877d59d2b",
{'id': str(profile_id), 'first': 1},
rhx_gis=context.root_rhx_gis)['data']['user']
@@ -415,7 +417,9 @@ class Profile:
raise ProfileHasNoPicsException("Profile with ID {0}: no pics found.".format(str(profile_id)))
else:
raise LoginRequiredException("Login required to determine username (ID: " + str(profile_id) + ").")
return Post(context, data['edges'][0]['node']).owner_profile
profile = Post(context, data['edges'][0]['node']).owner_profile
context.profile_id_cache[profile_id] = profile
return profile
def _asdict(self):
json_node = self._node.copy()