def setup_function(): Account.clear_cache() Comment.clear_cache() Location.clear_cache() Media.clear_cache() Story.clear_cache() Tag.clear_cache()
def test_clear_cache_comment(id): account = Account("test") media = Media("test") comment = Comment(id, media=media, owner=account, text="test", created_at=0) assert Comment.cache == {id: comment} Comment.clear_cache() assert Comment.cache == dict() assert Media.cache == {"test": media} assert Account.cache == {"test": account}
def test_comment(login, password, shortcode): agent = AgentAccount(login, password) media = Media(shortcode) comment = agent.add_comment(media, "test") agent.delete_comment(comment) Account.clear_cache() Media.clear_cache() Comment.clear_cache()
def test_clear_cache_comment(): account = Account("test") media = Media("test") comment = Comment(1488, media=media, owner=account, text="test", created_at=0) Media.clear_cache() Comment.clear_cache() assert(Comment._cache == dict()) assert(Media._cache == dict())
def add_comment(self, media, text, settings={}): if not isinstance(media, Media): raise TypeError("'media' must be Media type") if not isinstance(text, str): raise TypeError("'text' must be str type") if not isinstance(settings, dict): raise TypeError("'settings' must be dict type") if media.id is None: self.update(media) response = self._action_request( referer="https://www.instagram.com/p/%s/" % media.code, url="https://www.instagram.com/web/comments/%s/add/" % media.id, data={"comment_text": text}, ) try: data = response.json() if data["status"] == "ok": comment = Comment( data["id"], media=media, owner=self, text=data["text"], created_at=data["created_time"], ) return comment return None except (ValueError, KeyError) as exception: raise UnexpectedResponse(exception, response.url, response.text)
def get_post_comments(post, num=None, path=None): agent = Agent() comments = set() pointer = None if num == None: comments_count = int(post.comments_count) else: comments_count = num limit = 50 batch_num = math.ceil(comments_count / limit) for i in range(batch_num): if i == batch_num - 1: count = comments_count - limit * (batch_num - 1) batch_comments, pointer = agent.get_comments(post, pointer=pointer, count=count) else: batch_comments, pointer = agent.get_comments(post, pointer=pointer, count=limit) for j, item in enumerate(batch_comments): comments.add(Comment(item.id)) comments_info = {} for i, item in enumerate(comments): comment_info = copy.copy(item) comment_info.media = str(comment_info.media) comment_info.owner = str(comment_info.owner) comments_info[i] = comment_info.__dict__ comments_dict = {"comments": comments_info} comments_json = json.dumps(comments_dict, indent=2) if path == None: path = './data' pathlib.Path(path + '/comments').mkdir(parents=True, exist_ok=True) postcode = post.code filename = path + '/comments/' + postcode + '__last_comments.json' with open(filename, 'w', newline='', encoding='utf8') as f: f.write(comments_json) return comments
def get_comments(self, media, pointer=None, count=35, settings={}, limit=50): if not isinstance(settings, dict): raise TypeError("'settings' must be dict type") if not isinstance(count, int): raise TypeError("'count' must be int type") if not isinstance(media, Media): raise TypeError("'media' must be Media type") if not isinstance(limit, int): raise TypeError("'limit' must be int type") data = self.update(media, settings) comments = [] if pointer is None: try: data = data["edge_media_to_comment"] edges = data["edges"] page_info = data["page_info"] for index in range(min(len(edges), count)): node = edges[index]["node"] c = Comment(node["id"], media=media, owner=Account(node["owner"]["username"]), text=node["text"], created_at=node["created_at"]) media.comments.add(c) comments.append(c) if page_info["has_next_page"]: pointer = page_info["end_cursor"] if len(edges) < count and not pointer is None: count = count - len(edges) else: return comments, pointer except (ValueError, KeyError) as exception: raise UnexpectedResponse(exception, media) variables_string = '{{"shortcode":"{code}","first":{first},"after":"{after}"}}' while True: data = { "after": pointer, "code": media.code, "first": min(limit, count) } response = self._graphql_request( query_hash="33ba35852cb50da46f5b5e889df7d159", variables=variables_string.format(**data), settings=settings, ) try: data = response.json( )["data"]["shortcode_media"]["edge_media_to_comment"] media.comments_count = data["count"] edges = data["edges"] page_info = data["page_info"] for index in range(min(len(edges), count)): node = edges[index]["node"] c = Comment(node["id"], media=media, owner=Account(node["owner"]["username"]), text=node["text"], created_at=node["created_at"]) media.comments.add(c) comments.append(c) if page_info["has_next_page"]: pointer = page_info["end_cursor"] else: pointer = None if len(edges) < count and page_info["has_next_page"]: count = count - len(edges) else: return comments, pointer except (ValueError, KeyError) as exception: raise UnexpectedResponse(exception, response.url, response.text)
def get_comments(self, media, pointer=None, count=35, settings={}, limit=50): if not isinstance(settings, dict): raise TypeError("'settings' must be dict type") if not isinstance(count, int): raise TypeError("'count' must be int type") if not isinstance(media, Media): raise TypeError("'media' must be Media type") if not isinstance(limit, int): raise TypeError("'limit' must be int type") data = self.update(media, settings) query_hash = "33ba35852cb50da46f5b5e889df7d159" variables_string = '{{"shortcode":"{code}","first":{first},"after":"{after}"}}' comments = [] if pointer is None: try: data = data["edge_media_to_comment"] edges = data["edges"] page_info = data["page_info"] for index in range(min(len(edges), count)): node = edges[index]["node"] c = Comment(node["id"], media=media, owner=Account(node["owner"]["username"]), text=node["text"], created_at=node["created_at"]) media.comments.add(c) comments.append(c) if page_info["has_next_page"]: pointer = page_info["end_cursor"] if len(edges) < count and not pointer is None: count = count-len(edges) else: return comments, pointer except (ValueError, KeyError): raise UnexpectedResponse(media) if not "params" in settings: settings["params"] = {"query_hash": query_hash} else: settings["params"]["query_hash"] = query_hash while True: data = {"after": pointer, "code": media.code, "first": min(limit, count)} settings["params"]["variables"] = variables_string.format(**data) if not "headers" in settings: settings["headers"] = { "X-Instagram-GIS": "%s:%s" % (self._rhx_gis, settings["params"]["variables"]), } else: settings["headers"]["X-Instagram-GIS"] = \ "%s:%s" % (self._rhx_gis, settings["params"]["variables"]) settings["headers"]["X-Instagram-GIS"] = \ hashlib.md5(settings["headers"]["X-Instagram-GIS"].encode("utf-8")).hexdigest() settings["headers"]["X-Requested-With"] = "XMLHttpRequest" response = self._get_request("https://www.instagram.com/graphql/query/", **settings) try: data = response.json()["data"]["shortcode_media"]["edge_media_to_comment"] media.comments_count = data["count"] edges = data["edges"] page_info = data["page_info"] for index in range(min(len(edges), count)): node = edges[index]["node"] c = Comment(node["id"], media=media, owner=Account(node["owner"]["username"]), text=node["text"], created_at=node["created_at"]) media.comments.add(c) comments.append(c) if page_info["has_next_page"]: pointer = page_info["end_cursor"] else: pointer = None if len(edges) < count and page_info["has_next_page"]: count = count-len(edges) else: return comments, pointer except (ValueError, KeyError): raise UnexpectedResponse(response.url, response.text)