updater now has the logic to turn itself off and back on (although for now only in...
authorThierry Parmentelat <thierry.parmentelat@inria.fr>
Thu, 11 Apr 2013 17:34:37 +0000 (19:34 +0200)
committerThierry Parmentelat <thierry.parmentelat@inria.fr>
Thu, 11 Apr 2013 17:34:37 +0000 (19:34 +0200)
+ various tweaks all over the place

manifold/js/manifold.js
manifold/manifoldapi.py
manifold/manifoldquery.py
manifold/manifoldresult.py
plugins/hazelnut/hazelnut.js
plugins/querycode/querycode.py
plugins/updater/updater.js
plugins/updater/updater.py
trash/pluginview.py
unfold/page.py

index bea64c6..9f24bac 100644 (file)
@@ -29,11 +29,6 @@ var manifold = {
     find_query : function (query_uuid) { 
        return manifold.all_queries[query_uuid];
     },
-    debug_all_queries : function (msg) {
-       for (var query_uuid in manifold.all_queries) {
-           messages.debug("manifold.debug " + msg + " " + query_uuid + " -> " + manifold.all_queries[query_uuid]);
-       }
-    },
 
     // trigger a query asynchroneously
     proxy_url : '/manifold/proxy/json/',
@@ -79,27 +74,30 @@ var manifold = {
     // however in some cases we wish to publish the results under a different uuid
     // e.g. an updater wants to publish its results as if from the original (get) query
     asynchroneous_success : function (data, query, publish_uuid, domid) {
-       if (manifold.asynchroneous_debug) messages.debug("received manifold result with code " + data.code);
+       if (manifold.asynchroneous_debug) 
+           messages.debug("received manifold result with code " + data.code + " for publish on " + publish_uuid);
        // xxx should have a nicer declaration of that enum in sync with the python code somehow
        if (data.code == 1) {
            alert("Your session has expired, please log in again");
            window.location="/logout/";
            return;
        } else if (data.code != 0) {
-           alert("Error received from manifold backend at " + MANIFOLD_URL + " [" + data.output + "]");
+           messages.error("Error received from manifold backend at " + MANIFOLD_URL + " [" + data.output + "]");
+           // publish error code and text message on a separate channel for whoever is interested
+           jQuery.publish("/results/" + publish_uuid + "/failed", [data.code, data.output] );
            return;
        }
        // once everything is checked we can use the 'value' part of the manifoldresult
-       data=data.value;
-       if (data) {
+       var value=data.value;
+       if (value) {
             if (!!domid) {
                /* Directly inform the requestor */
                if (manifold.asynchroneous_debug) messages.debug("directing results to " + domid);
-               jQuery('#' + domid).trigger('results', [data]);
+               jQuery('#' + domid).trigger('results', [value]);
             } else {
                /* Publish an update announce */
                if (manifold.asynchroneous_debug) messages.debug("publishing results on " + publish_uuid);
-               jQuery.publish("/results/" + publish_uuid + "/changed", [data, query]);
+               jQuery.publish("/results/" + publish_uuid + "/changed", [value, query]);
             }
 
        }
index ef7e457..4d25031 100644 (file)
@@ -50,26 +50,31 @@ class ManifoldAPI:
                 # 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 debug: print "Session Expired"
                 if error.faultCode == 8002:
                     reason="most likely your session has expired"
                     reason += " (the manifold API has no unambiguous error reporting mechanism yet)"
                     return ManifoldResult (code=ManifoldCode.SESSION_EXPIRED, output=reason)
+                else:
+                    reason="xmlrpclib.Fault with faultCode = %s (not taken as session expired)"%error.faultCode
+                    return ManifoldResult (code=ManifoldCode.UNKNOWN_ERROR, output=reason)
             except Exception,error:
                 print "ManifoldAPI: unexpected exception",error
-                return ManifoldResult (code=ManifoldResult.UNKNOWN_ERROR, output="%s"%error)
+                return ManifoldResult (code=ManifoldCode.UNKNOWN_ERROR, output="%s"%error)
         return func
 
     def send_manifold_query (self, query):
         (action,subject)= (query.action,query.subject)
-        # use e.g. self.Get rather than self.server.Get so we catch exceptions as per __getattr__
+        # use e.g. self.Get rather than self.server.Get so we use the __getattr__ code
         if action=='get':
 # this makes the backend to squeak and one can't login anymore...
 #            return self.Get(subject, query.filters, query.timestamp, query.fields)
             return self.Get(subject, query.filters, {}, query.fields)
-        if action=='update':
-            return self.Update(subject, query.filters, query.params, query.fields)
+        elif action=='update':
+            answer=self.Update(subject, query.filters, query.params, query.fields)
+            if not isinstance (answer, ManifoldResult): print "UNEXECPECTED answer", answer
+            return answer
         else:
             warning="WARNING: ManifoldAPI.send_manifold_query: %s not implemented for now"%action
             print warning
+            print 3
             return ManifoldResult(code=ManifoldCode.NOT_IMPLEMENTED, output=warning)
index da3bbc5..91b6c0b 100644 (file)
@@ -31,8 +31,9 @@ class ManifoldQuery:
         self.subqueries = {}
 
     def __repr__ (self):
-        result="Q: id=%(query_uuid)s - %(action)s on %(subject)s "%self.__dict__
+        result="[[Q: id=%(query_uuid)s - %(action)s on %(subject)s "%self.__dict__
         result += " with %d filters, %d fields"%(len(self.filters),len(self.params))
+        result += "]]"
         return result
 
     def to_json (self):
index fcda3ad..1c812f0 100644 (file)
@@ -6,7 +6,7 @@ ManifoldCode = enum (
     SUCCESS=0,
     SESSION_EXPIRED=1,
     NOT_IMPLEMENTED=2,
-    OTHERS=3,
+    UNKNOWN_ERROR=3,
 )
 
 # being a dict this can be used with json.dumps
@@ -29,3 +29,14 @@ class ManifoldResult (dict):
     def error (self):
         return "code=%s -- %s"%(self['code'],self['output'])
     
+
+    def __repr__ (self):
+        result="[[MFresult code=%s"%self['code']
+        if self['code']==0:
+            value=self['value']
+            if isinstance(value,list): result += " [value=list with %d elts]"%len(value)
+            else: result += " [value=other %s]"%value
+        else:
+            result += " [output=%s]"%self['output']
+        result += "]]"
+        return result
index 3a9335f..4bf182e 100644 (file)
                 var update_channel  = '/update-set/' + options.query_uuid;
                 var results_channel = '/results/' + options.query_uuid + '/changed';
 
+               // xxx not tested yet
                 $.subscribe(query_channel,  function(e, query) { hazelnut.set_query(query); });
+               // xxx not tested yet
                 $.subscribe(update_channel, function(e, resources, instance) { hazelnut.set_resources(resources, instance); });
+               // expected to work
                 $.subscribe(results_channel, $this, function(e, rows) { hazelnut.update_plugin(e,rows); });
                if (debug) messages.debug("hazelnut '" + this.id + "' subscribed to e.g." + results_channel);
 
index b29917d..55da3e9 100644 (file)
@@ -5,8 +5,6 @@ class QueryCode (Plugin):
     def __init__ (self, query, **settings):
         Plugin.__init__ (self, **settings)
         self.query=query
-        # our javascript requires the details of the manifold server
-        self.page.expose_js_manifold_config()
 
     def template_file (self):
         return "querycode.html"
index b28a05b..7986fee 100644 (file)
@@ -8,6 +8,9 @@
 
 ( function ( $ ) {
     
+    var debug=false;
+//    debug=true
+
     $.fn.Updater = function ( method ) {
         /* Method calling logic */
         if ( methods[method] ) {
                var $this = $(this);
                var updater = new Updater (options);
                $this.data('Updater',updater);
-               /* Subscribe to query updates */
+               // xxx not tested yet
                 var results_channel = '/results/' + options.query_uuid + '/changed';
-               $.subscribe(results_channel, function (e,rows) { updater.update_slice (e,rows); } );
+               $.subscribe(results_channel, function (e,rows) { updater.query_completed (e,rows); } );
+               // under test..
+               var failed_channel = '/results/' + options.query_uuid + '/failed';
+               $.subscribe(failed_channel, $this, function (e,code,output) { updater.query_failed (e, code, output); } );
            });
        },
        destroy : function( ) {
@@ -51,7 +57,6 @@
        // implementation wouldn't fly
        // we keep this for a later improvement
        var query=manifold.find_query (options.query_uuid);
-       messages.info("retrieved query " + query.__repr());
        // very rough way of filling this for now
        this.update_query = 
            new ManifoldQuery ("update", query.subject, null, query.filters, 
            $('#updater-' + this.options.plugin_uuid).click(this, this.submit_update_request);
        },
        this.submit_update_request = function (e) {
-           messages.debug("submit_update_request");
            var query_uuid = e.data.options.query_uuid;
            var update_query = e.data.update_query;
-           messages.debug("Updater.submit_update_request " + update_query.__repr());
+           if (debug) messages.debug("Updater.submit_update_request " + update_query.__repr());
            // actually send the Update query, but publish results as if coming from the original query
-           manifold.asynchroneous_exec ( [ {'query_uuid': update_query.query_uuid, 'publish_uuid' : query_uuid} ]);
-           // looks like a previous attempt to disable the button while the query is flying
-            //$('#updateslice-' + options.plugin_uuid).prop('disabled', true);
+           manifold.asynchroneous_exec ( [ {'query_uuid': update_query.query_uuid, 'publish_uuid' : query_uuid} ], false);
+           // disable button while the query is flying
+            $('#updater-' + e.data.options.plugin_uuid).attr('disabled', 'disabled');
         },
 
+       this.query_failed = function (e, code, output) {
+           var plugindiv=e.data;
+           var updater=plugindiv.data('Updater');
+            $('#updater-' + updater.options.plugin_uuid).removeAttr('disabled');
+           // just as a means to deom how to retrieve the stuff passed on the channel
+           if (debug) messages.debug("retrieved error code " + code + " and output " + output);
+       }
+           
        update_resources = function (e, resources, change) {
             data = e.data.instance.data().Slices;
 
            $.publish('/update/' + data.options.query_uuid, [data.update_query, true]);
        },
   
-       update_slice = function (e, rows, query) {
+           
 
-           /* This function is called twice : get and update */
+       query_completed = function (e, rows, query) {
 
+           /* This function is called twice : get and update */
+           messages.info("updater.query_completed - not implemented yet");
       
            var data = e.data.instance.data().Slices;
       
index f04afc2..2f68b41 100644 (file)
@@ -4,8 +4,8 @@ class Updater (Plugin):
 
     def __init__ (self, query, label="Update", **settings):
         Plugin.__init__ (self, **settings)
-        # xxx would make sense to check this is a Get query...
         self.query=query
+        if query.action != "get": print "Updater on non-get query: ",query.action
         self.label=label
 
     def template_file (self):
@@ -23,7 +23,7 @@ class Updater (Plugin):
     # although this has no query, we need a plugin instance to be created in the js output
     def export_json_settings (self):     return True
     # the js plugin expects a domid
-    def json_settings_list (self):       return [ 'plugin_uuid', 'query_uuid' ]
+    def json_settings_list (self):       return [ 'plugin_uuid', 'query_uuid', ]
 
     # and we don't need a spin wheel 
     def start_with_spin (self):          return False
index e75c82e..922096e 100644 (file)
@@ -14,6 +14,7 @@ from plugins.stack.stack import Stack
 from plugins.tabs.tabs import Tabs
 from plugins.lists.staticlist import StaticList
 from plugins.quickfilter.quickfilter import QuickFilter
+from plugins.querycode.querycode import QueryCode
 from plugins.raw.raw import Raw
 from plugins.messages.messages import Messages
 from plugins.hazelnut.hazelnut import Hazelnut
@@ -32,7 +33,7 @@ def test_plugin_view (request):
     
     slicename='ple.inria.omftest'
     main_query = ManifoldQuery (action='get',
-                                subject='resource',
+                                subject='slice',
                                 timestamp='latest',
                                 fields=['network','type','hrn','hostname'],
                                 filters= [ [ 'slice_hrn', '=', slicename, ] ],
index fe9412a..54d3309 100644 (file)
@@ -74,8 +74,10 @@ class Page:
             return result
         env['query_publish_dom_tuples'] = [ query_publish_dom_tuple (a,b) for (a,b) in self._queue ]
         javascript = render_to_string ("page-queries.js",env)
-#        self.reset_queue()
         self.add_js_chunks (javascript)
+#        self.reset_queue()
+        # unconditionnally expose MANIFOLD_URL, this is small and manifold.js uses that for various messages
+        self.expose_js_manifold_config()
 
 
     # needs to be called explicitly and only when metadata is actually required