Merge branch 'master' of ssh://git.onelab.eu/git/myslice
authorYasin <mohammed-yasin.rahman@lip6.fr>
Fri, 15 Nov 2013 11:33:22 +0000 (12:33 +0100)
committerYasin <mohammed-yasin.rahman@lip6.fr>
Fri, 15 Nov 2013 11:33:22 +0000 (12:33 +0100)
manifold/static/js/manifold.js
plugins/messages/__init__.py
plugins/querycode/__init__.py
plugins/queryupdater/__init__.py
plugins/tabs/__init__.py
unfold/page.py
unfold/plugin.py
unfold/prelude.py
unfold/templates/page-queries.js
unfold/templates/plugin.html
unfold/templates/prelude.html

index 877b69c..3f51434 100644 (file)
@@ -323,9 +323,9 @@ var manifold = {
      * \brief We use js function closure to be able to pass the query (array)
      * to the callback function used when data is received
      */
-    success_closure: function(query, publish_uuid, callback /*domid*/) {
+    success_closure: function(query, publish_uuid, callback) {
         return function(data, textStatus) {
-            manifold.asynchroneous_success(data, query, publish_uuid, callback /*domid*/);
+            manifold.asynchroneous_success(data, query, publish_uuid, callback);
         }
     },
 
@@ -341,25 +341,16 @@ var manifold = {
         //    manifold.raise_record_event(sq.query_uuid, IN_PROGRESS);
         //});
 
-        $.post(manifold.proxy_url, {'json': query_json} , manifold.success_closure(query, null, callback /*domid*/));
+        $.post(manifold.proxy_url, {'json': query_json} , manifold.success_closure(query, null, callback));
     },
 
-    // Executes all async. queries
-    // input queries are specified as a list of {'query_uuid': <query_uuid>, 'id': <possibly null>}
-    asynchroneous_exec : function (query_publish_dom_tuples) {
-// start spinners - be robust if the spin stuff was not loaded for any reason
-// turned off because each plugin is responsible for doing that through on_query_in_progress
-//        try {
-//         var subjects=$(".need-spin");
-//            if (manifold.asynchroneous_debug) {
-//             messages.debug("Turning on spin with " + subjects.length + " matches for .need-spin");
-//             $.map (subjects, function (subject) { messages.debug("need-spin: "+ subject.id);});
-//         }
-//            subjects.spin(manifold.spin_presets);
-//        } catch (err) { messages.debug("Cannot turn on spins " + err); }
+    // Executes all async. queries - intended for the javascript header to initialize queries
+    // input queries are specified as a list of {'query_uuid': <query_uuid> }
+    // each plugin is responsible for managing its spinner through on_query_in_progress
+    asynchroneous_exec : function (query_exec_tuples) {
         
         // Loop through input array, and use publish_uuid to publish back results
-        $.each(query_publish_dom_tuples, function(index, tuple) {
+        $.each(query_exec_tuples, function(index, tuple) {
             var query=manifold.find_query(tuple.query_uuid);
             var query_json=JSON.stringify (query);
             var publish_uuid=tuple.publish_uuid;
@@ -376,7 +367,7 @@ var manifold = {
             // not quite sure what happens if we send a string directly, as POST data is named..
             // this gets reconstructed on the proxy side with ManifoldQuery.fill_from_POST
             $.post(manifold.proxy_url, {'json':query_json}, 
-                  manifold.success_closure(query, publish_uuid, tuple.callback /*domid*/));
+                  manifold.success_closure(query, publish_uuid, tuple.callback));
         })
     },
 
@@ -384,13 +375,11 @@ var manifold = {
      * \brief Forward a query to the manifold backend
      * \param query (dict) the query to be executed asynchronously
      * \param callback (function) the function to be called when the query terminates
-     * Deprecated:
-     * \param domid (string) the domid to be notified about the results (null for using the pub/sub system
      */
-    forward: function(query, callback /*domid*/) {
+    forward: function(query, callback) {
         var query_json = JSON.stringify(query);
         $.post(manifold.proxy_url, {'json': query_json} , 
-              manifold.success_closure(query, query.query_uuid, callback/*domid*/));
+              manifold.success_closure(query, query.query_uuid, callback));
     },
 
     /*!
@@ -695,27 +684,17 @@ var manifold = {
         }
     },
 
-    // if set domid allows the result to be directed to just one plugin
+    // if set callback is provided it is called
     // most of the time publish_uuid will be query.query_uuid
     // however in some cases we wish to publish the result under a different uuid
     // e.g. an updater wants to publish its result as if from the original (get) query
-    asynchroneous_success : function (data, query, publish_uuid, callback /*domid*/) {
+    asynchroneous_success : function (data, query, publish_uuid, callback) {
         // xxx should have a nicer declaration of that enum in sync with the python code somehow
        
        var start = new Date();
        if (manifold.asynchroneous_debug)
            messages.debug(">>>>>>>>>> asynchroneous_success query.object=" + query.object);
 
-        /* If a callback has been specified, we redirect results to it */
-        if (!!callback) { 
-           callback(data); 
-           if (manifold.asynchroneous_debug) {
-               duration=new Date()-start;
-               messages.debug ("<<<<<<<<<< asynchroneous_success " + query.object + " -- callback ended " + duration + " ms");
-           }
-           return; 
-       }
-
         if (data.code == 2) { // ERROR
             // We need to make sense of error codes here
             alert("Your session has expired, please log in again");
@@ -732,16 +711,18 @@ var manifold = {
             if (publish_uuid)
                 $.publish("/results/" + publish_uuid + "/failed", [data.code, data.description] );
 
-/* DEMO - Debug Messages desactivated
-            $("#notifications").notify("create", "sticky", {
-              title: 'Warning',
-              text: data.description
-            },{
-              expires: false,
-              speed: 1000
-            });
-*/
         }
+
+        // If a callback has been specified, we redirect results to it 
+        if (!!callback) { 
+           callback(data); 
+           if (manifold.asynchroneous_debug) {
+               duration=new Date()-start;
+               messages.debug ("<<<<<<<<<< asynchroneous_success " + query.object + " -- callback ended " + duration + " ms");
+           }
+           return; 
+       }
+
        if (manifold.asynchroneous_debug) 
            messages.debug ("========== asynchroneous_success " + query.object + " -- before process_query_records");
 
@@ -769,7 +750,15 @@ var manifold = {
     raise_event_handler: function(type, query_uuid, event_type, value) {
         if ((type != 'query') && (type != 'record'))
             throw 'Incorrect type for manifold.raise_event()';
+       // xxx we observe quite a lot of incoming calls with an undefined query_uuid
+       // this should be fixed upstream
+       if (query_uuid === undefined) {
+           messages.warning("undefined query in raise_event_handler");
+           return;
+       }
 
+       // notify the change to objects that either listen to this channel specifically,
+       // or to the wildcard channel
         var channels = [ manifold.get_channel(type, query_uuid), manifold.get_channel(type, '*') ];
 
         $.each(channels, function(i, channel) {
index 7ee0c3c..f765d50 100644 (file)
@@ -41,6 +41,3 @@ class Messages (Plugin):
     def json_settings_list (self):
         return [ 'plugin_uuid', 'levels' ]
 
-    # and we don't need a spin wheel 
-    def start_with_spin (self):
-        return False
index 55da3e9..d46a842 100644 (file)
@@ -25,6 +25,3 @@ class QueryCode (Plugin):
             }
 
     def json_settings_list (self): return ['plugin_uuid','query_uuid']
-        
-    # because we have a link to a query it looks like we need a spin, let's make this right
-    def start_with_spin (self): return False
index ad345c8..d74caa3 100644 (file)
@@ -15,5 +15,3 @@ class QueryUpdater(Plugin):
     def json_settings_list (self):
         return ['plugin_uuid', 'domid', 'query_uuid']
 
-    def export_json_settings (self):
-        return True
index 6da94da..d1b9bda 100644 (file)
@@ -15,5 +15,3 @@ class Tabs (Composite):
     def json_settings_list (self):
         return []
 
-    def export_json_settings(self):
-        return True
index 71c5978..7f071c0 100644 (file)
@@ -80,7 +80,7 @@ class Page:
             result={'query_uuid':a}
             if b: result['domid']=b
             return result
-        env['query_publish_dom_tuples'] = [ query_publish_dom_tuple (a,b) for (a,b) in self._queue ]
+        env['query_exec_tuples'] = [ query_publish_dom_tuple (a,b) for (a,b) in self._queue ]
         javascript = render_to_string ("page-queries.js",env)
         self.add_js_chunks (javascript)
 #        self.reset_queue()
@@ -88,29 +88,6 @@ class Page:
         self.expose_js_manifold_config()
 
 
-# DEPRECATED #    # needs to be called explicitly and only when metadata is actually required
-# DEPRECATED #    # in particular user needs to be logged
-# DEPRECATED #    def get_metadata (self):
-# DEPRECATED #        # look in session's cache - we don't want to retrieve this for every request
-# DEPRECATED #        session=self.request.session
-# DEPRECATED #        if 'manifold' not in session:
-# DEPRECATED #            print "Page.expose_js_metadata: no 'manifold' in session... - cannot retrieve metadata - skipping"
-# DEPRECATED #            return
-# DEPRECATED #        manifold=session['manifold']
-# DEPRECATED #        # if cached, use it
-# DEPRECATED #        if 'metadata' in manifold and isinstance(manifold['metadata'],MetaData):
-# DEPRECATED #            if debug: print "Page.get_metadata: return cached value"
-# DEPRECATED #            return manifold['metadata']
-# DEPRECATED #        # otherwise retrieve it
-# DEPRECATED #        manifold_api_session_auth = session['manifold']['auth']
-# DEPRECATED #        print "get_metadata(), manifold_api_session_auth =", session['manifold']['auth']
-# DEPRECATED #        metadata=MetaData (manifold_api_session_auth)
-# DEPRECATED #        metadata.fetch()
-# DEPRECATED #        # store it for next time
-# DEPRECATED #        manifold['metadata']=metadata
-# DEPRECATED #        if debug: print "Page.get_metadata: return new value"
-# DEPRECATED #        return metadata
-
     # needs to be called explicitly and only when metadata is actually required
     # in particular user needs to be logged
     def get_metadata (self):
@@ -136,12 +113,13 @@ class Page:
         return metadata
             
     def expose_js_metadata (self):
-        # export in this js global...
-        self.add_js_chunks("var MANIFOLD_METADATA =" + self.get_metadata().to_json() + ";")
+        # expose global MANIFOLD_METADATA as a js variable
+        # xxx this is fetched synchroneously..
+        self.add_js_init_chunks("var MANIFOLD_METADATA =" + self.get_metadata().to_json() + ";")
 
     def expose_js_manifold_config (self):
         config=Config()
-        self.add_js_chunks(config.manifold_js_export())
+        self.add_js_init_chunks(config.manifold_js_export())
 
     #################### requirements/prelude management
     # just forward to self.prelude - see decorator above
@@ -150,6 +128,8 @@ class Page:
     @to_prelude
     def add_css_files (self):pass
     @to_prelude
+    def add_js_init_chunks (self):pass
+    @to_prelude
     def add_js_chunks (self):pass
     @to_prelude
     def add_css_chunks (self):pass
index 61af0e0..229f196 100644 (file)
@@ -163,10 +163,6 @@ class Plugin:
     def export_json_settings (self):
         return 'query_uuid' in self.json_settings_list()
     
-    # by default we create a timer if there's a query attached, redefine to change this behaviour
-    def start_with_spin (self):
-        return self.export_json_settings()
-
     # returns the html code for that plugin
     # in essence, wraps the results of self.render_content ()
     def render (self, request):
@@ -175,8 +171,6 @@ class Plugin:
         # shove this into plugin.html
         env = {}
         env ['plugin_content']= plugin_content
-        # need_spin is used in plugin.html
-        self.need_spin=self.start_with_spin()
         env.update(self.__dict__)
         # translate high-level 'toggled' into 4 different booleans
         self.need_toggle = False
@@ -201,7 +195,8 @@ class Plugin:
             env ['settings_json' ] = self.settings_json()
             # compute plugin-specific initialization
             js_init = render_to_string ( 'plugin-init.js', env )
-            self.add_js_chunks (js_init)
+            # make sure this happens first in js
+            self.add_js_init_chunks (js_init)
         
         # interpret the result of requirements ()
         self.handle_requirements (request)
@@ -258,6 +253,8 @@ class Plugin:
     @to_prelude
     def add_css_files (self):pass
     @to_prelude
+    def add_js_init_chunks (self):pass
+    @to_prelude
     def add_js_chunks (self):pass
     @to_prelude
     def add_css_chunks (self):pass
@@ -312,6 +309,3 @@ class Plugin:
     #
     # whether we export the json settings to js
     # def export_json_settings (self)
-    #
-    # whether we show an initial spinner
-    # def start_with_spin (self)
index 8c90a19..03e6def 100644 (file)
@@ -2,17 +2,29 @@ from types import StringTypes, ListType
 
 from django.template.loader import render_to_string
 
-debug=True
+debug=False
 
+# the need for js_init_chunks is because we need to have the plugins initialized
+# before the queries fly
+# and when writing a view it is not very easy to remember in which order
+# all the js initialization will end up, so we use these 2 categories 
+# as a simple way to enforce this dependency
+# far from perfect but good enough for now
 class Prelude:
 
-    """A class for collecting dependencies on js/css files or fragments"""
+    """A class for collecting dependencies on js/css stuff
+    files are expected from your 'static' area, typically 'css/foo.css' or 'js/foo.js'
+    fragments (chunks) is for raw code
+    you can specify a string or a list of strings
+    js_init_chunks get collated with js_chunks but come first
+    """
 
-    keys=[ 'js_files','css_files','js_chunks', 'css_chunks' ]
-    def __init__ (self, js_files=None, css_files=None, js_chunks=None, css_chunks=None):
+    keys=[ 'js_files', 'css_files', 'js_init_chunks', 'js_chunks', 'css_chunks' ]
+    def __init__ (self, js_files=None, css_files=None, js_init_chunks=None, js_chunks=None, css_chunks=None):
         # it's tempting to use sets but sets are not ordered..
         self.js_files  = Prelude._normalize(js_files)
         self.css_files = Prelude._normalize(css_files)
+        self.js_init_chunks = Prelude._normalize(js_init_chunks)
         self.js_chunks = Prelude._normalize(js_chunks)
         self.css_chunks= Prelude._normalize(css_chunks)
 
@@ -29,6 +41,8 @@ class Prelude:
     def add_css_files (self, x):
         for i in Prelude._normalize (x):
             if i not in self.css_files: self.css_files.append(i)
+    def add_js_init_chunks (self, x):
+        self.js_init_chunks += Prelude._normalize (x)
     def add_js_chunks (self, x):
         self.js_chunks += Prelude._normalize (x)
     def add_css_chunks (self, x):
@@ -36,7 +50,7 @@ class Prelude:
 
     def inspect_string (self,msg):
         result =  'Prelude.inspect %s (%s) with '%(msg,self)
-        result += ",".join( [ "%s->%s"%(k,len(getattr(self,k))) for k in ['js_files','js_chunks','css_files','css_chunks'] ] )
+        result += ",".join( [ "%s->%s"%(k,len(getattr(self,k))) for k in Prelude.keys ] )
         return result
     def inspect (self,msg):
         print self.inspect_string(msg)
@@ -69,11 +83,11 @@ class Prelude:
         env={}
         env['js_urls'] = [ Prelude.full_url (js_file) for js_file in self.js_files ]
         env['css_urls'] = [ Prelude.full_url (css_file) for css_file in self.css_files ]
-        env['js_chunks']= self.js_chunks
+        env['all_js_chunks']= self.js_init_chunks + self.js_chunks
         env['css_chunks']=self.css_chunks
         if debug:
-            print "prelude has %d js_files, %d css files, %d js chunks and %d css_chunks"%\
-                (len(self.js_files),len(self.css_files),len(self.js_chunks),len(self.css_chunks),)
+            print "prelude has %d js_files, %d css files, (%d+%d) js chunks and %d css_chunks"%\
+                (len(self.js_files),len(self.css_files),len(self.js_init_chunks),len(self.js_chunks),len(self.css_chunks),)
         # render this with prelude.html and put the result in header_prelude
         header_prelude = render_to_string ('prelude.html',env)
         return { 'header_prelude' : header_prelude }
index a6ab97f..a7c3e22 100644 (file)
@@ -1,9 +1,8 @@
 {% for json in queries_json %}manifold.insert_query({{ json|safe }});
 {% endfor %}
 $(document).ready(function () {
-var query_publish_dom_tuples = new Array();
-{% for d in query_publish_dom_tuples %}try {query_publish_dom_tuples.push({'query_uuid':"{{ d.query_uuid }}"{%if d.domid %},'domid':"{{ d.domid }}"{% endif %}}) } 
-catch(err){messages.debug ("Could not expose query {{ d.query_uuid }}")}
+var query_exec_tuples = [];
+{% for tuple in query_exec_tuples %} query_exec_tuples.push({'query_uuid':"{{ tuple.query_uuid }}"}); 
 {% endfor %}
-manifold.asynchroneous_exec(query_publish_dom_tuples);
+manifold.asynchroneous_exec(query_exec_tuples);
 })
index 354b560..0c022f6 100644 (file)
@@ -1,5 +1,5 @@
 {% if visible %}
-<div id='complete-{{ domid }}' class='{% if need_toggle %}plugin-toggle{% endif %}{% if need_spin %} need-spin{% endif %}{% if persistent_toggle %} persistent-toggle{% endif %}{% if outline_complete %} plugin-outline-complete{% endif %}'>
+<div id='complete-{{ domid }}' class='{% if need_toggle %}plugin-toggle{% endif %}{% if persistent_toggle %} persistent-toggle{% endif %}{% if outline_complete %} plugin-outline-complete{% endif %}'>
 {% if togglable %}
 <h4 id='show-{{ domid }}' class='plugin-show'{% if not display_show_button %} style='display:none;'{% endif %}>
 <span class="glyphicon glyphicon-chevron-right"></span>
index 898624e..4e2fc20 100644 (file)
@@ -2,5 +2,5 @@
 {% endfor %}
 {% for css_url in css_urls %} <link rel='stylesheet' type='text/css' href='{{ css_url|safe }}' /> 
 {% endfor %}
-<script type="text/javascript"> {% for js_chunk in js_chunks %} {{ js_chunk|safe }} {% endfor %} </script>
+<script type="text/javascript"> {% for js_chunk in all_js_chunks %} {{ js_chunk|safe }} {% endfor %} </script>
 <style type="text/css"> {% for css_chunk in css_chunks %} {{ css_chunk|safe }} {% endfor %} </style>