119 lines
3 KiB
Python
119 lines
3 KiB
Python
|
#!/usr/bin/env python3
|
||
|
|
||
|
import sys
|
||
|
import json
|
||
|
|
||
|
import hashlib
|
||
|
import gevent
|
||
|
import fbchat
|
||
|
|
||
|
# ---- MESSAGE TYPES ----
|
||
|
|
||
|
# ezbr -> external
|
||
|
CONFIGURE = "configure"
|
||
|
GET_USER = "get_user"
|
||
|
SET_USER_INFO = "set_user_info"
|
||
|
SET_ROOM_INFO = "set_room_info"
|
||
|
JOIN = "join"
|
||
|
INVITE = "invite"
|
||
|
LEAVE = "leave"
|
||
|
SEND = "send"
|
||
|
CLOSE = "close"
|
||
|
|
||
|
# external -> ezbr
|
||
|
JOINED = "joined"
|
||
|
LEFT = "left"
|
||
|
USER_INFO_UPDATED = "user_info_updated"
|
||
|
ROOM_INFO_UPDATED = "room_info_updated"
|
||
|
EVENT = "event"
|
||
|
CACHE_PUT = "cache_put"
|
||
|
CACHE_GET = "cache_get"
|
||
|
|
||
|
# reply messages
|
||
|
# ezbr -> external: all must wait for a reply!
|
||
|
# external -> ezbr: only CACHE_GET produces a reply
|
||
|
REP_OK = "rep_ok"
|
||
|
REP_ERROR = "rep_error"
|
||
|
|
||
|
|
||
|
# ---- MESSENGER CLIENT CLASS THAT HANDLES EVENTS ----
|
||
|
|
||
|
class MessengerBridgeClient(fbchat.Client):
|
||
|
def __init__(self, bridge, *args, **kwargs):
|
||
|
self.bridge = bridge
|
||
|
|
||
|
super(MessengerBridgeClient, self).__init__(*args, **kwargs)
|
||
|
|
||
|
# TODO: handle events
|
||
|
|
||
|
|
||
|
# ---- MAIN LOOP THAT HANDLES REQUESTS FROM BRIDGE ----
|
||
|
|
||
|
class MessengerBridge:
|
||
|
def run(self):
|
||
|
self.client = None
|
||
|
self.keep_running = True
|
||
|
|
||
|
while self.keep_running:
|
||
|
line = sys.stdin.readline()
|
||
|
sys.stderr.write("(python) reading {}\n".format(line.strip()))
|
||
|
cmd = json.loads(line)
|
||
|
|
||
|
try:
|
||
|
rep = self.handle_cmd(cmd)
|
||
|
if rep is None:
|
||
|
rep = {}
|
||
|
if "_type" not in rep:
|
||
|
rep["_type"] = REP_OK
|
||
|
except Exception as e:
|
||
|
rep = {
|
||
|
"_type": REP_ERROR,
|
||
|
"error": "{}".format(e)
|
||
|
}
|
||
|
|
||
|
rep["_id"] = cmd["_id"]
|
||
|
self.write(rep)
|
||
|
|
||
|
def write(self, msg):
|
||
|
msgstr = json.dumps(msg)
|
||
|
sys.stderr.write("(python) writing {}\n".format(msgstr))
|
||
|
sys.stdout.write(msgstr + "\n")
|
||
|
sys.stdout.flush()
|
||
|
|
||
|
def handle_cmd(self, cmd):
|
||
|
ty = cmd["_type"]
|
||
|
if ty == CONFIGURE:
|
||
|
cookies_file = "/tmp/cookies_" + hashlib.sha224(cmd["data"]["email"].encode("utf-8")).hexdigest()
|
||
|
|
||
|
try:
|
||
|
f = open(cookies_file, "r")
|
||
|
cookies = json.load(f)
|
||
|
f.close()
|
||
|
sys.stderr.write("(python messenger) using previous cookies: {}\n".format(cookies))
|
||
|
except:
|
||
|
cookies = None
|
||
|
|
||
|
self.client = MessengerBridgeClient(self, cmd["data"]["email"], cmd["data"]["password"], session_cookies=cookies)
|
||
|
|
||
|
if self.client.isLoggedIn():
|
||
|
cookies = self.client.getSession()
|
||
|
try:
|
||
|
f = open(cookies_file, "w")
|
||
|
json.dump(cookies, f)
|
||
|
f.close()
|
||
|
except:
|
||
|
pass
|
||
|
|
||
|
elif ty == CLOSE:
|
||
|
self.client.logout()
|
||
|
self.keep_running = False
|
||
|
|
||
|
else:
|
||
|
return {"_type": REP_ERROR, "error": "Not implemented"}
|
||
|
|
||
|
|
||
|
if __name__ == "__main__":
|
||
|
bridge = MessengerBridge()
|
||
|
bridge.run()
|
||
|
|