diff options
Diffstat (limited to 'external')
-rwxr-xr-x | external/messenger.py | 40 |
1 files changed, 27 insertions, 13 deletions
diff --git a/external/messenger.py b/external/messenger.py index 89cf5be..481fdb9 100755 --- a/external/messenger.py +++ b/external/messenger.py @@ -1,5 +1,9 @@ #!/usr/bin/env python3 +# @FIXME: make revUserId work correctly (e.g.: talking to a contact not in your top 20 recent threads will fail) - could we do this with a search request? +# @FIXME: store the client pickle in the config automatically +# @FIXME: add a way to search for users and initiate a discussion + import sys import json import signal @@ -13,7 +17,6 @@ from urllib.parse import unquote as UrlUnquote import base64 import getpass import zlib -import hashlib import fbchat from fbchat.models import * @@ -89,10 +92,9 @@ class MessengerBridgeClient(fbchat.Client): # ---- SEPARATE THREADS FOR INITIAL SYNC & CLIENT LISTEN ---- class SyncerThread(threading.Thread): - def __init__(self, client, bridge, thread_queue, *args, **kwargs): + def __init__(self, bridge, thread_queue, *args, **kwargs): super(SyncerThread, self).__init__(*args, **kwargs) - self.client = client self.bridge = bridge self.thread_queue = thread_queue @@ -118,12 +120,22 @@ class ClientListenThread(threading.Thread): class MessengerBridge: def __init__(self): - self.rev_uid = {} - self.uid_map = {} - self.others_joined_map = {} - self.my_joined_rooms = {} self.init_backlog_length = 100 + # We cache maps between two kinds of identifiers: + # - facebook uids of users + # - identifiers for the bridge, which are the username when defined (otherwise equal to above) + # Generally speaking, the first is referred to as uid whereas the second is just id + # THESE MAPS SHOULD NOT BE USED DIRECTLY, instead functions getUserId, getUserIdFromUid and revUserId should be used + self.uid_map = {} # map from fb user uid to bridge id + self.rev_uid = {} # map fro bridge id to fb user uid + + # caches the room we (the user of the bridge) have joined (map keys = room uid) + self.my_joined_rooms = {} + + # caches for the people that are in rooms so that we don't send JOINED every time (map keys = "<userId>--<threadId>") + self.others_joined_map = {} + def getUserId(self, user): retval = None if user.url is not None and not "?" in user.url: @@ -142,7 +154,7 @@ class MessengerBridge: user_info["avatar"] = mediaObjectOfURL(user.photo) self.write({ "_type": USER_INFO_UPDATED, - "user": self.getUserId(user), + "user": retval, "data": user_info, }) @@ -159,6 +171,9 @@ class MessengerBridge: if user_id in self.rev_uid: return self.rev_uid[user_id] else: + # TODO this doesn't work always... + # we should try to find the api endpoint that resolves usernames ? + # or do a search request and try to find a user that has that username return user_id def getUserShortName(self, user): @@ -172,6 +187,7 @@ class MessengerBridge: self.keep_running = True self.cache_gets = {} self.num = 0 + self.my_user_id = "" while self.keep_running: try: @@ -179,8 +195,7 @@ class MessengerBridge: except KeyboardInterrupt: sys.stderr.write("(python messenger) shutting down") self.close() - time.sleep(5) - sys.exit(0) + break sys.stderr.write("(python) reading {}\n".format(line.strip())) cmd = json.loads(line) @@ -211,7 +226,6 @@ class MessengerBridge: ty = cmd["_type"] if ty == CONFIGURE: self.init_backlog_length = int(cmd["data"]["initial_backlog"]) - client_file = "/tmp/fbclient_" + hashlib.sha224(cmd["data"]["email"].encode("utf-8")).hexdigest() if "client_pickle" in cmd["data"] and len(cmd["data"]["client_pickle"]) > 0: data = base64.b64decode(cmd["data"]["client_pickle"]) @@ -223,7 +237,7 @@ class MessengerBridge: ## TODO: save client in new client_pickle config value if not self.client.isLoggedIn(): - return {"_type": "rep_error", "error": "Unable to login (invalid pickle?)"} + return {"_type": REP_ERROR, "error": "Unable to login (invalid pickle?)"} self.client.setBridge(self) @@ -237,7 +251,7 @@ class MessengerBridge: self.getUserId(thread) self.sync_thread_queue = queue.Queue(100) - SyncerThread(self.client, self, self.sync_thread_queue).start() + SyncerThread(self, self.sync_thread_queue).start() for thread in threads: self.sync_thread_queue.put(thread) |