diff options
author | Marco Pesenti Gritti <mpg@redhat.com> | 2006-05-04 20:11:16 (GMT) |
---|---|---|
committer | Marco Pesenti Gritti <mpg@redhat.com> | 2006-05-04 20:11:16 (GMT) |
commit | 91670df8b25856b28e4b7f688c9978756a062c37 (patch) | |
tree | 0d2d76df3c177f5000166d0c8632bbc027503fc5 /chat/p2p.py | |
parent | 14d572e72a6c18fba6b6676682e8722614484520 (diff) |
Factor out a very simple p2p messaging system from chat
Diffstat (limited to 'chat/p2p.py')
-rw-r--r-- | chat/p2p.py | 158 |
1 files changed, 158 insertions, 0 deletions
diff --git a/chat/p2p.py b/chat/p2p.py new file mode 100644 index 0000000..b421a88 --- /dev/null +++ b/chat/p2p.py @@ -0,0 +1,158 @@ +import os +import pwd + +import presence +import BuddyList +import network + +class GroupRequestHandler(object): + def __init__(self, group): + self._group = group + + def message(self, message): + address = network.get_authinfo() + self._group.recv(address, message) + +class Owner: + instance = None + + def __init__(self): + ent = pwd.getpwuid(os.getuid()) + self._nick = ent[0] + if not self._nick or not len(self._nick): + self._nick = "n00b" + self._realname = ent[4] + if not self._realname or not len(self._realname): + self._realname = "Some Clueless User" + + def get_realname(self): + return self._realname + + def get_nick(self): + return self._nick + + def get_instance(): + if not Owner.instance: + Owner.instance = Owner() + return Owner.instance + + get_instance = staticmethod(get_instance) + +class Group: + instance = None + + _SERVER_PORT = 6666 + + def __init__(self): + self._pipes = {} + + def get_instance(): + if not Group.instance: + Group.instance = Group() + Group.instance.join() + return Group.instance + + get_instance = staticmethod(get_instance) + + def join(self): + self._pannounce = presence.PresenceAnnounce() + + realname = Owner.get_instance().get_realname() + nick = Owner.get_instance().get_nick() + + self._buddy_list = BuddyList.BuddyList(realname) + self._buddy_list.start() + + self._pannounce.register_service(realname, self._SERVER_PORT, presence.OLPC_CHAT_SERVICE, + name = nick, realname = realname) + + self._p2p_req_handler = GroupRequestHandler(self) + self._p2p_server = network.GlibXMLRPCServer(("", self._SERVER_PORT)) + self._p2p_server.register_instance(self._p2p_req_handler) + + self._gc_controller = network.GroupChatController('224.0.0.221', 6666, self._recv_group_message) + self._gc_controller.start() + + def get_buddy_list(self): + return self._buddy_list + + def _serialize_msg(self, pipe_id, msg): + return pipe_id + "|" + msg + + def _deserialize_msg(self, msg): + sep_index = msg.find("|") + pipe_id = msg[0 : sep_index] + message = msg[sep_index + 1 :] + return [pipe_id, message] + + def send(self, buddy, pipe_id, msg): + addr = "http://%s:%d" % (buddy.address(), buddy.port()) + peer = xmlrpclib.ServerProxy(addr) + msg = text + success = True + try: + peer.message(self._serialize_msg(pipe_id, msg)) + except (socket.error, xmlrpclib.Fault), e: + msg = str(e) + success = False + return success + + def broadcast(self, pipe_id, msg): + self._gc_controller.send_msg(self._serialize_msg(pipe_id, msg)) + + def register_pipe(self, input_pipe): + self._pipes[input_pipe.get_id()] = input_pipe + + def _recv_group_message(self, msg): + self.recv(msg['addr'], msg['data']) + + def recv(self, address, message): + sender = self._buddy_list.find_buddy_by_address(address) + [pipe_id, msg] = self._deserialize_msg(message) + pipe = self._pipes[pipe_id] + if pipe: + pipe.recv(sender, msg) + +class AbstractPipe: + def __init__(self, group, pipe_id=None): + self._group = group + self._pipe_id = pipe_id + + def get_id(self): + return self._pipe_id + + def send(self, msg): + pass + +class AbstractOutputPipe(AbstractPipe): + def __init__(self, group, pipe_id=None): + AbstractPipe.__init__(self, group, pipe_id) + + def send(self, msg): + pass + +class OutputPipe(AbstractOutputPipe): + def __init__(self, group, buddy, pipe_id=None): + AbstractOutputPipe.__init__(self, group, pipe_id) + self._buddy = buddy + + def send(self, msg): + self._group.send(self._buddy, self._pipe_id, msg) + +class BroadcastOutputPipe(AbstractOutputPipe): + def __init__(self, group, pipe_id=None): + AbstractOutputPipe.__init__(self, group, pipe_id) + + def send(self, msg): + self._group.broadcast(self._pipe_id, msg) + +class InputPipe(AbstractPipe): + def __init__(self, group, pipe_id=None): + AbstractPipe.__init__(self, group, pipe_id) + group.register_pipe(self) + + def listen(self, callback): + self.__callback = callback + + def recv(self, sender, msg): + self.__callback(sender, msg) |