Merge SVGdraw.py
This commit is contained in:
+1
-1
@@ -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
|
||||
|
||||
+33
-25
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -0,0 +1,6 @@
|
||||
sugardir = $(pythondir)/sugar/p2p/model
|
||||
sugar_PYTHON = \
|
||||
__init__.py \
|
||||
LocalModel.py \
|
||||
RemoteModel.py \
|
||||
Store.py
|
||||
@@ -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)
|
||||
@@ -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,)
|
||||
|
||||
Reference in New Issue
Block a user