summaryrefslogtreecommitdiff
path: root/fs/expose
diff options
context:
space:
mode:
authorwillmcgugan <willmcgugan@67cdc799-7952-0410-af00-57a81ceafa0f>2011-08-07 15:12:10 +0000
committerwillmcgugan <willmcgugan@67cdc799-7952-0410-af00-57a81ceafa0f>2011-08-07 15:12:10 +0000
commit19a25b721353cc4fc2ed7adcbdb1709dc83b621d (patch)
treeba26b1383d532e357fb9167533a74ddbcf343a90 /fs/expose
parent038c0022c0d07069815ca46af0215ffa8ca2cf52 (diff)
downloadpyfilesystem-19a25b721353cc4fc2ed7adcbdb1709dc83b621d.tar.gz
Fixes and documentation
git-svn-id: http://pyfilesystem.googlecode.com/svn/trunk@718 67cdc799-7952-0410-af00-57a81ceafa0f
Diffstat (limited to 'fs/expose')
-rw-r--r--fs/expose/serve/server.py72
-rw-r--r--fs/expose/sftp.py6
2 files changed, 65 insertions, 13 deletions
diff --git a/fs/expose/serve/server.py b/fs/expose/serve/server.py
index c8082a1..7ac8c1f 100644
--- a/fs/expose/serve/server.py
+++ b/fs/expose/serve/server.py
@@ -19,10 +19,28 @@ class _SocketFile(object):
def write(self, data):
self.socket.sendall(data)
-class ConnectionThread(threading.Thread):
+
+def remote_call(method_name=None):
+ method = method_name
+ def deco(f):
+ if not hasattr(f, '_remote_call_names'):
+ f._remote_call_names = []
+ f._remote_call_names.append(method or f.__name__)
+ return f
+ return deco
+
+
+class RemoteResponse(Exception):
+ def __init__(self, header, payload):
+ self.header = header
+ self.payload = payload
+
+class ConnectionHandlerBase(threading.Thread):
+
+ _methods = {}
def __init__(self, server, connection_id, socket, address):
- super(ConnectionThread, self).__init__()
+ super(ConnectionHandlerBase, self).__init__()
self.server = server
self.connection_id = connection_id
self.socket = socket
@@ -33,6 +51,16 @@ class ConnectionThread(threading.Thread):
self._lock = threading.RLock()
self.socket_error = None
+
+ if not self._methods:
+ for method_name in dir(self):
+ method = getattr(self, method_name)
+ if callable(method) and hasattr(method, '_remote_call_names'):
+ for name in method._remote_call_names:
+
+ self._methods[name] = method
+
+ print self._methods
self.fs = None
@@ -70,17 +98,37 @@ class ConnectionThread(threading.Thread):
def on_packet(self, header, payload):
print '-' * 30
print repr(header)
- print repr(payload)
-
- if header['method'] == 'ping':
- self.encoder.write({'client_ref':header['client_ref']}, payload)
-
+ print repr(payload)
+ if header['type'] == 'rpc':
+ method = header['method']
+ args = header['args']
+ kwargs = header['kwargs']
+ method_callable = self._methods[method]
+ remote = dict(type='rpcresult',
+ client_ref = header['client_ref'])
+ try:
+ response = method_callable(*args, **kwargs)
+ remote['response'] = response
+ self.encoder.write(remote, '')
+ except RemoteResponse, response:
+ self.encoder.write(response.header, response.payload)
+class RemoteFSConnection(ConnectionHandlerBase):
+
+ @remote_call()
+ def auth(self, username, password, resource):
+ self.username = username
+ self.password = password
+ self.resource = resource
+ from fs.memoryfs import MemoryFS
+ self.fs = MemoryFS()
+
class Server(object):
- def __init__(self, addr='', port=3000):
+ def __init__(self, addr='', port=3000, connection_factory=RemoteFSConnection):
self.addr = addr
self.port = port
+ self.connection_factory = connection_factory
self.socket = None
self.connection_id = 0
self.threads = {}
@@ -124,10 +172,10 @@ class Server(object):
print "Connection from", address
with self._lock:
self.connection_id += 1
- thread = ConnectionThread(self,
- self.connection_id,
- clientsocket,
- address)
+ thread = self.connection_factory(self,
+ self.connection_id,
+ clientsocket,
+ address)
self.threads[self.connection_id] = thread
thread.start()
diff --git a/fs/expose/sftp.py b/fs/expose/sftp.py
index df4a806..7872c9c 100644
--- a/fs/expose/sftp.py
+++ b/fs/expose/sftp.py
@@ -245,7 +245,10 @@ class SFTPRequestHandler(sockserv.StreamRequestHandler):
t.start_server(server=self.server)
-class BaseSFTPServer(sockserv.TCPServer,paramiko.ServerInterface):
+class ThreadedTCPServer(sockserv.TCPServer, sockserv.ThreadingMixIn):
+ pass
+
+class BaseSFTPServer(ThreadedTCPServer, paramiko.ServerInterface):
"""SocketServer.TCPServer subclass exposing an FS via SFTP.
BaseSFTPServer combines a simple SocketServer.TCPServer subclass with an
@@ -318,6 +321,7 @@ if __name__ == "__main__":
from fs.tempfs import TempFS
server = BaseSFTPServer(("localhost",8022),TempFS())
try:
+ #import rpdb2; rpdb2.start_embedded_debugger('password')
server.serve_forever()
except (SystemExit,KeyboardInterrupt):
server.server_close()