From 08cf72ecadd7c829770f25d5743fc9f13894ee99 Mon Sep 17 00:00:00 2001 From: krzesu0 Date: Tue, 25 Jun 2019 21:19:52 +0200 Subject: [PATCH 01/11] Working on fetchThreadImages --- fbchat/_client.py | 20 ++++++++++++++++++-- fbchat/_util.py | 1 + 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/fbchat/_client.py b/fbchat/_client.py index d9f96b72..efcea807 100644 --- a/fbchat/_client.py +++ b/fbchat/_client.py @@ -33,7 +33,7 @@ class Client(object): See https://fbchat.readthedocs.io for complete documentation of the API. """ - ssl_verify = True + ssl_verify = False """Verify ssl certificate, set to False to allow debugging with a proxy""" listening = False """Whether the client is listening. Used when creating an external event loop to determine when to stop listening""" @@ -79,6 +79,10 @@ def __init__( self._req_url = ReqUrl() self._markAlive = True self._buddylist = dict() + self._proxies = { + "http": "127.0.0.1:8080", + "https": "127.0.0.1:8080" + } if not user_agent: user_agent = choice(USER_AGENTS) @@ -159,7 +163,7 @@ def _post( ): payload = self._generatePayload(query) r = self._session.post( - url, headers=self._header, data=payload, verify=self.ssl_verify + url, headers=self._header, data=payload, verify=self.ssl_verify, proxies=self._proxies ) if not fix_request: return r @@ -1197,6 +1201,18 @@ def getUserActiveStatus(self, user_id): """ return self._buddylist.get(str(user_id)) + def fetchThreadImages(self, thread_id=None): + """ + TODO: this doc + """ + thread_id, thread_type = self._getThread(thread_id, None) + data = { + "id": thread_id, # ID of an thread + "first": 12, # Default is 12 + } + j = self._post(self._req_url.WEBGRAPHQL.format(urllib.parse.quote(str(data)))) + return j + """ END FETCH METHODS """ diff --git a/fbchat/_util.py b/fbchat/_util.py index 22443dd9..3688437e 100644 --- a/fbchat/_util.py +++ b/fbchat/_util.py @@ -115,6 +115,7 @@ class ReqUrl(object): MARK_SPAM = "https://www.facebook.com/ajax/mercury/mark_spam.php?dpr=1" UNSEND = "https://www.facebook.com/messaging/unsend_message/?dpr=1" FORWARD_ATTACHMENT = "https://www.facebook.com/mercury/attachments/forward/" + WEBGRAPHQL = "https://www.facebook.com/webgraphql/query/?query_id=515216185516880&variables={}" pull_channel = 0 From 3d1f976c9c20f1b7410521603edc67c639bca3c0 Mon Sep 17 00:00:00 2001 From: krzesu0 Date: Sun, 30 Jun 2019 12:57:24 +0200 Subject: [PATCH 02/11] Adding fetchThreadImages and tidyng up some dev leftovers --- fbchat/_client.py | 54 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 41 insertions(+), 13 deletions(-) diff --git a/fbchat/_client.py b/fbchat/_client.py index efcea807..025c1758 100644 --- a/fbchat/_client.py +++ b/fbchat/_client.py @@ -79,10 +79,6 @@ def __init__( self._req_url = ReqUrl() self._markAlive = True self._buddylist = dict() - self._proxies = { - "http": "127.0.0.1:8080", - "https": "127.0.0.1:8080" - } if not user_agent: user_agent = choice(USER_AGENTS) @@ -163,7 +159,7 @@ def _post( ): payload = self._generatePayload(query) r = self._session.post( - url, headers=self._header, data=payload, verify=self.ssl_verify, proxies=self._proxies + url, headers=self._header, data=payload, verify=self.ssl_verify ) if not fix_request: return r @@ -1201,17 +1197,49 @@ def getUserActiveStatus(self, user_id): """ return self._buddylist.get(str(user_id)) - def fetchThreadImages(self, thread_id=None): + def _fetchImages(self, thread_id=None, after=None): + if after is None: + data = urllib.parse.quote( + str( + { + "id": thread_id, # ID of an thread + "first": 12, # Default is 12, facebook will do more, but im kinda scared + } + ) + ) + else: + data = urllib.parse.quote( + str( + { + "id": thread_id, + "after": after, # id of an image from which you want to start the query + "first": 12, # passed as "token", 154 characters + } + ) + ) + j = self._post(self._req_url.WEBGRAPHQL.format(data)) + if j.status_code == 200: + return json.loads(j.text[9:]) + else: + raise (FBchatUserError("Passed something thread_id")) + + def fetchThreadImages(self, thread_id=None, after=None): """ - TODO: this doc + Gets list of images sent in given thread. + :param thread_id: ID of the thread + :param after: So called Cursor + :return: List of images in thread with corresponding Cursor values. + :rtype: list """ thread_id, thread_type = self._getThread(thread_id, None) - data = { - "id": thread_id, # ID of an thread - "first": 12, # Default is 12 - } - j = self._post(self._req_url.WEBGRAPHQL.format(urllib.parse.quote(str(data)))) - return j + reply = self._fetchImages(thread_id=thread_id, after=after) + try: + return [ + [i["cursor"], i["node"]["image"]["uri"]] + for i in reply["payload"][thread_id]["message_shared_media"]["edges"] + ] + except TypeError: + return [] """ END FETCH METHODS From 98dcfe8fb0831edacf871ef397136503f238b71d Mon Sep 17 00:00:00 2001 From: krzesu0 Date: Sun, 30 Jun 2019 13:00:06 +0200 Subject: [PATCH 03/11] Forgot about ssl lmao --- fbchat/_client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fbchat/_client.py b/fbchat/_client.py index 025c1758..14e8dfab 100644 --- a/fbchat/_client.py +++ b/fbchat/_client.py @@ -33,7 +33,7 @@ class Client(object): See https://fbchat.readthedocs.io for complete documentation of the API. """ - ssl_verify = False + ssl_verify = True """Verify ssl certificate, set to False to allow debugging with a proxy""" listening = False """Whether the client is listening. Used when creating an external event loop to determine when to stop listening""" From 77a364a66b1ce716a8a137bc20b2e1c36139374e Mon Sep 17 00:00:00 2001 From: krzesu0 Date: Sun, 30 Jun 2019 13:14:32 +0200 Subject: [PATCH 04/11] Adding fetchThreadImages --- fbchat/_client.py | 90 +++++++++++++++++++++++++++-------------------- fbchat/_util.py | 1 + 2 files changed, 52 insertions(+), 39 deletions(-) diff --git a/fbchat/_client.py b/fbchat/_client.py index e99307c1..14e8dfab 100644 --- a/fbchat/_client.py +++ b/fbchat/_client.py @@ -128,22 +128,10 @@ def _fix_fb_errors(self, error_code): return True return False - def _get( - self, - url, - query=None, - timeout=30, - fix_request=False, - as_json=False, - error_retries=3, - ): + def _get(self, url, query=None, fix_request=False, as_json=False, error_retries=3): payload = self._generatePayload(query) r = self._session.get( - url, - headers=self._header, - params=payload, - timeout=timeout, - verify=self.ssl_verify, + url, headers=self._header, params=payload, verify=self.ssl_verify ) if not fix_request: return r @@ -154,7 +142,6 @@ def _get( return self._get( url, query=query, - timeout=timeout, fix_request=fix_request, as_json=as_json, error_retries=error_retries - 1, @@ -165,7 +152,6 @@ def _post( self, url, query=None, - timeout=30, fix_request=False, as_json=False, as_graphql=False, @@ -173,11 +159,7 @@ def _post( ): payload = self._generatePayload(query) r = self._session.post( - url, - headers=self._header, - data=payload, - timeout=timeout, - verify=self.ssl_verify, + url, headers=self._header, data=payload, verify=self.ssl_verify ) if not fix_request: return r @@ -192,7 +174,6 @@ def _post( return self._post( url, query=query, - timeout=timeout, fix_request=fix_request, as_json=as_json, as_graphql=as_graphql, @@ -200,24 +181,19 @@ def _post( ) raise e - def _cleanGet(self, url, query=None, timeout=30, allow_redirects=True): + def _cleanGet(self, url, query=None, allow_redirects=True): return self._session.get( url, headers=self._header, params=query, - timeout=timeout, verify=self.ssl_verify, allow_redirects=allow_redirects, ) - def _cleanPost(self, url, query=None, timeout=30): + def _cleanPost(self, url, query=None): self._req_counter += 1 return self._session.post( - url, - headers=self._header, - data=query, - timeout=timeout, - verify=self.ssl_verify, + url, headers=self._header, data=query, verify=self.ssl_verify ) def _postFile( @@ -225,7 +201,6 @@ def _postFile( url, files=None, query=None, - timeout=30, fix_request=False, as_json=False, error_retries=3, @@ -236,12 +211,7 @@ def _postFile( (i, self._header[i]) for i in self._header if i != "Content-Type" ) r = self._session.post( - url, - headers=headers, - data=payload, - timeout=timeout, - files=files, - verify=self.ssl_verify, + url, headers=headers, data=payload, files=files, verify=self.ssl_verify ) if not fix_request: return r @@ -253,7 +223,6 @@ def _postFile( url, files=files, query=query, - timeout=timeout, fix_request=fix_request, as_json=as_json, error_retries=error_retries - 1, @@ -500,7 +469,6 @@ def logout(self): """ Safely logs out the client - :param timeout: See `requests timeout `_ :return: True if the action was successful :rtype: bool """ @@ -1229,6 +1197,50 @@ def getUserActiveStatus(self, user_id): """ return self._buddylist.get(str(user_id)) + def _fetchImages(self, thread_id=None, after=None): + if after is None: + data = urllib.parse.quote( + str( + { + "id": thread_id, # ID of an thread + "first": 12, # Default is 12, facebook will do more, but im kinda scared + } + ) + ) + else: + data = urllib.parse.quote( + str( + { + "id": thread_id, + "after": after, # id of an image from which you want to start the query + "first": 12, # passed as "token", 154 characters + } + ) + ) + j = self._post(self._req_url.WEBGRAPHQL.format(data)) + if j.status_code == 200: + return json.loads(j.text[9:]) + else: + raise (FBchatUserError("Passed something thread_id")) + + def fetchThreadImages(self, thread_id=None, after=None): + """ + Gets list of images sent in given thread. + :param thread_id: ID of the thread + :param after: So called Cursor + :return: List of images in thread with corresponding Cursor values. + :rtype: list + """ + thread_id, thread_type = self._getThread(thread_id, None) + reply = self._fetchImages(thread_id=thread_id, after=after) + try: + return [ + [i["cursor"], i["node"]["image"]["uri"]] + for i in reply["payload"][thread_id]["message_shared_media"]["edges"] + ] + except TypeError: + return [] + """ END FETCH METHODS """ diff --git a/fbchat/_util.py b/fbchat/_util.py index 22443dd9..3688437e 100644 --- a/fbchat/_util.py +++ b/fbchat/_util.py @@ -115,6 +115,7 @@ class ReqUrl(object): MARK_SPAM = "https://www.facebook.com/ajax/mercury/mark_spam.php?dpr=1" UNSEND = "https://www.facebook.com/messaging/unsend_message/?dpr=1" FORWARD_ATTACHMENT = "https://www.facebook.com/mercury/attachments/forward/" + WEBGRAPHQL = "https://www.facebook.com/webgraphql/query/?query_id=515216185516880&variables={}" pull_channel = 0 From 6f22df9506933a47e7c40753617ee6fdeaa76456 Mon Sep 17 00:00:00 2001 From: krzesu0 Date: Mon, 8 Jul 2019 13:54:25 +0200 Subject: [PATCH 05/11] Completing fetchThreadImages functionality. --- fbchat/_client.py | 68 +++++++++++++++++++++-------------------------- fbchat/_file.py | 24 +++++++++++++++++ fbchat/_util.py | 4 --- 3 files changed, 54 insertions(+), 42 deletions(-) diff --git a/fbchat/_client.py b/fbchat/_client.py index 82bc093f..b6fdaa9d 100644 --- a/fbchat/_client.py +++ b/fbchat/_client.py @@ -976,49 +976,41 @@ def getUserActiveStatus(self, user_id): """ return self._buddylist.get(str(user_id)) - def _fetchImages(self, thread_id=None, after=None): - if after is None: - data = urllib.parse.quote( - str( - { - "id": thread_id, # ID of an thread - "first": 12, # Default is 12, facebook will do more, but im kinda scared - } - ) - ) - else: - data = urllib.parse.quote( - str( - { - "id": thread_id, - "after": after, # id of an image from which you want to start the query - "first": 12, # passed as "token", 154 characters - } - ) - ) - j = self._post(self._req_url.WEBGRAPHQL.format(data)) - if j.status_code == 200: - return json.loads(j.text[9:]) - else: - raise (FBchatUserError("Passed something thread_id")) + def _fetchImages(self, thread_id): + data = {"id": thread_id, "first": 12} + j = self.graphql_request(_graphql.from_query_id("515216185516880", data)) + to_continue = True + while to_continue: + page_info = j[thread_id]["message_shared_media"]["page_info"] + end_cursor = page_info.get("end_cursor") + try: + yield j[thread_id]["message_shared_media"]["edges"][0] + del j[thread_id]["message_shared_media"]["edges"][0] + except IndexError: + if page_info.get("has_next_page"): + data["after"] = end_cursor + j = self.graphql_request( + _graphql.from_query_id("515216185516880", data) + ) + else: + to_continue = False - def fetchThreadImages(self, thread_id=None, after=None): + def fetchThreadImages(self, thread_id=None): """ - Gets list of images sent in given thread. + Creates generator object for fetching images posted in thread. :param thread_id: ID of the thread - :param after: So called Cursor - :return: List of images in thread with corresponding Cursor values. - :rtype: list + :return: :class:`ImageAttachment` or :class:`VideoAttachment`. + :rtype: iterable """ thread_id, thread_type = self._getThread(thread_id, None) - reply = self._fetchImages(thread_id=thread_id, after=after) - try: - return [ - [i["cursor"], i["node"]["image"]["uri"]] - for i in reply["payload"][thread_id]["message_shared_media"]["edges"] - ] - except TypeError: - return [] + j = self._fetchImages(thread_id) + for i in j: + if i["node"].get("__typename") == "MessageImage": + yield ImageAttachment._from_list(i) + elif i["node"].get("__typename") == "MessageVideo": + yield VideoAttachment._from_list(i) + else: + return None # TODO: return legacyAttachment """ END FETCH METHODS diff --git a/fbchat/_file.py b/fbchat/_file.py index 45cd282a..a645b050 100644 --- a/fbchat/_file.py +++ b/fbchat/_file.py @@ -155,6 +155,18 @@ def _from_graphql(cls, data): uid=data.get("legacy_attachment_id"), ) + @classmethod + def _from_list(cls, data): + data = data["node"] + return cls( + width=data["original_dimensions"].get("x"), + height=data["original_dimensions"].get("y"), + thumbnail_url=data["image"].get("uri"), + large_preview=data["image2"], + preview=data["image1"], + uid=data["id"], + ) + @attr.s(cmp=False, init=False) class VideoAttachment(Attachment): @@ -252,6 +264,18 @@ def _from_subattachment(cls, data): uid=data["target"].get("video_id"), ) + @classmethod + def _from_list(cls, data): + data = data["node"] + return cls( + width=data["original_dimensions"].get("x"), + height=data["original_dimensions"].get("y"), + small_image=data["image"], + medium_image=data["image1"], + large_image=data["image2"], + uid=data["id"], + ) + def graphql_to_attachment(data): _type = data["__typename"] diff --git a/fbchat/_util.py b/fbchat/_util.py index 7f22eaac..27d9b95f 100644 --- a/fbchat/_util.py +++ b/fbchat/_util.py @@ -53,7 +53,6 @@ ] -<<<<<<< HEAD class ReqUrl(object): """A class containing all urls used by `fbchat`""" @@ -122,7 +121,6 @@ class ReqUrl(object): MARK_SPAM = "https://www.facebook.com/ajax/mercury/mark_spam.php?dpr=1" UNSEND = "https://www.facebook.com/messaging/unsend_message/?dpr=1" FORWARD_ATTACHMENT = "https://www.facebook.com/mercury/attachments/forward/" - WEBGRAPHQL = "https://www.facebook.com/webgraphql/query/?query_id=515216185516880&variables={}" pull_channel = 0 @@ -140,8 +138,6 @@ def change_pull_channel(self, channel=None): facebookEncoding = "UTF-8" -======= ->>>>>>> 281a20f56a79ace5e8bfcc44dfae8c04bb9b349b def now(): return int(time() * 1000) From 848c80fc85c86b2e18293f3873f380105fdae84d Mon Sep 17 00:00:00 2001 From: krzesu0 Date: Mon, 8 Jul 2019 14:05:00 +0200 Subject: [PATCH 06/11] Fix build error. --- fbchat/_client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fbchat/_client.py b/fbchat/_client.py index b6fdaa9d..0f78b19b 100644 --- a/fbchat/_client.py +++ b/fbchat/_client.py @@ -1010,7 +1010,7 @@ def fetchThreadImages(self, thread_id=None): elif i["node"].get("__typename") == "MessageVideo": yield VideoAttachment._from_list(i) else: - return None # TODO: return legacyAttachment + yield Attachment(uid=i["node"]["uid"]) """ END FETCH METHODS From e8bb42039cf347d90f132a540249495a38b38d48 Mon Sep 17 00:00:00 2001 From: krzesu0 Date: Wed, 10 Jul 2019 11:51:23 +0200 Subject: [PATCH 07/11] Fix #433 removal. --- fbchat/_util.py | 85 ------------------------------------------------- 1 file changed, 85 deletions(-) diff --git a/fbchat/_util.py b/fbchat/_util.py index 27d9b95f..58fa6572 100644 --- a/fbchat/_util.py +++ b/fbchat/_util.py @@ -53,91 +53,6 @@ ] -class ReqUrl(object): - """A class containing all urls used by `fbchat`""" - - SEARCH = "https://www.facebook.com/ajax/typeahead/search.php" - LOGIN = "https://m.facebook.com/login.php?login_attempt=1" - SEND = "https://www.facebook.com/messaging/send/" - UNREAD_THREADS = "https://www.facebook.com/ajax/mercury/unread_threads.php" - UNSEEN_THREADS = "https://www.facebook.com/mercury/unseen_thread_ids/" - THREADS = "https://www.facebook.com/ajax/mercury/threadlist_info.php" - MOVE_THREAD = "https://www.facebook.com/ajax/mercury/move_thread.php" - ARCHIVED_STATUS = ( - "https://www.facebook.com/ajax/mercury/change_archived_status.php?dpr=1" - ) - PINNED_STATUS = ( - "https://www.facebook.com/ajax/mercury/change_pinned_status.php?dpr=1" - ) - MESSAGES = "https://www.facebook.com/ajax/mercury/thread_info.php" - READ_STATUS = "https://www.facebook.com/ajax/mercury/change_read_status.php" - DELIVERED = "https://www.facebook.com/ajax/mercury/delivery_receipts.php" - MARK_SEEN = "https://www.facebook.com/ajax/mercury/mark_seen.php" - BASE = "https://www.facebook.com" - MOBILE = "https://m.facebook.com/" - STICKY = "https://0-edge-chat.facebook.com/pull" - PING = "https://0-edge-chat.facebook.com/active_ping" - UPLOAD = "https://upload.facebook.com/ajax/mercury/upload.php" - INFO = "https://www.facebook.com/chat/user_info/" - CONNECT = "https://www.facebook.com/ajax/add_friend/action.php?dpr=1" - REMOVE_USER = "https://www.facebook.com/chat/remove_participants/" - LOGOUT = "https://www.facebook.com/logout.php" - ALL_USERS = "https://www.facebook.com/chat/user_info_all" - SAVE_DEVICE = "https://m.facebook.com/login/save-device/cancel/" - CHECKPOINT = "https://m.facebook.com/login/checkpoint/" - THREAD_COLOR = "https://www.facebook.com/messaging/save_thread_color/?source=thread_settings&dpr=1" - THREAD_NICKNAME = "https://www.facebook.com/messaging/save_thread_nickname/?source=thread_settings&dpr=1" - THREAD_EMOJI = "https://www.facebook.com/messaging/save_thread_emoji/?source=thread_settings&dpr=1" - THREAD_IMAGE = "https://www.facebook.com/messaging/set_thread_image/?dpr=1" - THREAD_NAME = "https://www.facebook.com/messaging/set_thread_name/?dpr=1" - MESSAGE_REACTION = "https://www.facebook.com/webgraphql/mutation" - TYPING = "https://www.facebook.com/ajax/messaging/typ.php" - GRAPHQL = "https://www.facebook.com/api/graphqlbatch/" - ATTACHMENT_PHOTO = "https://www.facebook.com/mercury/attachments/photo/" - PLAN_CREATE = "https://www.facebook.com/ajax/eventreminder/create" - PLAN_INFO = "https://www.facebook.com/ajax/eventreminder" - PLAN_CHANGE = "https://www.facebook.com/ajax/eventreminder/submit" - PLAN_PARTICIPATION = "https://www.facebook.com/ajax/eventreminder/rsvp" - MODERN_SETTINGS_MENU = "https://www.facebook.com/bluebar/modern_settings_menu/" - REMOVE_FRIEND = "https://m.facebook.com/a/removefriend.php" - BLOCK_USER = "https://www.facebook.com/messaging/block_messages/?dpr=1" - UNBLOCK_USER = "https://www.facebook.com/messaging/unblock_messages/?dpr=1" - SAVE_ADMINS = "https://www.facebook.com/messaging/save_admins/?dpr=1" - APPROVAL_MODE = "https://www.facebook.com/messaging/set_approval_mode/?dpr=1" - CREATE_GROUP = "https://m.facebook.com/messages/send/?icm=1" - DELETE_THREAD = "https://www.facebook.com/ajax/mercury/delete_thread.php?dpr=1" - DELETE_MESSAGES = "https://www.facebook.com/ajax/mercury/delete_messages.php?dpr=1" - MUTE_THREAD = "https://www.facebook.com/ajax/mercury/change_mute_thread.php?dpr=1" - MUTE_REACTIONS = ( - "https://www.facebook.com/ajax/mercury/change_reactions_mute_thread/?dpr=1" - ) - MUTE_MENTIONS = ( - "https://www.facebook.com/ajax/mercury/change_mentions_mute_thread/?dpr=1" - ) - CREATE_POLL = "https://www.facebook.com/messaging/group_polling/create_poll/?dpr=1" - UPDATE_VOTE = "https://www.facebook.com/messaging/group_polling/update_vote/?dpr=1" - GET_POLL_OPTIONS = "https://www.facebook.com/ajax/mercury/get_poll_options" - SEARCH_MESSAGES = "https://www.facebook.com/ajax/mercury/search_snippets.php?dpr=1" - MARK_SPAM = "https://www.facebook.com/ajax/mercury/mark_spam.php?dpr=1" - UNSEND = "https://www.facebook.com/messaging/unsend_message/?dpr=1" - FORWARD_ATTACHMENT = "https://www.facebook.com/mercury/attachments/forward/" - - pull_channel = 0 - - def change_pull_channel(self, channel=None): - if channel is None: - self.pull_channel = (self.pull_channel + 1) % 5 # Pull channel will be 0-4 - else: - self.pull_channel = channel - self.STICKY = "https://{}-edge-chat.facebook.com/pull".format(self.pull_channel) - self.PING = "https://{}-edge-chat.facebook.com/active_ping".format( - self.pull_channel - ) - - -facebookEncoding = "UTF-8" - - def now(): return int(time() * 1000) From a4ee2a2f7ee2ad7d20c9b589066c8c1ac2e6d47c Mon Sep 17 00:00:00 2001 From: krzesu0 Date: Mon, 22 Jul 2019 13:31:21 +0200 Subject: [PATCH 08/11] #434 Fixes and changes. --- examples/fetch.py | 7 +++++++ fbchat/_client.py | 34 ++++++++++++++-------------------- 2 files changed, 21 insertions(+), 20 deletions(-) diff --git a/examples/fetch.py b/examples/fetch.py index 5db97b80..cbcef403 100644 --- a/examples/fetch.py +++ b/examples/fetch.py @@ -1,5 +1,6 @@ # -*- coding: UTF-8 -*- +from itertools import islice from fbchat import Client from fbchat.models import * @@ -62,3 +63,9 @@ # Here should be an example of `getUnread` + + +# Print image url for 20 last images from thread. +images = client.fetchThreadImages("") +for image in islice(image, 20): + print(image.large_preview_url) diff --git a/fbchat/_client.py b/fbchat/_client.py index 0f78b19b..4ce15ad3 100644 --- a/fbchat/_client.py +++ b/fbchat/_client.py @@ -976,24 +976,6 @@ def getUserActiveStatus(self, user_id): """ return self._buddylist.get(str(user_id)) - def _fetchImages(self, thread_id): - data = {"id": thread_id, "first": 12} - j = self.graphql_request(_graphql.from_query_id("515216185516880", data)) - to_continue = True - while to_continue: - page_info = j[thread_id]["message_shared_media"]["page_info"] - end_cursor = page_info.get("end_cursor") - try: - yield j[thread_id]["message_shared_media"]["edges"][0] - del j[thread_id]["message_shared_media"]["edges"][0] - except IndexError: - if page_info.get("has_next_page"): - data["after"] = end_cursor - j = self.graphql_request( - _graphql.from_query_id("515216185516880", data) - ) - else: - to_continue = False def fetchThreadImages(self, thread_id=None): """ @@ -1003,14 +985,26 @@ def fetchThreadImages(self, thread_id=None): :rtype: iterable """ thread_id, thread_type = self._getThread(thread_id, None) - j = self._fetchImages(thread_id) - for i in j: + data = {"id": thread_id, "first": 48} + j = self.graphql_request(_graphql.from_query_id("515216185516880", data)) + while True: + try: + i = j[thread_id]["message_shared_media"]["edges"][0] + except IndexError: + if j[thread_id]["message_shared_media"]["page_info"].get("has_next_page"): + data["after"] = j[thread_id]["message_shared_media"]["page_info"].get("end_cursor") + j = self.graphql_request(_graphql.from_query_id("515216185516880", data)) + continue + else: + break + if i["node"].get("__typename") == "MessageImage": yield ImageAttachment._from_list(i) elif i["node"].get("__typename") == "MessageVideo": yield VideoAttachment._from_list(i) else: yield Attachment(uid=i["node"]["uid"]) + del j[thread_id]["message_shared_media"]["edges"][0] """ END FETCH METHODS From 4d9ffe9de4344c62361201d24dc197006b4d6aae Mon Sep 17 00:00:00 2001 From: krzesu0 Date: Mon, 22 Jul 2019 13:37:46 +0200 Subject: [PATCH 09/11] Fixed formating. --- fbchat/_client.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/fbchat/_client.py b/fbchat/_client.py index 4ce15ad3..4e47ec51 100644 --- a/fbchat/_client.py +++ b/fbchat/_client.py @@ -976,7 +976,6 @@ def getUserActiveStatus(self, user_id): """ return self._buddylist.get(str(user_id)) - def fetchThreadImages(self, thread_id=None): """ Creates generator object for fetching images posted in thread. @@ -991,9 +990,15 @@ def fetchThreadImages(self, thread_id=None): try: i = j[thread_id]["message_shared_media"]["edges"][0] except IndexError: - if j[thread_id]["message_shared_media"]["page_info"].get("has_next_page"): - data["after"] = j[thread_id]["message_shared_media"]["page_info"].get("end_cursor") - j = self.graphql_request(_graphql.from_query_id("515216185516880", data)) + if j[thread_id]["message_shared_media"]["page_info"].get( + "has_next_page" + ): + data["after"] = j[thread_id]["message_shared_media"][ + "page_info" + ].get("end_cursor") + j = self.graphql_request( + _graphql.from_query_id("515216185516880", data) + ) continue else: break From 71d2097c9643ba6e62d633308b78b7393b806d54 Mon Sep 17 00:00:00 2001 From: Przemek <42300497+krzesu0@users.noreply.github.com> Date: Wed, 24 Jul 2019 12:58:32 +0200 Subject: [PATCH 10/11] Changing from uid to leagacy_attachment_id. > Use the attachment ID instead of the ID returned by the endpoint. > Use legacy_attachment_id instead of uid. And for some attachments, such as MessageAudio (which this endpoint also return), you won't even get an id! Co-Authored-By: Mads Marquart --- fbchat/_client.py | 2 +- fbchat/_file.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/fbchat/_client.py b/fbchat/_client.py index 4e47ec51..ac9b0be9 100644 --- a/fbchat/_client.py +++ b/fbchat/_client.py @@ -1008,7 +1008,7 @@ def fetchThreadImages(self, thread_id=None): elif i["node"].get("__typename") == "MessageVideo": yield VideoAttachment._from_list(i) else: - yield Attachment(uid=i["node"]["uid"]) + yield Attachment(uid=i["node"].get("legacy_attachment_id")) del j[thread_id]["message_shared_media"]["edges"][0] """ diff --git a/fbchat/_file.py b/fbchat/_file.py index a645b050..13bd9db5 100644 --- a/fbchat/_file.py +++ b/fbchat/_file.py @@ -164,7 +164,7 @@ def _from_list(cls, data): thumbnail_url=data["image"].get("uri"), large_preview=data["image2"], preview=data["image1"], - uid=data["id"], + uid=data["legacy_attachment_id"], ) @@ -273,7 +273,7 @@ def _from_list(cls, data): small_image=data["image"], medium_image=data["image1"], large_image=data["image2"], - uid=data["id"], + uid=data["legacy_attachment_id"], ) From ec4a7b9917167f331a74c1093d88d8f60e1c9030 Mon Sep 17 00:00:00 2001 From: krzesu0 Date: Wed, 24 Jul 2019 13:19:38 +0200 Subject: [PATCH 11/11] str(thread_id) --- fbchat/_client.py | 1 + 1 file changed, 1 insertion(+) diff --git a/fbchat/_client.py b/fbchat/_client.py index ac9b0be9..ab85b0bc 100644 --- a/fbchat/_client.py +++ b/fbchat/_client.py @@ -985,6 +985,7 @@ def fetchThreadImages(self, thread_id=None): """ thread_id, thread_type = self._getThread(thread_id, None) data = {"id": thread_id, "first": 48} + thread_id = str(thread_id) j = self.graphql_request(_graphql.from_query_id("515216185516880", data)) while True: try: