Merge branch 'master' of ssh://git.onelab.eu/git/myslice
authorAnthony Garcia <anthony.garcia@inria.fr>
Mon, 18 Nov 2013 08:23:34 +0000 (09:23 +0100)
committerAnthony Garcia <anthony.garcia@inria.fr>
Mon, 18 Nov 2013 08:23:34 +0000 (09:23 +0100)
22 files changed:
README
manifold/metadata.py
manifold/static/js/manifold.js
plugins/googlemap/static/js/googlemap.js
plugins/lists/static/js/simplelist.js
plugins/messages/__init__.py
plugins/querycode/__init__.py
plugins/querytable/static/js/querytable.js
plugins/queryupdater/__init__.py
plugins/tabs/__init__.py
portal/accountview.py
portal/registrationview.py
portal/static/css/onelab_marko.css
portal/static/js/common.functions.js
portal/templates/contact.html
ui/static/css/topmenu.css
unfold/page.py
unfold/plugin.py
unfold/prelude.py
unfold/templates/page-queries.js
unfold/templates/plugin.html
unfold/templates/prelude.html

diff --git a/README b/README
index 3a894cc..3c0f943 100644 (file)
--- a/README
+++ b/README
@@ -16,6 +16,7 @@ See the devel/ subdir for more devel-oriented doc.
 
 * edit myslice/config.py and enter the details of your manifold backend
 
+$ apt-get install python-django-south
 * init django
 $ ./manage.py syncdb
 $ ./manage.py migrate
@@ -43,7 +44,7 @@ $ make redo == make redo-static redo-templates
 
 
 * run a local server:
-$ manage.py runserver 0.0.0.0:8000
+$ ./manage.py runserver 0.0.0.0:8000
 -- or -- my advice:
 $ devel/server-loop.sh
 when you just need to hit ^C yourself when your static files need to be refreshed - see below
index 4fbbc06..90a09ea 100644 (file)
@@ -27,24 +27,29 @@ class MetaData:
             except:
                 print "metadata.work_offline: failed to decode %s"%offline_filename
         manifold_api = ManifoldAPI(self.auth)
-        fields = ['table', 'column.name', 'column.qualifier', 'column.type', 'column.is_array', 'column.description', 'column.default', 'key', 'capability']
+        fields = ['table', 'column.name', 'column.qualifier', 'column.type', 
+                  'column.is_array', 'column.description', 'column.default', 'key', 'capability']
         #fields = ['table', 'column.column',
         #          'column.description','column.header', 'column.title',
         #          'column.unit', 'column.info_type',
         #          'column.resource_type', 'column.value_type',
         #          'column.allowed_values', 'column.platforms.platform',
         #          'column.platforms.platform_url']
-        result = manifold_api.forward({
-            'action': 'get',
-            'object': 'local:object', # proposed to replace metadata:table
-            'fields':     fields 
-        })
+        request={ 'action': 'get',
+                  'object': 'local:object', # proposed to replace metadata:table
+                  'fields':  fields ,
+                  }
+        result = manifold_api.forward(request)
 
+        # xxx need a way to export error messages to the UI
         if result['code'] == 1: # warning
-            messages.warning(request, result['description'])
+            # messages.warning(request, result['description'])
+            print ("METADATA WARNING -",request,result['description'])
         elif result['code'] == 2:
-            messages.error(request, result['description'])
+            # messages.error(request, result['description'])
+            print ("METADATA ERROR -",request,result['description'])
             # XXX FAIL HERE XXX
+            return
 
         rows = result.ok_value()
 # API errors will be handled by the outer logic
index 11fad7d..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,23 +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
-
-        // in case the spin stuff was not loaded, let's make sure we proceed to the exit 
-        //try {
-        //    if (manifold.asynchroneous_debug) 
-        //   messages.debug("Turning on spin with " + jQuery(".need-spin").length + " matches for .need-spin");
-        //    jQuery('.need-spin').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
-        jQuery.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;
@@ -373,8 +366,8 @@ 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
-            jQuery.post(manifold.proxy_url, {'json':query_json}, 
-                       manifold.success_closure(query, publish_uuid, tuple.callback /*domid*/));
+            $.post(manifold.proxy_url, {'json':query_json}, 
+                  manifold.success_closure(query, publish_uuid, tuple.callback));
         })
     },
 
@@ -382,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));
     },
 
     /*!
@@ -431,7 +422,7 @@ var manifold = {
         /* Publish an update announce */
         var channel="/results/" + query.query_uuid + "/changed";
         if (manifold.publish_result_debug) messages.debug(".. publish_result OLD API (3) " + channel);
-        jQuery.publish(channel, [result, query]);
+        $.publish(channel, [result, query]);
 
        if (manifold.publish_result_debug) messages.debug(".. publish_result - END (4) q=" + query.__repr());
     },
@@ -451,7 +442,7 @@ var manifold = {
        if (manifold.publish_result_debug) messages.debug (">>>>> publish_result_rec " + query.object);
         if (manifold.query_expects_unique_result(query)) {
             /* Also publish subqueries */
-            jQuery.each(query.subqueries, function(object, subquery) {
+            $.each(query.subqueries, function(object, subquery) {
                 manifold.publish_result_rec(subquery, result[0][object]);
                 /* TODO remove object from result */
             });
@@ -693,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");
@@ -730,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");
 
@@ -767,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 39e80cc..8501c74 100644 (file)
@@ -146,7 +146,11 @@ googlemap_debug_detailed=false;
        // retrieve DOM checkbox and make sure it is checked/unchecked
         set_checkbox: function(record, checked) {
            var hrn=this.record_hrn (record);
-           if (! hrn) { messages.warning ("googlemap.set_checkbox: record has no hrn"); return; }
+           if (! hrn) { 
+               try {messages.warning ("googlemap.set_checkbox: record has no hrn -- hostname="+record.hostname); }
+               catch (err) {messages.warning ("googlemap.set_checkbox: record has no hrn"); }
+               return; 
+           }
            var checkbox_s = this.by_hrn [ hrn ];
            if (! checkbox_s ) { messages.warning ("googlemap.set_checkbox: could not spot checkbox for hrn "+hrn); return; }
            checkbox_s.checkbox.prop('checked',checked);
index ad6985c..a8f90b9 100644 (file)
     var debug=false;
     debug=true
 
-    $.fn.SimpleList = function( method ) {
-        /* Method calling logic */
-        if ( methods[method] ) {
-            return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ));
-        } else if ( typeof method === 'object' || ! method ) {
-            return methods.init.apply( this, arguments );
-        } else {
-            $.error( 'Method ' +  method + ' does not exist on jQuery.SimpleList' );
-        }    
-    };
+    var SimpleList = Plugin.extend ({
 
-    var methods = {
-       init : function( options ) {
-           return this.each(function(){
-               var $this = $(this), data = $this.data('SimpleList');
-               /* Subscribe to query updates */
-               var channel='/results/' + options.query_uuid + '/changed';
-               /* passing $this as 2nd arg: callbacks will retrieve $this as e.data */
-               $.subscribe(channel, $this, update_plugin);
-               if (debug) window.messages.debug('subscribing to ' + channel);
-               $this.data('SimpleList', options);
-           });
-       },
-       destroy : function( ) {
-           if (debug) messages.debug("SimpleList.destroy...");
-            return this.each(function(){
-               var $this = $(this), data = $this.data('SimpleList');
-               // xxx not too sure what this is about
-               $(window).unbind('SimpleList');
-               $this.removeData('SimpleList');
-            });
-       },
-       update : function( content ) { 
-           if (debug) messages.debug("SimpleList.update...");
-       },
-    }; // methods
+       init: function (options, element) {
+           this._super (options, element);
+           this.buffered_records=[];
+            this.listen_query(options.query_uuid);
+       }, 
 
-    /* Private methods */
-    // complexity here is mostly because a datatables-enabled table cannot
-    // be updated in a "normal" way using .html()
-    function update_plugin(e, rows) {
-        // e.data is what we passed in second argument to subscribe
-        // so here it is the jquery object attached to the plugin <div>
-        var $plugindiv = e.data;
-        var options = $plugindiv.data().SimpleList;
-       var classname=options.classname;
-        // locate the <table> element; with datatables in the way,
-        // this might not be a direct son of the div-plugin
-        var $table = $plugindiv.find("table."+classname).first();
-        // also we may or may not have a header
-        var $tbody = $table.find("tbody."+classname).first();
-        var use_datatables = $table.hasClass("with-datatables");
-        if (debug) 
-            messages.debug($plugindiv.attr('id') + " udt= " + use_datatables + " rows="+rows.length);
-       
-       // clear the spinning wheel: look up an ancestor that has the need-spin class
-       // do this before we might return
-           $plugindiv.closest('.need-spin').spin(false);
+        on_query_in_progress: function() {
+           messages.debug("on_query_in_progress");
+            this.spin();
+        },
 
-        if (rows.length == 0) {
-           if (use_datatables)
-                datatables_set_message ($table, $tbody, unfold.warning("No result"));
-           else
-               regular_set_message ($table, $tbody, unfold.warning("No result"));
-            return;
-        }
+        on_query_done: function() {
+           this._display_table();
+            this.unspin();
+        },
+        
+        on_new_record: function(record) {
+           this.buffered_records.push(record);
+        },
 
-        if (typeof rows[0].error != 'undefined') {
-           var error="ERROR: " + rows[0].error;
-           if (use_datatables) 
-                datatables_set_message ($table, $tbody, unfold.error(error));
-           else
-               regular_set_message ($table, $tbody, unfold.error(error));
-            return;
-        }
+    /* Private methods */
 
-       if (use_datatables)     
-            datatables_update_table($table, $tbody, rows, options.key);
-       else
-           regular_update_table($table, $tbody, rows, options.key, classname);
+       _display_table: function() {
+           var self=this;
+            var $plugindiv = this.elmt();
+            var options = this.options;
+           var classname=options.classname;
+            // locate the <table> element; with datatables in the way,
+            // this might not be a direct son of the div-plugin
+            var $table = $plugindiv.find("table."+classname).first();
+            // also we may or may not have a header
+            var $tbody = $table.find("tbody."+classname).first();
+            var use_datatables = $table.hasClass("with-datatables");
+           var rows=self.buffered_records;
+           self.buffered_records=[];
+            if (debug) 
+               messages.debug($plugindiv.attr('id') + " udt= " + use_datatables + " rows="+rows.length);
+       
+            if (rows.length == 0) {
+               if (use_datatables)
+                    this._datatables_set_message ($table, $tbody, unfold.warning("No result"));
+               else
+                   this._regular_set_message ($table, $tbody, unfold.warning("No result"));
+               return;
+            }
 
-    }
+            if (typeof rows[0].error != 'undefined') {
+               var error="ERROR: " + rows[0].error;
+               if (use_datatables) 
+                    this._datatables_set_message ($table, $tbody, unfold.error(error));
+               else
+                   this._regular_set_message ($table, $tbody, unfold.error(error));
+               return;
+            }
 
-    // hard-wire a separate presentation depending on the key being used....
-    function cell(key, value) {
-        if (key == 'slice.slice_hrn') {
-            return "<i class='icon-play-circle'></i><a href='/portal/slice/" + value + "'>" + value + "</a>";
-        } else if (key == 'platform') {
-            return "<i class='icon-play-circle'></i><a href='/portal/platform/" + value + "'>" + value + "</a>";
-        } else {
-            return value;
-        }
-    }
+           if (use_datatables) 
+               this._datatables_update_table($table, $tbody, rows, options.key);
+           else
+               this._regular_update_table($table, $tbody, rows, options.key, classname);
+       },
 
-    function regular_set_message ($table, $tbody, message) {
-       $tbody.html("<tr><td>"+message+"</td></tr>");
-    }
+       _regular_set_message: function ($table, $tbody, message) {
+           $tbody.html("<tr><td>"+message+"</td></tr>");
+       },
 
-    function regular_update_table ($table, $tbody, rows, key, classname) {
-        if (debug)
-            messages.debug('regular_update_table ' + rows.length + " rows" + " key=" + key + " classname=" + classname);
-       var html=$.map(rows, function (row) {
-            value = row;
-            $.each(key.split('.'), function(i, k) {
-                if ($.isArray(value)) {
-                    value = $.map(value, function(val, i) { return val[k]});
-                } else {
-                    value = value[k];
-                }
-            });
+       _regular_update_table: function ($table, $tbody, rows, key, classname) {
+            if (debug)
+               messages.debug('regular_update_table ' + rows.length + " rows" + " key=" + key + " classname=" + classname);
+           var self=this;
+           var html=$.map(rows, function (row) {
+               var value = row;
+               $.each(key.split('.'), function(i, k) {
+                    if ($.isArray(value)) {
+                       value = $.map(value, function(val, i) { return val[k]});
+                    } else {
+                       value = value[k];
+                    }
+               });
                if ($.isArray(value)) {
-                x = $.map(value, function(val, i) { 
-                   messages.debug("loop.loop val="+val+" i="+i);
-                   return html_row ( cell (key, val), classname); });
-                return x;
-            } else {
-                return html_row ( cell (key, value), classname);
-            }
-        }).join();
-       $tbody.html(html);
-    }
+                    return $.map(value, function(val, i) { 
+                       return self._html_row ( self._cell (key, val), classname); 
+                   });
+               } else {
+                    return self._html_row ( self._cell (key, value), classname);
+               }
+            }).join();
+           $tbody.html(html);
+       },
     
-    function datatables_set_message ($table, $tbody, message) {
-        $table.dataTable().fnClearTable();
-        $table.dataTable().fnAddData( [ message ] );
-        $table.dataTable().fnDraw();
-    }
+       _datatables_set_message: function ($table, $tbody, message) {
+            $table.dataTable().fnClearTable();
+            $table.dataTable().fnAddData( [ message ] );
+            $table.dataTable().fnDraw();
+       },
 
-    function datatables_update_table ($table, $tbody, rows, key) {
-       if (debug) messages.debug('datatables_update_table ' + rows.length + " rows");
-       $table.dataTable().fnClearTable();
-       // the lambda here returns a [[]] because $.map is kind of broken; as per the doc:
-       // The function can return any value to add to the array. A returned array will be flattened into the resulting array.
-       // this is wrong indeed so let's work around that
-       $table.dataTable().fnAddData( $.map(rows, function (row) { return [[ cell (key,row[key]) ]] }) );
-       $table.dataTable().fnDraw();
-    }  
+       _datatables_update_table: function ($table, $tbody, rows, key) {
+           if (debug) messages.debug('datatables_update_table ' + rows.length + " rows");
+           $table.dataTable().fnClearTable();
+           // the lambda here returns a [[]] because $.map is kind of broken; as per the doc:
+           // The function can return any value to add to the array. A returned array will be flattened into the resulting array.
+           // this is wrong indeed so let's work around that
+           var self=this;
+           $table.dataTable().fnAddData( $.map(rows, function (row) { return [[ self._cell (key,row[key]) ]] }) );
+           $table.dataTable().fnDraw();
+       },
     
-    function html_row (cell, classname) { 
-        return "<tr><td class='"+classname+"'>"+cell+"</td></tr>"; 
-    }
+       _html_row: function (cell, classname) { 
+            return "<tr><td class='"+classname+"'>"+cell+"</td></tr>"; 
+       },
     
+       // hard-wire a separate presentation depending on the key being used....
+       _cell: function (key, value) {
+            if (key == 'slice.slice_hrn') {
+               return "<i class='icon-play-circle'></i><a href='/portal/slice/" + value + "'>" + value + "</a>";
+            } else if (key == 'platform') {
+               return "<i class='icon-play-circle'></i><a href='/portal/platform/" + value + "'>" + value + "</a>";
+            } else {
+               return value;
+            }
+       },
+    });
+
+    $.plugin('SimpleList', SimpleList);
+
 })( jQuery );
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 30c727b..6a553bc 100644 (file)
         on_new_record: function(record)
         {
             if (this.received_all_query) {
-                       // if the 'all' query has been dealt with already we may turn on the checkbox
-                       if (debug) messages.debug("turning on checkbox for record "+record[this.key]);
+               // if the 'all' query has been dealt with already we may turn on the checkbox
+               if (debug) messages.debug("turning on checkbox for record "+record[this.key]);
                 this.set_checkbox(record, true);
-               } else {
-                       // otherwise we need to remember that and do it later on
-                       if (debug) messages.debug("Remembering record to check " + record[this.key]);
+            } else {
+               // otherwise we need to remember that and do it later on
+               if (debug) messages.debug("Remembering record to check " + record[this.key]);
                 this.buffered_records_to_check.push(record);
-               }
+            }
         },
 
         on_clear_records: function()
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 d4b68f4..f7fa1b8 100644 (file)
@@ -161,12 +161,20 @@ def account_process(request):
 #                        private_key = k.as_pem()
 #                        private_key = ''.join(private_key.split())
 #                        public_key = "ssh-rsa " + public_key
-                        keypair = '{"user_public_key":'+ public_key + ', "user_private_key":'+ private_key + '}'
+                        # now we overwrite the config field with keypair
+                        # once there will be user_hrn, we need to keep user_hrn and change only the keypair
+                        # see submit_name section for implementing this    
 #                       keypair = re.sub("\r", "", keypair)
 #                       keypair = re.sub("\n", "\\n", keypair)
 #                       #keypair = keypair.rstrip('\r\n')
 #                       keypair = ''.join(keypair.split())
                         # updating maniolf local:account table
+                        account_config = json.loads(account_detail['config'])
+                        # preserving user_hrn
+                        user_hrn = account_config.get('user_hrn','N/A')
+                        keypair = '{"user_public_key":'+ public_key + ', "user_private_key":'+ private_key + ', "user_hrn":"'+ user_hrn + '"}'
+                        updated_config = json.dumps(account_config) 
+
                         user_params = { 'config': keypair, 'auth_type':'managed'}
                         manifold_update_account(request,user_params)
                         messages.success(request, 'Sucess: New Keypair Generated!')
@@ -186,7 +194,10 @@ def account_process(request):
                         file_extension = os.path.splitext(file_name)[1] 
                         allowed_extension =  ['.pub','.txt']
                         if file_extension in allowed_extension and re.search(r'ssh-rsa',file_content):
-                            file_content = '{"user_public_key":"'+ file_content +'"}'
+                            account_config = json.loads(account_detail['config'])
+                            # preserving user_hrn
+                            user_hrn = account_config.get('user_hrn','N/A')
+                            file_content = '{"user_public_key":"'+ file_content + '", "user_hrn":"'+ user_hrn +'"}'
                             #file_content = re.sub("\r", "", file_content)
                             #file_content = re.sub("\n", "\\n",file_content)
                             file_content = ''.join(file_content.split())
index e27dfb4..85935f2 100644 (file)
@@ -63,7 +63,11 @@ class RegistrationView (FreeAccessView):
             reg_auth   = request.POST.get('authority_hrn', '')
             reg_login  = request.POST.get('login', '')
             reg_email  = request.POST.get('email','').lower()
-      
+            #prepare user_hrn 
+            split_email = reg_email.split("@")[0] 
+            split_email = split_email.replace(".", "_")
+            user_hrn = reg_auth + '.' + split_email
+
             #POST value validation  
             if (re.search(r'^[\w+\s.@+-]+$', reg_fname)==None):
                 errors.append('First Name may contain only letters, numbers, spaces and @/./+/-/_ characters.')
@@ -89,7 +93,7 @@ class RegistrationView (FreeAccessView):
 #                private_key = ''.join(private_key.split())
 #                public_key = "ssh-rsa " + public_key
                 # Saving to DB
-                keypair = '{"user_public_key":'+ public_key + ', "user_private_key":'+ private_key + '}'
+                keypair = '{"user_public_key":'+ public_key + ', "user_private_key":'+ private_key + ', "user_hrn":"'+ user_hrn + '"}'
                 #keypair = re.sub("\r", "", keypair)
                 #keypair = re.sub("\n", "\\n", keypair)
                 #keypair = keypair.rstrip('\r\n')
@@ -101,7 +105,7 @@ class RegistrationView (FreeAccessView):
                 file_extension = os.path.splitext(file_name)[1]
                 allowed_extension =  ['.pub','.txt']
                 if file_extension in allowed_extension and re.search(r'ssh-rsa',file_content):
-                    keypair = '{"user_public_key":"'+ file_content +'"}'
+                    keypair = '{"user_public_key":"'+ file_content + '", "user_hrn":"'+ user_hrn +'"}'
                     keypair = re.sub("\r", "", keypair)
                     keypair = re.sub("\n", "\\n",keypair)
                     keypair = ''.join(keypair.split())
@@ -131,11 +135,11 @@ class RegistrationView (FreeAccessView):
                     'first_name'    : reg_fname, 
                     'last_name'     : reg_lname, 
                     'authority_hrn' : reg_auth,
-                    'email'         : reg_email, 
+                    'email'         : reg_email,
+                    'user_hrn'      : user_hrn,
                     'keypair'       : 'Public Key :' + public_key,
                     'cc_myself'     : True # form.cleaned_data['cc_myself']
                     }
-
                 recipients = authority_get_pi_emails(request,reg_auth)
 
                 if ctx['cc_myself']:
index a7b256c..2d4f71c 100644 (file)
@@ -165,7 +165,10 @@ h2.well.well-lg {
 
 
 
-
+/* if window enlarged wider than background picture */
+body {
+    background: black !important;
+}
 
 /* TOPMENU.CSS */
 
index 56b02ca..d6f3f99 100644 (file)
@@ -1,6 +1,3 @@
-/*
- * This file is included in tophat_render.php
- */
 // Escape special characters in jQuery Selector
 function escape_id( myid ) {
     return "#" + myid.replace( /(:|\.|\[|\])/g, "\\$1" );
index b256d37..ab00b15 100644 (file)
@@ -9,7 +9,7 @@
 <link rel="stylesheet" type="text/css" href="{{STATIC_URL}}/css/onelab.css" />
 <div class="onelab-title well-lg">
   <h2>Onelab Support</h2>
-  <h4>If you have already registered, then please <a href="mailto:support@myslice.info">send an e-mail</a>
+  <h4>If you have already registered, then please send an <a href="mailto:support@myslice.info">e-mail</a>
   or <a href="http://trac.myslice.info/" >visit us</a></h4>
 </div>
 
index 792377b..70acc0e 100644 (file)
@@ -1,13 +1,12 @@
 /* this is to get the content below the navbar */
 body {
     padding-top: 60px;
-    padding-bottom: 20px;
 }
 
 /* center the buttons vertically in the header */
 div.topmenu { padding-top: 7px; }
 ul.logged-in { 
-    padding-top: 12px; 
+    padding-top: 14px; 
 }
 button.logged-in { 
     font-size: small; 
index 7c6d60b..7f071c0 100644 (file)
@@ -33,10 +33,7 @@ class Page:
         # queue of queries with maybe a domid, see enqueue_query
         self._queue=[]
         # global prelude object
-        self.prelude=Prelude(css_files='css/plugin.css')
-        print "Loading... CSS OneLab"
-        self.prelude=Prelude(css_files='css/onelab_marko.css')
-#        self.prelude=Prelude(css_files=['css/plugin.css','css/onelab_marko.css',])
+        self.prelude=Prelude(css_files=['css/plugin.css','css/onelab_marko.css',])
 
     # record known plugins hashed on their domid
     def record_plugin (self, plugin):
@@ -83,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()
@@ -91,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):
@@ -139,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
@@ -153,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>