aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xexternal/messenger.py40
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)