Merge SVGdraw.py
This commit is contained in:
		
							parent
							
								
									0ca5a7fed5
								
							
						
					
					
						commit
						6b78600646
					
				@ -22,5 +22,6 @@ sugar/__installed__.py
 | 
			
		||||
sugar/browser/Makefile
 | 
			
		||||
sugar/chat/Makefile
 | 
			
		||||
sugar/p2p/Makefile
 | 
			
		||||
sugar/p2p/model/Makefile
 | 
			
		||||
sugar/shell/Makefile
 | 
			
		||||
])
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										32
									
								
								pylint.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										32
									
								
								pylint.sh
									
									
									
									
									
										Executable file
									
								
							@ -0,0 +1,32 @@
 | 
			
		||||
#!/bin/sh
 | 
			
		||||
 | 
			
		||||
# Errors that we may fix in the future
 | 
			
		||||
#
 | 
			
		||||
# C0301 Line length
 | 
			
		||||
# W0201 Attribute defined outside __init__
 | 
			
		||||
# R0201 Method could be a function
 | 
			
		||||
TODO="C0301,W0201,R0201"
 | 
			
		||||
 | 
			
		||||
# Errors we don't like
 | 
			
		||||
#
 | 
			
		||||
# W0613 Unused argument (glib signals)
 | 
			
		||||
# W0511 - FIXME/TODO/XXX
 | 
			
		||||
DISABLE="W0613,W0511"
 | 
			
		||||
 | 
			
		||||
MSGS="$TODO,$DISABLE"
 | 
			
		||||
ARG="sugar"
 | 
			
		||||
 | 
			
		||||
pylint \
 | 
			
		||||
  --disable-all \
 | 
			
		||||
  --include-ids=y \
 | 
			
		||||
  --enable-variables=y \
 | 
			
		||||
  --enable-exceptions=y \
 | 
			
		||||
  --enable-miscellaneous=y \
 | 
			
		||||
  --enable-format=y \
 | 
			
		||||
  --enable-classes=y \
 | 
			
		||||
  --disable-msg=$MSGS \
 | 
			
		||||
  --reports=n \
 | 
			
		||||
  --enable-metrics=n \
 | 
			
		||||
  --indent-string="	" \
 | 
			
		||||
  --ignore="SVGdraw.py" \
 | 
			
		||||
  $ARG
 | 
			
		||||
@ -11,6 +11,7 @@ import gtk
 | 
			
		||||
import geckoembed
 | 
			
		||||
 | 
			
		||||
from sugar.shell import activity
 | 
			
		||||
from sugar.p2p.Group import LocalGroup
 | 
			
		||||
import sugar.env
 | 
			
		||||
 | 
			
		||||
class AddressToolbar(gtk.Toolbar):
 | 
			
		||||
@ -77,7 +78,7 @@ class AddressEntry(gtk.HBox):
 | 
			
		||||
		return self.folded
 | 
			
		||||
	
 | 
			
		||||
	def set_folded(self, folded):
 | 
			
		||||
		self.folded = not self.folded
 | 
			
		||||
		self.folded = folded
 | 
			
		||||
		self._update_folded_state()		
 | 
			
		||||
	
 | 
			
		||||
	def __button_clicked_cb(self, button):
 | 
			
		||||
@ -88,11 +89,12 @@ class AddressEntry(gtk.HBox):
 | 
			
		||||
		self.set_folded(True)
 | 
			
		||||
 | 
			
		||||
class NavigationToolbar(gtk.Toolbar):
 | 
			
		||||
	def __init__(self, embed):
 | 
			
		||||
	def __init__(self, browser):
 | 
			
		||||
		gtk.Toolbar.__init__(self)
 | 
			
		||||
		self.embed = embed
 | 
			
		||||
		self._browser = browser
 | 
			
		||||
		self._embed = self._browser.get_embed()
 | 
			
		||||
		
 | 
			
		||||
		self.set_style(gtk.TOOLBAR_ICONS)
 | 
			
		||||
		self.set_style(gtk.TOOLBAR_BOTH_HORIZ)
 | 
			
		||||
		
 | 
			
		||||
		self.back = gtk.ToolButton(gtk.STOCK_GO_BACK)
 | 
			
		||||
		self.back.connect("clicked", self.__go_back_cb)
 | 
			
		||||
@ -113,7 +115,9 @@ class NavigationToolbar(gtk.Toolbar):
 | 
			
		||||
		self.insert(separator, -1)
 | 
			
		||||
		separator.show()
 | 
			
		||||
 | 
			
		||||
		share = gtk.ToolButton("Share")
 | 
			
		||||
		share = gtk.ToolButton(None, "Share")
 | 
			
		||||
		share.set_icon_name('stock_shared-by-me')
 | 
			
		||||
		share.set_is_important(True)
 | 
			
		||||
		share.connect("clicked", self.__share_cb)
 | 
			
		||||
		self.insert(share, -1)
 | 
			
		||||
		share.show()
 | 
			
		||||
@ -128,34 +132,42 @@ class NavigationToolbar(gtk.Toolbar):
 | 
			
		||||
 | 
			
		||||
		self._update_sensitivity()
 | 
			
		||||
 | 
			
		||||
		self.embed.connect("location", self.__location_changed)
 | 
			
		||||
		self._embed.connect("location", self.__location_changed)
 | 
			
		||||
 | 
			
		||||
	def _update_sensitivity(self):
 | 
			
		||||
		self.back.set_sensitive(self.embed.can_go_back())
 | 
			
		||||
		self.forward.set_sensitive(self.embed.can_go_forward())
 | 
			
		||||
		self.back.set_sensitive(self._embed.can_go_back())
 | 
			
		||||
		self.forward.set_sensitive(self._embed.can_go_forward())
 | 
			
		||||
		
 | 
			
		||||
	def __go_back_cb(self, button):
 | 
			
		||||
		self.embed.go_back()
 | 
			
		||||
		self._embed.go_back()
 | 
			
		||||
	
 | 
			
		||||
	def __go_forward_cb(self, button):
 | 
			
		||||
		self.embed.go_forward()
 | 
			
		||||
		self._embed.go_forward()
 | 
			
		||||
		
 | 
			
		||||
	def __reload_cb(self, button):
 | 
			
		||||
		self.embed.reload()
 | 
			
		||||
		self._embed.reload()
 | 
			
		||||
 | 
			
		||||
	def __share_cb(self, button):
 | 
			
		||||
		pass
 | 
			
		||||
		self._browser.share()
 | 
			
		||||
 | 
			
		||||
	def __location_changed(self, embed):
 | 
			
		||||
		self._update_sensitivity()
 | 
			
		||||
 | 
			
		||||
	def __open_address_cb(self, address):
 | 
			
		||||
		self.embed.load_address(address)
 | 
			
		||||
		self._embed.load_address(address)
 | 
			
		||||
 | 
			
		||||
class BrowserActivity(activity.Activity):
 | 
			
		||||
	def __init__(self, uri):
 | 
			
		||||
	def __init__(self, group, uri):
 | 
			
		||||
		activity.Activity.__init__(self)
 | 
			
		||||
 | 
			
		||||
		self.uri = uri
 | 
			
		||||
		self._group = group
 | 
			
		||||
		
 | 
			
		||||
	def _setup_shared(self, uri):
 | 
			
		||||
		self._model = self._group.get_store().get_model(uri)
 | 
			
		||||
		if self._model:
 | 
			
		||||
			self._load_shared_address()
 | 
			
		||||
			self._model.add_listener(self.__shared_address_changed_cb)
 | 
			
		||||
	
 | 
			
		||||
	def activity_on_connected_to_shell(self):
 | 
			
		||||
		self.activity_set_ellipsize_tab(True)
 | 
			
		||||
@ -173,7 +185,7 @@ class BrowserActivity(activity.Activity):
 | 
			
		||||
		self.embed.show()
 | 
			
		||||
		self.embed.load_address(self.uri)
 | 
			
		||||
		
 | 
			
		||||
		nav_toolbar = NavigationToolbar(self.embed)
 | 
			
		||||
		nav_toolbar = NavigationToolbar(self)
 | 
			
		||||
		vbox.pack_start(nav_toolbar, False)
 | 
			
		||||
		nav_toolbar.show()
 | 
			
		||||
 | 
			
		||||
@ -182,12 +194,36 @@ class BrowserActivity(activity.Activity):
 | 
			
		||||
		plug.show()
 | 
			
		||||
 | 
			
		||||
		vbox.show()
 | 
			
		||||
		
 | 
			
		||||
		self._setup_shared(uri)
 | 
			
		||||
	
 | 
			
		||||
	def get_embed(self):
 | 
			
		||||
		return self.embed
 | 
			
		||||
	
 | 
			
		||||
	def share(self):
 | 
			
		||||
		address = self.embed.get_address()
 | 
			
		||||
		self._model = self._group.get_store().create_model(address)
 | 
			
		||||
		self._model.set_value('current_address', address)
 | 
			
		||||
		self._model.add_listener(self.__shared_address_changed_cb)
 | 
			
		||||
	
 | 
			
		||||
		bus = dbus.SessionBus()
 | 
			
		||||
		proxy_obj = bus.get_object('com.redhat.Sugar.Chat', '/com/redhat/Sugar/Chat')
 | 
			
		||||
		chat_shell = dbus.Interface(proxy_obj, 'com.redhat.Sugar.ChatShell')
 | 
			
		||||
		chat_shell.send_message('<richtext><link href="' + address + '">' +
 | 
			
		||||
								self.embed.get_title() + '</link></richtext>')
 | 
			
		||||
	
 | 
			
		||||
	def __title_cb(self, embed):
 | 
			
		||||
		self.activity_set_tab_text(embed.get_title())
 | 
			
		||||
		# Temporary hack, we need an UI
 | 
			
		||||
		self._model.set_value('current_address', self.embed.get_address())
 | 
			
		||||
 | 
			
		||||
	def _load_shared_address(self):
 | 
			
		||||
		address = self._model.get_value("current_address")
 | 
			
		||||
		if address != self.embed.get_address():
 | 
			
		||||
			self.embed.load_address(address)
 | 
			
		||||
		
 | 
			
		||||
	def __shared_address_changed_cb(self, model, key):
 | 
			
		||||
		self._load_shared_address()
 | 
			
		||||
 | 
			
		||||
	def activity_on_close_from_user(self):
 | 
			
		||||
		self.activity_shutdown()
 | 
			
		||||
@ -229,7 +265,6 @@ class WebActivity(activity.Activity):
 | 
			
		||||
 | 
			
		||||
	def activity_on_disconnected_from_shell(self):
 | 
			
		||||
		gtk.main_quit()
 | 
			
		||||
		gc.collect()
 | 
			
		||||
 | 
			
		||||
class BrowserShell(dbus.service.Object):
 | 
			
		||||
	instance = None
 | 
			
		||||
@ -249,6 +284,7 @@ class BrowserShell(dbus.service.Object):
 | 
			
		||||
		dbus.service.Object.__init__(self, bus_name, object_path)
 | 
			
		||||
 | 
			
		||||
		self.__browsers = []
 | 
			
		||||
		self._group = LocalGroup()
 | 
			
		||||
 | 
			
		||||
	def open_web_activity(self):
 | 
			
		||||
		web_activity = WebActivity()
 | 
			
		||||
@ -267,17 +303,13 @@ class BrowserShell(dbus.service.Object):
 | 
			
		||||
 | 
			
		||||
	@dbus.service.method('com.redhat.Sugar.BrowserShell')
 | 
			
		||||
	def open_browser(self, uri):
 | 
			
		||||
		browser = BrowserActivity(uri)
 | 
			
		||||
		browser = BrowserActivity(self._group, uri)
 | 
			
		||||
		self.__browsers.append(browser)
 | 
			
		||||
		browser.activity_connect_to_shell()
 | 
			
		||||
 | 
			
		||||
def main():
 | 
			
		||||
	BrowserShell.get_instance().open_web_activity()
 | 
			
		||||
	
 | 
			
		||||
	try:
 | 
			
		||||
		gtk.main()
 | 
			
		||||
	except KeyboardInterrupt:
 | 
			
		||||
		pass
 | 
			
		||||
	gtk.main()
 | 
			
		||||
 | 
			
		||||
if __name__=="__main__":
 | 
			
		||||
		main()
 | 
			
		||||
if __name__ == "__main__":
 | 
			
		||||
	main()
 | 
			
		||||
 | 
			
		||||
@ -1,121 +0,0 @@
 | 
			
		||||
# -*- tab-width: 4; indent-tabs-mode: t -*- 
 | 
			
		||||
 | 
			
		||||
import presence
 | 
			
		||||
import avahi
 | 
			
		||||
 | 
			
		||||
ACTION_BUDDY_ADDED = "added"
 | 
			
		||||
ACTION_BUDDY_REMOVED = "removed"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Buddy(object):
 | 
			
		||||
	def __init__(self, nick, realname, servicename, host, address, port, key=None):
 | 
			
		||||
		self._nick = nick
 | 
			
		||||
		self._realname = realname
 | 
			
		||||
		self._servicename = servicename
 | 
			
		||||
		self._key = key
 | 
			
		||||
		self._host = host
 | 
			
		||||
		self._address = str(address)
 | 
			
		||||
		self._port = int(port)
 | 
			
		||||
		self._chat = None
 | 
			
		||||
 | 
			
		||||
	def set_chat(self, chat):
 | 
			
		||||
		self._chat = chat
 | 
			
		||||
 | 
			
		||||
	def chat(self):
 | 
			
		||||
		return self._chat
 | 
			
		||||
 | 
			
		||||
	def nick(self):
 | 
			
		||||
		return self._nick
 | 
			
		||||
 | 
			
		||||
	def realname(self):
 | 
			
		||||
		return self._realname
 | 
			
		||||
 | 
			
		||||
	def servicename(self):
 | 
			
		||||
		return self._servicename
 | 
			
		||||
 | 
			
		||||
	def host(self):
 | 
			
		||||
		return self._host
 | 
			
		||||
 | 
			
		||||
	def address(self):
 | 
			
		||||
		return self._address
 | 
			
		||||
 | 
			
		||||
	def port(self):
 | 
			
		||||
		return self._port
 | 
			
		||||
 | 
			
		||||
	def key(self):
 | 
			
		||||
		return self._key
 | 
			
		||||
 | 
			
		||||
class BuddyList(object):
 | 
			
		||||
	""" Manage a list of buddies """
 | 
			
		||||
 | 
			
		||||
	def __init__(self, servicename):
 | 
			
		||||
		self._listeners = []
 | 
			
		||||
		self._buddies = {}
 | 
			
		||||
		self._servicename = servicename
 | 
			
		||||
		self._pdiscovery = presence.PresenceDiscovery()
 | 
			
		||||
		self._pdiscovery.add_service_listener(self._on_service_change)
 | 
			
		||||
 | 
			
		||||
	def start(self):
 | 
			
		||||
		self._pdiscovery.start()
 | 
			
		||||
 | 
			
		||||
	def add_buddy_listener(self, listener):
 | 
			
		||||
		self._listeners.append(listener)
 | 
			
		||||
 | 
			
		||||
	def _add_buddy(self, host, address, port, servicename, data):
 | 
			
		||||
		# Ignore ourselves
 | 
			
		||||
		if servicename == self._servicename:
 | 
			
		||||
			return
 | 
			
		||||
 | 
			
		||||
		if len(data) > 0 and 'name' in data.keys():
 | 
			
		||||
			buddy = self._find_buddy_by_service_name(servicename)
 | 
			
		||||
			if not buddy:
 | 
			
		||||
				buddy = Buddy(data['name'], data['realname'], servicename, host, address, port)
 | 
			
		||||
				self._buddies[data['name']] = buddy
 | 
			
		||||
				self._notify_listeners(ACTION_BUDDY_ADDED, buddy)
 | 
			
		||||
 | 
			
		||||
	def _remove_buddy(self, buddy):
 | 
			
		||||
		nick = buddy.nick()
 | 
			
		||||
		self._notify_listeners(ACTION_BUDDY_REMOVED, buddy)
 | 
			
		||||
		del self._buddies[nick]
 | 
			
		||||
 | 
			
		||||
	def _find_buddy_by_service_name(self, servicename):
 | 
			
		||||
		for buddy in self._buddies.values():
 | 
			
		||||
			if buddy.servicename() == servicename:
 | 
			
		||||
				return buddy
 | 
			
		||||
		return None
 | 
			
		||||
 | 
			
		||||
	def find_buddy_by_address(self, address):
 | 
			
		||||
		for buddy_name in self._buddies.keys():
 | 
			
		||||
			buddy = self._buddies[buddy_name]
 | 
			
		||||
			if buddy.address() == address:
 | 
			
		||||
				return buddy
 | 
			
		||||
		return None
 | 
			
		||||
 | 
			
		||||
	def _notify_listeners(self, action, buddy):
 | 
			
		||||
		for listener in self._listeners:
 | 
			
		||||
			listener(action, buddy)
 | 
			
		||||
 | 
			
		||||
	def _on_service_change(self, action, interface, protocol, name, stype, domain, flags):
 | 
			
		||||
		if stype != presence.OLPC_CHAT_SERVICE:
 | 
			
		||||
			return
 | 
			
		||||
		if action == presence.ACTION_SERVICE_NEW:
 | 
			
		||||
			self._pdiscovery.resolve_service(interface, protocol, name, stype, domain, self._on_service_resolved)
 | 
			
		||||
		elif action == presence.ACTION_SERVICE_REMOVED:
 | 
			
		||||
			buddy = self._find_buddy_by_service_name(name)
 | 
			
		||||
			if buddy:
 | 
			
		||||
				self._remove_buddy(buddy)
 | 
			
		||||
 | 
			
		||||
	def _pair_to_dict(self, l):
 | 
			
		||||
		res = {}
 | 
			
		||||
		for el in l:
 | 
			
		||||
			tmp = el.split('=', 1)
 | 
			
		||||
			if len(tmp) > 1:
 | 
			
		||||
				res[tmp[0]] = tmp[1]
 | 
			
		||||
			else:
 | 
			
		||||
				res[tmp[0]] = ''
 | 
			
		||||
		return res
 | 
			
		||||
 | 
			
		||||
	def _on_service_resolved(self, interface, protocol, name, stype, domain, host, aprotocol, address, port, txt, flags):
 | 
			
		||||
		data = self._pair_to_dict(avahi.txt_array_to_string_array(txt))
 | 
			
		||||
		self._add_buddy(host, address, port, name, data)
 | 
			
		||||
 | 
			
		||||
@ -10,9 +10,11 @@ pygtk.require('2.0')
 | 
			
		||||
import gtk, gobject
 | 
			
		||||
 | 
			
		||||
from sugar.shell import activity
 | 
			
		||||
from sugar.p2p.Group import *
 | 
			
		||||
from sugar.p2p.StreamReader import *
 | 
			
		||||
from sugar.p2p.StreamWriter import *
 | 
			
		||||
from sugar.p2p.Group import Group
 | 
			
		||||
from sugar.p2p.Group import LocalGroup
 | 
			
		||||
from sugar.p2p.Service import Service
 | 
			
		||||
from sugar.p2p.StreamReader import StreamReader
 | 
			
		||||
from sugar.p2p.StreamWriter import StreamWriter
 | 
			
		||||
import sugar.env
 | 
			
		||||
 | 
			
		||||
import richtext
 | 
			
		||||
@ -71,14 +73,14 @@ class Chat(activity.Activity):
 | 
			
		||||
		self._hbox = gtk.HBox(False, 12)
 | 
			
		||||
		self._hbox.set_border_width(12)
 | 
			
		||||
 | 
			
		||||
		[chat_vbox, buffer] = self._create_chat()
 | 
			
		||||
		[chat_vbox, buf] = self._create_chat()
 | 
			
		||||
		self._hbox.pack_start(chat_vbox)
 | 
			
		||||
		chat_vbox.show()
 | 
			
		||||
		
 | 
			
		||||
		vbox.pack_start(self._hbox)
 | 
			
		||||
		self._hbox.show()
 | 
			
		||||
 | 
			
		||||
		toolbar = self._create_toolbar(buffer)
 | 
			
		||||
		toolbar = self._create_toolbar(buf)
 | 
			
		||||
		vbox.pack_start(toolbar, False)
 | 
			
		||||
		toolbar.show()
 | 
			
		||||
 | 
			
		||||
@ -130,37 +132,37 @@ class Chat(activity.Activity):
 | 
			
		||||
		button.set_menu(menu)
 | 
			
		||||
		
 | 
			
		||||
	def activity_on_close_from_user(self):
 | 
			
		||||
		print "act %d: in activity_on_close_from_user"%self.activity_get_id()
 | 
			
		||||
		print "act %d: in activity_on_close_from_user" % self.activity_get_id()
 | 
			
		||||
		self.activity_shutdown()
 | 
			
		||||
 | 
			
		||||
	def activity_on_lost_focus(self):
 | 
			
		||||
		print "act %d: in activity_on_lost_focus"%self.activity_get_id()
 | 
			
		||||
		print "act %d: in activity_on_lost_focus" % self.activity_get_id()
 | 
			
		||||
 | 
			
		||||
	def activity_on_got_focus(self):
 | 
			
		||||
		print "act %d: in activity_on_got_focus"%self.activity_get_id()
 | 
			
		||||
		self._controller.notify_activate(self)
 | 
			
		||||
		print "act %d: in activity_on_got_focus" % self.activity_get_id()
 | 
			
		||||
		# FIXME self._controller.notify_activate(self)
 | 
			
		||||
 | 
			
		||||
	def recv_message(self, buddy, msg):
 | 
			
		||||
		self._insert_rich_message(buddy.get_nick_name(), msg)
 | 
			
		||||
		self._controller.notify_new_message(self, buddy)
 | 
			
		||||
 | 
			
		||||
	def _insert_rich_message(self, nick, msg):
 | 
			
		||||
		buffer = self._chat_view.get_buffer()
 | 
			
		||||
		aniter = buffer.get_end_iter()
 | 
			
		||||
		buffer.insert(aniter, nick + ": ")
 | 
			
		||||
		buf = self._chat_view.get_buffer()
 | 
			
		||||
		aniter = buf.get_end_iter()
 | 
			
		||||
		buf.insert(aniter, nick + ": ")
 | 
			
		||||
		
 | 
			
		||||
		serializer = richtext.RichTextSerializer()
 | 
			
		||||
		serializer.deserialize(msg, buffer)
 | 
			
		||||
		serializer.deserialize(msg, buf)
 | 
			
		||||
 | 
			
		||||
		aniter = buffer.get_end_iter()
 | 
			
		||||
		buffer.insert(aniter, "\n")
 | 
			
		||||
		aniter = buf.get_end_iter()
 | 
			
		||||
		buf.insert(aniter, "\n")
 | 
			
		||||
 | 
			
		||||
	def _local_message(self, success, text):
 | 
			
		||||
		if not success:
 | 
			
		||||
			message = "Error: %s\n" % text
 | 
			
		||||
			buffer = self._chat_view.get_buffer()
 | 
			
		||||
			aniter = buffer.get_end_iter()
 | 
			
		||||
			buffer.insert(aniter, message)
 | 
			
		||||
			buf = self._chat_view.get_buffer()
 | 
			
		||||
			aniter = buf.get_end_iter()
 | 
			
		||||
			buf.insert(aniter, message)
 | 
			
		||||
		else:
 | 
			
		||||
			owner = self._controller.get_group().get_owner()
 | 
			
		||||
			self._insert_rich_message(owner.get_nick_name(), text)
 | 
			
		||||
@ -325,11 +327,11 @@ class GroupChat(Chat):
 | 
			
		||||
		if buddy.get_nick_name() == self._group.get_owner().get_nick_name():
 | 
			
		||||
			# Do not show ourself in the buddy list
 | 
			
		||||
			pass
 | 
			
		||||
		elif action == BUDDY_JOIN:
 | 
			
		||||
		elif action == Group.BUDDY_JOIN:
 | 
			
		||||
			aniter = self._buddy_list_model.append(None)
 | 
			
		||||
			self._buddy_list_model.set(aniter, self._MODEL_COL_NICK, buddy.get_nick_name(),
 | 
			
		||||
					self._MODEL_COL_ICON, None, self._MODEL_COL_BUDDY, buddy)
 | 
			
		||||
		elif action == BUDDY_LEAVE:
 | 
			
		||||
		elif action == Group.BUDDY_LEAVE:
 | 
			
		||||
			aniter = self._get_iter_for_buddy(buddy)
 | 
			
		||||
			if aniter:
 | 
			
		||||
				self._buddy_list_model.remove(aniter)
 | 
			
		||||
@ -346,7 +348,7 @@ class GroupChat(Chat):
 | 
			
		||||
		aniter = self._get_iter_for_buddy(buddy)
 | 
			
		||||
		self._buddy_list_model.set(aniter, self._MODEL_COL_ICON, self._pixbuf_new_message)
 | 
			
		||||
 | 
			
		||||
	def notify_activate(self, chat):
 | 
			
		||||
	def notify_activate(self, chat, buddy):
 | 
			
		||||
		aniter = self._get_iter_for_buddy(buddy)
 | 
			
		||||
		self._buddy_list_model.set(aniter, self._MODEL_COL_ICON, self._pixbuf_active_chat)
 | 
			
		||||
 | 
			
		||||
@ -387,19 +389,16 @@ class ChatShell(dbus.service.Object):
 | 
			
		||||
		dbus.service.Object.__init__(self, bus_name, object_path)
 | 
			
		||||
 | 
			
		||||
	def open_group_chat(self):
 | 
			
		||||
		group_chat = GroupChat()
 | 
			
		||||
		group_chat.activity_connect_to_shell()
 | 
			
		||||
		self._group_chat = GroupChat()
 | 
			
		||||
		self._group_chat.activity_connect_to_shell()
 | 
			
		||||
 | 
			
		||||
	@dbus.service.method('com.redhat.Sugar.ChatShell')
 | 
			
		||||
	def send_message(self, message):
 | 
			
		||||
		pass
 | 
			
		||||
		self._group_chat.send_message(message)
 | 
			
		||||
		
 | 
			
		||||
def main():
 | 
			
		||||
	ChatShell.get_instance().open_group_chat()
 | 
			
		||||
	try:
 | 
			
		||||
		gtk.main()
 | 
			
		||||
	except KeyboardInterrupt:
 | 
			
		||||
		pass
 | 
			
		||||
	gtk.main()
 | 
			
		||||
 | 
			
		||||
if __name__ == "__main__":
 | 
			
		||||
	main()
 | 
			
		||||
 | 
			
		||||
@ -45,7 +45,7 @@ class RichTextView(gtk.TextView):
 | 
			
		||||
 | 
			
		||||
	def __motion_notify_cb(self, widget, event):
 | 
			
		||||
		if event.is_hint:
 | 
			
		||||
			[x, y, state] = event.window.get_pointer();
 | 
			
		||||
			event.window.get_pointer();
 | 
			
		||||
		
 | 
			
		||||
		it = self.__get_event_iter(event)
 | 
			
		||||
		if it:
 | 
			
		||||
@ -134,9 +134,9 @@ class RichTextBuffer(gtk.TextBuffer):
 | 
			
		||||
	
 | 
			
		||||
	def __insert_text_cb(self, widget, pos, text, length):
 | 
			
		||||
		for tag in self.active_tags:
 | 
			
		||||
				pos_end = pos.copy()
 | 
			
		||||
				pos_end.backward_chars(length)
 | 
			
		||||
				self.apply_tag_by_name(tag, pos, pos_end)
 | 
			
		||||
			pos_end = pos.copy()
 | 
			
		||||
			pos_end.backward_chars(length)
 | 
			
		||||
			self.apply_tag_by_name(tag, pos, pos_end)
 | 
			
		||||
		
 | 
			
		||||
class RichTextToolbar(gtk.Toolbar):
 | 
			
		||||
	def __init__(self, buf):
 | 
			
		||||
@ -205,6 +205,7 @@ class RichTextToolbar(gtk.Toolbar):
 | 
			
		||||
			
 | 
			
		||||
class RichTextHandler(xml.sax.handler.ContentHandler):
 | 
			
		||||
	def __init__(self, serializer, buf):
 | 
			
		||||
		xml.sax.handler.ContentHandler.__init__(self)
 | 
			
		||||
		self.buf = buf
 | 
			
		||||
		self.serializer = serializer
 | 
			
		||||
		self.tags = []
 | 
			
		||||
@ -286,7 +287,7 @@ class RichTextSerializer:
 | 
			
		||||
	def serialize(self, buf):
 | 
			
		||||
		self.buf = buf
 | 
			
		||||
		
 | 
			
		||||
		xml = "<richtext>"
 | 
			
		||||
		res = "<richtext>"
 | 
			
		||||
 | 
			
		||||
		next_it = buf.get_start_iter()
 | 
			
		||||
		while not next_it.is_end():
 | 
			
		||||
@ -299,29 +300,29 @@ class RichTextSerializer:
 | 
			
		||||
			for tag in it.get_toggled_tags(False):
 | 
			
		||||
				while 1:
 | 
			
		||||
					open_tag = self._open_tags.pop()
 | 
			
		||||
					xml += self.serialize_tag_end(tag)
 | 
			
		||||
					res += self.serialize_tag_end(tag)
 | 
			
		||||
					if open_tag == tag:
 | 
			
		||||
						break						
 | 
			
		||||
					tags_to_reopen.append(open_tag)
 | 
			
		||||
					
 | 
			
		||||
			for tag in tags_to_reopen:
 | 
			
		||||
				self._open_tags.append(tag)
 | 
			
		||||
				xml += self.serialize_tag_start(tag, it)
 | 
			
		||||
				res += self.serialize_tag_start(tag, it)
 | 
			
		||||
			
 | 
			
		||||
			for tag in it.get_toggled_tags(True):
 | 
			
		||||
				self._open_tags.append(tag)
 | 
			
		||||
				xml += self.serialize_tag_start(tag, it)
 | 
			
		||||
				res += self.serialize_tag_start(tag, it)
 | 
			
		||||
			
 | 
			
		||||
			xml += buf.get_text(it, next_it, False)
 | 
			
		||||
			res += buf.get_text(it, next_it, False)
 | 
			
		||||
 | 
			
		||||
		if next_it.is_end():
 | 
			
		||||
			self._open_tags.reverse()
 | 
			
		||||
			for tag in self._open_tags:
 | 
			
		||||
				xml += self.serialize_tag_end(tag)
 | 
			
		||||
				res += self.serialize_tag_end(tag)
 | 
			
		||||
		
 | 
			
		||||
		xml += "</richtext>"
 | 
			
		||||
		res += "</richtext>"
 | 
			
		||||
		
 | 
			
		||||
		return xml
 | 
			
		||||
		return res
 | 
			
		||||
 | 
			
		||||
	def deserialize(self, xml_string, buf):
 | 
			
		||||
		parser = xml.sax.make_parser()
 | 
			
		||||
@ -330,11 +331,11 @@ class RichTextSerializer:
 | 
			
		||||
		parser.feed(xml_string)
 | 
			
		||||
		parser.close()
 | 
			
		||||
 | 
			
		||||
def test_quit(window, rich_buf):
 | 
			
		||||
	print RichTextSerializer().serialize(rich_buf)
 | 
			
		||||
def test_quit(w, rb):
 | 
			
		||||
	print RichTextSerializer().serialize(rb)
 | 
			
		||||
	gtk.main_quit()
 | 
			
		||||
	
 | 
			
		||||
def link_clicked(view, address):
 | 
			
		||||
def link_clicked(v, address):
 | 
			
		||||
	print "Link clicked " + address
 | 
			
		||||
 | 
			
		||||
if __name__ == "__main__":
 | 
			
		||||
@ -350,15 +351,15 @@ if __name__ == "__main__":
 | 
			
		||||
 | 
			
		||||
	rich_buf = view.get_buffer()
 | 
			
		||||
	
 | 
			
		||||
	xml_string = "<richtext>"	
 | 
			
		||||
	test_xml = "<richtext>"	
 | 
			
		||||
 | 
			
		||||
	xml_string += "<bold><italic>Test</italic>one</bold>\n"
 | 
			
		||||
	xml_string += "<bold><italic>Test two</italic></bold>"
 | 
			
		||||
	xml_string += "<font size=\"xx-small\">Test three</font>"
 | 
			
		||||
	xml_string += "<link href=\"http://www.gnome.org\">Test link</link>"
 | 
			
		||||
	xml_string += "</richtext>"
 | 
			
		||||
	test_xml += "<bold><italic>Test</italic>one</bold>\n"
 | 
			
		||||
	test_xml += "<bold><italic>Test two</italic></bold>"
 | 
			
		||||
	test_xml += "<font size=\"xx-small\">Test three</font>"
 | 
			
		||||
	test_xml += "<link href=\"http://www.gnome.org\">Test link</link>"
 | 
			
		||||
	test_xml += "</richtext>"
 | 
			
		||||
 | 
			
		||||
	RichTextSerializer().deserialize(xml_string, rich_buf)
 | 
			
		||||
	RichTextSerializer().deserialize(test_xml, rich_buf)
 | 
			
		||||
	
 | 
			
		||||
	toolbar = RichTextToolbar(rich_buf)
 | 
			
		||||
	vbox.pack_start(toolbar, False)
 | 
			
		||||
 | 
			
		||||
@ -1,9 +1,7 @@
 | 
			
		||||
import os
 | 
			
		||||
 | 
			
		||||
try:
 | 
			
		||||
	from sugar.__uninstalled__ import *
 | 
			
		||||
	from sugar.__uninstalled__ import internal_get_data_file
 | 
			
		||||
except ImportError:
 | 
			
		||||
	from sugar.__installed__ import *
 | 
			
		||||
	from sugar.__installed__ import internal_get_data_file
 | 
			
		||||
	
 | 
			
		||||
def get_data_file(filename):
 | 
			
		||||
	return internal_get_data_file(filename)
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
import pwd
 | 
			
		||||
import os
 | 
			
		||||
 | 
			
		||||
from Service import *
 | 
			
		||||
from Service import Service
 | 
			
		||||
 | 
			
		||||
PRESENCE_SERVICE_TYPE = "_olpc_presence._tcp"
 | 
			
		||||
PRESENCE_SERVICE_PORT = 6000
 | 
			
		||||
 | 
			
		||||
@ -1,21 +1,26 @@
 | 
			
		||||
import avahi
 | 
			
		||||
 | 
			
		||||
from Buddy import Buddy
 | 
			
		||||
from Buddy import Owner
 | 
			
		||||
from Buddy import PRESENCE_SERVICE_TYPE
 | 
			
		||||
from Service import Service
 | 
			
		||||
from sugar.p2p.model.Store import Store
 | 
			
		||||
import presence
 | 
			
		||||
from Buddy import *
 | 
			
		||||
from Service import *
 | 
			
		||||
 | 
			
		||||
SERVICE_ADDED = "service_added"
 | 
			
		||||
SERVICE_REMOVED = "service_removed"
 | 
			
		||||
 | 
			
		||||
BUDDY_JOIN = "buddy_join"
 | 
			
		||||
BUDDY_LEAVE = "buddy_leave"
 | 
			
		||||
 | 
			
		||||
class Group:
 | 
			
		||||
	SERVICE_ADDED = "service_added"
 | 
			
		||||
	SERVICE_REMOVED = "service_removed"
 | 
			
		||||
 | 
			
		||||
	BUDDY_JOIN = "buddy_join"
 | 
			
		||||
	BUDDY_LEAVE = "buddy_leave"
 | 
			
		||||
 | 
			
		||||
	def __init__(self):
 | 
			
		||||
		self._service_listeners = []
 | 
			
		||||
		self._presence_listeners = []
 | 
			
		||||
		self._store = Store(self)
 | 
			
		||||
	
 | 
			
		||||
	def join(self, buddy):
 | 
			
		||||
	def get_store(self):
 | 
			
		||||
		return self._store
 | 
			
		||||
	
 | 
			
		||||
	def join(self):
 | 
			
		||||
		pass
 | 
			
		||||
	
 | 
			
		||||
	def add_service_listener(self, listener):
 | 
			
		||||
@ -26,19 +31,19 @@ class Group:
 | 
			
		||||
		
 | 
			
		||||
	def _notify_service_added(self, service):
 | 
			
		||||
		for listener in self._service_listeners:
 | 
			
		||||
			listener(SERVICE_ADDED, buddy)
 | 
			
		||||
			listener(Group.SERVICE_ADDED, service)
 | 
			
		||||
	
 | 
			
		||||
	def _notify_service_removed(self, service):
 | 
			
		||||
	def _notify_service_removed(self, service_id):
 | 
			
		||||
		for listener in self._service_listeners:
 | 
			
		||||
			listener(SERVICE_REMOVED,buddy)
 | 
			
		||||
			listener(Group.SERVICE_REMOVED, service_id)
 | 
			
		||||
 | 
			
		||||
	def _notify_buddy_join(self, buddy):
 | 
			
		||||
		for listener in self._presence_listeners:
 | 
			
		||||
			listener(BUDDY_JOIN, buddy)
 | 
			
		||||
			listener(Group.BUDDY_JOIN, buddy)
 | 
			
		||||
	
 | 
			
		||||
	def _notify_buddy_leave(self, buddy):
 | 
			
		||||
		for listener in self._presence_listeners:
 | 
			
		||||
			listener(BUDDY_LEAVE, buddy)
 | 
			
		||||
			listener(Group.BUDDY_LEAVE, buddy)
 | 
			
		||||
 | 
			
		||||
class LocalGroup(Group):
 | 
			
		||||
	def __init__(self):
 | 
			
		||||
@ -59,16 +64,19 @@ class LocalGroup(Group):
 | 
			
		||||
		self._services[sid] = service
 | 
			
		||||
		self._notify_service_added(service)
 | 
			
		||||
 | 
			
		||||
	def remove_service(self, sid):
 | 
			
		||||
		self._notify_service_removed(service)
 | 
			
		||||
		del self._services[sid]
 | 
			
		||||
	def remove_service(self, service_id):
 | 
			
		||||
		self._notify_service_removed(service_id)
 | 
			
		||||
		del self._services[service_id]
 | 
			
		||||
 | 
			
		||||
	def join(self):
 | 
			
		||||
		self._owner = Owner(self)
 | 
			
		||||
		self._owner.register()
 | 
			
		||||
 | 
			
		||||
	def get_service(self, name, stype):
 | 
			
		||||
		return self._services[(name, stype)]
 | 
			
		||||
		if self._services.has_key((name, stype)):
 | 
			
		||||
			return self._services[(name, stype)]
 | 
			
		||||
		else:
 | 
			
		||||
			return None
 | 
			
		||||
 | 
			
		||||
	def get_buddy(self, name):
 | 
			
		||||
		return self._buddies[name]
 | 
			
		||||
@ -95,8 +103,8 @@ class LocalGroup(Group):
 | 
			
		||||
						
 | 
			
		||||
	def _on_service_resolved(self, interface, protocol, name, stype, domain,
 | 
			
		||||
							 host, aprotocol, address, port, txt, flags):
 | 
			
		||||
			service = Service(name, stype, address, port)
 | 
			
		||||
			if stype == PRESENCE_SERVICE_TYPE:
 | 
			
		||||
				self._add_buddy(Buddy(service, name))
 | 
			
		||||
			elif stype.startswith("_olpc"):
 | 
			
		||||
				self.add_service(service)
 | 
			
		||||
		service = Service(name, stype, address, port)
 | 
			
		||||
		if stype == PRESENCE_SERVICE_TYPE:
 | 
			
		||||
			self._add_buddy(Buddy(service, name))
 | 
			
		||||
		elif stype.startswith("_olpc"):
 | 
			
		||||
			self.add_service(service)
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										27
									
								
								sugar/p2p/NotificationListener.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								sugar/p2p/NotificationListener.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,27 @@
 | 
			
		||||
from Service import Service
 | 
			
		||||
import network
 | 
			
		||||
 | 
			
		||||
class NotificationListener:
 | 
			
		||||
	TYPE = "_olpc_model_notification._udp"
 | 
			
		||||
	ADDRESS = "224.0.0.222"
 | 
			
		||||
	PORT = 6300
 | 
			
		||||
	
 | 
			
		||||
	def __init__(self, group, name):
 | 
			
		||||
		server = network.GroupServer(NotificationListener.TYPE,
 | 
			
		||||
									 NotificationListener.PORT,
 | 
			
		||||
									 self._recv_multicast)
 | 
			
		||||
		server.start()
 | 
			
		||||
 | 
			
		||||
		service = Service(name, NotificationListener.TYPE,
 | 
			
		||||
						  NotificationListener.ADDRESS,
 | 
			
		||||
						  NotificationListener.PORT, True)
 | 
			
		||||
		service.register(group)
 | 
			
		||||
		
 | 
			
		||||
		self._listeners = {}
 | 
			
		||||
	
 | 
			
		||||
	def add_listener(self, listener):
 | 
			
		||||
		self._listeners.add(listener)
 | 
			
		||||
	
 | 
			
		||||
	def _recv_multicast(self, msg):
 | 
			
		||||
		for listener in self._listeners:
 | 
			
		||||
			listener(msg)
 | 
			
		||||
							
								
								
									
										11
									
								
								sugar/p2p/Notifier.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								sugar/p2p/Notifier.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,11 @@
 | 
			
		||||
import network
 | 
			
		||||
 | 
			
		||||
class Notifier:
 | 
			
		||||
	def __init__(self, group, name):
 | 
			
		||||
		service = group.get_service(name)
 | 
			
		||||
		address = service.get_address()
 | 
			
		||||
		port = service.get_port()
 | 
			
		||||
		self._client = network.GroupClient(address, port)
 | 
			
		||||
		
 | 
			
		||||
	def notify(self, msg):
 | 
			
		||||
		self._client.send_msg(msg)
 | 
			
		||||
@ -1,3 +1,5 @@
 | 
			
		||||
import socket
 | 
			
		||||
 | 
			
		||||
import network
 | 
			
		||||
 | 
			
		||||
class StreamReaderRequestHandler(object):
 | 
			
		||||
@ -5,7 +7,6 @@ class StreamReaderRequestHandler(object):
 | 
			
		||||
		self._reader = reader
 | 
			
		||||
 | 
			
		||||
	def message(self, nick_name, message):
 | 
			
		||||
		address = network.get_authinfo()
 | 
			
		||||
		self._reader.recv(nick_name, message)
 | 
			
		||||
		return True
 | 
			
		||||
 | 
			
		||||
@ -37,7 +38,7 @@ class StreamReader:
 | 
			
		||||
				p2p_server = network.GlibXMLRPCServer(("", port))
 | 
			
		||||
				p2p_server.register_instance(StreamReaderRequestHandler(self))
 | 
			
		||||
				started = True
 | 
			
		||||
			except:
 | 
			
		||||
			except(socket.error):
 | 
			
		||||
				port = port + 1
 | 
			
		||||
				tries = tries - 1
 | 
			
		||||
		self._service.set_port(port)
 | 
			
		||||
 | 
			
		||||
@ -31,7 +31,7 @@ class StreamWriter:
 | 
			
		||||
			nick_name = self._group.get_owner().get_nick_name()
 | 
			
		||||
			self._uclient.message(nick_name, data)
 | 
			
		||||
			return True
 | 
			
		||||
		except (socket.error, xmlrpclib.Fault, xmlrpclib.ProtocolError), e:
 | 
			
		||||
		except (socket.error, xmlrpclib.Fault, xmlrpclib.ProtocolError):
 | 
			
		||||
			traceback.print_exc()
 | 
			
		||||
			return False
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										10
									
								
								sugar/p2p/model/AbstractModel.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								sugar/p2p/model/AbstractModel.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,10 @@
 | 
			
		||||
class AbstractModel:
 | 
			
		||||
	def __init__(self):
 | 
			
		||||
		self._listeners = []
 | 
			
		||||
	
 | 
			
		||||
	def add_listener(self, listener):
 | 
			
		||||
		self._listeners.append(listener)
 | 
			
		||||
	
 | 
			
		||||
	def _notify_model_change(self, key):
 | 
			
		||||
		for listener in self._listeners:
 | 
			
		||||
			listener(self, key)
 | 
			
		||||
							
								
								
									
										55
									
								
								sugar/p2p/model/LocalModel.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								sugar/p2p/model/LocalModel.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,55 @@
 | 
			
		||||
import socket
 | 
			
		||||
 | 
			
		||||
from sugar.p2p.Service import Service
 | 
			
		||||
from sugar.p2p.model.AbstractModel import AbstractModel
 | 
			
		||||
from sugar.p2p import network
 | 
			
		||||
 | 
			
		||||
class ModelRequestHandler(object):
 | 
			
		||||
	def __init__(self, model):
 | 
			
		||||
		self._model = model
 | 
			
		||||
 | 
			
		||||
	def get_value(self, key):
 | 
			
		||||
		return self._model.get_value(key)
 | 
			
		||||
 | 
			
		||||
	def set_value(self, key, value):
 | 
			
		||||
		return self._model.set_value(key, value)
 | 
			
		||||
 | 
			
		||||
class LocalModel(AbstractModel):
 | 
			
		||||
	SERVICE_TYPE = "_olpc_model._tcp"
 | 
			
		||||
	SERVICE_PORT = 6300
 | 
			
		||||
 | 
			
		||||
	def __init__(self, group, model_id):
 | 
			
		||||
		AbstractModel.__init__(self)
 | 
			
		||||
		self._group = group
 | 
			
		||||
		self._model_id = model_id
 | 
			
		||||
		self._values = {}
 | 
			
		||||
		
 | 
			
		||||
		self._setup_service()
 | 
			
		||||
	
 | 
			
		||||
	def get_value(self, key):
 | 
			
		||||
		return self._values[key]
 | 
			
		||||
		
 | 
			
		||||
	def set_value(self, key, value):
 | 
			
		||||
		self._values[key] = value
 | 
			
		||||
		self._notify_model_change(key)
 | 
			
		||||
 | 
			
		||||
	def _setup_service(self):
 | 
			
		||||
		service = Service(self._model_id, LocalModel.SERVICE_TYPE, '',
 | 
			
		||||
						  LocalModel.SERVICE_PORT)
 | 
			
		||||
		self._setup_server(service)
 | 
			
		||||
		service.register(self._group)
 | 
			
		||||
	
 | 
			
		||||
	# FIXME this is duplicated with StreamReader
 | 
			
		||||
	def _setup_server(self, service):
 | 
			
		||||
		started = False
 | 
			
		||||
		tries = 10
 | 
			
		||||
		port = service.get_port()
 | 
			
		||||
		while not started and tries > 0:
 | 
			
		||||
			try:
 | 
			
		||||
				p2p_server = network.GlibXMLRPCServer(("", port))
 | 
			
		||||
				p2p_server.register_instance(ModelRequestHandler(self))
 | 
			
		||||
				started = True
 | 
			
		||||
			except(socket.error):
 | 
			
		||||
				port = port + 1
 | 
			
		||||
				tries = tries - 1
 | 
			
		||||
		service.set_port(port)
 | 
			
		||||
							
								
								
									
										6
									
								
								sugar/p2p/model/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								sugar/p2p/model/Makefile.am
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,6 @@
 | 
			
		||||
sugardir = $(pythondir)/sugar/p2p/model
 | 
			
		||||
sugar_PYTHON =			\
 | 
			
		||||
	__init__.py		\
 | 
			
		||||
	LocalModel.py		\
 | 
			
		||||
	RemoteModel.py		\
 | 
			
		||||
	Store.py
 | 
			
		||||
							
								
								
									
										26
									
								
								sugar/p2p/model/RemoteModel.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								sugar/p2p/model/RemoteModel.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,26 @@
 | 
			
		||||
import xmlrpclib
 | 
			
		||||
 | 
			
		||||
from sugar.p2p.NotificationListener import NotificationListener
 | 
			
		||||
from sugar.p2p.model.AbstractModel import AbstractModel
 | 
			
		||||
 | 
			
		||||
class RemoteModel(AbstractModel):
 | 
			
		||||
	def __init__(self, service):
 | 
			
		||||
		AbstractModel.__init__(self)
 | 
			
		||||
		
 | 
			
		||||
		self._service = service
 | 
			
		||||
		
 | 
			
		||||
		addr = "http://%s:%d" % (service.get_address(), service.get_port())
 | 
			
		||||
		self._client = xmlrpclib.ServerProxy(addr)
 | 
			
		||||
		
 | 
			
		||||
		self._setup_notification_listener()
 | 
			
		||||
 | 
			
		||||
	def get_value(self, key):
 | 
			
		||||
		return self._client.get_value(key)
 | 
			
		||||
		
 | 
			
		||||
	def set_value(self, key, value):
 | 
			
		||||
		self._client.set_value(key, value)
 | 
			
		||||
	
 | 
			
		||||
	def _setup_notification_listener(self):
 | 
			
		||||
		name = self._service.get_name()
 | 
			
		||||
		self._notification = NotificationListener(self._group, name)
 | 
			
		||||
		self._notification.add_listener(self._notify_model_change)
 | 
			
		||||
							
								
								
									
										22
									
								
								sugar/p2p/model/Store.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								sugar/p2p/model/Store.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,22 @@
 | 
			
		||||
from sugar.p2p.model.RemoteModel import RemoteModel
 | 
			
		||||
from sugar.p2p.model.LocalModel import LocalModel
 | 
			
		||||
 | 
			
		||||
class Store:
 | 
			
		||||
	def __init__(self, group):
 | 
			
		||||
		self._group = group
 | 
			
		||||
		self._local_models = {}
 | 
			
		||||
	
 | 
			
		||||
	def create_model(self, model_id):
 | 
			
		||||
		model = LocalModel(self._group, model_id)
 | 
			
		||||
		self._local_models[model_id] = model
 | 
			
		||||
		return model
 | 
			
		||||
	
 | 
			
		||||
	def get_model(self, model_id):
 | 
			
		||||
		if self._local_models.has_key(model_id):
 | 
			
		||||
			return self._local_models(model_id)
 | 
			
		||||
		else:
 | 
			
		||||
			service = self._group.get_service(model_id, LocalModel.SERVICE_TYPE)
 | 
			
		||||
			if service:
 | 
			
		||||
				return RemoteModel(service)
 | 
			
		||||
			else:
 | 
			
		||||
				return None
 | 
			
		||||
@ -1,10 +1,6 @@
 | 
			
		||||
# -*- tab-width: 4; indent-tabs-mode: t -*- 
 | 
			
		||||
 | 
			
		||||
import socket
 | 
			
		||||
import threading
 | 
			
		||||
import traceback
 | 
			
		||||
import select
 | 
			
		||||
import time
 | 
			
		||||
import xmlrpclib
 | 
			
		||||
import sys
 | 
			
		||||
 | 
			
		||||
@ -133,10 +129,6 @@ class GroupServer(object):
 | 
			
		||||
 | 
			
		||||
		# Set some options to make it multicast-friendly
 | 
			
		||||
		self._listen_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
 | 
			
		||||
		try:
 | 
			
		||||
			self._listen_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
 | 
			
		||||
		except:
 | 
			
		||||
			pass
 | 
			
		||||
		self._listen_sock.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_TTL, 20)
 | 
			
		||||
		self._listen_sock.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_LOOP, 1)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -65,7 +65,7 @@ class PresenceDiscovery(object):
 | 
			
		||||
 | 
			
		||||
		self._service_type_browsers[(interface, protocol, domain)] = b
 | 
			
		||||
 | 
			
		||||
	def new_domain(self,interface, protocol, domain, flags):
 | 
			
		||||
	def new_domain(self, interface, protocol, domain, flags):
 | 
			
		||||
		if domain != "local":
 | 
			
		||||
			return
 | 
			
		||||
		self.browse_domain(interface, protocol, domain)
 | 
			
		||||
@ -84,7 +84,7 @@ class PresenceAnnounce(object):
 | 
			
		||||
				self._hostname = "%s:%s" % (self.server.GetHostName(), rs_port)
 | 
			
		||||
				rs_name = self._hostname
 | 
			
		||||
 | 
			
		||||
		info = ["%s=%s" % (k,v) for k,v in kwargs.items()]
 | 
			
		||||
		info = ["%s=%s" % (k, v) for k, v in kwargs.items()]
 | 
			
		||||
		g.AddService(avahi.IF_UNSPEC, avahi.PROTO_UNSPEC, 0, rs_name, rs_service,
 | 
			
		||||
				"", "", # domain, host (let the system figure it out)
 | 
			
		||||
				dbus.UInt16(rs_port), info,)
 | 
			
		||||
 | 
			
		||||
@ -1,15 +1,11 @@
 | 
			
		||||
# -*- tab-width: 4; indent-tabs-mode: t -*- 
 | 
			
		||||
 | 
			
		||||
import string
 | 
			
		||||
 | 
			
		||||
import gc
 | 
			
		||||
import dbus
 | 
			
		||||
import dbus.service
 | 
			
		||||
import dbus.glib
 | 
			
		||||
import gobject
 | 
			
		||||
import pygtk
 | 
			
		||||
pygtk.require('2.0')
 | 
			
		||||
import gtk,sys
 | 
			
		||||
import gtk
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Activity(dbus.service.Object):
 | 
			
		||||
@ -36,21 +32,21 @@ class Activity(dbus.service.Object):
 | 
			
		||||
												   "com.redhat.Sugar.Shell.ActivityContainer")
 | 
			
		||||
 | 
			
		||||
		self.__activity_id = self.__activity_container.add_activity("")
 | 
			
		||||
		self.__object_path = "/com/redhat/Sugar/Shell/Activities/%d"%self.__activity_id
 | 
			
		||||
		self.__object_path = "/com/redhat/Sugar/Shell/Activities/%d" % self.__activity_id
 | 
			
		||||
 | 
			
		||||
		print "object_path = %s"%self.__object_path
 | 
			
		||||
		print "object_path = %s" % self.__object_path
 | 
			
		||||
 | 
			
		||||
		self.__activity_object = dbus.Interface(self.__bus.get_object("com.redhat.Sugar.Shell", self.__object_path), \
 | 
			
		||||
											  "com.redhat.Sugar.Shell.ActivityHost")
 | 
			
		||||
		self.__window_id = self.__activity_object.get_host_xembed_id()
 | 
			
		||||
 | 
			
		||||
		print "XEMBED window_id = %d"%self.__window_id
 | 
			
		||||
		print "XEMBED window_id = %d" % self.__window_id
 | 
			
		||||
 | 
			
		||||
		self.__plug = gtk.Plug(self.__window_id)
 | 
			
		||||
 | 
			
		||||
		# Now let the Activity register a peer service so the Shell can poke it
 | 
			
		||||
		self.__peer_service_name = "com.redhat.Sugar.Activity%d"%self.__activity_id
 | 
			
		||||
		self.__peer_object_name = "/com/redhat/Sugar/Activity/%d"%self.__activity_id
 | 
			
		||||
		self.__peer_service_name = "com.redhat.Sugar.Activity%d" % self.__activity_id
 | 
			
		||||
		self.__peer_object_name = "/com/redhat/Sugar/Activity/%d" % self.__activity_id
 | 
			
		||||
		self.__service = dbus.service.BusName(self.__peer_service_name, bus=self.__bus)
 | 
			
		||||
		dbus.service.Object.__init__(self, self.__service, self.__peer_object_name)
 | 
			
		||||
 | 
			
		||||
@ -86,7 +82,7 @@ class Activity(dbus.service.Object):
 | 
			
		||||
		pixarray = []
 | 
			
		||||
		pixstr = pixbuf.get_pixels();
 | 
			
		||||
		for c in pixstr:
 | 
			
		||||
				pixarray.append(c)
 | 
			
		||||
			pixarray.append(c)
 | 
			
		||||
		self.__activity_object.set_tab_icon(pixarray, \
 | 
			
		||||
											pixbuf.get_colorspace(), \
 | 
			
		||||
											pixbuf.get_has_alpha(),  \
 | 
			
		||||
@ -163,16 +159,16 @@ class Activity(dbus.service.Object):
 | 
			
		||||
	# pure virtual methods
 | 
			
		||||
 | 
			
		||||
	def activity_on_connected_to_shell(self):
 | 
			
		||||
		print "act %d: you need to override activity_on_connected_to_shell"%self.activity_get_id()
 | 
			
		||||
		print "act %d: you need to override activity_on_connected_to_shell" % self.activity_get_id()
 | 
			
		||||
 | 
			
		||||
	def activity_on_disconnected_from_shell(self):
 | 
			
		||||
		print "act %d: you need to override activity_on_disconnected_from_shell"%self.activity_get_id()
 | 
			
		||||
 | 
			
		||||
		print "act %d: you need to override activity_on_disconnected_from_shell" % self.activity_get_id()
 | 
			
		||||
 
 | 
			
		||||
	def activity_on_close_from_user(self):
 | 
			
		||||
		print "act %d: you need to override activity_on_close_from_user"%self.activity_get_id()
 | 
			
		||||
		print "act %d: you need to override activity_on_close_from_user" % self.activity_get_id()
 | 
			
		||||
 | 
			
		||||
	def activity_on_lost_focus(self):
 | 
			
		||||
		print "act %d: you need to override activity_on_lost_focus"%self.activity_get_id()
 | 
			
		||||
		print "act %d: you need to override activity_on_lost_focus" % self.activity_get_id()
 | 
			
		||||
 | 
			
		||||
	def activity_on_got_focus(self):
 | 
			
		||||
		print "act %d: you need to override activity_on_got_focus"%self.activity_get_id()
 | 
			
		||||
		print "act %d: you need to override activity_on_got_focus" % self.activity_get_id()
 | 
			
		||||
 | 
			
		||||
@ -1,12 +1,9 @@
 | 
			
		||||
#!/usr/bin/python
 | 
			
		||||
# -*- tab-width: 4; indent-tabs-mode: t -*- 
 | 
			
		||||
 | 
			
		||||
import string
 | 
			
		||||
 | 
			
		||||
import dbus
 | 
			
		||||
import dbus.service
 | 
			
		||||
import dbus.glib
 | 
			
		||||
import gobject
 | 
			
		||||
import pygtk
 | 
			
		||||
pygtk.require('2.0')
 | 
			
		||||
import gtk
 | 
			
		||||
@ -27,7 +24,7 @@ class ActivityHost(dbus.service.Object):
 | 
			
		||||
		self.activity_id = activity_counter
 | 
			
		||||
		activity_counter += 1
 | 
			
		||||
		
 | 
			
		||||
		self.dbus_object_name = "/com/redhat/Sugar/Shell/Activities/%d"%self.activity_id
 | 
			
		||||
		self.dbus_object_name = "/com/redhat/Sugar/Shell/Activities/%d" % self.activity_id
 | 
			
		||||
		#print "object name = %s"%self.dbus_object_name
 | 
			
		||||
		
 | 
			
		||||
		dbus.service.Object.__init__(self, activity_container.service, self.dbus_object_name)
 | 
			
		||||
@ -143,7 +140,7 @@ class ActivityHost(dbus.service.Object):
 | 
			
		||||
		#print "  data = ", data
 | 
			
		||||
		pixstr = ""
 | 
			
		||||
		for c in data:
 | 
			
		||||
		    pixstr += chr(c)
 | 
			
		||||
			pixstr += chr(c)
 | 
			
		||||
 | 
			
		||||
		pixbuf = gtk.gdk.pixbuf_new_from_data(pixstr, colorspace, has_alpha, bits_per_sample, width, height, rowstride)
 | 
			
		||||
		#print pixbuf
 | 
			
		||||
@ -225,10 +222,11 @@ class ActivityContainer(dbus.service.Object):
 | 
			
		||||
		self.window.add(self.notebook)
 | 
			
		||||
		
 | 
			
		||||
		self.window.connect("destroy", lambda w: gtk.main_quit())
 | 
			
		||||
		self.window.show()
 | 
			
		||||
		
 | 
			
		||||
		self.current_activity = None
 | 
			
		||||
 | 
			
		||||
	def show(self):
 | 
			
		||||
		self.window.show()
 | 
			
		||||
 | 
			
		||||
	def __focus_reply_cb(self):
 | 
			
		||||
		pass
 | 
			
		||||
@ -283,10 +281,10 @@ class ActivityContainer(dbus.service.Object):
 | 
			
		||||
		return activity.get_host_activity_id()
 | 
			
		||||
 | 
			
		||||
	def __print_activities(self):
 | 
			
		||||
		print "__print_activities: %d activities registered"%len(self.activities)
 | 
			
		||||
		print "__print_activities: %d activities registered" % len(self.activities)
 | 
			
		||||
		i = 0
 | 
			
		||||
		for owner, activity in self.activities:
 | 
			
		||||
			print "  %d: owner=%s activity_object_name=%s"%(i, owner, activity.dbus_object_name)
 | 
			
		||||
			print "  %d: owner=%s activity_object_name=%s" % (i, owner, activity.dbus_object_name)
 | 
			
		||||
			i += 1
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -295,11 +293,9 @@ def main():
 | 
			
		||||
	service = dbus.service.BusName("com.redhat.Sugar.Shell", bus=session_bus)
 | 
			
		||||
 | 
			
		||||
	activityContainer = ActivityContainer(service, session_bus)
 | 
			
		||||
	activityContainer.show()
 | 
			
		||||
 | 
			
		||||
	try:
 | 
			
		||||
		gtk.main()
 | 
			
		||||
	except KeyboardInterrupt:
 | 
			
		||||
		pass
 | 
			
		||||
	gtk.main()
 | 
			
		||||
 | 
			
		||||
if __name__=="__main__":
 | 
			
		||||
		main()
 | 
			
		||||
if __name__ == "__main__":
 | 
			
		||||
	main()
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user