From d6ca091b7b6e1c71e9b7df7b1410a056f8d49100 Mon Sep 17 00:00:00 2001 From: Kacper Ziubryniewicz Date: Thu, 30 Aug 2018 19:56:18 +0200 Subject: [PATCH 1/5] Merge `Room` with `Group` model --- fbchat/models.py | 31 +++++++++---------------------- 1 file changed, 9 insertions(+), 22 deletions(-) diff --git a/fbchat/models.py b/fbchat/models.py index 5fce5a7..51e8019 100644 --- a/fbchat/models.py +++ b/fbchat/models.py @@ -102,8 +102,16 @@ class Group(Thread): color = None #: The groups's default emoji emoji = None + # Set containing user IDs of thread admins + admins = None + # True if users need approval to join + approval_mode = None + # Set containing user IDs requesting to join + approval_requests = None + # Link for joining group + join_link = None - def __init__(self, uid, participants=None, nicknames=None, color=None, emoji=None, **kwargs): + def __init__(self, uid, participants=None, nicknames=None, color=None, emoji=None, admins=None, approval_mode=None, approval_requests=None, join_link=None, privacy_mode=None, **kwargs): """Represents a Facebook group. Inherits `Thread`""" super(Group, self).__init__(ThreadType.GROUP, uid, **kwargs) if participants is None: @@ -114,24 +122,6 @@ class Group(Thread): self.nicknames = nicknames self.color = color self.emoji = emoji - - -class Room(Group): - # Set containing user IDs of thread admins - admins = None - # True if users need approval to join - approval_mode = None - # Set containing user IDs requesting to join - approval_requests = None - # Link for joining room - join_link = None - # True is room is not discoverable - privacy_mode = None - - def __init__(self, uid, admins=None, approval_mode=None, approval_requests=None, join_link=None, privacy_mode=None, **kwargs): - """Represents a Facebook room. Inherits `Group`""" - super(Room, self).__init__(uid, **kwargs) - self.type = ThreadType.ROOM if admins is None: admins = set() self.admins = admins @@ -140,8 +130,6 @@ class Room(Group): approval_requests = set() self.approval_requests = approval_requests self.join_link = join_link - self.privacy_mode = privacy_mode - class Page(Thread): #: The page's custom url @@ -531,7 +519,6 @@ class ThreadType(Enum): USER = 1 GROUP = 2 PAGE = 3 - ROOM = 4 class ThreadLocation(Enum): """Used to specify where a thread is located (inbox, pending, archived, other).""" From 2c73cabe229801ef618b8acf4f947a97e1c9c00a Mon Sep 17 00:00:00 2001 From: Kacper Ziubryniewicz Date: Thu, 30 Aug 2018 19:57:12 +0200 Subject: [PATCH 2/5] Merge `Room` with `Group` graphql methods --- fbchat/graphql.py | 78 +++++++++++++++++++++++++++++++---------------- 1 file changed, 51 insertions(+), 27 deletions(-) diff --git a/fbchat/graphql.py b/fbchat/graphql.py index ba73903..f023a16 100644 --- a/fbchat/graphql.py +++ b/fbchat/graphql.py @@ -42,7 +42,7 @@ def get_customization_info(thread): 'emoji': info.get('emoji'), 'color': graphql_color_to_enum(info.get('outgoing_bubble_color')) } - if thread.get('thread_type') in ('GROUP', 'ROOM') or thread.get('is_group_thread') or thread.get('thread_key', {}).get('thread_fbid'): + if thread.get('thread_type') == 'GROUP' or thread.get('is_group_thread') or thread.get('thread_key', {}).get('thread_fbid'): rtn['nicknames'] = {} for k in info.get('participant_customizations', []): rtn['nicknames'][k['participant_id']] = k.get('nickname') @@ -220,7 +220,9 @@ def graphql_to_user(user): if user.get('profile_picture') is None: user['profile_picture'] = {} c_info = get_customization_info(user) - plan = graphql_to_plan(user['event_reminders']['nodes'][0]) if user.get('event_reminders', dict()).get('nodes') else None + plan = None + if user.get('event_reminders'): + plan = graphql_to_plan(user['event_reminders']['nodes'][0]) if user['event_reminders'].get('nodes') else None return User( user['id'], url=user.get('url'), @@ -258,7 +260,9 @@ def graphql_to_thread(thread): else: last_name = user.get('name').split(first_name, 1).pop().strip() - plan = graphql_to_plan(thread['event_reminders']['nodes'][0]) if thread.get('event_reminders', dict()).get('nodes') else None + plan = None + if thread.get('event_reminders'): + plan = graphql_to_plan(thread['event_reminders']['nodes'][0]) if thread['event_reminders'].get('nodes') else None return User( user['id'], @@ -288,13 +292,19 @@ def graphql_to_group(group): last_message_timestamp = None if 'last_message' in group: last_message_timestamp = group['last_message']['nodes'][0]['timestamp_precise'] - plan = graphql_to_plan(group['event_reminders']['nodes'][0]) if group.get('event_reminders', dict()).get('nodes') else None + plan = None + if group.get('event_reminders'): + plan = graphql_to_plan(group['event_reminders']['nodes'][0]) if group['event_reminders'].get('nodes') else None return Group( group['thread_key']['thread_fbid'], participants=set([node['messaging_actor']['id'] for node in group['all_participants']['nodes']]), nicknames=c_info.get('nicknames'), color=c_info.get('color'), emoji=c_info.get('emoji'), + admins = set([node.get('id') for node in group.get('thread_admins')]), + approval_mode = bool(group.get('approval_mode')), + approval_requests = set(node["requester"]['id'] for node in group['group_approval_queue']['nodes']), + join_link = group['joinable_mode'].get('link'), photo=group['image'].get('uri'), name=group.get('name'), message_count=group.get('messages_count'), @@ -302,34 +312,14 @@ def graphql_to_group(group): plan=plan, ) -def graphql_to_room(room): - if room.get('image') is None: - room['image'] = {} - c_info = get_customization_info(room) - plan = graphql_to_plan(room['event_reminders']['nodes'][0]) if room.get('event_reminders', dict()).get('nodes') else None - return Room( - room['thread_key']['thread_fbid'], - participants=set([node['messaging_actor']['id'] for node in room['all_participants']['nodes']]), - nicknames=c_info.get('nicknames'), - color=c_info.get('color'), - emoji=c_info.get('emoji'), - photo=room['image'].get('uri'), - name=room.get('name'), - message_count=room.get('messages_count'), - admins = set([node.get('id') for node in room.get('thread_admins')]), - approval_mode = bool(room.get('approval_mode')), - approval_requests = set(node.get('id') for node in room['thread_queue_metadata'].get('approval_requests', {}).get('nodes')), - join_link = room['joinable_mode'].get('link'), - privacy_mode = bool(room.get('privacy_mode')), - plan=plan, - ) - def graphql_to_page(page): if page.get('profile_picture') is None: page['profile_picture'] = {} if page.get('city') is None: page['city'] = {} - plan = graphql_to_plan(page['event_reminders']['nodes'][0]) if page.get('event_reminders', dict()).get('nodes') else None + plan = None + if page.get('event_reminders'): + plan = graphql_to_plan(page['event_reminders']['nodes'][0]) if page['event_reminders'].get('nodes') else None return Page( page['id'], url=page.get('url'), @@ -433,6 +423,40 @@ class GraphQL(object): }, outgoing_bubble_color, emoji + }, + thread_admins { + id + }, + group_approval_queue { + nodes { + requester { + id + } + } + }, + approval_mode, + joinable_mode { + mode, + link + }, + event_reminders { + nodes { + id, + lightweight_event_creator { + id + }, + time, + location_name, + event_title, + event_reminder_members { + edges { + node { + id + }, + guest_list_state + } + } + } } } """ From 753b9cbae222798c0d3f3b370281508a54f93a27 Mon Sep 17 00:00:00 2001 From: Kacper Ziubryniewicz Date: Thu, 30 Aug 2018 19:57:47 +0200 Subject: [PATCH 3/5] Merge `Room` with `Group` methods --- fbchat/client.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/fbchat/client.py b/fbchat/client.py index e943200..ec71f54 100644 --- a/fbchat/client.py +++ b/fbchat/client.py @@ -544,7 +544,6 @@ class Client(object): return [graphql_to_page(node) for node in j[name]['pages']['nodes']] - # TODO intergrate Rooms def searchForGroups(self, name, limit=1): """ Find and get group thread by its name @@ -585,7 +584,6 @@ class Client(object): elif node['__typename'] == 'Group': # We don't handle Facebook "Groups" pass - # TODO Add Rooms else: log.warning('Unknown __typename: {} in {}'.format(repr(node['__typename']), node)) @@ -818,9 +816,6 @@ class Client(object): if entry.get('thread_type') == 'GROUP': _id = entry['thread_key']['thread_fbid'] rtn[_id] = graphql_to_group(entry) - elif entry.get('thread_type') == 'ROOM': - _id = entry['thread_key']['thread_fbid'] - rtn[_id] = graphql_to_room(entry) elif entry.get('thread_type') == 'ONE_TO_ONE': _id = entry['thread_key']['other_user_id'] if pages_and_users.get(_id) is None: From 4eb49b9119e051c4fa01f3deca5fd51779f5573b Mon Sep 17 00:00:00 2001 From: Kacper Ziubryniewicz Date: Fri, 31 Aug 2018 13:25:37 +0200 Subject: [PATCH 4/5] Backwards compability for `Room`s --- fbchat/models.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/fbchat/models.py b/fbchat/models.py index 51e8019..fa37447 100644 --- a/fbchat/models.py +++ b/fbchat/models.py @@ -131,6 +131,17 @@ class Group(Thread): self.approval_requests = approval_requests self.join_link = join_link + +class Room(Group): + # True is room is not discoverable + privacy_mode = None + + def __init__(self, uid, privacy_mode=None, **kwargs): + """Deprecated. Use :class:`Group` instead""" + super(Room, self).__init__(ThreadType.Room, uid, **kwargs) + self.privacy_mode = privacy_mode + + class Page(Thread): #: The page's custom url url = None @@ -518,6 +529,7 @@ class ThreadType(Enum): """Used to specify what type of Facebook thread is being used. See :ref:`intro_threads` for more info""" USER = 1 GROUP = 2 + ROOM = 2 PAGE = 3 class ThreadLocation(Enum): From 11501e689954aa7bcaa847025530538deb4ce0e8 Mon Sep 17 00:00:00 2001 From: Kacper Ziubryniewicz Date: Mon, 3 Sep 2018 15:05:11 +0200 Subject: [PATCH 5/5] Fix `Room` model initialization --- fbchat/models.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fbchat/models.py b/fbchat/models.py index fa37447..cb4f678 100644 --- a/fbchat/models.py +++ b/fbchat/models.py @@ -138,7 +138,8 @@ class Room(Group): def __init__(self, uid, privacy_mode=None, **kwargs): """Deprecated. Use :class:`Group` instead""" - super(Room, self).__init__(ThreadType.Room, uid, **kwargs) + super(Room, self).__init__(uid, **kwargs) + self.type = ThreadType.ROOM self.privacy_mode = privacy_mode