Refactor user info fetching logic

This commit is contained in:
Alex 2020-03-01 14:30:51 +01:00
parent 6055544313
commit 75a1dee061

98
external/messenger.py vendored
View file

@ -79,16 +79,17 @@ class MessengerBridgeClient(fbchat.Client):
# ---- SEPARATE THREADS FOR INITIAL SYNC & CLIENT LISTEN ----
class InitialSyncThread(threading.Thread):
def __init__(self, client, bridge, *args, **kwargs):
def __init__(self, client, bridge, threads, *args, **kwargs):
super(InitialSyncThread, self).__init__(*args, **kwargs)
self.client = client
self.bridge = bridge
self.threads = threads
def run(self):
threads = self.client.fetchThreadList()
sys.stderr.write("fb thread list: {}\n".format(threads))
for thread in threads:
for thread in self.threads:
sys.stderr.write("fb thread: {}\n".format(thread))
if thread.type == ThreadType.GROUP:
members = self.client.fetchAllUsersFromThreads([thread])
@ -100,8 +101,6 @@ class InitialSyncThread(threading.Thread):
self.send_room_info(thread, members)
self.send_room_members(thread, members)
elif thread.type == ThreadType.USER:
self.bridge.getUserId(thread)
self.backlog_room(thread)
@ -134,25 +133,7 @@ class InitialSyncThread(threading.Thread):
def send_room_members(self, thread, members):
for member in members:
sys.stderr.write("fb thread member: {}\n".format(member))
self.bridge.write({
"_type": EVENT,
"data": {
"type": EVENT_JOIN,
"author": self.bridge.getUserId(member),
"room": thread.uid,
}
})
user_info = {
"display_name": member.name,
}
if member.photo is not None:
user_info["avatar"] = mediaObjectOfURL(member.photo)
self.bridge.write({
"_type": USER_INFO_UPDATED,
"user": self.bridge.getUserId(member),
"data": user_info,
})
self.bridge.ensureJoined(self.bridge.getUserId(member), thread.uid)
def backlog_room(self, thread):
prev_last_seen = self.bridge.cache_get("last_seen_%s"%thread.uid)
@ -194,16 +175,32 @@ class MessengerBridge:
def __init__(self):
self.rev_uid = {}
self.uid_map = {}
self.joined_map = {}
def getUserId(self, user):
retval = None
if user.url is not None and not "?" in user.url:
user_id = user.url.split("/")[-1]
self.rev_uid[user_id] = user.uid
self.uid_map[user.uid] = user_id
retval = user_id
else:
self.uid_map[user.uid] = user.uid
retval = user.uid
return self.uid_map[user.uid]
if user.uid not in self.uid_map:
self.uid_map[user.uid] = retval
user_info = {
"display_name": user.name,
}
if user.photo is not None:
user_info["avatar"] = mediaObjectOfURL(user.photo)
self.bridge.write({
"_type": USER_INFO_UPDATED,
"user": self.bridge.getUserId(user),
"data": user_info,
})
return retval
def getUserIdFromUid(self, uid):
if uid in self.uid_map:
@ -218,7 +215,6 @@ class MessengerBridge:
else:
return user_id
def getUserShortName(self, user):
if user.first_name != None:
return user.first_name
@ -281,17 +277,27 @@ class MessengerBridge:
email, password = cmd["data"]["email"], cmd["data"]["password"]
self.client = MessengerBridgeClient(email=email, password=password, max_tries=1)
if self.client.isLoggedIn():
try:
f = open(client_file, "wb")
pickle.dump(self.client, f)
f.close()
except:
pass
if not self.client.isLoggedIn():
return {"_type": "ret_error", "error": "Unable to login (?)"}
self.client.setBridge(self)
InitialSyncThread(self.client, self).start()
ClientListenThread(self.client).start()
try:
f = open(client_file, "wb")
pickle.dump(self.client, f)
f.close()
except:
pass
self.client.setBridge(self)
threads = self.client.fetchThreadList()
# ensure we have a correct mapping for bridged user IDs to fb uids
# (this should be fast)
for thread in threads:
if thread.type == ThreadType.GROUP:
self.getUserId(thread)
InitialSyncThread(self.client, self, threads).start()
ClientListenThread(self.client).start()
elif ty == CLOSE:
self.close()
@ -344,6 +350,19 @@ class MessengerBridge:
def cache_put(self, key, value):
self.write({"_type": CACHE_PUT, "key": key, "value": value})
def ensureJoined(self, userId, room):
key = "{}--{}".format(userId, room)
if not key in self.joined_map:
self.bridge.write({
"_type": EVENT,
"data": {
"type": EVENT_JOIN,
"author": userId,
"room": room,
}
})
self.joined_map[key] = true
def onMessage(self, thread_id, thread_type, message_object, **kwargs):
if message_object.author == self.client.uid:
# Ignore our own messages
@ -358,6 +377,8 @@ class MessengerBridge:
}
if thread_type == ThreadType.GROUP:
event["room"] = thread_id
self.ensureJoined(author, thread_id)
self.write({"_type": EVENT, "data": event})
self.cache_put("last_seen_%s"%thread_id, message_object.uid)
@ -369,7 +390,6 @@ class MessengerBridge:
def onTitleChange(self, *args, **kwargs):
pass
if __name__ == "__main__":
bridge = MessengerBridge()
bridge.run()