added sticky notifications for warnings and errors + clean up code for v2 only
authorJordan Augé <jordan.auge@lip6.fr>
Wed, 10 Jul 2013 00:16:01 +0000 (02:16 +0200)
committerJordan Augé <jordan.auge@lip6.fr>
Wed, 10 Jul 2013 00:16:01 +0000 (02:16 +0200)
manifold/js/manifold.js
manifold/manifoldapi.py
manifold/manifoldproxy.py
manifold/metadata.py
portal/views.py
third-party/jquery-notify/ui.notify.css

index c3aac9f..5c43e71 100644 (file)
@@ -247,6 +247,7 @@ var manifold = {
         if (!!callback) { callback(data); return; }
 
         if (data.code == 2) { // ERROR
         if (!!callback) { callback(data); return; }
 
         if (data.code == 2) { // ERROR
+            // We need to make sense of error codes here
             alert("Your session has expired, please log in again");
             window.location="/logout/";
             return;
             alert("Your session has expired, please log in again");
             window.location="/logout/";
             return;
@@ -255,6 +256,15 @@ var manifold = {
             messages.error("Some errors have been received from the manifold backend at " + MANIFOLD_URL + " [" + data.description + "]");
             // publish error code and text message on a separate channel for whoever is interested
             jQuery.publish("/results/" + publish_uuid + "/failed", [data.code, data.description] );
             messages.error("Some errors have been received from the manifold backend at " + MANIFOLD_URL + " [" + data.description + "]");
             // publish error code and text message on a separate channel for whoever is interested
             jQuery.publish("/results/" + publish_uuid + "/failed", [data.code, data.description] );
+
+            $("#notifications").notify("create", "sticky", {
+              title: 'Warning',
+              text: data.description
+            },{
+              expires: false,
+              speed: 1000
+            });
+            
         }
         // once everything is checked we can use the 'value' part of the manifoldresult
         var result=data.value;
         }
         // once everything is checked we can use the 'value' part of the manifoldresult
         var result=data.value;
index d2a4a51..eaf9266 100644 (file)
@@ -3,7 +3,9 @@ import xmlrpclib
 
 from myslice.config import Config
 
 
 from myslice.config import Config
 
+from django.contrib import messages
 from manifoldresult import ManifoldResult, ManifoldCode, ManifoldException
 from manifoldresult import ManifoldResult, ManifoldCode, ManifoldException
+from manifold.core.result_value import ResultValue
 
 debug=False
 debug=True
 
 debug=False
 debug=True
@@ -46,52 +48,12 @@ class ManifoldAPI:
                     print '<==== backend call %s(*%s,**%s) returned'%(methodName,args,kwds),
                     print '.ctd. Authmethod=',self.auth['AuthMethod'], self.url,'->',
                     self._print_result(result)
                     print '<==== backend call %s(*%s,**%s) returned'%(methodName,args,kwds),
                     print '.ctd. Authmethod=',self.auth['AuthMethod'], self.url,'->',
                     self._print_result(result)
-                ### attempt to cope with old APIs and new APIs
-                if isinstance (result, dict) and 'code' in result:
-                    if debug: print "taken as new API"
-                    # this sounds like a result from a new API
-                    # minimal treatment is required, but we do want to turn this into a 
-                    # class instance
-                    if result['code'] != 2: # in the manifold world, this can be either
-                                            # 0 (ok) 1 (partial result) or 2 (which means error)
-                        if debug: print "OK (new API)"
-                        return ManifoldResult(code=result['code'], value=result['value'])
-                    else:
-                        if debug: print "KO (new API) - raising ManifoldException"
-                        print "RESULT=", result
-                        raise ManifoldException(ManifoldResult(code=result['code'], output=result['description']))
-                else:
-                    if debug: print "taken as old API"
-                    # we're talking to an old API
-                    # so if we make it here it should mean success
-                    return ManifoldResult (code=ManifoldCode.SUCCESS, value=result)
-            except xmlrpclib.Fault, error:
-                ### xxx this is very rough for now
-                # until we have some agreement about how the API calls should return error conditions
-                # in some less unpolite way than this anonymous exception, we assume it's a problem with the session
-                # that needs to be refreshed
-                if error.faultCode == 8002:
-                    if debug: print "KO (old API - 8002) - raising ManifoldException"
-                    reason="most likely your session has expired"
-                    reason += " (the manifold API has no unambiguous error reporting mechanism yet)"
-                    import traceback
-                    traceback.print_exc()
-                    raise ManifoldException ( ManifoldResult (code=ManifoldCode.SESSION_EXPIRED, output=reason))
-                else:
-                    if debug: print "KO (old API - other) - raising ManifoldException"
-                    reason="xmlrpclib.Fault with faultCode = %s (not taken as session expired)"%error.faultCode
-                    raise ManifoldException ( ManifoldResult (code=ManifoldCode.UNKNOWN_ERROR, output=reason))
+
+                return ResultValue(**result)
+
             except Exception,error:
                 if debug: print "KO (unexpected exception)",error
                 raise ManifoldException ( ManifoldResult (code=ManifoldCode.UNKNOWN_ERROR, output="%s"%error) )
             except Exception,error:
                 if debug: print "KO (unexpected exception)",error
                 raise ManifoldException ( ManifoldResult (code=ManifoldCode.UNKNOWN_ERROR, output="%s"%error) )
+
         return func
 
         return func
 
-    def send_manifold_query (self, query):
-        # We use a dictionary representation of the query for forwarding it to the API
-        ret = self.forward(query.to_dict())
-        if debug:
-            print "="*80
-            print "Result:"
-            print ret
-            print "="*80
-        return ret
index a8bec58..984531e 100644 (file)
@@ -84,33 +84,29 @@ with the query passed using POST"""
         if debug: print '===> manifoldproxy.proxy: sending to backend', manifold_query
         # for the benefit of the python code, manifoldAPI raises an exception if something is wrong
         # however in this case we want to propagate the complete manifold result to the js world
         if debug: print '===> manifoldproxy.proxy: sending to backend', manifold_query
         # for the benefit of the python code, manifoldAPI raises an exception if something is wrong
         # however in this case we want to propagate the complete manifold result to the js world
-        try:
-            answer=manifold_api.send_manifold_query (manifold_query)
-        except ManifoldException, manifold_result:
-            print "MANIFOLD EXCEPTION"
-            answer=manifold_result
-        print "="*80
-        print "ANSWER IN PROXY", answer
-        print answer.ok_value()
-        print "="*80
-        if debug: 
-            print '<=== manifoldproxy.proxy: received from backend with code', answer['code']
-            if answer['code']==0:
-                print ".... ctd ",
-                value=answer.ok_value()
-                if isinstance (value, list): print "result is a list with %d entries"%len(value)
-                elif isinstance (value, dict): print "result is a dict with keys %s"%value.keys()
-                else: print "result is other (type=%s) : %s"%(type(value),value)
-        json_answer=json.dumps(answer)
+
+
+        result = manifold_api.forward(manifold_query.to_dict())
+
+        # XXX TEMP HACK
+        import pprint
+        htmlLines = []
+        for textLine in pprint.pformat(result['description']).splitlines():
+            htmlLines.append('<br/>%s' % textLine) # or something even nicer
+        result['description'] = ('\n'.join(htmlLines)).replace(' ', '&nbsp;')
+
+        json_answer=json.dumps(result)
         # if in debug mode we save this so we can use offline mode later
         if debug:
             with (file(offline_filename,"w")) as f:
                 f.write(json_answer)
         # if in debug mode we save this so we can use offline mode later
         if debug:
             with (file(offline_filename,"w")) as f:
                 f.write(json_answer)
+
         # this is an artificial delay added for debugging purposes only
         if debug_spin>0:
             print "Adding additional artificial delay",debug_spin
             import time
             time.sleep(debug_spin)
         # this is an artificial delay added for debugging purposes only
         if debug_spin>0:
             print "Adding additional artificial delay",debug_spin
             import time
             time.sleep(debug_spin)
+
         return HttpResponse (json_answer, mimetype="application/json")
 
     except:
         return HttpResponse (json_answer, mimetype="application/json")
 
     except:
index 4bb3284..1b0e270 100644 (file)
@@ -36,6 +36,13 @@ class MetaData:
             'object': 'local:object', # proposed to replace metadata:table
             'fields':     fields 
         })
             'object': 'local:object', # proposed to replace metadata:table
             'fields':     fields 
         })
+
+        if row_results['code'] == 1: # warning
+            messages.warning(request, result['description'])
+        elif row_results['code'] == 2:
+            messages.error(request, result['description'])
+            # XXX FAIL HERE XXX
+
         rows = rows_result.ok_value()
 # API errors will be handled by the outer logic
 #        if not rows:
         rows = rows_result.ok_value()
 # API errors will be handled by the outer logic
 #        if not rows:
index 815c16a..597f319 100644 (file)
@@ -22,7 +22,7 @@
 
 from django.conf                 import settings
 from django.contrib.sites.models import Site, RequestSite
 
 from django.conf                 import settings
 from django.contrib.sites.models import Site, RequestSite
-from django.contrib import messages
+from django.contrib              import messages
 from django.views.generic        import View
 from django.views.generic.base   import TemplateView
 from django.shortcuts            import render
 from django.views.generic        import View
 from django.views.generic.base   import TemplateView
 from django.shortcuts            import render
index 845ab3e..5f1a71b 100644 (file)
@@ -1,12 +1,12 @@
 .ui-notify { width:350px; position:fixed; top: 67px; right:10px; z-index: 999;}
 /* .ui-notify { width:350px; position:fixed; top:10px; right:10px; } */
 .ui-notify { width:350px; position:fixed; top: 67px; right:10px; z-index: 999;}
 /* .ui-notify { width:350px; position:fixed; top:10px; right:10px; } */
-.ui-notify-message { padding:10px; margin-bottom:15px; -moz-border-radius:8px; -webkit-border-radius:8px; border-radius:8px }
+.ui-notify-message { padding:10px; margin-bottom:15px; -moz-border-radius:8px; -webkit-border-radius:8px; border-radius:8px; /* jordan */ max-height: 600px; }
 .ui-notify-message h1 { font-size:14px; margin:0; padding:0 }
 .ui-notify-message p { margin:3px 0; padding:0; line-height:18px }
 .ui-notify-message:last-child { margin-bottom:0 }
 .ui-notify-message-style { background:#000; background:rgba(0,0,0,0.8); -moz-box-shadow: 0 0 6px #000; -webkit-box-shadow: 0 0 6px #000; box-shadow: 0 0 6px #000; }
 .ui-notify-message-style h1 { color:#fff; font-weight:bold }
 .ui-notify-message h1 { font-size:14px; margin:0; padding:0 }
 .ui-notify-message p { margin:3px 0; padding:0; line-height:18px }
 .ui-notify-message:last-child { margin-bottom:0 }
 .ui-notify-message-style { background:#000; background:rgba(0,0,0,0.8); -moz-box-shadow: 0 0 6px #000; -webkit-box-shadow: 0 0 6px #000; box-shadow: 0 0 6px #000; }
 .ui-notify-message-style h1 { color:#fff; font-weight:bold }
-.ui-notify-message-style p { color:#fff }
+.ui-notify-message-style p { color:#fff; /* jordan */ max-height: 500px; overflow-y: scroll; }
 .ui-notify-close { color:#fff; text-decoration:underline }
 .ui-notify-click { cursor:pointer }
 .ui-notify-cross { margin-top:-4px; float:right; cursor:pointer; text-decoration:none; font-size:12px; font-weight:bold; text-shadow:0 1px 1px #fff; padding:2px }
 .ui-notify-close { color:#fff; text-decoration:underline }
 .ui-notify-click { cursor:pointer }
 .ui-notify-cross { margin-top:-4px; float:right; cursor:pointer; text-decoration:none; font-size:12px; font-weight:bold; text-shadow:0 1px 1px #fff; padding:2px }