1
0
mirror of https://github.com/instaloader/instaloader.git synced 2024-11-04 09:22:29 +01:00

Post_get_comments() yield namedtuple PostComment

This commit is contained in:
Alexander Graf 2018-04-28 18:17:00 +02:00
parent 0e40da1c70
commit 147cd1a580
2 changed files with 23 additions and 11 deletions

View File

@ -8,7 +8,7 @@ import string
import sys import sys
import tempfile import tempfile
from contextlib import contextmanager, suppress from contextlib import contextmanager, suppress
from datetime import datetime from datetime import datetime, timezone
from functools import wraps from functools import wraps
from io import BytesIO from io import BytesIO
from typing import Callable, Iterator, List, Optional, Any from typing import Callable, Iterator, List, Optional, Any
@ -185,12 +185,17 @@ class Instaloader:
self.context.log('json', end=' ', flush=True) self.context.log('json', end=' ', flush=True)
def update_comments(self, filename: str, post: Post) -> None: def update_comments(self, filename: str, post: Post) -> None:
def _postcomment_asdict(comment):
return {'id': comment.id,
'created_at': comment.created_at_utc.replace(tzinfo=timezone.utc).timestamp(),
'text': comment.text,
'owner': comment.owner._asdict()}
filename += '_comments.json' filename += '_comments.json'
try: try:
comments = json.load(open(filename)) comments = json.load(open(filename))
except FileNotFoundError: except FileNotFoundError:
comments = list() comments = list()
comments.extend(post.get_comments()) comments.extend(_postcomment_asdict(comment) for comment in post.get_comments())
if comments: if comments:
with open(filename, 'w') as file: with open(filename, 'w') as file:
comments_list = sorted(sorted(list(comments), key=lambda t: t['id']), comments_list = sorted(sorted(list(comments), key=lambda t: t['id']),

View File

@ -25,6 +25,7 @@ def mediaid_to_shortcode(mediaid: int) -> str:
PostSidecarNode = namedtuple('PostSidecarNode', ['is_video', 'display_url', 'video_url']) PostSidecarNode = namedtuple('PostSidecarNode', ['is_video', 'display_url', 'video_url'])
PostComment = namedtuple('PostComment', ['id', 'created_at_utc', 'text', 'owner'])
PostLocation = namedtuple('PostLocation', ['id', 'name', 'slug', 'has_public_page', 'lat', 'lng']) PostLocation = namedtuple('PostLocation', ['id', 'name', 'slug', 'has_public_page', 'lat', 'lng'])
@ -273,25 +274,31 @@ class Post:
"""Comment count""" """Comment count"""
return self._field('edge_media_to_comment', 'count') return self._field('edge_media_to_comment', 'count')
def get_comments(self) -> Iterator[Dict[str, Any]]: def get_comments(self) -> Iterator[PostComment]:
"""Iterate over all comments of the post. """Iterate over all comments of the post.
Each comment is represented by a dictionary having the keys text, created_at, id and owner, which is a Each comment is represented by a PostComment namedtuple with fields text (string), created_at (datetime),
dictionary with keys username, profile_pic_url and id. id (int) and owner (:class:`Profile`).
""" """
def _postcomment(node):
return PostComment(id=int(node['id']),
created_at_utc=datetime.utcfromtimestamp(node['created_at']),
text=node['text'],
owner=Profile(self._context, node['owner']))
if self.comments == 0: if self.comments == 0:
# Avoid doing additional requests if there are no comments # Avoid doing additional requests if there are no comments
return return
comment_edges = self._field('edge_media_to_comment', 'edges') comment_edges = self._field('edge_media_to_comment', 'edges')
if self.comments == len(comment_edges): if self.comments == len(comment_edges):
# If the Post's metadata already contains all comments, don't do GraphQL requests to obtain them # If the Post's metadata already contains all comments, don't do GraphQL requests to obtain them
yield from (comment['node'] for comment in comment_edges) yield from (_postcomment(comment['node']) for comment in comment_edges)
return return
yield from self._context.graphql_node_list("33ba35852cb50da46f5b5e889df7d159", yield from (_postcomment(node) for node in
self._context.graphql_node_list("33ba35852cb50da46f5b5e889df7d159",
{'shortcode': self.shortcode}, {'shortcode': self.shortcode},
'https://www.instagram.com/p/' + self.shortcode + '/', 'https://www.instagram.com/p/' + self.shortcode + '/',
lambda d: d['data']['shortcode_media']['edge_media_to_comment'], lambda d: d['data']['shortcode_media']['edge_media_to_comment'],
self._rhx_gis) self._rhx_gis))
def get_likes(self) -> Iterator['Profile']: def get_likes(self) -> Iterator['Profile']:
"""Iterate over all likes of the post. A :class:`Profile` instance of each likee is yielded.""" """Iterate over all likes of the post. A :class:`Profile` instance of each likee is yielded."""