From af26704d7c1b01f4b3574cde724f3608f0343277 Mon Sep 17 00:00:00 2001
From: Luke Leighton <lkcl@lkcl.net>
Date: Tue, 14 Sep 2010 18:07:23 +0100
Subject: [PATCH 34/34] adding logout - bit broken, needs work

---
 gnumed/gnumed/client/ProxiedWeb/gmWebGuiServer.py  |    8 +++-
 gnumed/gnumed/client/ProxiedWeb/gui/LoginPanel.py  |    1 +
 .../gnumed/client/ProxiedWeb/gui/LogoutCommand.py  |   27 ++++++++++
 gnumed/gnumed/client/ProxiedWeb/gui/Remote.py      |    2 +-
 gnumed/gnumed/client/ProxiedWeb/jsonserver.py      |   52 ++++++++++++--------
 5 files changed, 68 insertions(+), 22 deletions(-)

diff --git a/gnumed/gnumed/client/ProxiedWeb/gmWebGuiServer.py b/gnumed/gnumed/client/ProxiedWeb/gmWebGuiServer.py
index 03f88da..33af16f 100644
--- a/gnumed/gnumed/client/ProxiedWeb/gmWebGuiServer.py
+++ b/gnumed/gnumed/client/ProxiedWeb/gmWebGuiServer.py
@@ -12,7 +12,7 @@ import re, sys, time, os, cPickle, zlib, locale, os.path
 import datetime as pyDT, webbrowser, shutil, logging, urllib2
 
 # json-rpc
-from jsonserver import SimpleForkingJSONRPCServer
+from jsonserver import SimpleForkingJSONRPCServer, CloseConnection
 
 # GNUmed libs
 from Gnumed.pycommon import gmI18N, gmTools, gmDateTime, gmHooks
@@ -341,6 +341,7 @@ class HTTPServer(SimpleForkingJSONRPCServer):
 
         self.register_function(self.echo)
         self.register_function(self.login)
+        self.register_function(self.logout)
         self.register_function(self.search_patient)
         self.register_function(self.get_provider_inbox_data)
         self.register_function(self.get_patient_messages)
@@ -374,6 +375,11 @@ class HTTPServer(SimpleForkingJSONRPCServer):
             )
         return connected
 
+    def logout(self):
+        """ return value is in the exception
+        """
+        raise CloseConnection(True)
+
     def search_patient(self, search_term):
         from Gnumed.business import gmPerson
         self.__person_searcher = gmPerson.cPatientSearcher_SQL()
diff --git a/gnumed/gnumed/client/ProxiedWeb/gui/LoginPanel.py b/gnumed/gnumed/client/ProxiedWeb/gui/LoginPanel.py
index 1deedb6..b68bbdd 100644
--- a/gnumed/gnumed/client/ProxiedWeb/gui/LoginPanel.py
+++ b/gnumed/gnumed/client/ProxiedWeb/gui/LoginPanel.py
@@ -56,6 +56,7 @@ class cLoginPanel:
         #       'data' : extra-error-data
         #     }
         message = errobj['message']
+        self.lp.button_login.setEnabled(True) # re-enable after response
         if code != 0:
             self.setStatus("HTTP error %d: %s" % 
                                 (code, message))
diff --git a/gnumed/gnumed/client/ProxiedWeb/gui/LogoutCommand.py b/gnumed/gnumed/client/ProxiedWeb/gui/LogoutCommand.py
index 4bc5604..e7cef3d 100644
--- a/gnumed/gnumed/client/ProxiedWeb/gui/LogoutCommand.py
+++ b/gnumed/gnumed/client/ProxiedWeb/gui/LogoutCommand.py
@@ -1,4 +1,5 @@
 import GMWevents
+import Remote
 
 #======================================================
 class cLogoutCommand:
@@ -9,4 +10,30 @@ class cLogoutCommand:
         # connection close, or just exit from persistent
         # process would do.
         GMWevents.events.onLoginEvent(self, None, False) # indicate logged out
+        Remote.svc.logout(self)
+
+    #--------------------------------------------------
+    def onRemoteResponse(self, response, request_info):
+        method = request_info.method
+
+    #--------------------------------------------------
+    def onRemoteError(self, code, errobj, request_info):
+        # onRemoteError gets the HTTP error code or 0 and
+        # errobj is an jsonrpc 2.0 error dict:
+        #     {
+        #       'code': jsonrpc-error-code (integer) ,
+        #       'message': jsonrpc-error-message (string) ,
+        #       'data' : extra-error-data
+        #     }
+        message = errobj['message']
+        if code != 0:
+            self.setStatus("HTTP error %d: %s" % 
+                                (code, message))
+        else:
+            code = errobj['code']
+            if message['message'] == 'Cannot request login parameters.':
+                self.setStatus("You need to log in first")
+            else:
+                self.setStatus("JSONRPC Error %s: %s" %
+                                (code, message))
 
diff --git a/gnumed/gnumed/client/ProxiedWeb/gui/Remote.py b/gnumed/gnumed/client/ProxiedWeb/gui/Remote.py
index 6b5cce5..66458a5 100644
--- a/gnumed/gnumed/client/ProxiedWeb/gui/Remote.py
+++ b/gnumed/gnumed/client/ProxiedWeb/gui/Remote.py
@@ -7,7 +7,7 @@ class EchoServicePython(JSONProxy):
     def __init__(self):
         JSONProxy.__init__(self, "/JSON",
                 ["login",
-                "echo", "get_doc_types",
+                "logout", "get_doc_types",
                 "get_schema_version",
                 "get_documents",
                 "get_provider_inbox_data",
diff --git a/gnumed/gnumed/client/ProxiedWeb/jsonserver.py b/gnumed/gnumed/client/ProxiedWeb/jsonserver.py
index 6b96b5c..351f9bc 100644
--- a/gnumed/gnumed/client/ProxiedWeb/jsonserver.py
+++ b/gnumed/gnumed/client/ProxiedWeb/jsonserver.py
@@ -28,6 +28,9 @@ try:
 except ImportError:
     from StringIO import StringIO
 
+class CloseConnection(Exception):
+    pass
+
 
 ###
 ### Server code
@@ -48,10 +51,16 @@ class SimpleJSONRPCDispatcher(SimpleXMLRPCServer.SimpleXMLRPCDispatcher):
             id     = req['id']
             print "decoded and about to call. pid:", os.getpid(), method, params
 
-            if dispatch_method is not None:
-                result = dispatch_method(method, params)
-            else:
-                result = self._dispatch(method, params)
+            close_connection = False
+            try:
+                if dispatch_method is not None:
+                    result = dispatch_method(method, params)
+                else:
+                    result = self._dispatch(method, params)
+            except CloseConnection, e:
+                close_connection = True
+                result = e.args[0]
+            print "result", close_connection, result
             response = dict(id=id, result=result, error=None)
         except:
             extpe, exv, extrc = sys.exc_info()
@@ -60,14 +69,15 @@ class SimpleJSONRPCDispatcher(SimpleXMLRPCServer.SimpleXMLRPCDispatcher):
                        traceback=''.join(traceback.format_tb(extrc)))
             response = dict(id=id, result=None, error=err)
         try:
-            return cjson.encode(response)
+            print "response", response
+            return (cjson.encode(response), close_connection)
         except:
             extpe, exv, extrc = sys.exc_info()
             err = dict(type=str(extpe),
                        message=str(exv),
                        traceback=''.join(traceback.format_tb(extrc)))
             response = dict(id=id, result=None, error=err)
-            return cjson.encode(response)
+            return (cjson.encode(response), close_connection)
 
 
 class SimpleJSONRPCRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
@@ -253,25 +263,27 @@ class SimpleJSONRPCRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
             # SimpleXMLRPCDispatcher. To maintain backwards compatibility,
             # check to see if a subclass implements _dispatch and dispatch
             # using that method if present.
-            response = self.server._marshaled_dispatch(
-                    data, getattr(self, '_dispatch', None)
-                )
+            response, close_connection = self.server._marshaled_dispatch(
+                                data, getattr(self, '_dispatch', None)
+                                                                        )
         except: # This should only happen if the module is buggy
             # internal error, report as HTTP server error
             self.send_response(500)
             self.end_headers()
-        else:
-            # got a valid JSONRPC response
-            self.send_response(200)
-            self.send_header("Content-type", "text/x-json")
-            self.send_header("Connection", "keep-alive")
-            self.send_header("Content-length", str(len(response)))
-            self.end_headers()
-            print "response", repr(response)
-            self.wfile.write(response)
+            return
+        # got a valid JSONRPC response
+        self.send_response(200)
+        self.send_header("Content-type", "text/x-json")
+        self.send_header("Connection", "keep-alive")
+        self.send_header("Content-length", str(len(response)))
+        self.end_headers()
+        print "response", repr(response)
+        self.wfile.write(response)
 
-            self.wfile.flush()
-            print "flushed"
+        self.wfile.flush()
+        print "flushed"
+        if close_connection:
+            self.connection.shutdown(1)
 
     def report_404 (self):
             # Report a 404 error
-- 
1.7.1

