Commits

Jesper Nøhr committed 38113ed

client works better, basic marshaller, simple types aren't proxied

Comments (0)

Files changed (3)

 from twisted.internet import reactor
 
 class PuckProxy(object):
-    pass
+    def __init__(self, sock, payload):
+        dso = simplejson.loads(payload)
+
+        self.raw = False
+        self.sock = sock
+        self.id = dso['id']
+        
+        if dso.has_key('object'):
+            for attr in dso['object']:
+                setattr(self, attr, dso['object'][attr])
+        elif dso.has_key('data'):
+            self.raw = True
+            self.data = dso['data']
+    
+    def __getattr__(self, attr):
+        return PuckShallowMethod(self.sock, attr, id_=self.id)
+
+    def to_native(self):
+        if self.raw:
+            return self.data
+        return self
     
 class JSONCall(object):
     def __init__(self, module='', id_=None, args=( ), kwargs={ }):
         return simplejson.dumps(kwd)
 
 class PuckShallowMethod(object):
-    def __init__(self, sock, method):
+    def __init__(self, sock, method, id_=None):
         self.sock = sock
         self.method = method
+        self.id = id_
         
     def __getattr__(self, attr):
         return PuckShallowMethod(self.sock, "%s.%s" % (self.method, attr))
         
     def __call__(self, *args, **kwargs):
-        packet = JSONCall(module=self.method, id_=None, args=args, kwargs=kwargs)
+        packet = JSONCall(module=self.method, id_=self.id, args=args, kwargs=kwargs)
         self.sock.sendall(packet.to_json()+'\r\n')
         f = self.sock.makefile('rb')
-        return simplejson.loads(f.readline())
+        return PuckProxy(self.sock, f.readline()).to_native()
 
 class PuckClient(object):
     def __init__(self, host, port):
     def __init__(self, obj):
         self.obj = obj
         
-    def is_raw(self, obj=None):
-        if obj is None:
-            obj = self.obj
-            
+    def is_raw(self, obj):
         for type_ in JSONMarshaller.RAW_TYPES:
-            if isinstance(self.obj, type_):
+            if isinstance(obj, type_):
                 return True
-
         return False
         
-    def to_json(self, kwd={ 'reply': 'ok.' }):
-        if self.is_raw():
+    def to_json(self):
+        kwd = { 'reply': 'ok.' }
+
+        if self.is_raw(self.obj):
             kwd.update({ 'data': self.obj })
         else:
-            for attr in dir(self.obj):
-                if self.is_raw(attr):
-                    kwd.update({attr:getattr(self.obj, attr)})
+            kwd.update({'object': self.obj.__dict__})
         
-        kwd.update({'id':id(self.obj)})
+        kwd.update({'id': id(self.obj)})
             
         return simplejson.dumps(kwd)
 
             self.respond('json error.')
             return
 
-        print "dso", dso
-
-        if dso.has_key('onId'):
-            cmd = getattr(self.stack[dso.get('onId')], dso['method'])
+        if dso.has_key('id') and dso.get('id', None) is not None:
+            cmd = getattr(self.stack[dso.get('id')], dso['method'])
         else:
             cmd = self.find_command(dso['method'])
         

tests/example-fs/ehub.py

 from puck.hub import Hub, HubFactory
 
 class fakerepo(object):
+    def __init__(self):
+        self.candy = 42
+        self.string = "sixteen"
+        
     def changectx(self, *args):
         return { 'changectx': 'reply' }
 
 class EFSHub(Hub):
     def remote_repository(self, *args):
         return fakerepo()
-        
-    def remote_complex(self, *args):
-        return { 'more': 'complex', 'object': 42 }
 
 class EFSHubFactory(HubFactory):
     protocol = EFSHub