Commits

Jesper Nøhr committed 83b0af2

hghub

  • Participants
  • Parent commits 82858cb

Comments (0)

Files changed (7)

File puck/client.py

 #!/usr/bin/python
 import os, sys, simplejson, socket
-from puck.core import ServerTimeoutException
+from puck.core import decode, encode, ServerTimeoutException, ServerHiccup
 
 class PuckProxy(object):
     def __init__(self, sock, payload):
+        if payload == "":
+            raise ServerHiccup("No data returned.")
+
         dso = simplejson.loads(payload)
 
+        if dso.get('reply', 'fail.') != 'ok.':
+            raise ServerHiccup("Fail in response.")
+
         self.raw = False
+        self.dso = dso
         self.sock = sock
         self.id = dso.get('id')
         self.repr = dso.get('repr', None)
         
         if dso.has_key('object'):
             for attr in dso.get('object'):
-                setattr(self, attr, dso.get('object').get(attr))
+                value = decode(dso.get('object').get(attr))
+                setattr(self, attr, value)
+                
         elif dso.has_key('data'):
             self.raw = True
-            self.data = dso.get('data')
-    
+            self.data = decode(dso.get('data'))
+                
     def __getattr__(self, attr):
         return PuckShallowMethod(self.sock, attr, id_=self.id)
 
             return self.data
         return self
     
-class JSONCall(object):
+def obj_hook(foo):
+    print "foo", foo
+    return foo
+
+class ProxyMarshaller(simplejson.JSONEncoder):        
+    def default(self, obj):
+        if isinstance(obj, PuckProxy):
+            return obj.dso
+        elif isinstance(obj, basestring):
+            print "encode", obj
+        return simplejson.JSONEncoder.default(self, obj)    
+    
+class JSONCall(simplejson.JSONEncoder):
     def __init__(self, module='', id_=None, args=( ), kwargs={ }):
         self.module = module
         self.id = id_
         self.args = args
         self.kwargs = kwargs
-    
+
     def to_json(self):
         kwd = { 
             'method': self.module, 
             'id': self.id,
-            'args': self.args,
-            'kwargs': self.kwargs,
+            'args': encode(self.args),
+            'kwargs': encode(self.kwargs),
         }
 
-        return simplejson.dumps(kwd, skipkeys=True)
+        return simplejson.dumps(kwd, skipkeys=True, cls=ProxyMarshaller)
 
 class PuckShallowMethod(object):
     def __init__(self, sock, method, id_=None):

File puck/core.py

 VERSION = "0.1"
 
 class ServerTimeoutException(Exception):
-    pass
+    pass
+    
+class ServerHiccup(Exception):
+    pass
+    
+def encode(obj):
+    if isinstance(obj, str):
+        try:
+            obj = unicode(obj, 'latin1')
+        except: pass
+    elif isinstance(obj, (list, tuple)):
+        aggr = [ ]
+        for thing in obj:
+            aggr.append(encode(thing))
+        if isinstance(obj, tuple):
+            return tuple(aggr)
+        return aggr
+    elif isinstance(obj, dict):
+        kwd = { }
+        for key, thing in obj.iteritems():
+            kwd[key] = encode(thing)
+        return kwd
+    return obj
+    
+def decode(obj):
+    if isinstance(obj, unicode):
+        try:
+            obj = obj.encode('latin1')
+        except: pass
+    elif isinstance(obj, (list, tuple)):
+        aggr = [ ]
+        for thing in obj:
+            aggr.append(decode(thing))
+        if isinstance(obj, tuple):
+            return tuple(aggr)
+        return aggr
+    elif isinstance(obj, dict):
+        kwd = { }
+        for key, thing in obj.iteritems():
+            kwd[key] = decode(thing)
+        return kwd
+    return obj
 import simplejson, types
 from twisted.internet.protocol import Factory, Protocol
 from twisted.protocols.basic import LineOnlyReceiver
-
-from mercurial import hg, ui
+from puck.core import encode, decode
 
 class JSONMarshaller(object):
     RAW_TYPES = [ types.StringType, types.BooleanType, types.DictType,
         kwd = { 'reply': 'ok.' }
 
         if self.is_raw(self.obj):
-            kwd.update({ 'data': self.obj })
+            kwd.update({ 'data': encode(self.obj) })
         elif hasattr(self.obj, '__dict__'):
             obj_d = { }
             
             for maybe_attr in [ '__doc__', '__name__' ]:
                 if hasattr(self.obj, maybe_attr):
-                    obj_d.update({maybe_attr:getattr(self.obj, maybe_attr)})
+                    obj_d.update({maybe_attr:encode(getattr(self.obj, maybe_attr))})
                         
             for key, value in self.obj.__dict__.iteritems():
                 if self.is_raw(value):
-                    obj_d.update({key:value})
+                    obj_d.update({key:encode(value)})
             kwd.update({'object': obj_d})
         
         kwd.update({'id': id(self.obj)})
-        kwd.update({'repr': repr(self.obj)})
+        kwd.update({'repr': repr(encode(self.obj))})
         
-        print simplejson.dumps(kwd)
-
         return simplejson.dumps(kwd, skipkeys=True)
 
 class Hub(LineOnlyReceiver):
         else:
             cmd = self.find_command(dso.get('method'))
         
+        args = decode(dso.get('args'))
+        kwargs = decode(dso.get('kwargs'))
+        
         if cmd is not None:
-            ret = cmd(*dso.get('args'), **dso.get('kwargs'))
+            ret = cmd(*args, **kwargs)
             id_ = id(ret)
             self.stack[id_] = ret
             reply = JSONMarshaller(ret)
             self.respond(reply.to_json())
         else:
-            self.respond('what?')
+            self.respond(Hub.REPLY_FAIL)
             
     def connectionLost(self, reason):
         del self

File tests/example-fs/client.py

 from puck.client import PuckClient
 
 if __name__ == "__main__":
-    c = PuckClient('localhost', 8080)
+    c = PuckClient('bitbucket.org', 8090)
     print "Now use 'c'."

File tests/hghub/client.py

+#!/usr/bin/python
+import os, sys
+sys.path.append('../../')
+
+from puck.client import PuckClient
+
+if __name__ == "__main__":
+    c = PuckClient('localhost', 8080)
+    
+    repo = c.repository('/Users/jespern/Work/puck')
+    ctx = repo.changectx('tip')
+    
+    

File tests/hghub/hghub.py

+from puck.hub import Hub, HubFactory
+from mercurial import ui, hg
+
+class HGHub(Hub):
+    def __init__(self):
+        self.ui = ui.ui(interactive=False)
+
+    def remote_repository(self, path, *args, **kwargs):
+        return hg.repository(self.ui, path, *args, **kwargs)
+
+class HGHubFactory(HubFactory):
+    protocol = HGHub

File tests/hghub/hghub.tac

+#!/usr/bin/python
+import os, sys
+sys.path.append('../../')
+
+from twisted.application import service, internet
+from hghub import HGHubFactory
+
+def getHub():
+    return internet.TCPServer(8080, HGHubFactory())
+    
+application = service.Application("hghub server")
+service = getHub()
+service.setServiceParent(application)