Get one-to-one chat to actually work...

This commit is contained in:
Marco Pesenti Gritti 2006-06-22 18:07:54 -04:00
parent c234b7b4a3
commit 59f25b0741
7 changed files with 87 additions and 45 deletions

View File

@ -1,13 +1,16 @@
import dbus
import random
import logging
import pygtk
pygtk.require('2.0')
import gtk
import gobject
from sugar.activity.Activity import Activity
from sugar.LogWriter import LogWriter
from sugar.presence.Service import Service
from sugar.presence import Service
from sugar.chat.Chat import Chat
from sugar.chat.BuddyChat import BuddyChat
from sugar.p2p.Stream import Stream
from sugar.presence.PresenceService import PresenceService
@ -17,21 +20,24 @@ _CHAT_ACTIVITY_TYPE = "_chat_activity_type._tcp"
class ChatActivity(Activity):
def __init__(self, service):
Activity.__init__(self, _GMAIL_ACTIVITY_TYPE)
Activity.__init__(self, _CHAT_ACTIVITY_TYPE)
self._service = service
self._chat = BuddyChat(self._service)
def on_connected_to_shell(self):
self.set_tab_text(self._service.get_name())
self.set_can_close(True)
self.set_tab_icon(icon_name="im")
self.set_tab_icon(name = "im")
self.set_show_tab_icon(True)
plug = self.gtk_plug()
chat = BuddyChat(self._service)
plug.add(chat)
chat.show()
plug.add(self._chat)
self._chat.show()
plug.show()
def recv_message(self, message):
self._chat.recv_message(message)
class ChatShellDbusService(dbus.service.Object):
def __init__(self, parent):
@ -42,8 +48,8 @@ class ChatShellDbusService(dbus.service.Object):
dbus.service.Object.__init__(self, bus_name, object_path)
@dbus.service.method('com.redhat.Sugar.ChatShell')
def open_chat(self, message):
self._parent.send_text_message(message)
def open_chat(self, serialized_service):
self._parent.open_chat(Service.deserialize(serialized_service))
class ChatShell:
instance = None
@ -55,25 +61,49 @@ class ChatShell:
get_instance = staticmethod(get_instance)
def __init__(self):
ChatShellDbusService(self)
self._chats = {}
self._pservice = PresenceService.get_instance()
self._pservice.start()
self._pservice.track_service_type(BuddyChat.SERVICE_TYPE)
def start(self):
port = random.randint(5000, 65535)
service = Service(sugar.env.get_nick_name(), BuddyChat.SERVICE_TYPE,
'local', '', port)
service = Service.Service(sugar.env.get_nick_name(), BuddyChat.SERVICE_TYPE,
'local', '', port)
self._buddy_stream = Stream.new_from_service(service)
self._buddy_stream.set_data_listener(getattr(self, "_recv_message"))
self._buddy_stream.set_data_listener(self._recv_message)
self._pservice.register_service(service)
def _recv_message(self, address, msg):
print msg
def _recv_message(self, address, message):
[nick, msg] = Chat.deserialize_message(message)
buddy = self._pservice.get_buddy_by_nick_name(nick)
if buddy:
if buddy == self._pservice.get_owner():
return
service = buddy.get_service_of_type(BuddyChat.SERVICE_TYPE)
name = service.get_name()
if service:
if not self._chats.has_key(name):
self.open_chat(service)
self._chats[name].recv_message(message)
else:
logging.error('The buddy %s does not have a chat service.' % (nick))
else:
logging.error('The buddy %s is not present.' % (nick))
return
def open_chat(self, serialized_service):
service = Service.deserialize(serialized_service)
self._chat = ChatActivity(service)
self._chat.connect_to_shell()
def open_chat(self, service):
chat = ChatActivity(service)
self._chats[service.get_name()] = chat
gobject.idle_add(self._connect_chat, chat)
return chat
def _connect_chat(self, chat):
chat.connect_to_shell()
return False
log_writer = LogWriter("Chat")
log_writer.start()

View File

@ -2,8 +2,10 @@ import pygtk
pygtk.require('2.0')
import gtk
import gobject
import dbus
from sugar.presence.PresenceService import PresenceService
from sugar.presence.Service import Service
from sugar.chat.BuddyChat import BuddyChat
class PresenceWindow(gtk.Window):
@ -23,6 +25,8 @@ class PresenceWindow(gtk.Window):
self._pservice.connect("buddy-disappeared", self._on_buddy_disappeared_cb)
self._pservice.start()
self._pservice.track_service_type(BuddyChat.SERVICE_TYPE)
self._setup_ui()
def _is_buddy_visible(self, buddy):

View File

@ -1,15 +1,14 @@
from sugar.activity.Activity import Activity
from sugar.chat.Chat import Chat
from sugar.p2p.Stream import Stream
class BuddyChat(Activity):
class BuddyChat(Chat):
SERVICE_TYPE = "_olpc_buddy_chat._tcp"
def __init__(self, service):
Chat.__init__(self)
self._stream = Stream.new_from_service(service)
self._stream.set_data_listener(self._recv_message)
self._stream_writer = self._group_stream.new_writer()
self._stream = Stream.new_from_service(service, False)
self._stream_writer = self._stream.new_writer(service)
def recv_message(self, address, msg):
print msg
# Chat.recv_message(self, self._buddy, msg)
def _recv_message_cb(self, address, msg):
self.recv_message(msg)

View File

@ -28,6 +28,9 @@ class Chat(gtk.VBox):
def __init__(self):
gtk.VBox.__init__(self, False, 6)
self._pservice = PresenceService.get_instance()
self._pservice.start()
self._stream_writer = None
self.set_border_width(12)
@ -193,13 +196,16 @@ class Chat(gtk.VBox):
return msg[desc_start:svg_last + len(tag_svg_end)]
return None
def recv_message(self, buddy, msg):
def recv_message(self, message):
"""Insert a remote chat message into the chat buffer."""
[nick, msg] = Chat.deserialize_message(message)
buddy = self._pservice.get_buddy_by_nick_name(nick)
if not buddy:
logging.error('The buddy %s is not present.' % (nick))
return
# FIXME a better way to compare buddies?
owner = PresenceService.get_instance().get_owner()
owner = self._pservice.get_owner()
if buddy.get_nick_name() == owner.get_nick_name():
return
@ -236,5 +242,7 @@ class Chat(gtk.VBox):
owner = PresenceService.get_instance().get_owner()
return owner.get_nick_name() + '||' + message
def deserialize_message(self, message):
def deserialize_message(message):
return message.split('||', 1)
deserialize_message = staticmethod(deserialize_message)

View File

@ -8,8 +8,6 @@ import sugar.env
class GroupChat(Chat):
def __init__(self):
Chat.__init__(self)
self._pservice = PresenceService.get_instance()
self._pservice.start()
self._group_stream = None
def _setup_stream(self, service):
@ -18,10 +16,4 @@ class GroupChat(Chat):
self._stream_writer = self._group_stream.new_writer()
def _group_recv_message(self, address, msg):
pservice = PresenceService.get_instance()
[nick, msg] = self.deserialize_message(msg)
buddy = pservice.get_buddy_by_nick_name(nick)
if buddy:
self.recv_message(buddy, msg)
else:
logging.error('The buddy %s is not present.' % (nick))
self.recv_message(msg)

View File

@ -142,8 +142,8 @@ class Buddy(gobject.GObject):
for service in self._services.values():
if service.get_type() == stype and service.get_activity_id() == actid:
return service
if self._services.has_key(short_stype):
return self._services[short_stype]
if self._services.has_key(stype):
return self._services[stype]
return None
def is_valid(self):

View File

@ -69,9 +69,6 @@ def deserialize(sdict):
stype = sdict['stype']
if type(stype) == type(u""):
stype = stype.encode()
activity_id = sdict['activity_id']
if type(activity_id) == type(u""):
activity_id = activity_id.encode()
domain = sdict['domain']
if type(domain) == type(u""):
domain = domain.encode()
@ -87,7 +84,18 @@ def deserialize(sdict):
address = address.encode()
except KeyError:
pass
name = compose_service_name(name, activity_id)
activity_id = None
try:
activity_id = sdict['activity_id']
if type(activity_id) == type(u""):
activity_id = activity_id.encode()
except KeyError:
pass
if activity_id is not None:
name = compose_service_name(name, activity_id)
return Service(name, stype, domain, address=address,
port=port, properties=properties)
@ -152,7 +160,8 @@ class Service(object):
else:
sdict['name'] = dbus.Variant(self._name)
sdict['stype'] = dbus.Variant(self._stype)
sdict['activity_id'] = dbus.Variant(self._activity_id)
if self._activity_id:
sdict['activity_id'] = dbus.Variant(self._activity_id)
sdict['domain'] = dbus.Variant(self._domain)
if self._address:
sdict['address'] = dbus.Variant(self._address)