changeset 26:346114023528 0.2.0a

Added __getfile__ mechanism
author Ben Croston <ben@croston.org>
date Mon, 02 Jan 2012 00:12:41 +0000
parents d86e7357a91b
children 689d75bb60c2
files AuthRPC/client/__init__.py AuthRPC/server/__init__.py AuthRPC/tests.py CHANGELOG.txt README.txt setup.py
diffstat 6 files changed, 70 insertions(+), 28 deletions(-) [+]
line wrap: on
line diff
--- a/AuthRPC/client/__init__.py	Sun Jan 01 15:59:39 2012 +0000
+++ b/AuthRPC/client/__init__.py	Mon Jan 02 00:12:41 2012 +0000
@@ -59,9 +59,13 @@
         if self._password is not None:
             request['password'] = _encrypt_password(self._password)
 
+        if request['method'] == '__getfile__':
+            return self.call(json.dumps(request))
+
         resp = self.call(json.dumps(request))
         if resp is None:
             raise Exception('Server response is None')
+        resp = json.loads(resp.decode())
         if resp['id'] != request['id']:
             raise Exception('Inconsistent JSON request id returned')
         if resp['error'] is not None:
@@ -165,7 +169,7 @@
         except socket.error:
             raise NetworkSocketException
         if response.status == 200:
-            return json.loads(response.read().decode())
+            return response.read()
         elif response.status == 400:
             raise BadRequestException(response.read().decode())
         elif response.status == 401:
@@ -182,10 +186,7 @@
             raise Exception('HTTP Status %s'%response.status)
 
     def __repr__(self):
-        return (
-            "<ServerProxy for %s%s>" %
-            (self.__host, self.__handler)
-            )
+        return "<ServerProxy for %s%s>" %(self.__host, self.__handler)
 
     __str__ = __repr__
 
@@ -193,7 +194,6 @@
         # magic method dispatcher
         return _Method(self._request, name, self._username, self._password)
 
-
 ################# batch calls vvv
 
 class _BatchMethod(object):
@@ -256,7 +256,7 @@
         req += ', '.join(str(q) for q in self._queue)
         req += ']'
 
-        response = self._server._request(req)
+        response = json.loads(self._server._request(req).decode())
 
         result = []
         for i,r in enumerate(response):
--- a/AuthRPC/server/__init__.py	Sun Jan 01 15:59:39 2012 +0000
+++ b/AuthRPC/server/__init__.py	Mon Jan 02 00:12:41 2012 +0000
@@ -86,31 +86,42 @@
             except KeyError as e:
                 raise exc.HTTPBadRequest("JSON body missing parameter: %s" % e)
             self._check_auth(username, password, req.user_agent, id)
+
+            if method == '__getfile__':
+                try:
+                    with open(params[0],'rb') as f:
+                        body = f.read()
+                except IOError:
+                    raise exc.HTTPNotFound('File not found: %s'%params[0])
+                return Response(content_type='application/octet-stream',
+                                body=body)
+
             result = self._process_single(method, params, id)
 
         return Response(content_type='application/json',
                         body=dumps(result).encode())
 
     def _check_auth(self, username, password, user_agent, id=None):
-        if self.auth is not None:
-            try:
-                auth_result = self.auth(username, password, user_agent)
-            except:
-                text = traceback.format_exc()
-                exc_value = sys.exc_info()[1]
-                error_value = dict(
-                    name='JSONRPCError',
-                    code=100,
-                    message=str(exc_value),
-                    error=text)
-                return Response(
-                    status=500,
-                    content_type='application/json',
-                    body=dumps(dict(result=None,
-                                    error=error_value,
-                                    id=id)))
-            if not auth_result:
-                raise exc.HTTPUnauthorized()
+        if self.auth is None:
+            return
+        try:
+            auth_result = self.auth(username, password, user_agent)
+        except:
+            text = traceback.format_exc()
+            exc_value = sys.exc_info()[1]
+            error_value = dict(
+                name='JSONRPCError',
+                code=100,
+                message=str(exc_value),
+                error=text)
+            return Response(
+                status=500,
+                content_type='application/json',
+                body=dumps(dict(result=None,
+                                error=error_value,
+                                id=id)))
+        if not auth_result:
+            raise exc.HTTPUnauthorized()
 
     def _process_single(self, method, params, id):
         retval = {}
@@ -130,7 +141,7 @@
                    break
         elif method.startswith('%s.'%self.obj.__class__.__name__):
             method = method.replace('%s.'%self.obj.__class__.__name__,'',1)
-        if method.startswith('_'):
+        if method.startswith('_') and method != '__getfile__':
             retval['error'] = 'Bad method name %s: must not start with _' % method
             return retval
         try:
--- a/AuthRPC/tests.py	Sun Jan 01 15:59:39 2012 +0000
+++ b/AuthRPC/tests.py	Mon Jan 02 00:12:41 2012 +0000
@@ -156,6 +156,29 @@
         with self.assertRaises(ProtocolError):
             self.client.api.test(1, '2', three=3)
 
+class FileTest(AuthRPCTests):
+    def runTest(self):
+        filename = 'LICENCE.txt' 
+        with open(filename,'rb') as f:
+            source = f.read()
+        self.assertEqual(self.client.__getfile__(filename), source)
+
+class NonExistentFileTest(AuthRPCTests):
+    def runTest(self):
+        from client import NotFoundException
+        with self.assertRaises(NotFoundException):
+            self.client.__getfile__('nonexistant.file')
+
+class BadAuthFileTest(unittest.TestCase):
+    def runTest(self):
+        from client import ServerProxy, UnauthorisedException
+        self.client = ServerProxy('http://localhost:1337/',
+                                  username='testuser',
+                                  password='s3cr3t',
+                                  user_agent='InternetExploiter')
+        with self.assertRaises(UnauthorisedException):
+            self.client.__getfile__('LICENCE.txt')
+
 class BatchTest(AuthRPCTests):
     def runTest(self):
         from client import BatchCall
@@ -205,6 +228,9 @@
     suite.addTest(AddTest())
     suite.addTest(ReturnNothing())
     suite.addTest(ProtocolErrorTest())
+    suite.addTest(FileTest())
+    suite.addTest(NonExistentFileTest())
+    suite.addTest(BadAuthFileTest())
     suite.addTest(BatchTest())
     suite.addTest(SetFinishedFlag())
     suite.addTest(BadBatchTest())
--- a/CHANGELOG.txt	Sun Jan 01 15:59:39 2012 +0000
+++ b/CHANGELOG.txt	Mon Jan 02 00:12:41 2012 +0000
@@ -1,6 +1,10 @@
 Change Log
 ==========
 
+0.2.0a
+------
+- Added __getfile__ mechanism
+
 0.1.0a
 ------
 - Added batch requests
--- a/README.txt	Sun Jan 01 15:59:39 2012 +0000
+++ b/README.txt	Mon Jan 02 00:12:41 2012 +0000
@@ -33,6 +33,7 @@
                          password='secret',
                          user_agent='myprogram')
     retval = client.do_something('test')
+    file_contents = client.__getfile__('myfile.pdf')
     batch = BatchCall(client)
     batch.do_something('call 1')
     batch.do_something('call 2')
--- a/setup.py	Sun Jan 01 15:59:39 2012 +0000
+++ b/setup.py	Mon Jan 02 00:12:41 2012 +0000
@@ -18,7 +18,7 @@
     extra['use_2to3'] = True
 
 setup(name             = 'AuthRPC',
-      version          = '0.1.0a',
+      version          = '0.2.0a',
       packages         = find_packages(),
       install_requires = 'WebOb>=1.2b2',
       author           = 'Ben Croston',