Get one-to-one chat to actually work...
This commit is contained in:
parent
c234b7b4a3
commit
59f25b0741
@ -1,13 +1,16 @@
|
|||||||
import dbus
|
import dbus
|
||||||
import random
|
import random
|
||||||
|
import logging
|
||||||
|
|
||||||
import pygtk
|
import pygtk
|
||||||
pygtk.require('2.0')
|
pygtk.require('2.0')
|
||||||
import gtk
|
import gtk
|
||||||
|
import gobject
|
||||||
|
|
||||||
from sugar.activity.Activity import Activity
|
from sugar.activity.Activity import Activity
|
||||||
from sugar.LogWriter import LogWriter
|
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.chat.BuddyChat import BuddyChat
|
||||||
from sugar.p2p.Stream import Stream
|
from sugar.p2p.Stream import Stream
|
||||||
from sugar.presence.PresenceService import PresenceService
|
from sugar.presence.PresenceService import PresenceService
|
||||||
@ -17,22 +20,25 @@ _CHAT_ACTIVITY_TYPE = "_chat_activity_type._tcp"
|
|||||||
|
|
||||||
class ChatActivity(Activity):
|
class ChatActivity(Activity):
|
||||||
def __init__(self, service):
|
def __init__(self, service):
|
||||||
Activity.__init__(self, _GMAIL_ACTIVITY_TYPE)
|
Activity.__init__(self, _CHAT_ACTIVITY_TYPE)
|
||||||
self._service = service
|
self._service = service
|
||||||
|
self._chat = BuddyChat(self._service)
|
||||||
|
|
||||||
def on_connected_to_shell(self):
|
def on_connected_to_shell(self):
|
||||||
|
self.set_tab_text(self._service.get_name())
|
||||||
self.set_can_close(True)
|
self.set_can_close(True)
|
||||||
self.set_tab_icon(icon_name="im")
|
self.set_tab_icon(name = "im")
|
||||||
self.set_show_tab_icon(True)
|
self.set_show_tab_icon(True)
|
||||||
|
|
||||||
plug = self.gtk_plug()
|
plug = self.gtk_plug()
|
||||||
|
plug.add(self._chat)
|
||||||
chat = BuddyChat(self._service)
|
self._chat.show()
|
||||||
plug.add(chat)
|
|
||||||
chat.show()
|
|
||||||
|
|
||||||
plug.show()
|
plug.show()
|
||||||
|
|
||||||
|
def recv_message(self, message):
|
||||||
|
self._chat.recv_message(message)
|
||||||
|
|
||||||
class ChatShellDbusService(dbus.service.Object):
|
class ChatShellDbusService(dbus.service.Object):
|
||||||
def __init__(self, parent):
|
def __init__(self, parent):
|
||||||
self._parent = parent
|
self._parent = parent
|
||||||
@ -42,8 +48,8 @@ class ChatShellDbusService(dbus.service.Object):
|
|||||||
dbus.service.Object.__init__(self, bus_name, object_path)
|
dbus.service.Object.__init__(self, bus_name, object_path)
|
||||||
|
|
||||||
@dbus.service.method('com.redhat.Sugar.ChatShell')
|
@dbus.service.method('com.redhat.Sugar.ChatShell')
|
||||||
def open_chat(self, message):
|
def open_chat(self, serialized_service):
|
||||||
self._parent.send_text_message(message)
|
self._parent.open_chat(Service.deserialize(serialized_service))
|
||||||
|
|
||||||
class ChatShell:
|
class ChatShell:
|
||||||
instance = None
|
instance = None
|
||||||
@ -55,25 +61,49 @@ class ChatShell:
|
|||||||
get_instance = staticmethod(get_instance)
|
get_instance = staticmethod(get_instance)
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
ChatShellDbusService(self)
|
||||||
|
|
||||||
|
self._chats = {}
|
||||||
|
|
||||||
self._pservice = PresenceService.get_instance()
|
self._pservice = PresenceService.get_instance()
|
||||||
self._pservice.start()
|
self._pservice.start()
|
||||||
self._pservice.track_service_type(BuddyChat.SERVICE_TYPE)
|
self._pservice.track_service_type(BuddyChat.SERVICE_TYPE)
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
port = random.randint(5000, 65535)
|
port = random.randint(5000, 65535)
|
||||||
service = Service(sugar.env.get_nick_name(), BuddyChat.SERVICE_TYPE,
|
service = Service.Service(sugar.env.get_nick_name(), BuddyChat.SERVICE_TYPE,
|
||||||
'local', '', port)
|
'local', '', port)
|
||||||
self._buddy_stream = Stream.new_from_service(service)
|
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)
|
self._pservice.register_service(service)
|
||||||
|
|
||||||
def _recv_message(self, address, msg):
|
def _recv_message(self, address, message):
|
||||||
print msg
|
[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):
|
def open_chat(self, service):
|
||||||
service = Service.deserialize(serialized_service)
|
chat = ChatActivity(service)
|
||||||
self._chat = ChatActivity(service)
|
self._chats[service.get_name()] = chat
|
||||||
self._chat.connect_to_shell()
|
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 = LogWriter("Chat")
|
||||||
log_writer.start()
|
log_writer.start()
|
||||||
|
@ -2,8 +2,10 @@ import pygtk
|
|||||||
pygtk.require('2.0')
|
pygtk.require('2.0')
|
||||||
import gtk
|
import gtk
|
||||||
import gobject
|
import gobject
|
||||||
|
import dbus
|
||||||
|
|
||||||
from sugar.presence.PresenceService import PresenceService
|
from sugar.presence.PresenceService import PresenceService
|
||||||
|
from sugar.presence.Service import Service
|
||||||
from sugar.chat.BuddyChat import BuddyChat
|
from sugar.chat.BuddyChat import BuddyChat
|
||||||
|
|
||||||
class PresenceWindow(gtk.Window):
|
class PresenceWindow(gtk.Window):
|
||||||
@ -23,6 +25,8 @@ class PresenceWindow(gtk.Window):
|
|||||||
self._pservice.connect("buddy-disappeared", self._on_buddy_disappeared_cb)
|
self._pservice.connect("buddy-disappeared", self._on_buddy_disappeared_cb)
|
||||||
self._pservice.start()
|
self._pservice.start()
|
||||||
|
|
||||||
|
self._pservice.track_service_type(BuddyChat.SERVICE_TYPE)
|
||||||
|
|
||||||
self._setup_ui()
|
self._setup_ui()
|
||||||
|
|
||||||
def _is_buddy_visible(self, buddy):
|
def _is_buddy_visible(self, buddy):
|
||||||
|
@ -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"
|
SERVICE_TYPE = "_olpc_buddy_chat._tcp"
|
||||||
|
|
||||||
def __init__(self, service):
|
def __init__(self, service):
|
||||||
Chat.__init__(self)
|
Chat.__init__(self)
|
||||||
|
|
||||||
self._stream = Stream.new_from_service(service)
|
self._stream = Stream.new_from_service(service, False)
|
||||||
self._stream.set_data_listener(self._recv_message)
|
self._stream_writer = self._stream.new_writer(service)
|
||||||
self._stream_writer = self._group_stream.new_writer()
|
|
||||||
|
|
||||||
def recv_message(self, address, msg):
|
def _recv_message_cb(self, address, msg):
|
||||||
print msg
|
self.recv_message(msg)
|
||||||
# Chat.recv_message(self, self._buddy, msg)
|
|
||||||
|
@ -28,6 +28,9 @@ class Chat(gtk.VBox):
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
gtk.VBox.__init__(self, False, 6)
|
gtk.VBox.__init__(self, False, 6)
|
||||||
|
|
||||||
|
self._pservice = PresenceService.get_instance()
|
||||||
|
self._pservice.start()
|
||||||
|
|
||||||
self._stream_writer = None
|
self._stream_writer = None
|
||||||
self.set_border_width(12)
|
self.set_border_width(12)
|
||||||
|
|
||||||
@ -193,13 +196,16 @@ class Chat(gtk.VBox):
|
|||||||
return msg[desc_start:svg_last + len(tag_svg_end)]
|
return msg[desc_start:svg_last + len(tag_svg_end)]
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def recv_message(self, buddy, msg):
|
def recv_message(self, message):
|
||||||
"""Insert a remote chat message into the chat buffer."""
|
"""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:
|
if not buddy:
|
||||||
|
logging.error('The buddy %s is not present.' % (nick))
|
||||||
return
|
return
|
||||||
|
|
||||||
# FIXME a better way to compare buddies?
|
# 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():
|
if buddy.get_nick_name() == owner.get_nick_name():
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -236,5 +242,7 @@ class Chat(gtk.VBox):
|
|||||||
owner = PresenceService.get_instance().get_owner()
|
owner = PresenceService.get_instance().get_owner()
|
||||||
return owner.get_nick_name() + '||' + message
|
return owner.get_nick_name() + '||' + message
|
||||||
|
|
||||||
def deserialize_message(self, message):
|
def deserialize_message(message):
|
||||||
return message.split('||', 1)
|
return message.split('||', 1)
|
||||||
|
|
||||||
|
deserialize_message = staticmethod(deserialize_message)
|
||||||
|
@ -8,8 +8,6 @@ import sugar.env
|
|||||||
class GroupChat(Chat):
|
class GroupChat(Chat):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
Chat.__init__(self)
|
Chat.__init__(self)
|
||||||
self._pservice = PresenceService.get_instance()
|
|
||||||
self._pservice.start()
|
|
||||||
self._group_stream = None
|
self._group_stream = None
|
||||||
|
|
||||||
def _setup_stream(self, service):
|
def _setup_stream(self, service):
|
||||||
@ -18,10 +16,4 @@ class GroupChat(Chat):
|
|||||||
self._stream_writer = self._group_stream.new_writer()
|
self._stream_writer = self._group_stream.new_writer()
|
||||||
|
|
||||||
def _group_recv_message(self, address, msg):
|
def _group_recv_message(self, address, msg):
|
||||||
pservice = PresenceService.get_instance()
|
self.recv_message(msg)
|
||||||
[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))
|
|
||||||
|
@ -142,8 +142,8 @@ class Buddy(gobject.GObject):
|
|||||||
for service in self._services.values():
|
for service in self._services.values():
|
||||||
if service.get_type() == stype and service.get_activity_id() == actid:
|
if service.get_type() == stype and service.get_activity_id() == actid:
|
||||||
return service
|
return service
|
||||||
if self._services.has_key(short_stype):
|
if self._services.has_key(stype):
|
||||||
return self._services[short_stype]
|
return self._services[stype]
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def is_valid(self):
|
def is_valid(self):
|
||||||
|
@ -69,9 +69,6 @@ def deserialize(sdict):
|
|||||||
stype = sdict['stype']
|
stype = sdict['stype']
|
||||||
if type(stype) == type(u""):
|
if type(stype) == type(u""):
|
||||||
stype = stype.encode()
|
stype = stype.encode()
|
||||||
activity_id = sdict['activity_id']
|
|
||||||
if type(activity_id) == type(u""):
|
|
||||||
activity_id = activity_id.encode()
|
|
||||||
domain = sdict['domain']
|
domain = sdict['domain']
|
||||||
if type(domain) == type(u""):
|
if type(domain) == type(u""):
|
||||||
domain = domain.encode()
|
domain = domain.encode()
|
||||||
@ -87,7 +84,18 @@ def deserialize(sdict):
|
|||||||
address = address.encode()
|
address = address.encode()
|
||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
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,
|
return Service(name, stype, domain, address=address,
|
||||||
port=port, properties=properties)
|
port=port, properties=properties)
|
||||||
|
|
||||||
@ -152,7 +160,8 @@ class Service(object):
|
|||||||
else:
|
else:
|
||||||
sdict['name'] = dbus.Variant(self._name)
|
sdict['name'] = dbus.Variant(self._name)
|
||||||
sdict['stype'] = dbus.Variant(self._stype)
|
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)
|
sdict['domain'] = dbus.Variant(self._domain)
|
||||||
if self._address:
|
if self._address:
|
||||||
sdict['address'] = dbus.Variant(self._address)
|
sdict['address'] = dbus.Variant(self._address)
|
||||||
|
Loading…
Reference in New Issue
Block a user