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:
parent
0e40da1c70
commit
147cd1a580
@ -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']),
|
||||||
|
@ -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."""
|
||||||
|
Loading…
Reference in New Issue
Block a user