bi-directional message passing kind of works. needs more love due to Tox ID+nospam+checksum thing

master
Michał 'rysiek' Woźniak 2015-02-08 02:22:47 +01:00
parent 26f1f948d1
commit e2dbd34a1f
6 changed files with 119 additions and 30 deletions

1
tmoxmpp.run Normal file
View File

@ -0,0 +1 @@
docker run -t --rm -i --link tox-prosody:tox-prosody -v /home/rysiek/Projekty/toxmpp/toxmpp/data/:/opt/data --name toxmpp toxmpp tmuxinator start tmoxmpp

1
tox-prosody.run Normal file
View File

@ -0,0 +1 @@
docker run -d -v /tmp/prosody/:/var/log/prosody/ --name tox-prosody prosody

View File

@ -40,8 +40,11 @@ DEBUG_SERVER = [
# class for managing all the Tox instances we need to handle our work
class ToxManager(mp.Process):
# data passing queue to use
queue = False
# data passing queues to use
# x2t_queue -> XMPP to Tox queue, passing messages and presence information from XMPP to Tox
# t2x_queue -> Tox to XMPP queue, passing messages and presence information from Tox to XMPP
x2t_queue = False
t2x_queue = False
# Tox datafile to use
# TODO: this will be changed into a 'datadir' at some point
@ -50,20 +53,26 @@ class ToxManager(mp.Process):
# internal Tox nodes, JID-designated
toxnodes = {}
def __init__(self, datafile, queue):
def __init__(self, datafile, x2t_queue, t2x_queue):
"""
x2t_queue -> XMPP to Tox queue, passing messages and presence information from XMPP to Tox
t2x_queue -> Tox to XMPP queue, passing messages and presence information from Tox to XMPP
"""
# parent setup
super(ToxManager, self).__init__()
# set the data
print('DEBUG :: ToxManager.__init__()')
self.queue = queue
self.x2t_queue = x2t_queue
self.t2x_queue = t2x_queue
self.datafile = datafile
# that's a debug stub
# TODO: do it properly!
print('DEBUG :: +-- creating a ToxNode')
self.toxnodes['rysiek@tox-prosody'] = ToxNode(datafile=self.datafile, server=DEBUG_SERVER)
#self.toxnodes['rysiek@tox-prosody'] = ToxNode(datafile=self.datafile, server=DEBUG_SERVER, message_received_callback=self.handle_tox_message)
self.toxnodes['rysiek@tox-prosody'] = ToxNode(datafile=self.datafile, message_received_callback=self.handle_tox_message)
print('DEBUG :: +-- done.')
@ -73,8 +82,9 @@ class ToxManager(mp.Process):
while True:
# handle queue items
while not self.queue.empty():
self.handle_queue_item(self.queue.get())
# TODO: handle too many messages
while not self.x2t_queue.empty():
self.handle_x2t_queue_item(self.x2t_queue.get())
# run main Tox routine for each internal Tox instance
for jid in self.toxnodes:
@ -138,9 +148,18 @@ class ToxManager(mp.Process):
handling a presence probe
"""
def handle_tox_message(self, toxid, toxmsg):
# TODO: stubity-stub, build the message stanza
msg = Message(sto='rysiek@tox-prosody', sfrom='%s@tox.tox-prosody' % toxid)
msg['body'] = 'Got message from %s:\n%s' % (toxid, toxmsg)
msg['type'] = 'chat'
# put it in the Tox to XMPP queue
self.t2x_queue.put(msg)
# handling a queue item
def handle_queue_item(self, qitem):
def handle_x2t_queue_item(self, qitem):
"""
Possible stanza types:
presence - presence info about a particular user, and (un)subscribe notifications
@ -149,7 +168,7 @@ class ToxManager(mp.Process):
https://github.com/fritzy/SleekXMPP/wiki/Stanzas:-Message
"""
print('DEBUG :: handle_queue_item()')
print('DEBUG :: handle_x2t_queue_item()')
print('DEBUG :: +-- qitem: %s' % qitem)
print('DEBUG :: +-- type : %s' % type(qitem))
@ -196,12 +215,13 @@ if __name__ == '__main__':
if opts.datafile is None:
opts.datafile = input("Datafile path: ")
# message passing queue
q = mp.Queue()
# message passing queues
x2tq = mp.Queue()
t2xq = mp.Queue()
# run the Tox process
#tp = mp.Process(target=ToxManager, args=(opts.datafile, q))
tp = ToxManager(opts.datafile, q)
tp = ToxManager(opts.datafile, x2tq, t2xq)
tp.start()
txt = input('Testing keyboard, lol... Enter anything: ')

View File

@ -33,12 +33,12 @@ from time import sleep
from os.path import exists
SERVER = [
"172.17.42.1",
33445,
"3FA2E5273F0C368576FE120B374664E3B41E2CDF21639AFED3DC301490FFB01FAAA47B78D5F4"
# "80.232.246.79",
# "172.17.42.1",
# 33445,
# "0B8DCEAA7BDDC44BB11173F987CAE3566A2D7057D8DD3CC642BD472B9391002A"
# "3FA2E5273F0C368576FE120B374664E3B41E2CDF21639AFED3DC301490FFB01FAAA47B78D5F4"
"80.232.246.79",
33445,
"0B8DCEAA7BDDC44BB11173F987CAE3566A2D7057D8DD3CC642BD472B9391002A"
]
DATA = 'echo.data'
@ -90,6 +90,9 @@ class EchoBot(Tox):
print('%s: %s' % (name, message))
print('EchoBot: %s' % message)
self.send_message(friendId, message)
# debug
print('get_client_id: %s' % self.get_client_id(friendId))
print('get_friendlist: %s' % self.get_friendlist())
if len(sys.argv) == 2:
DATA = sys.argv[1]

View File

@ -34,6 +34,7 @@ import yaml_roster
import multiprocessing as mp
from mptox import ToxManager, DEBUG_SERVER
from time import sleep
# Python versions before 3.0 do not use UTF-8 encoding
# by default. To ensure that Unicode is handled properly
@ -55,8 +56,11 @@ class ToXMPPComponent(ComponentXMPP):
Tox <-> XMPP Transport/Gateway compnent
"""
# message passing queue
queue = None
# data passing queues to use
# x2t_queue -> XMPP to Tox queue, passing messages and presence information from XMPP to Tox
# t2x_queue -> Tox to XMPP queue, passing messages and presence information from Tox to XMPP
x2t_queue = False
t2x_queue = False
# ToxNodes manager
toxmanager = None
@ -91,13 +95,56 @@ class ToXMPPComponent(ComponentXMPP):
tdbg('+-- bound jid is: %s' % self.boundjid.bare)
# queue
self.queue = mp.Queue()
self.x2t_queue = mp.Queue()
self.t2x_queue = mp.Queue()
# ToxManager
self.toxmanager = ToxManager('toxdata/rysiek@tox-prosody', self.queue)
self.toxmanager = ToxManager('toxdata/rysiek@tox-prosody', self.x2t_queue, self.t2x_queue)
self.toxmanager.start()
def run(self):
"""
Main queue processing loop
"""
while True:
# handle the Tox to XMPP queue items
while not self.t2x_queue.empty():
tdbg('toxmpp.run() : we got message on the queue!')
msg = self.t2x_queue.get()
tdbg(' +-- from : %(from)s\nTOXMPP :: +-- to : %(to)s\nTOXMPP :: +-- msg : %(body)s\nTOXMPP :: +-- msg : %(type)s' % msg)
# could it be so simple?
if isinstance(msg, sleekxmpp.Message):
tdbg('toxmpp.run() : sending the message out');
self.send_message(mto=msg['to'],
mfrom=msg['from'],
mbody=msg['body'],
mtype=msg['type'])
"""
# set the stream
msg.stream = self
# send the message
msg.send()
"""
# wat
else:
raise TypeError('sleekxmpp.Message() expected')
#self.handle_t2x_queue_item(self.t2x_queue.get())
sleep(0.5)
def handle_message(self, qitem):
"""
handling the message stanza
this *should* be a message from an ixternal ToxID-based JID
to an external JID
"""
# forward the message
quitem.send()
def _verify_toxid(self, toxid):
"""
Checking if a given string is a valid ToxID, i.e. is 76 chars
@ -177,7 +224,8 @@ class ToXMPPComponent(ComponentXMPP):
toxmsg['id'] = msg['id']
toxmsg['type'] = msg['type']
toxmsg['subject'] = msg['subject']
self.queue.put(toxmsg)
# push the message to Tox
self.x2t_queue.put(toxmsg)
else:
tdbg('+-- invalid ToxID: %s' % msg['to'].user)
@ -353,7 +401,10 @@ if __name__ == '__main__':
# Connect to the XMPP server and start processing XMPP stanzas.
if xmpp.connect():
xmpp.process(block=True)
# start processing in background
xmpp.process(block=False)
# start the queue processing loop
xmpp.run()
print("Done")
else:
print("Unable to connect.")

View File

@ -38,12 +38,14 @@ from time import sleep
from os.path import exists
import random
class ToxNode(Tox):
# where should we save Tox data to?
datafile='echo.data'
# "message received" callback
message_received_callback = None
# servers
servers= [
# public Tox bootstraping servers
@ -74,11 +76,17 @@ class ToxNode(Tox):
queued_messages = []
# init
def __init__(self, datafile='echo.data', server=False, name="ToxNode"):
def __init__(self, datafile='echo.data', server=False, name="ToxNode", message_received_callback=None):
"""
Only Tox to XMPP queue is needed
"""
# set the datafile name
self.datafile = datafile
if callable(message_received_callback):
self.message_received_callback = message_received_callback
# get the data, if the datafile exists
if exists(self.datafile):
self.load_from_file(self.datafile)
@ -176,17 +184,22 @@ class ToxNode(Tox):
# handling friend request
def on_friend_request(self, pk, message):
print('Friend request from %s: %s' % (pk, message))
print('Friend request from %s: %s' % (pk.encode('utf-8'), message.encode('utf-8')))
self.add_friend_norequest(pk)
print('Accepted.')
# handling a message
def on_friend_message(self, friendId, message):
name = self.get_name(friendId)
print('%s (%s): %s' % (name, friendId, message.encode('utf-8')))
def on_friend_message(self, friend_id, message):
name = self.get_name(friend_id)
print('%s (%s): %s' % (name, friend_id, message.encode('utf-8')))
print('ToxNode: %s' % message.encode('utf-8'))
self.send_message(friendId, message)
self.send_message(friend_id, message)
# fire the callback
if callable(self.message_received_callback):
print('+-- calling message_received_callback()')
self.message_received_callback(self.get_client_id(friend_id), message)