allow self signed certificates
authorCiro Scognamiglio <ciro.scognamiglio@cslash.net>
Tue, 10 Mar 2015 16:36:07 +0000 (17:36 +0100)
committerCiro Scognamiglio <ciro.scognamiglio@cslash.net>
Tue, 10 Mar 2015 16:36:07 +0000 (17:36 +0100)
64 files changed:
Makefile
README
devel/server-loop.sh
manifoldapi/static/js/manifold.js
myslice/configengine.py
myslice/myslice.ini.onelab [new file with mode: 0644]
myslice/settings.py
myslice/urls.py
plugins/scheduler2/static/js/scheduler2.js
portal/accountview.py
portal/actions.py
portal/joinview.py
portal/projectrequestview.py
portal/registrationview.py
portal/slicetabexperiment.py
portal/static/css/smartfire.css
portal/static/icons/iotlab.png [moved from portal/static/icons/IoTLab.png with 100% similarity]
portal/static/icons/mobile.png [moved from portal/static/icons/Mobile.png with 100% similarity]
portal/static/icons/planetlab.png [moved from portal/static/icons/PlanetLab.png with 100% similarity]
portal/static/icons/wireless.png [moved from portal/static/icons/Wireless.png with 100% similarity]
portal/static/img/bg-smartfire.png [new file with mode: 0644]
portal/templates/_widget-topmenu.html
portal/templates/account-view.html
portal/templates/base.html
portal/templates/fed4fire/fed4fire_slice-tab-experiment.html [deleted file]
portal/templates/home-view.html
portal/templates/onelab/onelab_account-view.html
portal/templates/project-request-ack-view.html [new file with mode: 0644]
portal/templates/project-request-done-view.html [new file with mode: 0644]
portal/templates/registration_view.html
portal/templates/slice-resource-view.html
portal/templates/slice-tab-experiment.html
portal/templates/smartfire/smartfire_account-view.html
portal/templates/smartfire/smartfire_activate_user.html [new file with mode: 0644]
portal/templates/smartfire/smartfire_activate_user.txt [new file with mode: 0644]
portal/templates/smartfire/smartfire_authority_request_denied.html [new file with mode: 0644]
portal/templates/smartfire/smartfire_authority_request_denied.txt [new file with mode: 0644]
portal/templates/smartfire/smartfire_authority_request_email.html [new file with mode: 0644]
portal/templates/smartfire/smartfire_authority_request_email.txt [new file with mode: 0644]
portal/templates/smartfire/smartfire_authority_request_email_subject.txt [new file with mode: 0644]
portal/templates/smartfire/smartfire_contact_support_email.html [new file with mode: 0644]
portal/templates/smartfire/smartfire_contact_support_email.txt [new file with mode: 0644]
portal/templates/smartfire/smartfire_contact_support_email_subject.txt [new file with mode: 0644]
portal/templates/smartfire/smartfire_email_activation.html [new file with mode: 0644]
portal/templates/smartfire/smartfire_email_default_recipients.txt [new file with mode: 0644]
portal/templates/smartfire/smartfire_email_default_sender.txt [new file with mode: 0644]
portal/templates/smartfire/smartfire_home-view.html
portal/templates/smartfire/smartfire_slice_request_denied.html [new file with mode: 0644]
portal/templates/smartfire/smartfire_slice_request_denied.txt [new file with mode: 0644]
portal/templates/smartfire/smartfire_slice_request_email_subject.txt [new file with mode: 0644]
portal/templates/smartfire/smartfire_slice_request_validated.html [new file with mode: 0644]
portal/templates/smartfire/smartfire_slice_request_validated.txt [new file with mode: 0644]
portal/templates/smartfire/smartfire_user_request_denied.html [new file with mode: 0644]
portal/templates/smartfire/smartfire_user_request_denied.txt [new file with mode: 0644]
portal/templates/smartfire/smartfire_user_request_email.html [new file with mode: 0644]
portal/templates/smartfire/smartfire_user_request_email.txt [new file with mode: 0644]
portal/templates/smartfire/smartfire_user_request_email_subject.txt [new file with mode: 0644]
portal/templates/smartfire/smartfire_user_request_validated.html [new file with mode: 0644]
portal/templates/smartfire/smartfire_user_request_validated.txt [new file with mode: 0644]
portal/templates/smartfire/smartfire_widget-login-user.html
portal/templates/smartfire/smartfire_widget-topmenu.html
portal/templates/user_register_email.txt [deleted file]
portal/templates/user_register_email_subject.txt [deleted file]
sla/urls.py

index 69725db..80d49c4 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -110,8 +110,9 @@ ftags: force
 
 #################### sync : push current code on a box running myslice
 # this for now targets deployments based on the debian packaging
-SSHURL:=root@$(MYSLICEBOX):/
-SSHCOMMAND:=ssh root@$(MYSLICEBOX)
+SSHUSER    ?= root
+SSHURL     := $(SSHUSER)@$(MYSLICEBOX):
+SSHCOMMAND := ssh $(SSHUSER)@$(MYSLICEBOX)
 
 ### rsync options
 # the config file should probably not be overridden ??
@@ -163,3 +164,14 @@ ifeq (,$(MYSLICEBOX))
 else
        +$(SSHCOMMAND) apachectl restart
 endif
+
+#SSHUSER=tparment
+#MYSLICEBOX=srv-diana.inria.fr
+sync-devel:
+ifeq (,$(MYSLICEBOX))
+       @echo "you need to set MYSLICEBOX, like in e.g."
+       @echo "  $(MAKE) MYSLICEBOX=srv-diana.inria.fr "$@""
+       @exit 1
+else
+       +$(RSYNC) --relative $$(git ls-files) $(SSHURL)myslice/
+endif
diff --git a/README b/README
index eae4973..4e4e195 100644 (file)
--- a/README
+++ b/README
@@ -1,48 +1,66 @@
 This file documents the contents of this module
 change
-Last update 4 FEB. 2015
+Last update 20 FEB. 2015
 
-See the devel/ subdir for more devel-oriented doc.
+Installation
+=================================================================
+Recommended OS
+===============
+Debian GNU/Linux 7.5 (wheezy) x64
 
-==================== 1 minute howto
+PYTHON DEPENDENCIES
+=====================
+sudo apt-get install python-pip or sudo easy_install pip==1.4.1
+sudo apt-get install python-dev (for paramiko and pyOpenSSL)
+sudo apt-get install libffi-dev (for pyOpenSSL)
 
-*  REQUIREMENTS  is to have python + django (1.5.2) installed django
-** should be straightforward
-** see devel/django-install.txt in case of trouble
-$ apt-get install python-pip or sudo easy_install pip==1.4.1
-$ pip install django=="1.5.2
+$ pip install django=="1.5.2"
 $ apt-get install python-django-south
 $ pip install requests
 $ pip install djangorestframework
 $ pip install django-celery
 $ pip install geopy
 $ pip install paramiko
+$ pip install pyparsing
+$ pip install python-dateutil
+$ pip instal pyOpenSSL
 
-* git clone git://git.onelab.eu/myslice.git
--- or --
-* git clone ssh://yourlogin@git.onelab.eu/git/myslice.git
+MYSLICE
+=======
+git clone ssh://yourlogin@git.onelab.eu/git/myslice.git
+cd myslice
+git checkout onelab
 
-* edit/create myslice/myslice.ini and enter the details of your manifold backend
+edit/create myslice/myslice.ini and enter the details of your manifold backend
+
+mkdir /var/unfold
+copy unfold.sqlite3 to /var/unfold
 
-$ apt-get install python-django-south
-* init django
-** when django prompts for creating an admin account, create it and 
-** keep the username and password safe
 $ ./manage.py syncdb
 $ ./manage.py migrate
 
-* gather static files
-$ ./manage.py collectstatic 
--- or --
-$ ./manage.py collectstatic --noinput
--- or --
-$ make static (which is a shorthand for cleaning up and run manage collectstatic --noinput)
+use the unfold.sqlite3 i gave to u
+
+$ make redo
+$ ./devel/server-loop.sh
+
+MANIFOLD
+==========
+git clone git://git.onelab.eu/manifold.git
+cd manifold
+git checkout devel
+make && make install
+
+SFA
+===
+$ git clone -b geni-v3 git://git.onelab.eu/sfa.git
+$ cd sfa 
+$ git checkout geni-v3
 
-* gather templates files 
-  for now we still seem to rely on a make-based templates-collection process
-  that creates templates/ 
-$ make templates [$ make redo (each time when you pull, do that and restart the server)]
+$ make version
+$ python ./setup.py install
 
+=====================================================================
 
 ## Whenever doing a git pull the following operations are recommended:
 
index c77258f..78e1da1 100755 (executable)
@@ -2,9 +2,8 @@
 DIRNAME=$(dirname $0)
 cd $DIRNAME/..
 
-# default port : if hostname starts with z -> use 8080 ; otherwise take 80
-#hostname | grep -q '^z' && port=8080 || port=8080
-hostname | grep -q '^z' && port=8080 || port=80
+# default port : if hostname starts with z or with srv- -> use 8000 ; otherwise take 80
+hostname | egrep -q '^(z|srv-)' && port=8000 || port=80
 [[ -n "$@" ]] && port=$1
 
 while true; do 
index c880831..517ab69 100644 (file)
@@ -737,6 +737,12 @@ var manifold = {
                 } else {
                     console.log('Unknown field');
                 }
+            // FIX if the record contains a string instead of a key:value 
+            // example: select resource, slice_hrn from slice where slice_hrn=='xxx'
+            // Result will be {slice_hrn:'xxx', resource:'urn+zzz'}
+            // We don't have this resource:{urn:'urn+zzz'}
+            } else if(typeof(record) === 'string'){
+                return record;
             } else {
                 return record[fields];
             }
@@ -979,7 +985,8 @@ var manifold = {
             Loop per platform, allows a progressive loading per AM platform
             Update is run on all platforms at the same time to get a final answer, we don't manage partial answers yet...
         */
-        if((query.object == 'resource' || query.object == 'lease' || query.object == 'slice') && query.action != "update"){
+        // Removed slice from the per platform query - it's quick enough...
+        if((query.object == 'resource' || query.object == 'lease') && query.action != "update"){
             var obj = query.object;
             $.post("/rest/platform/", function( data ) {
                 $.each(data, function(index, p) {
index 3d92bb1..4b40cb2 100644 (file)
@@ -36,7 +36,7 @@ class ConfigEngine(object):
     default_myslice_theme           = 'onelab'
 
     #iotlab dev url
-    default_iotlab_url = "https://devgrenoble.senslab.info/rest/admin/users"
+    default_iotlab_url = "https://devwww.iot-lab.info/rest/admin/users"
     default_iotlab_admin_user = "xxx"
     default_iotlab_admin_password= "yyy"
 
diff --git a/myslice/myslice.ini.onelab b/myslice/myslice.ini.onelab
new file mode 100644 (file)
index 0000000..7cfe494
--- /dev/null
@@ -0,0 +1,2 @@
+[manifold]
+url = https://portal.onelab.eu:7080/
index bd1474b..10b3953 100644 (file)
@@ -1,5 +1,7 @@
 # Django settings for unfold project.
 
+from __future__ import print_function
+
 import os.path
 
 import djcelery
@@ -13,7 +15,9 @@ except:
     building=True
 
 DEBUG = True
-TEMPLATE_DEBUG = DEBUG
+
+# show the various settings as we go
+DEBUG_SETTINGS = False
 
 # compute ROOT from where this file is installed
 # should fit every need including developers
@@ -48,6 +52,10 @@ except:
 HTTPROOT="/var/myslice-f4f"
 # the place to store local data, like e.g. the sqlite db
 DATAROOT="/var/unfold"
+if not os.path.isdir(DATAROOT):
+    print("WARNING: {} is a non-existing directory".format(DATAROOT))
+    print("consequently we assume development mode and re-route DATAROOT to {}".format(ROOT))
+    DATAROOT=ROOT
 # if not there, then we assume it's from a devel tree
 if not os.path.isdir (os.path.join(HTTPROOT,"static")):
     HTTPROOT=ROOT
@@ -55,6 +63,11 @@ if not os.path.isdir (os.path.join(HTTPROOT,"static")):
 if not os.path.isdir(ROOT): raise Exception,"Cannot find ROOT %s for unfold"%ROOT
 if not os.path.isdir(HTTPROOT): raise Exception,"Cannot find HTTPROOT %s for unfold"%HTTPROOT
 
+if DEBUG_SETTINGS:
+    print('ROOT', ROOT)
+    print('DATAROOT', DATAROOT)
+    print('HTTPROOT', HTTPROOT)
+
 # dec 2013 - we currently have 2 auxiliary subdirs with various utilities
 # that we do not wish to package 
 # * sandbox is for plugin developers
@@ -101,6 +114,9 @@ DATABASES = {
     }
 }
 
+if DEBUG_SETTINGS:
+    print('DATABASE NAME',DATABASES['default']['NAME'])
+
 # Local time zone for this installation. Choices can be found here:
 # http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
 # although not all choices may be available on all operating systems.
@@ -252,7 +268,7 @@ BROKER_URL = "amqp://myslice:myslice@localhost:5672/myslice"
 
 for aux in auxiliaries:
     if os.path.isdir(os.path.join(ROOT,aux)): 
-        print "Using devel auxiliary",aux
+        print("Using devel auxiliary",aux)
         INSTALLED_APPS.append(aux)
 
 ACCOUNT_ACTIVATION_DAYS = 7 # One-week activation window; you may, of course, use a different value.
index da697cf..ca150a4 100644 (file)
@@ -132,7 +132,7 @@ urls = [
     url(r'^portal/', include('portal.urls')),
 
     # SLA
-    url(r'^sla/', include('sla.urls')),
+#    url(r'^sla/', include('sla.urls')),
 ]
 
 #this one would not match the convention
index 6b55b92..a72341e 100755 (executable)
-/*\r
-#\r
-# Copyright (c) 2013 NITLab, University of Thessaly, CERTH, Greece\r
-#\r
-# Permission is hereby granted, free of charge, to any person obtaining a copy\r
-# of this software and associated documentation files (the "Software"), to deal\r
-# in the Software without restriction, including without limitation the rights\r
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
-# copies of the Software, and to permit persons to whom the Software is\r
-# furnished to do so, subject to the following conditions:\r
-#\r
-# The above copyright notice and this permission notice shall be included in\r
-# all copies or substantial portions of the Software.\r
-#\r
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE\r
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r
-# THE SOFTWARE.\r
-#\r
-#\r
-# This is a MySlice plugin for the NITOS Scheduler\r
-# Nitos Scheduler v1\r
-#\r
-*/\r
-\r
-// XXX groupid = all slots those that go with a min granularity\r
-\r
-/* some params */\r
-var scheduler2;\r
-var scheduler2Instance;\r
-//is ctrl keyboard button pressed\r
-var schedulerCtrlPressed = false;\r
-//table Id\r
-var schedulerTblId = "scheduler-reservation-table";\r
-var SCHEDULER_FIRST_COLWIDTH = 200;\r
-\r
-\r
-/* Number of scheduler slots per hour. Used to define granularity. Should be inferred from resources XXX */\r
-var schedulerSlotsPerHour = 6;\r
-var RESOURCE_DEFAULT_GRANULARITY    = 1800 /* s */; // should be computed automatically from resource information\r
-var DEFAULT_GRANULARITY             = 1800 /* s */; // should be computed automatically from resource information. Test with 600\r
-var DEFAULT_PAGE_RANGE = 5;\r
-\r
-var schedulerMaxRows = 12;\r
-\r
-/* All resources */\r
-var SchedulerData = [];\r
-\r
-/* ??? */\r
-var SchedulerSlots = [];\r
-\r
-var SchedulerDateSelected = new Date();\r
-// Round to midnight\r
-SchedulerDateSelected.setHours(0,0,0,0);\r
-\r
-/* Filtered resources */\r
-var SchedulerDataViewData = [];\r
-\r
-var SchedulerSlotsViewData = [];\r
-//Help Variables\r
-var _schedulerCurrentCellPosition = 0;\r
-//Enable Debug\r
-var schedulerDebug = true;\r
-//tmp to delete\r
-var tmpSchedulerLeases = [];\r
-\r
-var SCHEDULER_COLWIDTH = 50;\r
-\r
-\r
-/******************************************************************************\r
- *                             ANGULAR CONTROLLER                             *\r
- ******************************************************************************/\r
-\r
-// Create a private execution space for our controller. When\r
-// executing this function expression, we're going to pass in\r
-// the Angular reference and our application module.\r
-(function (ng, app) {\r
-\r
-    // Define our Controller constructor.\r
-    function Controller($scope) {\r
-\r
-        // Store the scope so we can reference it in our\r
-        // class methods\r
-        this.scope = $scope;\r
-\r
-        // Set up the default scope value.\r
-        this.scope.errorMessage = null;\r
-        this.scope.name = "";\r
-\r
-        //Pagin\r
-        $scope.current_page = 1;\r
-        this.scope.items_per_page = 10;\r
-        $scope.from = 0; // JORDAN\r
-\r
-        $scope.instance = null;\r
-        $scope.resources = new Array();\r
-        $scope.slots = SchedulerSlotsViewData;\r
-        $scope.granularity = DEFAULT_GRANULARITY; /* Will be setup */\r
-        //$scope.msg = "hello";\r
-\r
-        angular.element(document).ready(function() {\r
-            //console.log('Hello World');\r
-            //alert('Hello World');\r
-            //afterAngularRendered();\r
-        });\r
-\r
-        // Pagination\r
-\r
-        $scope.range = function() {\r
-            var range_size = $scope.page_count() > DEFAULT_PAGE_RANGE ? DEFAULT_PAGE_RANGE : $scope.page_count();\r
-            var ret = [];\r
-            var start;\r
-\r
-            start = $scope.current_page;\r
-            if ( start > $scope.page_count()-range_size ) {\r
-              start = $scope.page_count()-range_size+1;\r
-            }\r
-\r
-            for (var i=start; i<start+range_size; i++) {\r
-              ret.push(i);\r
-            }\r
-            return ret;\r
-        };\r
-\r
-        $scope.prevPage = function() {\r
-          if ($scope.current_page > 1) {\r
-            $scope.current_page--;\r
-          }\r
-        };\r
-\r
-        $scope.prevPageDisabled = function() {\r
-          return $scope.current_page === 1 ? "disabled" : "";\r
-        };\r
-  \r
-        $scope.page_count = function()\r
-        {\r
-            // XXX need visible resources only\r
-            var query_ext, visible_resources_length;\r
-            if (!$scope.instance)\r
-                return 0;\r
-            query_ext = manifold.query_store.find_analyzed_query_ext($scope.instance.options.query_uuid);\r
-            var visible_resources_length = 0;\r
-            query_ext.state.each(function(i, state) {\r
-                if (state[STATE_VISIBLE])\r
-                    visible_resources_length++;\r
-            });\r
-            return Math.ceil(visible_resources_length/$scope.items_per_page);\r
-        };\r
-  \r
-        $scope.nextPage = function() {\r
-          if ($scope.current_page < $scope.page_count()) {\r
-            $scope.current_page++;\r
-          }\r
-        };\r
-  \r
-        $scope.nextPageDisabled = function() {\r
-          return $scope.current_page === $scope.page_count() ? "disabled" : "";\r
-        }; \r
-\r
-        $scope.setPage = function(n) {\r
-            $scope.current_page = n;\r
-        };\r
-        // END pagination\r
-\r
-        // FILTER\r
-\r
-        $scope.filter_visible = function(resource)\r
-        {\r
-            return manifold.query_store.get_record_state($scope.instance.options.query_uuid, resource['urn'], STATE_VISIBLE);\r
-        };\r
-\r
-        // SELECTION\r
-\r
-        $scope._create_new_lease = function(resource_urn, start_time, end_time)\r
-        {\r
-            var lease_key, new_lease, data;\r
-\r
-            lease_key = manifold.metadata.get_key('lease');\r
-\r
-            new_lease = {\r
-                resource:   resource_urn,\r
-                start_time: start_time,\r
-                end_time:   end_time,\r
-            };\r
-\r
-            // This is needed to create a hashable object\r
-            new_lease.hashCode = manifold.record_hashcode(lease_key.sort());\r
-            new_lease.equals   = manifold.record_equals(lease_key);\r
-\r
-            data = {\r
-                state: STATE_SET,\r
-                key  : null,\r
-                op   : STATE_SET_ADD,\r
-                value: new_lease\r
-            }\r
-            manifold.raise_event($scope.instance.options.query_lease_uuid, FIELD_STATE_CHANGED, data);\r
-            /* Add to local cache also, unless we listen to events from outside */\r
-            if (!(resource_urn in $scope._leases_by_resource))\r
-                $scope._leases_by_resource[resource_urn] = [];\r
-            $scope._leases_by_resource[resource_urn].push(new_lease);\r
-        }\r
-\r
-        $scope._remove_lease = function(other)\r
-        {\r
-            var lease_key, other_key, data;\r
-\r
-            lease_key = manifold.metadata.get_key('lease');\r
-\r
-            // XXX This could be a manifold.record_get_value\r
-            other_key = {\r
-                resource:   other.resource,\r
-                start_time: other.start_time,\r
-                end_time:   other.end_time\r
-            }\r
-            other_key.hashCode = manifold.record_hashcode(lease_key.sort());\r
-            other_key.equals   = manifold.record_equals(lease_key);\r
-\r
-            data = {\r
-                state: STATE_SET,\r
-                key  : null,\r
-                op   : STATE_SET_REMOVE,\r
-                value: other_key\r
-            }\r
-            manifold.raise_event($scope.instance.options.query_lease_uuid, FIELD_STATE_CHANGED, data);\r
-            /* Remove from local cache also, unless we listen to events from outside */\r
-            $scope._leases_by_resource[other.resource] = $.grep($scope._leases_by_resource[other.resource], function(x) { return x != other; });\r
-\r
-        }\r
-\r
-        $scope.select = function(index, model_lease, model_resource)\r
-        {\r
-            var data, resource_granularity;\r
-\r
-            //resource_granularity = model_resource.granularity === undefined ? RESOURCE_DEFAULT_GRANULARITY : model_resource.granularity;\r
-\r
-            console.log("Selected", index, model_lease, model_resource);\r
-\r
-            var day_timestamp = SchedulerDateSelected.getTime() / 1000;\r
-            var start_time = day_timestamp + index       * model_resource.granularity; // XXX resource_granularity\r
-            var end_time   = day_timestamp + (index + 1) * model_resource.granularity; //\r
-            var start_date = new Date(start_time * 1000);\r
-            var end_date   = new Date(end_time   * 1000);\r
-\r
-            var lease_key = manifold.metadata.get_key('lease');\r
-\r
-            // We search for leases in the cache we previously constructed\r
-            var resource_leases = $scope._leases_by_resource[model_resource.urn];\r
-\r
-            switch (model_lease.status)\r
-            {\r
-                case 'free': // out\r
-                case 'pendingout':\r
-                    if (resource_leases) {\r
-                        /* Search for leases before */\r
-                        $.each(resource_leases, function(i, other) {\r
-                            if (other.end_time != start_time)\r
-                                return true; // ~ continue\r
-        \r
-                            /* The lease 'other' is just before, and there should not exist\r
-                             * any other lease before it */\r
-                            start_time = other.start_time;\r
-        \r
-                            other_key = {\r
-                                resource:   other.resource,\r
-                                start_time: other.start_time,\r
-                                end_time:   other.end_time\r
-                            }\r
-                            // This is needed to create a hashable object\r
-                            other_key.hashCode = manifold.record_hashcode(lease_key.sort());\r
-                            other_key.equals   = manifold.record_equals(lease_key);\r
-        \r
-                            data = {\r
-                                state: STATE_SET,\r
-                                key  : null,\r
-                                op   : STATE_SET_REMOVE,\r
-                                value: other_key\r
-                            }\r
-                            manifold.raise_event($scope.instance.options.query_lease_uuid, FIELD_STATE_CHANGED, data);\r
-                            /* Remove from local cache also, unless we listen to events from outside */\r
-                            $scope._leases_by_resource[model_resource.urn] = $.grep($scope._leases_by_resource[model_resource.urn], function(x) { return x != other; });\r
-                            return false; // ~ break\r
-                        });\r
-        \r
-                        /* Search for leases after */\r
-                        $.each(resource_leases, function(i, other) {\r
-                            if (other.start_time != end_time)\r
-                                return true; // ~ continue\r
-        \r
-                            /* The lease 'other' is just after, and there should not exist\r
-                             * any other lease after it */\r
-                            end_time = other.end_time;\r
-                            other_key = {\r
-                                resource:   other.resource,\r
-                                start_time: other.start_time,\r
-                                end_time:   other.end_time\r
-                            }\r
-                            // This is needed to create a hashable object\r
-                            other_key.hashCode = manifold.record_hashcode(lease_key.sort());\r
-                            other_key.equals   = manifold.record_equals(lease_key);\r
-        \r
-                            data = {\r
-                                state: STATE_SET,\r
-                                key  : null,\r
-                                op   : STATE_SET_REMOVE,\r
-                                value: other_key\r
-                            }\r
-                            manifold.raise_event($scope.instance.options.query_lease_uuid, FIELD_STATE_CHANGED, data);\r
-                            /* Remove from local cache also, unless we listen to events from outside */\r
-                            $scope._leases_by_resource[model_resource.urn] = $.grep($scope._leases_by_resource[model_resource.urn], function(x) { return x != other; });\r
-                            return false; // ~ break\r
-                        });\r
-                    }\r
-        \r
-                    $scope._create_new_lease(model_resource.urn, start_time, end_time);\r
-                    model_lease.status = (model_lease.status == 'free') ? 'pendingin' : 'selected';\r
-                    // unless the exact same lease already existed (pending_out status for the lease, not the cell !!)\r
-\r
-                    break;\r
-\r
-                case 'selected':\r
-                case 'pendingin':\r
-                    // We remove the cell\r
-\r
-                    /* We search for leases including this cell. Either 0, 1 or 2.\r
-                     * 0 : NOT POSSIBLE, should be checked.\r
-                     * 1 : either IN or OUT, we have make no change in the session\r
-                     * 2 : both will be pending, since we have made a change in the session\r
-                    * /!\ need to properly remove pending_in leases when removed again\r
-                     */\r
-                    if (resource_leases) {\r
-                        $.each(resource_leases, function(i, other) {\r
-                            if ((other.start_time <= start_time) && (other.end_time >= end_time)) {\r
-                                // The cell is part of this lease.\r
-\r
-                                // If the cell is not at the beginning of the lease, we recreate a lease with cells before\r
-                                if (start_time > other.start_time) {\r
-                                    $scope._create_new_lease(model_resource.urn, other.start_time, start_time);\r
-                                }\r
-\r
-                                // If the cell is not at the end of the lease, we recreate a lease with cells after\r
-                                if (end_time < other.end_time) {\r
-                                    $scope._create_new_lease(model_resource.urn, end_time, other.end_time);\r
-                                }\r
-                                \r
-                                // The other lease will be removed\r
-                                $scope._remove_lease(other);\r
-                            }\r
-                            // NOTE: We can interrupt the search if we know that there is a single lease (depending on the status).\r
-                        });\r
-                    }\r
-                \r
-                    // cf comment in previous switch case\r
-                    model_lease.status = (model_lease.status == 'selected') ? 'pendingout' : 'free';\r
-\r
-                    break;\r
-\r
-                case 'reserved':\r
-                case 'maintainance':\r
-                    // Do nothing\r
-                    break;\r
-            }\r
-            \r
-\r
-            $scope._dump_leases();\r
-        };\r
-  \r
-        $scope._dump_leases = function()\r
-        {\r
-            // DEBUG: display all leases and their status in the log\r
-            var leases = manifold.query_store.get_records($scope.instance.options.query_lease_uuid);\r
-            console.log("--------------------");\r
-            $.each(leases, function(i, lease) {\r
-                var key = manifold.metadata.get_key('lease');\r
-                var lease_key = manifold.record_get_value(lease, key);\r
-                var state = manifold.query_store.get_record_state($scope.instance.options.query_lease_uuid, lease_key, STATE_SET);\r
-                var state_str;\r
-                switch(state) {\r
-                    case STATE_SET_IN:\r
-                        state_str = 'STATE_SET_IN';\r
-                        break;\r
-                    case STATE_SET_OUT:\r
-                        state_str = 'STATE_SET_OUT';\r
-                        break;\r
-                    case STATE_SET_IN_PENDING:\r
-                        state_str = 'STATE_SET_IN_PENDING';\r
-                        break;\r
-                    case STATE_SET_OUT_PENDING:\r
-                        state_str = 'STATE_SET_OUT_PENDING';\r
-                        break;\r
-                    case STATE_SET_IN_SUCCESS:\r
-                        state_str = 'STATE_SET_IN_SUCCESS';\r
-                        break;\r
-                    case STATE_SET_OUT_SUCCESS:\r
-                        state_str = 'STATE_SET_OUT_SUCCESS';\r
-                        break;\r
-                    case STATE_SET_IN_FAILURE:\r
-                        state_str = 'STATE_SET_IN_FAILURE';\r
-                        break;\r
-                    case STATE_SET_OUT_FAILURE:\r
-                        state_str = 'STATE_SET_OUT_FAILURE';\r
-                        break;\r
-                }\r
-                console.log("LEASE", new Date(lease.start_time * 1000), new Date(lease.end_time * 1000), lease.resource, state_str);\r
-            });\r
-        };\r
-\r
-        // Return this object reference.\r
-        return (this);\r
-\r
-    }\r
-\r
-    // Define the Controller as the constructor function.\r
-    app.controller("SchedulerCtrl", Controller);\r
-\r
-})(angular, ManifoldApp);\r
-\r
-/******************************************************************************\r
- *                              MANIFOLD PLUGIN                               *\r
- ******************************************************************************/\r
-\r
-(function($) {\r
-        scheduler2 = Plugin.extend({\r
-\r
-            /** XXX to check\r
-         * @brief Plugin constructor\r
-         * @param options : an associative array of setting values\r
-         * @param element : \r
-         * @return : a jQuery collection of objects on which the plugin is\r
-         *     applied, which allows to maintain chainability of calls\r
-         */\r
-            init: function(options, element) {\r
-                // Call the parent constructor, see FAQ when forgotten\r
-                this._super(options, element);\r
-\r
-                var scope = this._get_scope()\r
-                scope.instance = this;\r
-\r
-                // XXX not needed\r
-                scheduler2Instance = this;\r
-\r
-                // We need to remember the active filter for datatables filtering\r
-                // XXX not needed\r
-                this.filters = Array();\r
-\r
-                // XXX BETTER !!!!\r
-                $(window).delegate('*', 'keypress', function (evt){\r
-                        alert("erm");\r
-                      });\r
-\r
-                $(window).keydown(function(evt) {\r
-                    if (evt.which == 17) { // ctrl\r
-                        schedulerCtrlPressed = true;\r
-                    }\r
-                }).keyup(function(evt) {\r
-                    if (evt.which == 17) { // ctrl\r
-                        schedulerCtrlPressed = false;\r
-                    }\r
-                });\r
-\r
-                // XXX naming\r
-                //$("#" + schedulerTblId).on('mousedown', 'td', rangeMouseDown).on('mouseup', 'td', rangeMouseUp).on('mousemove', 'td', rangeMouseMove);\r
-\r
-                this._resources_received = false;\r
-                this._leases_received = false;\r
-                \r
-                scope._leases_by_resource = {};\r
-\r
-                /* Listening to queries */\r
-                this.listen_query(options.query_uuid, 'resources');\r
-                this.listen_query(options.query_lease_uuid, 'leases');\r
-\r
-                this.elmt().on('show', this, this.on_show);\r
-                this.elmt().on('shown.bs.tab', this, this.on_show);\r
-                this.elmt().on('resize', this, this.on_resize);\r
-\r
-                /* Generate slots according to the default granularity. Should\r
-                 * be updated when resources arrive.  Should be the pgcd in fact XXX */\r
-                this._granularity = DEFAULT_GRANULARITY;\r
-                scope.granularity = this._granularity;\r
-                this.scope_resources_by_key = {};\r
-\r
-                this.do_resize();\r
-    \r
-                scope.from = 0;\r
-\r
-                this._initUI();\r
-\r
-            },\r
-\r
-            do_resize: function()\r
-            {\r
-                var scope = this._get_scope();\r
-                var num_hidden_cells, new_max, lcm;\r
-\r
-                // do_resize has to be called when the window is resized, or one parameter changes\r
-                // e.g. when new resources have been received\r
-                //\r
-                this.resource_granularities = [3600, 1800]; //, 2400]; /* s */\r
-\r
-                /* Compute the slot length to accommodate all resources. This\r
-                 * is the GCD of all resource granularities. */\r
-                this._slot_length = this._gcdn(this.resource_granularities);\r
-\r
-                $('#' + schedulerTblId + ' thead tr th:eq(0)').css("width", SCHEDULER_FIRST_COLWIDTH);\r
-                //self get width might need fix depending on the template \r
-                var tblwidth = $('#scheduler-reservation-table').parent().outerWidth();\r
-\r
-                /* Number of visible cells...*/\r
-                this._num_visible_cells = parseInt((tblwidth - SCHEDULER_FIRST_COLWIDTH) / SCHEDULER_COLWIDTH);\r
-\r
-                /* ...should be a multiple of the lcm of all encountered granularities. */\r
-                lcm = this._lcmn(this.resource_granularities) / this._slot_length;\r
-                this._num_visible_cells = this._num_visible_cells - this._num_visible_cells % lcm;\r
-\r
-                // A list of {id, time} dictionaries representing the slots for the given day\r
-                this._all_slots = this._generate_all_slots();\r
-\r
-                /* scope also needs this value */\r
-                scope.slots = this._all_slots;\r
-                scope.slot_length = this._slot_length;\r
-                scope.num_visible_cells = this._num_visible_cells;\r
-                scope.lcm_colspan = this._lcmn(this.resource_granularities); // XXX WHY ?\r
-\r
-                /* Redraw... */\r
-                this._scope_clear_leases();\r
-                this._set_all_lease_slots();\r
-\r
-                // Slider max value\r
-                if ($('#tblSlider').data('slider') != undefined) {\r
-                    num_hidden_cells = this._all_slots.length - this._num_visible_cells;\r
-\r
-                    $('#tblSlider').slider('setAttribute', 'max', num_hidden_cells);\r
-                    $('#tblSlider').slider('setValue', scope.from, true);\r
-                }\r
-                this._get_scope().$apply();\r
-\r
-\r
-            },\r
-\r
-            on_show: function(e)\r
-            {\r
-                var self = e.data;\r
-                self.do_resize();\r
-                self._get_scope().$apply();\r
-            },\r
-\r
-            on_resize: function(e)\r
-            {\r
-                var self = e.data;\r
-                self.do_resize();\r
-                self._get_scope().$apply();\r
-            },\r
-\r
-            /* Handlers */\r
-\r
-            _get_scope : function()\r
-            {\r
-                return angular.element(document.getElementById('SchedulerCtrl')).scope();\r
-            },\r
-            \r
-            _scope_set_resources : function()\r
-            {\r
-                var self = this;\r
-                var scope = this._get_scope();\r
-\r
-                var records = manifold.query_store.get_records(this.options.query_uuid);\r
-\r
-                scope.resources = [];\r
-\r
-                $.each(records, function(i, record) {\r
-                    if (!record.exclusive)\r
-                        return true; // ~ continue\r
-\r
-                    // copy not to modify original record\r
-                    var resource = jQuery.extend(true, {}, record);\r
-\r
-                    // Fix granularity\r
-                    //resource_granularity = ((resource.granularity === undefined) || (typeof(resource.granularity) != "number")) ? RESOURCE_DEFAULT_GRANULARITY : resource.granularity;\r
-                    if (typeof(resource.granularity) != "number")\r
-                        resource.granularity = RESOURCE_DEFAULT_GRANULARITY;\r
-                    resource.leases = []; // a list of occupied timeslots\r
-\r
-                    self.scope_resources_by_key[resource['urn']] = resource;\r
-                    scope.resources.push(resource);\r
-                });\r
-            },\r
-\r
-            _scope_clear_leases: function()\r
-            {\r
-                var time, now;\r
-                var self = this;\r
-                var scope = this._get_scope();\r
-\r
-                now = new Date().getTime();\r
-\r
-                // Setup leases with a default free status...\r
-                $.each(this.scope_resources_by_key, function(resource_key, resource) {\r
-                    resource.leases = [];\r
-                    var colspan_lease = resource.granularity / self._slot_length; //eg. 3600 / 1800 => 2 cells\r
-                    time = SchedulerDateSelected.getTime();\r
-                    for (i=0; i < self._all_slots.length / colspan_lease; i++) { // divide by granularity\r
-                        resource.leases.push({\r
-                            id:     'coucou',\r
-                            status: (time < now) ? 'disabled':  'free', // 'selected', 'reserved', 'maintenance' XXX pending ??\r
-                        });\r
-                        time += resource.granularity * 1000;\r
-                    }\r
-                });\r
-\r
-            },\r
-\r
-            _scope_set_leases: function()\r
-            {\r
-                    var status;\r
-                var self = this;\r
-                var scope = this._get_scope();\r
-            \r
-                manifold.query_store.iter_records(this.options.query_lease_uuid, function(lease_key, lease) {\r
-                    console.log("SET LEASES", lease.resource, new Date(lease.start_time* 1000), new Date(lease.end_time* 1000));\r
-                    // XXX We should ensure leases are correctly merged, otherwise our algorithm won't work\r
-\r
-                    // Populate leases by resource array: this will help us merging leases later\r
-\r
-                    // let's only put _our_ leases\r
-                    lease_status = manifold.query_store.get_record_state(self.options.query_lease_uuid, lease_key, STATE_SET);\r
-                    if (lease_status != STATE_SET_IN)\r
-                        return true; // ~continue\r
-                    if (!(lease.resource in scope._leases_by_resource))\r
-                        scope._leases_by_resource[lease.resource] = [];\r
-                    scope._leases_by_resource[lease.resource].push(lease);\r
-\r
-                });\r
-\r
-                this._set_all_lease_slots();\r
-            },\r
-\r
-            _set_all_lease_slots: function()\r
-            {\r
-                var self = this;\r
-            \r
-                manifold.query_store.iter_records(this.options.query_lease_uuid, function(lease_key, lease) {\r
-                    self._set_lease_slots(lease_key, lease);\r
-                });\r
-            },\r
-\r
-            on_resources_query_done: function(data)\r
-            {\r
-                this._resources_received = true;\r
-                this._scope_set_resources();\r
-                this._scope_clear_leases();\r
-                if (this._leases_received)\r
-                    this._scope_set_leases();\r
-                    \r
-                this._get_scope().$apply();\r
-            },\r
-\r
-            on_leases_query_done: function(data)\r
-            {\r
-                this._leases_received = true;\r
-                if (this._resources_received) {\r
-                    this._scope_set_leases();\r
-                    this._get_scope().$apply();\r
-                }\r
-            },\r
-\r
-            /* Filters on resources */\r
-            on_resources_filter_added:   function(filter) { this._get_scope().$apply(); },\r
-            on_resources_filter_removed: function(filter) { this._get_scope().$apply(); },\r
-            on_resources_filter_clear:   function()       { this._get_scope().$apply(); },\r
-\r
-            /* Filters on leases ? */\r
-            on_leases_filter_added:      function(filter) { this._get_scope().$apply(); },\r
-            on_leases_filter_removed:    function(filter) { this._get_scope().$apply(); },\r
-            on_leases_filter_clear:      function()       { this._get_scope().$apply(); },\r
-\r
-            on_field_state_changed: function(data)\r
-            {\r
-                /*\r
-                this._set_lease_slots(lease_key, lease);\r
-\r
-                switch(data.state) {\r
-                    case STATE_SET:\r
-                        switch(data.op) {\r
-                            case STATE_SET_IN:\r
-                            case STATE_SET_IN_SUCCESS:\r
-                            case STATE_SET_OUT_FAILURE:\r
-                                this.set_checkbox_from_data(data.value, true);\r
-                                this.set_bgcolor(data.value, QUERYTABLE_BGCOLOR_RESET);\r
-                                break;  \r
-                            case STATE_SET_OUT:\r
-                            case STATE_SET_OUT_SUCCESS:\r
-                            case STATE_SET_IN_FAILURE:\r
-                                this.set_checkbox_from_data(data.value, false);\r
-                                this.set_bgcolor(data.value, QUERYTABLE_BGCOLOR_RESET);\r
-                                break;\r
-                            case STATE_SET_IN_PENDING:\r
-                                this.set_checkbox_from_data(data.key, true);\r
-                                this.set_bgcolor(data.value, QUERYTABLE_BGCOLOR_ADDED);\r
-                                break;  \r
-                            case STATE_SET_OUT_PENDING:\r
-                                this.set_checkbox_from_data(data.key, false);\r
-                                this.set_bgcolor(data.value, QUERYTABLE_BGCOLOR_REMOVED);\r
-                                break;\r
-                        }\r
-                        break;\r
-\r
-                    case STATE_WARNINGS:\r
-                        this.change_status(data.key, data.value);\r
-                        break;\r
-                }\r
-                */\r
-            },\r
-\r
-\r
-            /* INTERNAL FUNCTIONS */\r
-\r
-            _set_lease_slots: function(lease_key, lease)\r
-            {\r
-                var resource, lease_status, lease_class;\r
-                var day_timestamp, id_start, id_end, colspan_lease;\r
-\r
-                resource = this.scope_resources_by_key[lease.resource];\r
-                day_timestamp = SchedulerDateSelected.getTime() / 1000;\r
-                id_start = Math.floor((lease.start_time - day_timestamp) / resource.granularity);\r
-\r
-                /* Some leases might be in the past */\r
-                if (id_start < 0)\r
-                    id_start = 0;\r
-                /* Leases in the future: ignore */\r
-                if (id_start >= this._all_slots.length)\r
-                    return true; // ~ continue\r
-\r
-                id_end   = Math.ceil((lease.end_time   - day_timestamp) / resource.granularity);\r
-                colspan_lease = resource.granularity / this._slot_length; //eg. 3600 / 1800 => 2 cells\r
-                if (id_end >= this._all_slots.length / colspan_lease) {\r
-                    /* Limit the display to the current day */\r
-                    id_end = this._all_slots.length / colspan_lease\r
-                }\r
-                lease_status = manifold.query_store.get_record_state(this.options.query_lease_uuid, lease_key, STATE_SET);\r
-                // the same slots might be affected multiple times.\r
-                // PENDING_IN + PENDING_OUT => IN \r
-                //\r
-                // RESERVED vs SELECTED !\r
-                //\r
-                // PENDING !!\r
-                switch(lease_status) {\r
-                    case STATE_SET_IN:\r
-                        lease_class = 'selected'; // my leases\r
-                        lease_success = '';\r
-                        break;\r
-                    case STATE_SET_IN_SUCCESS:\r
-                        lease_class = 'selected'; // my leases\r
-                        lease_success = 'success';\r
-                    case STATE_SET_OUT_FAILURE:\r
-                        lease_class = 'selected'; // my leases\r
-                        lease_success = 'failure';\r
-                        break;\r
-                    case STATE_SET_OUT:\r
-                        lease_class = 'reserved'; // other leases\r
-                        lease_success = '';\r
-                        break;\r
-                    case STATE_SET_OUT_SUCCESS:\r
-                        lease_class = 'free'; // other leases\r
-                        lease_success = 'success';\r
-                        break;\r
-                    case STATE_SET_IN_FAILURE:\r
-                        lease_class = 'free'; // other leases\r
-                        lease_success = 'failure';\r
-                        break;\r
-                    case STATE_SET_IN_PENDING:\r
-                        lease_class = 'pendingin';\r
-                        lease_success = '';\r
-                        break;\r
-                    case STATE_SET_OUT_PENDING:\r
-                        // pending_in & pending_out == IN == replacement\r
-                        if (resource.leases[i].status == 'pendingin')\r
-                            lease_class = 'pendingin'\r
-                        else\r
-                            lease_class = 'pendingout';\r
-                        lease_success = '';\r
-                        break;\r
-                \r
-                }\r
-\r
-                for (i = id_start; i < id_end; i++) {\r
-                    resource.leases[i].status = lease_class;\r
-                    resource.leases[i].success = lease_success;\r
-                }\r
-            },\r
-\r
-/* XXX IN TEMPLATE XXX\r
-                if (SchedulerDataViewData.length == 0) {\r
-                    $("#plugin-scheduler").hide();\r
-                    $("#plugin-scheduler-empty").show();\r
-                    tmpScope.clearStuff();\r
-                } else {\r
-                    $("#plugin-scheduler-empty").hide();\r
-                    $("#plugin-scheduler").show();\r
-                    // initSchedulerResources\r
-                    tmpScope.initSchedulerResources(schedulerMaxRows < SchedulerDataViewData.length ? schedulerMaxRows : SchedulerDataViewData.length);\r
-                }\r
-*/\r
-\r
-            /**\r
-             * Initialize the date picker, the table, the slider and the buttons. Once done, display scheduler.\r
-             */\r
-            _initUI: function() \r
-            {\r
-                var self = this;\r
-                var scope = self._get_scope();\r
-\r
-                var num_hidden_cells;\r
-\r
-                $("#DateToRes").datepicker({\r
-                       dateFormat: "D, d M yy",\r
-                    onRender: function(date) {\r
-                        return date.valueOf() < now.valueOf() ? 'disabled' : '';\r
-                    }\r
-                }).on('changeDate', function(ev) {\r
-                    SchedulerDateSelected = new Date(ev.date);\r
-                    SchedulerDateSelected.setHours(0,0,0,0);\r
-                    // Set slider to origin\r
-                    //$('#tblSlider').slider('setValue', 0); // XXX\r
-                    // Refresh leases\r
-                    self._scope_clear_leases();\r
-                    self._set_all_lease_slots();\r
-                    // Refresh display\r
-                    self._get_scope().$apply();\r
-                }).datepicker('setValue', SchedulerDateSelected); //.data('datepicker');\r
-\r
-                //init Slider\r
-                num_hidden_cells = self._all_slots.length - self._num_visible_cells;\r
-                init_cell = (new Date().getHours() - 1) * 3600 / self._granularity;\r
-                if (init_cell > num_hidden_cells)\r
-                    init_cell = num_hidden_cells;\r
-\r
-                $('#tblSlider').slider({\r
-                    min: 0,\r
-                    max: num_hidden_cells,\r
-                    value: init_cell,\r
-                }).on('slide', function(ev) {\r
-                    var scope = self._get_scope();\r
-                    scope.from = ev.value;\r
-                    scope.$apply();\r
-                });\r
-                scope.from = init_cell;\r
-                scope.$apply();\r
-\r
-                $("#plugin-scheduler-loader").hide();\r
-                $("#plugin-scheduler").show();\r
-            },\r
-\r
-        // PRIVATE METHODS\r
-\r
-        /**\r
-         * Greatest common divisor\r
-         */\r
-        _gcd : function(x, y)\r
-        {\r
-            return (y==0) ? x : this._gcd(y, x % y);\r
-        },\r
-\r
-        _gcdn : function(array)\r
-        {\r
-            var self = this;\r
-            return array.reduce(function(prev, cur, idx, arr) { return self._gcd(prev, cur); });\r
-        },\r
-\r
-        /**\r
-         * Least common multiple\r
-         */\r
-        _lcm : function(x, y)\r
-        {\r
-            return x * y / this._gcd(x, y);\r
-        },\r
-\r
-        _lcmn : function(array)\r
-        {\r
-            var self = this;\r
-            return array.reduce(function(prev, cur, idx, arr) { return self._lcm(prev, cur); });\r
-        },\r
-    \r
-        _pad_str : function(i)\r
-        {\r
-            return (i < 10) ? "0" + i : "" + i;\r
-        },\r
-\r
-        /**\r
-         * Member variables used:\r
-         *   _granularity\r
-         * \r
-         * Returns:\r
-         *   A list of {id, time} dictionaries.\r
-         */\r
-        _generate_all_slots: function()\r
-        {\r
-            var slots = [];\r
-            // Start with a random date (a first of a month), only time will matter\r
-            var d = new Date(2014, 1, 1, 0, 0, 0, 0);\r
-            var i = 0;\r
-            // Loop until we change the day\r
-            while (d.getDate() == 1) {\r
-                // Nicely format the time...\r
-                var tmpTime = this._pad_str(d.getHours()) + ':' + this._pad_str(d.getMinutes());\r
-                /// ...and add the slot to the list of results\r
-                slots.push({ id: i, time: tmpTime });\r
-                // Increment the date with the granularity\r
-                d = new Date(d.getTime() + this._slot_length * 1000);\r
-                i++;\r
-            }\r
-            return slots;\r
-\r
-        },\r
-    });\r
-\r
-    /* Plugin registration */\r
-    $.plugin('Scheduler2', scheduler2);\r
-\r
-})(jQuery);\r
-\r
-\r
-\r
+/*
+#
+# Copyright (c) 2013 NITLab, University of Thessaly, CERTH, Greece
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+#
+# This is a MySlice plugin for the NITOS Scheduler
+# Nitos Scheduler v1
+#
+*/
+
+// XXX groupid = all slots those that go with a min granularity
+
+/* some params */
+var scheduler2;
+var scheduler2Instance;
+//is ctrl keyboard button pressed
+var schedulerCtrlPressed = false;
+//table Id
+var schedulerTblId = "scheduler-reservation-table";
+var SCHEDULER_FIRST_COLWIDTH = 200;
+
+
+/* Number of scheduler slots per hour. Used to define granularity. Should be inferred from resources XXX */
+var schedulerSlotsPerHour = 6;
+var RESOURCE_DEFAULT_GRANULARITY    = 1800 /* s */; // should be computed automatically from resource information
+var DEFAULT_GRANULARITY             = 1800 /* s */; // should be computed automatically from resource information. Test with 600
+var DEFAULT_PAGE_RANGE = 5;
+
+var schedulerMaxRows = 12;
+
+/* All resources */
+var SchedulerData = [];
+
+/* ??? */
+var SchedulerSlots = [];
+
+var SchedulerDateSelected = new Date();
+// Round to midnight
+SchedulerDateSelected.setHours(0,0,0,0);
+
+/* Filtered resources */
+var SchedulerDataViewData = [];
+
+var SchedulerSlotsViewData = [];
+//Help Variables
+var _schedulerCurrentCellPosition = 0;
+//Enable Debug
+var schedulerDebug = true;
+//tmp to delete
+var tmpSchedulerLeases = [];
+
+var SCHEDULER_COLWIDTH = 50;
+
+
+/******************************************************************************
+ *                             ANGULAR CONTROLLER                             *
+ ******************************************************************************/
+
+// Create a private execution space for our controller. When
+// executing this function expression, we're going to pass in
+// the Angular reference and our application module.
+(function (ng, app) {
+
+    // Define our Controller constructor.
+    function Controller($scope) {
+
+        // Store the scope so we can reference it in our
+        // class methods
+        this.scope = $scope;
+
+        // Set up the default scope value.
+        this.scope.errorMessage = null;
+        this.scope.name = "";
+
+        //Pagin
+        $scope.current_page = 1;
+        this.scope.items_per_page = 10;
+        $scope.from = 0; // JORDAN
+
+        $scope.instance = null;
+        $scope.resources = new Array();
+        $scope.slots = SchedulerSlotsViewData;
+        $scope.granularity = DEFAULT_GRANULARITY; /* Will be setup */
+        //$scope.msg = "hello";
+
+        angular.element(document).ready(function() {
+            //console.log('Hello World');
+            //alert('Hello World');
+            //afterAngularRendered();
+        });
+
+        // Pagination
+
+        $scope.range = function() {
+            var range_size = $scope.page_count() > DEFAULT_PAGE_RANGE ? DEFAULT_PAGE_RANGE : $scope.page_count();
+            var ret = [];
+            var start;
+
+            start = $scope.current_page;
+            if ( start > $scope.page_count()-range_size ) {
+              start = $scope.page_count()-range_size+1;
+            }
+
+            for (var i=start; i<start+range_size; i++) {
+              ret.push(i);
+            }
+            return ret;
+        };
+
+        $scope.prevPage = function() {
+          if ($scope.current_page > 1) {
+            $scope.current_page--;
+          }
+        };
+
+        $scope.prevPageDisabled = function() {
+          return $scope.current_page === 1 ? "disabled" : "";
+        };
+  
+        $scope.page_count = function()
+        {
+            // XXX need visible resources only
+            var query_ext, visible_resources_length;
+            if (!$scope.instance)
+                return 0;
+            query_ext = manifold.query_store.find_analyzed_query_ext($scope.instance.options.query_uuid);
+            var visible_resources_length = 0;
+            query_ext.state.each(function(i, state) {
+                if (state[STATE_VISIBLE])
+                    visible_resources_length++;
+            });
+            return Math.ceil(visible_resources_length/$scope.items_per_page);
+        };
+  
+        $scope.nextPage = function() {
+          if ($scope.current_page < $scope.page_count()) {
+            $scope.current_page++;
+          }
+        };
+  
+        $scope.nextPageDisabled = function() {
+          return $scope.current_page === $scope.page_count() ? "disabled" : "";
+        }; 
+
+        $scope.setPage = function(n) {
+            $scope.current_page = n;
+        };
+        // END pagination
+
+        // FILTER
+
+        $scope.filter_visible = function(resource)
+        {
+            return manifold.query_store.get_record_state($scope.instance.options.query_uuid, resource['urn'], STATE_VISIBLE);
+        };
+
+        // SELECTION
+
+        $scope._create_new_lease = function(resource_urn, start_time, end_time)
+        {
+            var lease_key, new_lease, data;
+
+            lease_key = manifold.metadata.get_key('lease');
+
+            new_lease = {
+                resource:   resource_urn,
+                start_time: start_time,
+                end_time:   end_time,
+            };
+
+            // This is needed to create a hashable object
+            new_lease.hashCode = manifold.record_hashcode(lease_key.sort());
+            new_lease.equals   = manifold.record_equals(lease_key);
+
+            data = {
+                state: STATE_SET,
+                key  : null,
+                op   : STATE_SET_ADD,
+                value: new_lease
+            }
+            manifold.raise_event($scope.instance.options.query_lease_uuid, FIELD_STATE_CHANGED, data);
+            /* Add to local cache also, unless we listen to events from outside */
+            if (!(resource_urn in $scope._leases_by_resource))
+                $scope._leases_by_resource[resource_urn] = [];
+            $scope._leases_by_resource[resource_urn].push(new_lease);
+        }
+
+        $scope._remove_lease = function(other)
+        {
+            var lease_key, other_key, data;
+
+            lease_key = manifold.metadata.get_key('lease');
+
+            // XXX This could be a manifold.record_get_value
+            other_key = {
+                resource:   other.resource,
+                start_time: other.start_time,
+                end_time:   other.end_time
+            }
+            other_key.hashCode = manifold.record_hashcode(lease_key.sort());
+            other_key.equals   = manifold.record_equals(lease_key);
+
+            data = {
+                state: STATE_SET,
+                key  : null,
+                op   : STATE_SET_REMOVE,
+                value: other_key
+            }
+            manifold.raise_event($scope.instance.options.query_lease_uuid, FIELD_STATE_CHANGED, data);
+            /* Remove from local cache also, unless we listen to events from outside */
+            $scope._leases_by_resource[other.resource] = $.grep($scope._leases_by_resource[other.resource], function(x) { return x != other; });
+
+        }
+
+        $scope.select = function(index, model_lease, model_resource)
+        {
+            var data, resource_granularity;
+
+            //resource_granularity = model_resource.granularity === undefined ? RESOURCE_DEFAULT_GRANULARITY : model_resource.granularity;
+
+            console.log("Selected", index, model_lease, model_resource);
+
+            var day_timestamp = SchedulerDateSelected.getTime() / 1000;
+            var start_time = day_timestamp + index       * model_resource.granularity; // XXX resource_granularity
+            var end_time   = day_timestamp + (index + 1) * model_resource.granularity; //
+            var start_date = new Date(start_time * 1000);
+            var end_date   = new Date(end_time   * 1000);
+
+            var lease_key = manifold.metadata.get_key('lease');
+
+            // We search for leases in the cache we previously constructed
+            var resource_leases = $scope._leases_by_resource[model_resource.urn];
+
+            switch (model_lease.status)
+            {
+                case 'free': // out
+                case 'pendingout':
+                    if (resource_leases) {
+                        /* Search for leases before */
+                        $.each(resource_leases, function(i, other) {
+                            if (other.end_time != start_time)
+                                return true; // ~ continue
+        
+                            /* The lease 'other' is just before, and there should not exist
+                             * any other lease before it */
+                            start_time = other.start_time;
+        
+                            other_key = {
+                                resource:   other.resource,
+                                start_time: other.start_time,
+                                end_time:   other.end_time
+                            }
+                            // This is needed to create a hashable object
+                            other_key.hashCode = manifold.record_hashcode(lease_key.sort());
+                            other_key.equals   = manifold.record_equals(lease_key);
+        
+                            data = {
+                                state: STATE_SET,
+                                key  : null,
+                                op   : STATE_SET_REMOVE,
+                                value: other_key
+                            }
+                            manifold.raise_event($scope.instance.options.query_lease_uuid, FIELD_STATE_CHANGED, data);
+                            /* Remove from local cache also, unless we listen to events from outside */
+                            $scope._leases_by_resource[model_resource.urn] = $.grep($scope._leases_by_resource[model_resource.urn], function(x) { return x != other; });
+                            return false; // ~ break
+                        });
+        
+                        /* Search for leases after */
+                        $.each(resource_leases, function(i, other) {
+                            if (other.start_time != end_time)
+                                return true; // ~ continue
+        
+                            /* The lease 'other' is just after, and there should not exist
+                             * any other lease after it */
+                            end_time = other.end_time;
+                            other_key = {
+                                resource:   other.resource,
+                                start_time: other.start_time,
+                                end_time:   other.end_time
+                            }
+                            // This is needed to create a hashable object
+                            other_key.hashCode = manifold.record_hashcode(lease_key.sort());
+                            other_key.equals   = manifold.record_equals(lease_key);
+        
+                            data = {
+                                state: STATE_SET,
+                                key  : null,
+                                op   : STATE_SET_REMOVE,
+                                value: other_key
+                            }
+                            manifold.raise_event($scope.instance.options.query_lease_uuid, FIELD_STATE_CHANGED, data);
+                            /* Remove from local cache also, unless we listen to events from outside */
+                            $scope._leases_by_resource[model_resource.urn] = $.grep($scope._leases_by_resource[model_resource.urn], function(x) { return x != other; });
+                            return false; // ~ break
+                        });
+                    }
+        
+                    $scope._create_new_lease(model_resource.urn, start_time, end_time);
+                    model_lease.status = (model_lease.status == 'free') ? 'pendingin' : 'selected';
+                    // unless the exact same lease already existed (pending_out status for the lease, not the cell !!)
+
+                    break;
+
+                case 'selected':
+                case 'pendingin':
+                    // We remove the cell
+
+                    /* We search for leases including this cell. Either 0, 1 or 2.
+                     * 0 : NOT POSSIBLE, should be checked.
+                     * 1 : either IN or OUT, we have make no change in the session
+                     * 2 : both will be pending, since we have made a change in the session
+                    * /!\ need to properly remove pending_in leases when removed again
+                     */
+                    if (resource_leases) {
+                        $.each(resource_leases, function(i, other) {
+                            if ((other.start_time <= start_time) && (other.end_time >= end_time)) {
+                                // The cell is part of this lease.
+
+                                // If the cell is not at the beginning of the lease, we recreate a lease with cells before
+                                if (start_time > other.start_time) {
+                                    $scope._create_new_lease(model_resource.urn, other.start_time, start_time);
+                                }
+
+                                // If the cell is not at the end of the lease, we recreate a lease with cells after
+                                if (end_time < other.end_time) {
+                                    $scope._create_new_lease(model_resource.urn, end_time, other.end_time);
+                                }
+                                
+                                // The other lease will be removed
+                                $scope._remove_lease(other);
+                            }
+                            // NOTE: We can interrupt the search if we know that there is a single lease (depending on the status).
+                        });
+                    }
+                
+                    // cf comment in previous switch case
+                    model_lease.status = (model_lease.status == 'selected') ? 'pendingout' : 'free';
+
+                    break;
+
+                case 'reserved':
+                case 'maintainance':
+                    // Do nothing
+                    break;
+            }
+            
+
+            $scope._dump_leases();
+        };
+  
+        $scope._dump_leases = function()
+        {
+            // DEBUG: display all leases and their status in the log
+            var leases = manifold.query_store.get_records($scope.instance.options.query_lease_uuid);
+            console.log("--------------------");
+            $.each(leases, function(i, lease) {
+                var key = manifold.metadata.get_key('lease');
+                var lease_key = manifold.record_get_value(lease, key);
+                var state = manifold.query_store.get_record_state($scope.instance.options.query_lease_uuid, lease_key, STATE_SET);
+                var state_str;
+                switch(state) {
+                    case STATE_SET_IN:
+                        state_str = 'STATE_SET_IN';
+                        break;
+                    case STATE_SET_OUT:
+                        state_str = 'STATE_SET_OUT';
+                        break;
+                    case STATE_SET_IN_PENDING:
+                        state_str = 'STATE_SET_IN_PENDING';
+                        break;
+                    case STATE_SET_OUT_PENDING:
+                        state_str = 'STATE_SET_OUT_PENDING';
+                        break;
+                    case STATE_SET_IN_SUCCESS:
+                        state_str = 'STATE_SET_IN_SUCCESS';
+                        break;
+                    case STATE_SET_OUT_SUCCESS:
+                        state_str = 'STATE_SET_OUT_SUCCESS';
+                        break;
+                    case STATE_SET_IN_FAILURE:
+                        state_str = 'STATE_SET_IN_FAILURE';
+                        break;
+                    case STATE_SET_OUT_FAILURE:
+                        state_str = 'STATE_SET_OUT_FAILURE';
+                        break;
+                }
+                console.log("LEASE", new Date(lease.start_time * 1000), new Date(lease.end_time * 1000), lease.resource, state_str);
+            });
+        };
+
+        // Return this object reference.
+        return (this);
+
+    }
+
+    // Define the Controller as the constructor function.
+    app.controller("SchedulerCtrl", Controller);
+
+})(angular, ManifoldApp);
+
+/******************************************************************************
+ *                              MANIFOLD PLUGIN                               *
+ ******************************************************************************/
+
+(function($) {
+        scheduler2 = Plugin.extend({
+
+            /** XXX to check
+         * @brief Plugin constructor
+         * @param options : an associative array of setting values
+         * @param element : 
+         * @return : a jQuery collection of objects on which the plugin is
+         *     applied, which allows to maintain chainability of calls
+         */
+            init: function(options, element) {
+                // Call the parent constructor, see FAQ when forgotten
+                this._super(options, element);
+
+                var scope = this._get_scope()
+                scope.instance = this;
+
+                // XXX not needed
+                scheduler2Instance = this;
+
+                // We need to remember the active filter for datatables filtering
+                // XXX not needed
+                this.filters = Array();
+
+                // XXX BETTER !!!!
+                $(window).delegate('*', 'keypress', function (evt){
+                        alert("erm");
+                      });
+
+                $(window).keydown(function(evt) {
+                    if (evt.which == 17) { // ctrl
+                        schedulerCtrlPressed = true;
+                    }
+                }).keyup(function(evt) {
+                    if (evt.which == 17) { // ctrl
+                        schedulerCtrlPressed = false;
+                    }
+                });
+
+                // XXX naming
+                //$("#" + schedulerTblId).on('mousedown', 'td', rangeMouseDown).on('mouseup', 'td', rangeMouseUp).on('mousemove', 'td', rangeMouseMove);
+
+                this._resources_received = false;
+                this._leases_received = false;
+                
+                scope._leases_by_resource = {};
+
+                /* Listening to queries */
+                this.listen_query(options.query_uuid, 'resources');
+                this.listen_query(options.query_lease_uuid, 'leases');
+
+                this.elmt().on('show', this, this.on_show);
+                this.elmt().on('shown.bs.tab', this, this.on_show);
+                this.elmt().on('resize', this, this.on_resize);
+
+                /* Generate slots according to the default granularity. Should
+                 * be updated when resources arrive.  Should be the pgcd in fact XXX */
+                this._granularity = DEFAULT_GRANULARITY;
+                scope.granularity = this._granularity;
+                this.scope_resources_by_key = {};
+
+                this.do_resize();
+    
+                scope.from = 0;
+
+                this._initUI();
+
+            },
+
+            do_resize: function()
+            {
+                var scope = this._get_scope();
+                var num_hidden_cells, new_max, lcm;
+
+                // do_resize has to be called when the window is resized, or one parameter changes
+                // e.g. when new resources have been received
+                //
+                this.resource_granularities = [3600, 1800]; //, 2400]; /* s */
+
+                /* Compute the slot length to accommodate all resources. This
+                 * is the GCD of all resource granularities. */
+                this._slot_length = this._gcdn(this.resource_granularities);
+
+                $('#' + schedulerTblId + ' thead tr th:eq(0)').css("width", SCHEDULER_FIRST_COLWIDTH);
+                //self get width might need fix depending on the template 
+                var tblwidth = $('#scheduler-reservation-table').parent().outerWidth();
+
+                /* Number of visible cells...*/
+                this._num_visible_cells = parseInt((tblwidth - SCHEDULER_FIRST_COLWIDTH) / SCHEDULER_COLWIDTH);
+
+                /* ...should be a multiple of the lcm of all encountered granularities. */
+                lcm = this._lcmn(this.resource_granularities) / this._slot_length;
+                this._num_visible_cells = this._num_visible_cells - this._num_visible_cells % lcm;
+
+                // A list of {id, time} dictionaries representing the slots for the given day
+                this._all_slots = this._generate_all_slots();
+
+                /* scope also needs this value */
+                scope.slots = this._all_slots;
+                scope.slot_length = this._slot_length;
+                scope.num_visible_cells = this._num_visible_cells;
+                scope.lcm_colspan = this._lcmn(this.resource_granularities); // XXX WHY ?
+
+                /* Redraw... */
+                this._scope_clear_leases();
+                this._set_all_lease_slots();
+
+                // Slider max value
+                if ($('#tblSlider').data('slider') != undefined) {
+                    num_hidden_cells = this._all_slots.length - this._num_visible_cells;
+
+                    $('#tblSlider').slider('setAttribute', 'max', num_hidden_cells);
+                    $('#tblSlider').slider('setValue', scope.from, true);
+                }
+                this._get_scope().$apply();
+
+
+            },
+
+            on_show: function(e)
+            {
+                var self = e.data;
+                self.do_resize();
+                self._get_scope().$apply();
+            },
+
+            on_resize: function(e)
+            {
+                var self = e.data;
+                self.do_resize();
+                self._get_scope().$apply();
+            },
+
+            /* Handlers */
+
+            _get_scope : function()
+            {
+                return angular.element(document.getElementById('SchedulerCtrl')).scope();
+            },
+            
+            _scope_set_resources : function()
+            {
+                var self = this;
+                var scope = this._get_scope();
+
+                var records = manifold.query_store.get_records(this.options.query_uuid);
+
+                scope.resources = [];
+
+                $.each(records, function(i, record) {
+                    if (!record.exclusive)
+                        return true; // ~ continue
+
+                    // copy not to modify original record
+                    var resource = jQuery.extend(true, {}, record);
+
+                    // Fix granularity
+                    //resource_granularity = ((resource.granularity === undefined) || (typeof(resource.granularity) != "number")) ? RESOURCE_DEFAULT_GRANULARITY : resource.granularity;
+                    if (typeof(resource.granularity) != "number")
+                        resource.granularity = RESOURCE_DEFAULT_GRANULARITY;
+                    resource.leases = []; // a list of occupied timeslots
+
+                    self.scope_resources_by_key[resource['urn']] = resource;
+                    scope.resources.push(resource);
+                });
+            },
+
+            _scope_clear_leases: function()
+            {
+                var time, now;
+                var self = this;
+                var scope = this._get_scope();
+
+                now = new Date().getTime();
+
+                // Setup leases with a default free status...
+                $.each(this.scope_resources_by_key, function(resource_key, resource) {
+                    resource.leases = [];
+                    var colspan_lease = resource.granularity / self._slot_length; //eg. 3600 / 1800 => 2 cells
+                    time = SchedulerDateSelected.getTime();
+                    for (i=0; i < self._all_slots.length / colspan_lease; i++) { // divide by granularity
+                        resource.leases.push({
+                            id:     'coucou',
+                            status: (time < now) ? 'disabled':  'free', // 'selected', 'reserved', 'maintenance' XXX pending ??
+                        });
+                        time += resource.granularity * 1000;
+                    }
+                });
+
+            },
+
+            _scope_set_leases: function()
+            {
+                    var status;
+                var self = this;
+                var scope = this._get_scope();
+            
+                manifold.query_store.iter_records(this.options.query_lease_uuid, function(lease_key, lease) {
+                    //console.log("SET LEASES", lease.resource, new Date(lease.start_time* 1000), new Date(lease.end_time* 1000));
+                    // XXX We should ensure leases are correctly merged, otherwise our algorithm won't work
+
+                    // Populate leases by resource array: this will help us merging leases later
+
+                    // let's only put _our_ leases
+                    lease_status = manifold.query_store.get_record_state(self.options.query_lease_uuid, lease_key, STATE_SET);
+                    if (lease_status != STATE_SET_IN)
+                        return true; // ~continue
+                    if (!(lease.resource in scope._leases_by_resource))
+                        scope._leases_by_resource[lease.resource] = [];
+                    scope._leases_by_resource[lease.resource].push(lease);
+
+                });
+
+                this._set_all_lease_slots();
+            },
+
+            _set_all_lease_slots: function()
+            {
+                var self = this;
+            
+                manifold.query_store.iter_records(this.options.query_lease_uuid, function(lease_key, lease) {
+                    self._set_lease_slots(lease_key, lease);
+                });
+            },
+
+            on_resources_query_done: function(data)
+            {
+                this._resources_received = true;
+                this._scope_set_resources();
+                this._scope_clear_leases();
+                if (this._leases_received)
+                    this._scope_set_leases();
+                    
+                this._get_scope().$apply();
+            },
+
+            on_leases_query_done: function(data)
+            {
+                this._leases_received = true;
+                if (this._resources_received) {
+                    this._scope_set_leases();
+                    this._get_scope().$apply();
+                }
+            },
+
+            /* Filters on resources */
+            on_resources_filter_added:   function(filter) { this._get_scope().$apply(); },
+            on_resources_filter_removed: function(filter) { this._get_scope().$apply(); },
+            on_resources_filter_clear:   function()       { this._get_scope().$apply(); },
+
+            /* Filters on leases ? */
+            on_leases_filter_added:      function(filter) { this._get_scope().$apply(); },
+            on_leases_filter_removed:    function(filter) { this._get_scope().$apply(); },
+            on_leases_filter_clear:      function()       { this._get_scope().$apply(); },
+
+            on_field_state_changed: function(data)
+            {
+                /*
+                this._set_lease_slots(lease_key, lease);
+
+                switch(data.state) {
+                    case STATE_SET:
+                        switch(data.op) {
+                            case STATE_SET_IN:
+                            case STATE_SET_IN_SUCCESS:
+                            case STATE_SET_OUT_FAILURE:
+                                this.set_checkbox_from_data(data.value, true);
+                                this.set_bgcolor(data.value, QUERYTABLE_BGCOLOR_RESET);
+                                break;  
+                            case STATE_SET_OUT:
+                            case STATE_SET_OUT_SUCCESS:
+                            case STATE_SET_IN_FAILURE:
+                                this.set_checkbox_from_data(data.value, false);
+                                this.set_bgcolor(data.value, QUERYTABLE_BGCOLOR_RESET);
+                                break;
+                            case STATE_SET_IN_PENDING:
+                                this.set_checkbox_from_data(data.key, true);
+                                this.set_bgcolor(data.value, QUERYTABLE_BGCOLOR_ADDED);
+                                break;  
+                            case STATE_SET_OUT_PENDING:
+                                this.set_checkbox_from_data(data.key, false);
+                                this.set_bgcolor(data.value, QUERYTABLE_BGCOLOR_REMOVED);
+                                break;
+                        }
+                        break;
+
+                    case STATE_WARNINGS:
+                        this.change_status(data.key, data.value);
+                        break;
+                }
+                */
+            },
+
+
+            /* INTERNAL FUNCTIONS */
+
+            _set_lease_slots: function(lease_key, lease)
+            {
+                var resource, lease_status, lease_class;
+                var day_timestamp, id_start, id_end, colspan_lease;
+
+                resource = this.scope_resources_by_key[lease.resource];
+                day_timestamp = SchedulerDateSelected.getTime() / 1000;
+                if(resource === undefined){
+                    console.log('resource undefined = '+lease.resource);
+                    return;
+                }
+                id_start = Math.floor((lease.start_time - day_timestamp) / resource.granularity);
+
+                /* Some leases might be in the past */
+                if (id_start < 0)
+                    id_start = 0;
+                /* Leases in the future: ignore */
+                if (id_start >= this._all_slots.length)
+                    return true; // ~ continue
+
+                id_end   = Math.ceil((lease.end_time   - day_timestamp) / resource.granularity);
+                colspan_lease = resource.granularity / this._slot_length; //eg. 3600 / 1800 => 2 cells
+                if (id_end >= this._all_slots.length / colspan_lease) {
+                    /* Limit the display to the current day */
+                    id_end = this._all_slots.length / colspan_lease
+                }
+                lease_status = manifold.query_store.get_record_state(this.options.query_lease_uuid, lease_key, STATE_SET);
+                // the same slots might be affected multiple times.
+                // PENDING_IN + PENDING_OUT => IN 
+                //
+                // RESERVED vs SELECTED !
+                //
+                // PENDING !!
+                switch(lease_status) {
+                    case STATE_SET_IN:
+                        lease_class = 'selected'; // my leases
+                        lease_success = '';
+                        break;
+                    case STATE_SET_IN_SUCCESS:
+                        lease_class = 'selected'; // my leases
+                        lease_success = 'success';
+                    case STATE_SET_OUT_FAILURE:
+                        lease_class = 'selected'; // my leases
+                        lease_success = 'failure';
+                        break;
+                    case STATE_SET_OUT:
+                        lease_class = 'reserved'; // other leases
+                        lease_success = '';
+                        break;
+                    case STATE_SET_OUT_SUCCESS:
+                        lease_class = 'free'; // other leases
+                        lease_success = 'success';
+                        break;
+                    case STATE_SET_IN_FAILURE:
+                        lease_class = 'free'; // other leases
+                        lease_success = 'failure';
+                        break;
+                    case STATE_SET_IN_PENDING:
+                        lease_class = 'pendingin';
+                        lease_success = '';
+                        break;
+                    case STATE_SET_OUT_PENDING:
+                        // pending_in & pending_out == IN == replacement
+                        if (resource.leases[i].status == 'pendingin')
+                            lease_class = 'pendingin'
+                        else
+                            lease_class = 'pendingout';
+                        lease_success = '';
+                        break;
+                
+                }
+
+                for (i = id_start; i < id_end; i++) {
+                    resource.leases[i].status = lease_class;
+                    resource.leases[i].success = lease_success;
+                }
+            },
+
+/* XXX IN TEMPLATE XXX
+                if (SchedulerDataViewData.length == 0) {
+                    $("#plugin-scheduler").hide();
+                    $("#plugin-scheduler-empty").show();
+                    tmpScope.clearStuff();
+                } else {
+                    $("#plugin-scheduler-empty").hide();
+                    $("#plugin-scheduler").show();
+                    // initSchedulerResources
+                    tmpScope.initSchedulerResources(schedulerMaxRows < SchedulerDataViewData.length ? schedulerMaxRows : SchedulerDataViewData.length);
+                }
+*/
+
+            /**
+             * Initialize the date picker, the table, the slider and the buttons. Once done, display scheduler.
+             */
+            _initUI: function() 
+            {
+                var self = this;
+                var scope = self._get_scope();
+
+                var num_hidden_cells;
+
+                $("#DateToRes").datepicker({
+                       dateFormat: "D, d M yy",
+                    onRender: function(date) {
+                        return date.valueOf() < now.valueOf() ? 'disabled' : '';
+                    }
+                }).on('changeDate', function(ev) {
+                    SchedulerDateSelected = new Date(ev.date);
+                    SchedulerDateSelected.setHours(0,0,0,0);
+                    // Set slider to origin
+                    //$('#tblSlider').slider('setValue', 0); // XXX
+                    // Refresh leases
+                    self._scope_clear_leases();
+                    self._set_all_lease_slots();
+                    // Refresh display
+                    self._get_scope().$apply();
+                }).datepicker('setValue', SchedulerDateSelected); //.data('datepicker');
+
+                //init Slider
+                num_hidden_cells = self._all_slots.length - self._num_visible_cells;
+                init_cell = (new Date().getHours() - 1) * 3600 / self._granularity;
+                if (init_cell > num_hidden_cells)
+                    init_cell = num_hidden_cells;
+
+                $('#tblSlider').slider({
+                    min: 0,
+                    max: num_hidden_cells,
+                    value: init_cell,
+                }).on('slide', function(ev) {
+                    var scope = self._get_scope();
+                    scope.from = ev.value;
+                    scope.$apply();
+                });
+                scope.from = init_cell;
+                scope.$apply();
+
+                $("#plugin-scheduler-loader").hide();
+                $("#plugin-scheduler").show();
+            },
+
+        // PRIVATE METHODS
+
+        /**
+         * Greatest common divisor
+         */
+        _gcd : function(x, y)
+        {
+            return (y==0) ? x : this._gcd(y, x % y);
+        },
+
+        _gcdn : function(array)
+        {
+            var self = this;
+            return array.reduce(function(prev, cur, idx, arr) { return self._gcd(prev, cur); });
+        },
+
+        /**
+         * Least common multiple
+         */
+        _lcm : function(x, y)
+        {
+            return x * y / this._gcd(x, y);
+        },
+
+        _lcmn : function(array)
+        {
+            var self = this;
+            return array.reduce(function(prev, cur, idx, arr) { return self._lcm(prev, cur); });
+        },
+    
+        _pad_str : function(i)
+        {
+            return (i < 10) ? "0" + i : "" + i;
+        },
+
+        /**
+         * Member variables used:
+         *   _granularity
+         * 
+         * Returns:
+         *   A list of {id, time} dictionaries.
+         */
+        _generate_all_slots: function()
+        {
+            var slots = [];
+            // Start with a random date (a first of a month), only time will matter
+            var d = new Date(2014, 1, 1, 0, 0, 0, 0);
+            var i = 0;
+            // Loop until we change the day
+            while (d.getDate() == 1) {
+                // Nicely format the time...
+                var tmpTime = this._pad_str(d.getHours()) + ':' + this._pad_str(d.getMinutes());
+                /// ...and add the slot to the list of results
+                slots.push({ id: i, time: tmpTime });
+                // Increment the date with the granularity
+                d = new Date(d.getTime() + this._slot_length * 1000);
+                i++;
+            }
+            return slots;
+
+        },
+    });
+
+    /* Plugin registration */
+    $.plugin('Scheduler2', scheduler2);
+
+})(jQuery);
+
+
+
index 264948a..dfda182 100644 (file)
@@ -418,7 +418,6 @@ def account_process(request):
                         sfa_update_user(request, user_hrn, user_pub_key)
                         result_sfa_user = sfa_get_user(request, user_hrn, public_key)
                         try:
-                            result_sfa_user = result_sfa_user[0]
                             if 'keys' in result_sfa_user and result_sfa_user['keys'][0] == public_key:
                                 # updating manifold
                                 updated_config = json.dumps(account_config) 
@@ -427,7 +426,7 @@ def account_process(request):
                                 messages.success(request, 'Sucess: New Keypair Generated! Delegation of your credentials will be automatic.')
                             else:
                                 raise Exception,"Keys are not matching"
-                        except Exception,e:
+                        except Exception, e:
                             messages.error(request, 'Error: An error occured during the update of your public key at the Registry, or your public key is not matching the one stored.')
                             print "Exception in accountview ", e
                         return HttpResponseRedirect("/portal/account/")
index fa3ed10..047288d 100644 (file)
@@ -1060,10 +1060,11 @@ def iotlab_create_user (wsgi_request, request, namespace = None, as_admin=False)
     import requests
     import time
     from requests.auth import HTTPBasicAuth
-    
-    URL_REST = ConfigEngine.default_iotlab_url
-    LOGIN_ADMIN = ConfigEngine.default_iotlab_admin_user
-    PASSWORD_ADMIN = ConfigEngine.default_iotlab_admin_password
+   
+    engine = ConfigEngine() 
+    URL_REST = engine.iotlab_url()
+    LOGIN_ADMIN = engine.iotlab_admin_user()
+    PASSWORD_ADMIN = engine.iotlab_admin_password()
 
     auth = HTTPBasicAuth(LOGIN_ADMIN,PASSWORD_ADMIN)
     headers = {'content-type': 'application/json'}
index 0282e96..2add3a4 100644 (file)
@@ -173,7 +173,7 @@ class JoinView (FreeAccessView, ThemeView):
                     'user_hrn'      : user_hrn,
                     'pi'            : [reg_auth],
                     'auth_type'     : 'managed',
-                    'validation_link': 'http://' + current_site + '/portal/email_activation/'+ email_hash
+                    'validation_link': current_site + '/portal/email_activation/'+ email_hash
                 }
 
                 
index aaa79b2..8a48428 100644 (file)
@@ -109,7 +109,7 @@ class ProjectRequestView(LoginRequiredAutoLogoutView, ThemeView):
                     errors.append('Organization is mandatory')
     
                 if (post['purpose'] is None or post['purpose'] == ''):
-                    errors.append('Experiment purpose is mandatory')
+                    errors.append('Project purpose is mandatory')
 
                 if (re.search(r'^[A-Za-z0-9_]*$', post['project_name']) == None):
                     errors.append('Project name may contain only letters, numbers, and underscore.')
@@ -128,14 +128,14 @@ class ProjectRequestView(LoginRequiredAutoLogoutView, ThemeView):
                         hrn = post['authority_hrn'] + '.' + post['project_name']
                         sfa_add_authority(wsgi_request, {'authority_hrn':hrn})
                         authority_add_pis(wsgi_request, hrn, user_hrn)
-                    self.template_name = 'slice-request-done-view.html'
+                    self.template_name = 'project-request-done-view.html'
                 else:
                     # Otherwise a wsgi_request is sent to the PI
                     if 'join' in wsgi_request.POST:
                         create_pending_join(wsgi_request, post)
                     else:
                         create_pending_project(wsgi_request, post)
-                    self.template_name = 'slice-request-ack-view.html'
+                    self.template_name = 'project-request-ack-view.html'
 
         # retrieves the pending projects creation list
         pending_projects = PendingProject.objects.all().filter(user_hrn=user_hrn)
index 47ae6c9..d1c12ca 100644 (file)
@@ -81,7 +81,7 @@ class RegistrationView (FreeAccessView, ThemeView):
                 'current_site'  : current_site,
                 'email_hash'    : email_hash,
                 'pi'            : '',
-                'validation_link': 'http://' + current_site + '/portal/email_activation/'+ email_hash
+                'validation_link': current_site + '/portal/email_activation/'+ email_hash
             }
 
             print "############ BREAKPOINT 4 #################"
index f198e15..1779d1c 100644 (file)
@@ -17,6 +17,8 @@ from myslice.configengine import ConfigEngine
 from myslice.theme import ThemeView
 from myslice.configengine import ConfigEngine
 
+from sfa.planetlab.plxrn import hash_loginbase
+
 import urllib2,json
 
 class ExperimentView (FreeAccessView, ThemeView):
@@ -26,12 +28,14 @@ class ExperimentView (FreeAccessView, ThemeView):
   
         username = self.request.user    
         
-        split_slicename = slicename.split('.')
-        ple_slicename = split_slicename[0] + '8' + split_slicename[1] + '_' + split_slicename[2]
-
-        query_current_resources = Query.get('slice').select('resource').filter_by('slice_hrn','==',slicename)
+        query_current_resources = Query.get('slice').select('resource','parent_authority').filter_by('slice_hrn','==',slicename)
         current_resources = execute_query(request, query_current_resources)
 
+        parent_authority = current_resources[0]['parent_authority']
+        
+        split_slicename = slicename.split('.')
+        ple_slicename = hash_loginbase(parent_authority) + '_' + split_slicename[-1]
+
         ple_resource_list=[]
         nitos_resource_list=[]
         nitos_paris_resource_list=[]
@@ -75,6 +79,7 @@ class ExperimentView (FreeAccessView, ThemeView):
         #print nitos_resource_list
 
         #get all  iotlab users
+        all_users = list() 
         try:
             engine = ConfigEngine()
             userData = "Basic " + (engine.iotlab_admin_user() + ":" + engine.iotlab_admin_password()).encode("base64").rstrip()
@@ -88,7 +93,6 @@ class ExperimentView (FreeAccessView, ThemeView):
         except urllib2.URLError as e:
             print "There is a problem in getting iotlab users %s" % e.reason
        
-        all_users = list() 
 
         #getting the login from email
         #initial value  no-account == contact_admin
index e6d06d7..4627124 100644 (file)
@@ -13,7 +13,7 @@ body {
 a, a:active, a:focus {
     outline: 0;
     text-decoration:none;
-    color:#760073;
+    color:#FF4400;
 }
 a:hover {
     color:#0D0049;
@@ -178,14 +178,14 @@ button.btn-danger:active {
 }
 button.btn-onelab, input.btn-onelab {
     border:0;
-    border-bottom:3px solid #760073;
-    background-color:#302562;
+    border-bottom:3px solid #FFA315;
+    background-color:#FFA315;
     color:white;
 }
 button.btn-onelab:hover, input.btn-onelab:hover {
     border:0;
-    border-bottom:3px solid #760073;
-    background-color:#302562;
+    border-bottom:3px solid #FF7E00;
+    background-color:#FF7E00;
     color:white;
 }
 button.btn-onelab:active, input.btn-onelab:active {
@@ -590,7 +590,7 @@ div.navigation li a {
     color:#0C0047;
 }
 div.navigation li a:hover, div.navigation li a.current {
-    color:#760073;
+    color:#FF4400;
     text-decoration:none;
 }
 
@@ -729,7 +729,7 @@ div.home {
     line-height:1.2em;
     letter-spacing:0.3pt;
     min-height:500px;
-    //background-image: url('../img/bg-experiment.png');
+    background-image: url('../img/bg-smartfire.png');
     background-repeat:no-repeat;
     background-size:cover;
     background-position:center top;
@@ -812,7 +812,6 @@ div.registration-form {
 div.slogan {
     text-align:center;
     color:white;
-    padding-top:60px;
     text-shadow: 1px 1px #013540;
 }
 
diff --git a/portal/static/img/bg-smartfire.png b/portal/static/img/bg-smartfire.png
new file mode 100644 (file)
index 0000000..f5340fc
Binary files /dev/null and b/portal/static/img/bg-smartfire.png differ
index 6236344..668c3d3 100644 (file)
@@ -1,51 +1,49 @@
-
-<div id="header">
-       <div class="wrapper">
-               <div class="logo">
-                       <a href="/"><img src="{{ STATIC_URL }}img/onelab-portal.png" alt="OneLab - Future Internet Testbeds" /></a>
+{% load portal_filters %}
+<div class="header">
+<div class="container">
+       <div class="row">
+               <div class="col-sm-3 col-md-3 logo">
+                       <a href="/"><img src="{{ STATIC_URL }}img/onelab-portal.png" alt="OneLab Portal - Future Internet Testbeds" /></a>
+               </div>
+               {% if username %}
+               <div class="col-sm-4 col-md-4 navigation">
+                       <ul>
+                               <li>
+                                       <a class="dropdown-toggle" data-toggle="dropdown" href="#">
+                                       EXPERIMENT <span class="caret"></span>
+                               </a>
+                                       
+                                       <div class="dropdown-menu" style="z-index:99;">
+                                                       <ul id="dropdown-slice-list">
+                                                               <li class="title"><a href="/portal/slice_request/">Request Slice</a></li>
+                                                       </ul>
+                                       </div>
+                               </li>
+                               {%if 'is_pi'  in pi %}  
+                               <li id="nav-institution" class=""><a href="/institution">MANAGEMENT</a></li>
+                                {%endif%}
+                               <li><a href="/support/">SUPPORT</a></li>
+                       </ul>
+               </div>
+               {% else %}
+               <div class="col-sm-4 col-md-4 navigation">
                </div>
-               
-               <div id="secondary">
+               {% endif %}
+               <div class="col-sm-5 col-md-5 secondary">
                        <ul>
                                <li><a href="/news">News</a></li>
-                               <li><a href="/portal/about">About</a></li>
-                               <li><a target="_blank" href="http://www.onelab.eu">Public Website</a></li>
+                               <li><a href="/about">About</a></li>
+                               <li><a target="_blank" href="https://www.onelab.eu">Public Website</a></li>
                                <li><a target="_blank" href="http://intranet.onelab.eu">Intranet</a></li>
                        </ul>
+                       {% if username %}
+                       <div class="account">You are logged in as &nbsp;<a href="/account/">{{ username }}</a> &nbsp;&nbsp;|&nbsp;&nbsp; <a id="logout" style="cursor:pointer;" data-username="{{ username }}"><span class="glyphicon glyphicon-off"></span> Logout</a></div>
+                       {% endif %}
                </div>
        </div>
-       
-       {% if username %}
-       <div id="navigation">
-               <div class="wrapper">
-               <ul>
-                       <li id="nav-account"><a href="/portal/account/">{{ username }}</a></li>
-                       <li>|</li>
-                       <li id="nav-institution" class=""><a href="/portal/institution">INSTITUTION</a></li>
-                       <li class="slices">
-                               <a class="dropdown-toggle" data-toggle="dropdown" href="#">
-                                       SLICES <span class="caret"></span>
-                       </a>
-                               
-                               <div class="dropdown-menu" style="z-index:99;">
-                                               <ul id="dropdown-slice-list">
-                                                       <li><a href="/portal/slice_request/">Request Slice</a></li>
-                                               </ul>
-                               </div>
-                               </li>
-                       <li id="nav-request"><a href="/portal/validate">REQUESTS</a></li>
-                       <li id="nav-support"><a href="/portal/support/">SUPPORT</a></li>
-                       <li>|</li>
-                       <li id="nav-logout" style="margin-top: 10px;"><a id="logout" style="cursor:pointer;" data-username="{{ username }}"><span class="glyphicon glyphicon-off"></span> LOGOUT</a></li>
-               </ul>
-               </div>
-       </div>
-       {% else %}
-       <div id="navigation">
-               <div class="wrapper"></div>
-       </div>
-       {% endif %}
 </div>
+</div>
+
 <script>
        $(document).ready(function() {
                $('li.slices').mouseenter(function() {
index 2b99be1..985974f 100644 (file)
@@ -1,7 +1,22 @@
-{% extends "layout_wide.html" %}
+{% extends "layout.html" %}
+{% load portal_filters %}
 {% block content %}
+{% widget "_widget-no_credentials.html" %}
+{% widget "_widget-tradeoff.html" %}
+<div class="row">
+       <div class="col-md-12">
+                <div class="breadcrumbs">
+                        Account &nbsp;>&nbsp; <a href="/account">{{ person.email }}</a>
+                </div>
+       </div>
+        {%if 'no_creds' in user_cred %}
+    <p class="command"><a href="#" style="color:red" data-toggle="modal" data-target="#myModal">NO CREDENTIALS</a> are delegated to the portal!</p>
+    {%endif%}
+        {%if 'creds_expired' in user_cred %}
+    <p class="command"><a href="#" style="color:red" data-toggle="modal" data-target="#myModal">EXPIRED CREDENTIALS</a> Please delegate again your credentials to the portal!</p>
+    {%endif%}
 
-
+</div>
 {% if messages %}
 <ul class="messages">
     {% for message in messages %}
     {% endfor %}
 </ul>
 {% endif %}
-<div class="container">
-       <div class="row">
-               <div class="col-md-12">
-                       <ul class="nav nav-tabs nav-section">
-                               <li class="active"><a href="#profile"><img src="{{ STATIC_URL }}icons/user-xs.png" alt="User Account" /> User Profile</a></li>
-                               <li><a href="#account">Account</a></li>
-                               <li><a href="#access">Testbed Access</a></li>
-                       </ul>
-           </div>
-       </div>
+
+<form id="editForm" method="post" action="account_process" enctype="multipart/form-data">
+<input type="hidden" id="button_value"  name="button_value" value="" />
+
+<div class="row">
+       <div class="col-md-12">
+               <ul class="nav nav-tabs nav-section">
+                       <li class="active"><a href="#profile">User Profile</a></li>
+                       <li><a href="#account">Account</a></li>
+                       <li><a href="#access">Testbed Access</a></li>
+               </ul>
+    </div>
 </div>
-<div class="container tab-content">
+<div class="tab-content">
        <div class="tab-pane active row" id="profile">
                
                <div class="col-md-12">
 
-                       <form id="editForm" method="post" action="account_process" enctype="multipart/form-data">
                                {% csrf_token %}
                                        <table class="profile">          
                                        <tr>
@@ -37,7 +53,7 @@
                                                <td class="key">Email</td>
                                                <td class="value">
                                                                <span id="emailval" class="value" >{{ person.email }}</span>
-                                                               <button class="btn btn-default btn-xs" type="button" id="edit_email" onclick="editAlert();"  title="To change your affiliation please contact the administrator">
+                                                               <button class="btn btn-default" type="button" id="edit_email" onclick="editAlert();"  title="To change your affiliation please contact the administrator">
                                                                <span class="glyphicon glyphicon-question-sign"></span> Edit
                                                                </button>
                                                        </td>
                                                <tr class="even">
                                                        <td class="key">Generate Keys</td>
                                                        <td>
-                                                               <input type="submit" name="generate" class="btn btn-danger btn-xs" value="Generate a new Key Pair" id="generate_keypair" 
+                                                               <input type="submit" name="generate" class="btn btn-primary" value="Generate a new Key Pair" id="generate_keypair" 
                                                                           onclick="return confirm('Are you sure? If you do so, your current credentials will be overwritten.');" 
                                                                           title="It will generate a new key Pair and your current credentials will be overwritten."/>
                                                </td> 
                                                <td class="value">
                                                                <span id="keyval" class="value">******** </span>
                                                                <span class="hide_this" id="span_upload">
-                                                                       <button type="button" class="btn btn-default btn-xs" title="Cancel" id="cancel_upload"> Cancel </button>
+                                                                       <button type="button" class="btn btn-default" title="Cancel" id="cancel_upload"> Cancel </button>
                                                                        <div style='display:none;'>
                                                                                <input type='hidden'  name='upload'  /></div>
                                                                                <input type="file" name="pubkey" class="required" id="pubkey"/>  
                                                                                   onclick="return confirm('Are you sure? It will overwrite your current credentials and you have delegate it manually.');"/>
                                                                </span>
                                                                <div style='display:none;'> <input type='hidden'  name='dload'  /> </div> 
-                                                               <button type="submit" name="dl_pubkey" class="btn btn-default btn-xs" title="Download your public key" id="dl_file">
+                                                               <button type="submit" name="dl_pubkey" class="btn btn-default btn-xs" title="Download your public key" id="dl_pubkey" onclick="javascript:document.getElementById('button_value').value='dl_pubkey';">
                                                                        <span class="glyphicon glyphicon-download"></span> Download
                                                                </button>
                                                                <button class="btn btn-default btn-xs" id="upload_file" type="button" title="Upload a public key">
                                                 {%if 'N/A' not in user_private_key%}
                                                <td class="key">Private Key </td> <!-- Hide if priv_key doesn't exist in myslice platform   -->
                                                <td class="value">********<a href="#"></a>
-                                                       <button type="submit" name="dl_pkey" class="btn btn-default btn-xs" title="Download your privaye key" id="dl_pkey">
+                                                       <button type="submit" name="dl_pkey" class="btn btn-default" title="Download your privaye key" id="dl_pkey" value="dl_pkey" onclick="javascript:document.getElementById('button_value').value='dl_pkey';">
                                                                        <span class="glyphicon glyphicon-download"></span> Download     
                                                                </button>
                                                        <input class="btn btn-danger btn-xs" id="delete" name="delete" type="submit"  value="Delete" title="Delete your private key"
-                                                                               onclick="return confirm('Are you sure? If you do so, you have to delegate your credentials manually.');"/> 
+                                                                               onclick="javascript:document.getElementById('button_value').value='delete'; return confirm('Are you sure? If you do so, you have to delegate your credentials manually.');"/> 
                                                </td>
                                                  {%else%}
                                                        <td class="key">Private Key </td> <!-- Hide if priv_key doesn't exist in myslice platform   -->
                                                        <td class="value">********<a href="#"></a>
-                                                       <button type="submit" name="dl_pkey" class="btn btn-default btn-xs disabled" title="Download your privaye key" id="dl_pkey">
+                                                       <button type="submit" name="dl_pkey" class="btn btn-default disabled" title="Download your privaye key" id="dl_pkey" value="dl_pkey">
                                                                <span class="glyphicon glyphicon-download"></span> Download 
                                                        </button>
                                                        <input class="btn btn-danger btn-xs disabled" id="delete" name="delete" type="submit" title="Delete your private key" value="Delete" />
                                        <tr class="even" id="sfi_config_row">
                                                <td class="key">sfi_config </td>
                                                <td class="value">use sfi_config file with sfi.py package (pip install sfa)<a href="#"></a>
-                                                       <button type="submit" name="dl_sfi_config" class="btn btn-default btn-xs" title="Download your privaye key" id="dl_sfi_config">
-                                                                       <span class="glyphicon glyphicon-download"></span> Download 
+                                                       <button type="submit" name="dl_sfi_config" class="btn btn-default btn-xs" title="Download your sfi_config" id="dl_sfi_config" value="dl_sfi_config" onclick="javascript:document.getElementById('button_value').value='dl_sfi_config';">
+                                                                       <span class="glyphicon glyphicon-download"></span> Download
                                                                </button>
                                                </td>
                         </tr>
+                                               <tr class="odd">
+                                                       {%if 'N/A' not in user_private_key%}
+                                                       <td class="key">Identity</td> 
+                                               <td>
+                                                               <button type="submit" name="dl_identity" class="btn btn-default btn-xs" title="You will require it to use jfed" id="dl_identity" onclick="javascript:document.getElementById('button_value').value='dl_identity';">
+                                                               <span class="glyphicon glyphicon-download"></span> Download 
+                                                               </button>
+                                                       </td>
+                                                       {%else%}
+                                                       <td class="key">Identity</td> 
+                                                       <td>
+                                                       <button type="submit" name="dl_identity" class="btn btn-default btn-xs disabled" title="You will require it to use jfed" id="dl_identity">
+                                                               <span class="glyphicon glyphicon-download"></span> Download 
+                                                       </button>
+                                                       </td>
+                                                       {%endif%} 
+                                               </tr>
+
                                                <tr class="even">
                                                <td colspan="2">
-                                                       <p class="message" id="pkey_del_msg"><b> Tradeoff:</b> Ease-of-use vs Security.<br>
-                                                                       <b>Ease-of-use:</b> Automatic account delegation. Don't delete private key.<br>
-                                                                       <b>Security:</b> Manual account delegation. Download & Delete private key.
+                                                               <p class="command">
+                                                                       <a href="#" style="color:green" data-toggle="modal" data-target="#tradeoffmodal">Automatic vs. Manual delegation of credentials:</a>
+                                                                       Trade-off between ease-of-use & security</p>
                                                                </p>
                                                </td>
                                                </tr>
                </table>
        
                </div>
-       
 
        {%if 'Enabled'  in user_status %}
                <div class="col-md-12">
                <h3>Credentials <small>Delegated to Principal Account</small></h3>
-                       <table class="table">
-                                       <caption><b>Delegated User Credential</b></caption> 
-                           <tr class="odd"> 
-                               <th>Expiration Date</th>
-                                               <th>Download</th>
-                           </tr>
-                                       {% for row in my_users %}         
-                                       <tr class="border_bottom">
-                                       <td class="odd"> {{ row.cred_exp }} </td>
-                                               <td class="odd">
-                                                       <button class="btn btn-default btn-xs" name= "dl_user_cred" type="submit" title="Download User Credential">
-                                                               <span class="glyphicon glyphicon-download"></span> Credential
-                                                       </button>
-                                                       <button class="btn btn-default btn-xs" name= "dl_user_cert" type="submit" title="Download User Certificate">
-                                                               <span class="glyphicon glyphicon-download"></span> Certificate
-                                                       </button>
-                             <button class="btn btn-default btn-xs" name= "dl_user_p12" type="submit" title="Download User PKCS12">
-                                 <span class="glyphicon glyphicon-download"></span> PKCS p12
-                             </button>
-                                               </td>
-                                       </tr>
-                                       {%endfor%}
-                                </table>
-                               <p></p>
-                               <table class="mytable table table-bordered table-hover">
-                                       <caption><b>Delegated Slice Credentials</b></caption>  
-                               <tr class="odd"> 
-                                               <th>Slice Name</th> 
-                                       <th>Expiration Date</th>
-                                               <th>Download</th>
-                               </tr>
-                                       {% for row in my_slices %}     
-                               <tr class="border_bottom">
-                                       <td class="odd"> {{ row.slice_name }} </td>
-                                               <td class="odd"> {{ row.cred_exp }} </td>
-                                               <td class="odd"> 
-                                                       <button class="btn btn-default btn-xs" name= "dl_{{row.slice_name}}" type="submit" title="Download Slice Credentials">
-                                                               <span class="glyphicon glyphicon-download"></span> Download
-                                                       </button> 
-                                               </td>
-                               </tr>
-                               {%endfor%}
-                               </table>
-                               <p></p>
-                               <table class="mytable table table-bordered table-hover">
-                                       <caption><b>Delegated Authority Credentials</b></caption>
-                                       <tr class="odd"> 
-                                       <th>Authority Name</th> 
-                                       <th>Expiration Date</th>
-                                               <th>Download</th>
-                                       </tr>
-                                       {% for row in my_auths %}
-                                       <tr class="border_bottom">
-                                       <td class="odd"> {{ row.auth_name }} </td>
-                                       <td class="odd"> {{ row.cred_exp }} </td>
-                                               <td class="odd">
-                                                       <button class="btn btn-default btn-xs" name= "dl_{{row.auth_name}}" type="submit" title="Download Authority Credentials">
-                                                               <span class="glyphicon glyphicon-download"></span> Download
-                                                       </button>
-                                               </td>
-                                       </tr>
-                                       {%endfor%}
-                               </table>
-                               <p></p>
-                                {%if '' not in my_users%}      
-                               <p><button class="btn btn-danger btn-lg btn-block"   name= "clear_cred" type="submit" title="Clear All Credentials">Clear Credentials</button></p>
-                               {%else%}
-                               <p><button class="btn btn-danger btn-lg btn-block disabled"   name= "clear_cred" type="submit" title="Clear All Credentials">Clear Credentials</button></p>
-                               {%endif%}
+                   <table class="table">
+                               <caption><b>Delegated User Credential</b></caption> 
+                       <tr class="odd"> 
+                           <th>Expiration Date</th>
+                                       <th>Download</th>
+                       </tr>
+                               {% for row in my_users %}         
+                               <tr class="border_bottom">
+                               <td class="odd"> {{ row.cred_exp }} </td>
+                                       <td class="odd">
+                                               <button class="btn btn-default btn-xs" name= "dl_user_cred" type="submit" title="Download User Credential" onclick="javascript:document.getElementById('button_value').value='dl_user_cred';">
+                                                       <span class="glyphicon glyphicon-download"></span> Credential
+                                               </button>
+                                               <button class="btn btn-default btn-xs" name= "dl_user_cert" type="submit" title="Download User Certificate" onclick="javascript:document.getElementById('button_value').value='dl_user_cert';">
+                                                       <span class="glyphicon glyphicon-download"></span> Certificate
+                                               </button>
+                         <button class="btn btn-default btn-xs" name= "dl_user_p12" type="submit" title="Download User PKCS12" onclick="javascript:document.getElementById('button_value').value='dl_user_p12';">
+                             <span class="glyphicon glyphicon-download"></span> PKCS p12
+                         </button>
+                                       </td>
+                               </tr>
+                               {%endfor%}
+                        </table>
+                       <p></p>
+                       <table class="mytable table table-bordered table-hover">
+                               <caption><b>Delegated Slice Credentials</b></caption>  
+                       <tr class="odd"> 
+                                       <th>Slice Name</th> 
+                               <th>Expiration Date</th>
+                                       <th>Download</th>
+                       </tr>
+                               {% for row in my_slices %}     
+                       <tr class="border_bottom">
+                               <td class="odd"> {{ row.slice_name }} </td>
+                                       <td class="odd"> {{ row.cred_exp }} </td>
+                                       <td class="odd"> 
+                                               <button class="btn btn-default btn-xs" name= "dl_{{row.slice_name}}" type="submit" title="Download Slice Credentials" onclick="javascript:document.getElementById('button_value').value='dl_{{row.slice_name}}';">
+                                                       <span class="glyphicon glyphicon-download"></span> Download
+                                               </button> 
+                                       </td>
+                       </tr>
+                       {%endfor%}
+                       </table>
+                       <p></p>
+                       <table class="mytable table table-bordered table-hover">
+                               <caption><b>Delegated Authority Credentials</b></caption>
+                               <tr class="odd"> 
+                               <th>Authority Name</th> 
+                               <th>Expiration Date</th>
+                                       <th>Download</th>
+                               </tr>
+                               {% for row in my_auths %}
+                               <tr class="border_bottom">
+                               <td class="odd"> {{ row.auth_name }} </td>
+                               <td class="odd"> {{ row.cred_exp }} </td>
+                                       <td class="odd">
+                                               <button class="btn btn-default btn-xs" name= "dl_{{row.auth_name}}" type="submit" title="Download Authority Credentials" onclick="javascript:document.getElementById('button_value').value='dl_{{row.auth_name}}';">
+                                                       <span class="glyphicon glyphicon-download"></span> Download
+                                               </button>
+                                       </td>
+                               </tr>
+                               {%endfor%}
+                       </table>
+                       <p></p>
+                        {%if '' not in my_users%}      
+                       <p><button class="btn btn-danger btn-lg btn-block"   name= "clear_cred" type="submit" title="Clear All Credentials" onclick="javascript:document.getElementById('button_value').value='clear_cred';">Clear Credentials</button></p>
+                       {%else%}
+                       <p><button class="btn btn-danger btn-lg btn-block disabled"   name= "clear_cred" type="submit" title="Clear All Credentials">Clear Credentials</button></p>
+                       {%endif%}
                </div>
        </div>
 
+
        <div class="tab-pane row" id="access">
                <div class="col-md-12">
        
                 <td class="odd"> {{ row.account_type }} </td>
                                <td class="odd"> {{ row.account_reference }} </td>
                                <td class="odd">
-                               <button class="btn btn-danger btn-xs" name="delete_{{row.platform_name}}" type="submit" title="Delete account from this platform">
+                               <button class="btn btn-danger" name="delete_{{row.platform_name}}" type="submit" title="Delete account from this platform" onclick="javascript:document.getElementById('button_value').value='delete_{{row.platform_name}}';">
                                                <span class="glyphicon glyphicon-minus"></span>
                                        </button>
                                </td>
             <tr class="border_bottom">
                 <td class="odd"> {{ platform.platform_no_access }} </td>
                 <td class="odd">
-                                       <button class="btn btn-success btn-sm" name= "add_{{platform.platform_no_access}}" type="submit" title="Add account to this platform">
+                                       <button class="btn btn-success btn-sm" name= "add_{{platform.platform_no_access}}" type="submit" title="Add account to this platform" onclick="javascript:document.getElementById('button_value').value='add_{{platform.platform_no_access}}';">
                                                <span class="glyphicon glyphicon-plus"></span>
                                        </button>
                                </td>
        </div>
 {%endif%} 
 </div>
-</form>
 </div>
 
+</form>
 <script>
     $(document).ready(function() {
+           {%if 'no_creds' in user_cred or 'creds_expired' in user_cred %}
+        localStorage.clear();
+        $.post("/cache/clear/", function( data ) {
+        });
+        {% endif %}
        $('.nav-tabs a').click(function (e) {
                        e.preventDefault();
                        $(this).tab('show');
                        id = $(this).attr('href').substr(1);
-               
                });
                
         $('button#createslice').click(function() {
index df38156..9c6eb1b 100644 (file)
@@ -3,7 +3,16 @@
 <html lang="en"><head>
 <title>{{theme}} portal - {{ section }}</title>
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
-<link rel="shortcut icon" href="/static/img/favicon.ico">
+
+<!--Selecting favicon based on theme. Add more for other portals -->
+{% if theme == "fed4fire" %}
+    <link rel="shortcut icon" href="/static/img/fed4fire_favicon.ico">
+{% elif theme == "smartfire" %}
+    <link rel="shortcut icon" href="/static/img/smartfire_favicon.ico">
+{% else %}
+    <link rel="shortcut icon" href="/static/img/favicon.ico">
+{% endif %}
+
 {# This is where insert_str will end up #}{% media_container prelude %}
 {% include 'messages-transient-header.html' %}
 <script type="text/javascript"> {# raw js code - use {% insert prelude_js %} ... {% endinsert %} #} {% container prelude_js %}</script>
diff --git a/portal/templates/fed4fire/fed4fire_slice-tab-experiment.html b/portal/templates/fed4fire/fed4fire_slice-tab-experiment.html
deleted file mode 100644 (file)
index 0ca237f..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-<div class="col-md-2">
-</div>
-<div class="col-md-8">
-       <h2>How to access your slice</h2>
-       <h3>PlanetLab Europe</h3>
-       
-       <p>
-               PlanetLab Europe resources are accessible directly via SSH. Your SSH public key is deployed automatically
-               on the reserved nodes. To access your slice on a resource just type the following command:
-       </p>
-       {%if ple_resources%}
-       <p class="command">
-       {%for resource in ple_resources %}
-               $ ssh {{ple_slicename}}@{{resource}}<br>
-       {%endfor%}
-       </p>
-        <h4>Windows users</h4>
-        <p>Use <a href="http://www.putty.org/" target="_blank">SSH client.</a></p>
-
-       {%else%}
-               <p><b>NOTE:</b> You did not reserve any PLE resources yet. Once reserved, you will get the actual SSH command. A specimen command is given below:</p>
-               <p class="command">
-               $ ssh {{ple_slicename}}@planetlab-resource.hostname.com<br>
-               </p>
-                <h4>Windows users</h4>
-                <p>Use <a href="http://www.putty.org/" target="_blank">SSH client.</a></p>
-
-       {%endif%}
-       <p><strong>NOTE:</strong> Your original slicename <b>{{slicename}}</b> has been converted to PlanetLab specific format <b>{{ple_slicename}}</b> in order to do SSH.</p>
-       <p>Please note that the first '.' is replaced by number 8 and the rest of the dot/s are replaced by underscore/s.</p>
-       <p>
-               Be aware that after you reserve a PlanetLab Europe resource your slice will be deployed with a delay of about 15 minutes, 
-               after witch you will be able to access the resource.
-       </p>
-       
-       <h3>NITOS</h3>
-       
-       <p>
-        NITOS resources are not directly accessible. You will need to log in on a gateway server and from there access the node.
-        The NITOS server address is nitlab.inf.uth.gr, so to connect to the NITOS server:
-       </p>
-       <p class="command">
-       $ ssh {{slicename}}@nitlab.inf.uth.gr
-       </p>
-       <h4>Windows users</h4>
-       <p>Use <a href="http://www.putty.org/" target="_blank">SSH client.</a></p>
-
-       <p>
-       <!-- In order to connect to NITOS server he has to upload his public key on the server. 
-       For now we do it this way: http://nitlab.inf.uth.gr/NITlab/index.php/your-ssh-keys. 
-       I think this is a procedure that needs to be done at the registration phase of the user, 
-       through myslice, Broker etc. but I will answer you in a couple of days for sure. -->
-       </p>
-
-       <p>
-               You will then need to prepare the resource by loading an OMF image on it:
-       </p>
-       
-       <p class="command">
-               $ omf load -i baseline_grid.ndz -t omf.nitos.node016
-       </p>
-
-       <p>
-               Turn on the node:
-       </p>
-       
-       <p class="command">
-               $ omf tell -a on -t omf.nitos.node016
-       </p>
-       <p>
-               And finally ssh on the node:
-       </p>
-       <p class="command">
-               $ ssh root@node016
-       </p>
-       <p>
-               On the node itself you will have to modify the file /etc/omf-resctl-5.3/omf-resctl.yaml according to your slice settings and then
-               restart the OMF Resource Controller and finally execute the experiment:
-       </p>
-       <p class="command">
-               $ omf exec --slice slice_name your_exp.rb
-       </p>
-       <p>
-       The complete tutorial is available at the following address:
-       <a target="_blank" href="http://nitlab.inf.uth.gr/NITlab/index.php/testbed/instructions/basic-tutorial">NITOS basic tutorial</a>
-       </p>
-       
-       <br />
-       
-       <h2>Available Tools</h2>
-       <p><img src="{{ STATIC_URL }}img/terminal_icon.png" width="50"> <b>SSH</b></p>
-       <p>
-       Secure Shell (SSH) is a cryptographic network protocol for secure data communication, remote command-line login, remote command execution, and other secure network services between two networked computers that connects, via a secure channel over an insecure network, a server and a client (running SSH server and SSH client programs, respectively). The protocol specification distinguishes between two major versions that are referred to as SSH-1 and SSH-2.
-       </p>
-       <p> More Info: <a href="http://en.wikipedia.org/wiki/Secure_Shell" target="_blank">http://en.wikipedia.org/wiki/Secure_Shell</a></p>
-       <br>
-       <br>
-       <p><img src="{{ STATIC_URL }}img/nepi_logo.png" width="90"></p>
-       <p>NEPI, the Network Experimentation Programming Interface, is a life-cycle management tool for network experiments. The idea behind NEPI is to provide a single tool to design, deploy, and control network experiments, and gather the experiment results. Going further, NEPI was specially conceived to function with arbitrary experimentation platforms, so researchers could use a single tool to work with network simulators, emulators, or physical testbeds, or even a mixture of them. To accomplish this, NEPI provides a high-level interface to describe experiments that is independent from any experimentation platform, but is able to capture platform specific configurations. Experiment definitions can be stored in XML format to be later reproduced, and modified according to experimentation needs. Experiment execution is orchestrated by a global experiment controller, that is platform independent, and different platform-dependent testbed controllers, creating a control hierarchy that is able t adapt to platform specific requirements while providing an integrated control scheme.</p>
-       <p> More Info: <a href="http://nepi.inria.fr" target="_blank">http://nepi.inria.fr</a></p>
-       <br>
-       <p><img src="{{ STATIC_URL }}img/omf-logo.png" width="90"></p>
-       <p>OMF is a Testbed Control, Measurement and Management Framework.</p>
-       <p>
-       OMF was originally developed for the ORBIT wireless testbed at Winlab, Rutgers University. Since 2007, OMF has been actively extended to operate on testbeds with many different type of network and resource technologies. It is now deployed and used on different testbeds in Australia, Europe, and in the U.S. OMF is currently being extended further to support exciting new features and technologies. This website is hosting this ongoing activity. OMF development is now conducted essentially within the TEMPO project at NICTA (Australia) in strong collaboration with Winlab (Rutgers University).
-       </p>
-       <p>In addition to the main OMF software, this site also hosts OMF sub-projects addressing various related aspects of a testbed's control, measurement, and management.</p>
-       <p>More Info: <a href="http://mytestbed.net/projects/omf" target="_blank">http://mytestbed.net/projects/omf</a></p>
-</div>
-<div class="col-md-2">
-</div>
index 383aa95..379547c 100644 (file)
-{% extends "layout.html" %}
+{% extends "layout_base.html" %}
 {% load portal_filters %}
 
 {% block content %}
-<div class="row">
+<!-- <div class="row">
 {% widget '_widget-news.html' %}
-</div>
-<div class="row" id="home-dashboard">
-       <ul class="nav nav-tabs">
-         <li class="active"><a class="home-tab" data-panel="user" href="#">USER</a></li>
-         <li><a class="home-tab" data-panel="manager" href="#">MANAGER</a></li>
-       </ul>
-       <div class="home-panel" id="user">
-               <table>
-                       <tr>
-                               <td>ACCOUNT</td>
-                               <td>SLICES</td>
-                               <td>SUPPORT</td>
-                       </tr>
-                       <tr>
-                               <td><a href="/portal/account/"><img src="{{ STATIC_URL }}img/icon_user_color.png" alt="" /></a></td>
-                               <td><a href="#"><img src="{{ STATIC_URL }}img/icon_slices.png" alt="" /></a></td>
-                               <td><a href="/portal/support"><img src="{{ STATIC_URL }}img/icon_support.png" alt="" /></a></td>
-                       </tr>
-                       <tr>
-                               {% if person %}
-                               <td class="logged-in">
-                                       <button id="logoutbtn" type="button" class="btn btn-default" data-username="{{ username }}"><span class="glyphicon glyphicon-off"></span> Logout</button>
-                                       <div>
-                                       {% if person.last_name %}
-                                               {{person.first_name}} {{person.last_name}}<br />
-                                       {% endif %}
-                                       <span class="label">Email:</span> <a href='/portal/account/'>{{person.email}}</a>
-                               </div>
-                               {% else %}
-                               <td>
-                                       {% widget '_widget-login-user.html' %}
-                               {% endif %}
-                               </td>
-                               <td>
-                               {% if person %}
-                                       <button id="slicerequestbtn" type="button" class="btn btn-default"><span class="glyphicon glyphicon-plus"></span> Request Slice</button>
-                                       <div id="home-slice-list"><img src="{{ STATIC_URL }}img/loading.gif" alt="Loading Slices" /></div>
-                               {% else %}
-                                       <button id="signupbtn" type="button" class="btn btn-default"><span class="glyphicon glyphicon-user"></span> Sign Up</button>
+</div> -->
+{% if username %}
+{% widget "_widget-no_credentials.html" %}
+<div class="container dashboard">
+       {%if 'no_creds'  in user_cred %}
+        <p class="command"><a href="#" style="color:red" data-toggle="modal" data-target="#myModal">NO CREDENTIALS</a> are delegated to the portal!</p>
+    {%endif%}
+       {%if 'creds_expired'  in user_cred %}
+        <p class="command"><a href="#" style="color:red" data-toggle="modal" data-target="#myModal">EXPIRED CREDENTIALS</a> Please delegate again your credentials to the portal!</p>
+    {%endif%}
+
+       <div class="row">
+               {% if pi %}
+               <div class="col-md-3">
+                       <h3>
+                               EXPERIMENT
+                       </h3>
+                       <div>
+                               <a href="#"><img src="{{ STATIC_URL }}img/icon_slices.png" alt="" /></a>
+                       </div>
+                       <div>
+                               <button id="slicerequestbtn" type="button" class="btn btn-default"><span class="glyphicon glyphicon-plus"></span> Create Slice</button>
+                       </div>
+                       <div>
+                               <p><strong>Your slices </strong>
+                                       <span title="A slice is a set of testbed resources on which you can conduct an experiment. 
+                                       Either ask your colleagues to give you access to an existing slice or request a new slice by clicking 'Request Slice'. 
+                                       However, on the OneLab portal, you will only see slices that you have created through OneLab. If you have created slices elsewhere, 
+                                       such as on the PlanetLab Europe portal, those slices will not appear here."
+                                       class="glyphicon glyphicon-info-sign">
+                               </span>
+
+                               </p>
+                       </div>
+                       <div>   
+                               <div id="home-slice-list"><img src="{{ STATIC_URL }}img/loading.gif" alt="Loading Slices" /></div>
+                       </div>
+               </div>
+               <div class="col-md-3">
+                       <h3>MANAGEMENT</h3>
+                       <div>
+                               <a href="/portal/institution"><img src="{{ STATIC_URL }}img/icon_authority_color.png" alt="" /></a>
+                       </div>
+                       <div>
+                               <button id="validaterequestbtn" type="button" class="btn btn-default"><span class="glyphicon glyphicon-ok"></span> Validate Requests</button>
+                       </div>
+               </div>
+               <div class="col-md-3">
+                       <h3>
+                               SUPPORT
+                       </h3>
+                       <div>
+                               <a href="/portal/support"><img src="{{ STATIC_URL }}img/icon_support.png" alt="" /></a>
+                       </div>
+                       <div>
+                               <button id="ticketbtn" type="button" class="btn btn-default"><span class="glyphicon glyphicon-envelope"></span> Contact</button>
+                       </div>
+               </div>
+               
+               <div class="col-md-3">
+                       <h3>
+                               ACCOUNT
+                       </h3>
+                       <div>
+                               <a href="/portal/account/"><img src="{{ STATIC_URL }}img/icon_user_color.png" alt="" /></a>
+                       </div>
+                       <div>
+                               <button id="logoutbtn" type="button" class="btn btn-default" data-username="{{ username }}"><span class="glyphicon glyphicon-off"></span> Logout</button>
+                       </div>
+                       <div>
+                               {% if person.last_name %}
+                                       {{person.first_name}} {{person.last_name}}<br />
                                {% endif %}
-                               </td>
-                               <td class="support">
-                                       <button id="ticketbtn" type="button" class="btn btn-default"><span class="glyphicon glyphicon-envelope"></span> Contact</button>
-                               </td>
-                       </tr>
-               </table>
+                       <span class="label">Username:</span> <a href='/portal/account/' title="Click here to see and edit your account details.">{{person.email}}</a>
+               </div>
+               </div>
        </div>
-       <div class="home-panel" id="manager">
-               <table>
-                       <tr>
-                               <td>INSTITUTION</td>
-                               <td>SLICES</td>
-                               <td>REQUESTS</td>
-                       </tr>
-                       <tr>
-                               <td><a href="/portal/institution"><img src="{{ STATIC_URL }}img/icon_authority_color.png" alt="" /></a></td>
-                               <td><a href="/portal/institution#slices"><img src="{{ STATIC_URL }}img/icon_slices.png" alt="" /></a></td>
-                               <td><a href="/portal/validate"><img src="{{ STATIC_URL }}img/icon_testbed_color.png" alt="" /></a></td>
-                       </tr>
-                       <tr>
-                               {% if person %}
-                               <td class="logged-in">
-                                       <button id="logoutbtn" type="button" class="btn btn-default" data-username="{{ username }}"><span class="glyphicon glyphicon-off"></span> Logout</button>
-                               {% else %}
-                               <td>
-                                       {% widget '_widget-login-manager.html' %}
+       {%else%}
+       <div class="row">
+               <div class="col-md-4">
+                       <h3>
+                               EXPERIMENT
+                       </h3>
+                       <div>
+                               <a href="#"><img src="{{ STATIC_URL }}img/icon_slices.png" alt="" /></a>
+                       </div>
+                       <div>
+                               <button id="slicerequestbtn" type="button" class="btn btn-default"><span class="glyphicon glyphicon-plus"></span> Request Slice</button>
+                       </div>
+                       <div>
+                               <p><strong>Your slices </strong>
+                               <span title="A slice is a set of testbed resources on which you can conduct an experiment. 
+                                       Either ask your colleagues to give you access to an existing slice or request a new slice by clicking 'Request Slice'. 
+                                       However, on the OneLab portal, you will only see slices that you have created through OneLab. If you have created slices elsewhere, 
+                                       such as on the PlanetLab Europe portal, those slices will not appear here."
+                                       class="glyphicon glyphicon-info-sign">
+                               </span>
+                               </p>
+                       </div>
+                       <div>   
+                               <div id="home-slice-list"><img src="{{ STATIC_URL }}img/loading.gif" alt="Loading Slices" /></div>
+                       </div>
+                       {% if pending_slices %}
+                       <p><strong>Pending slices</strong>
+                       <span title="Slices that you have requested and are pending for validation by the contact person of your organization."
+                               class="glyphicon glyphicon-info-sign">
+                       <ul>
+                       {% for slices in pending_slices %}
+                       <li>{{slices}}</li>
+                       {% endfor %}
+                       </ul>
+                       </span>
+                       </p>
+                       {%endif%}       
+               </div>
+               <div class="col-md-4">
+                       <h3>
+                               SUPPORT
+                       </h3>
+                       <div>
+                               <a href="/portal/support"><img src="{{ STATIC_URL }}img/icon_support.png" alt="" /></a>
+                       </div>
+                       <div>
+                               <button id="ticketbtn" type="button" class="btn btn-default"><span class="glyphicon glyphicon-envelope"></span> Contact</button>
+                       </div>
+               </div>
+               
+               <div class="col-md-4">
+                       <h3>
+                               ACCOUNT
+                       </h3>
+                       <div>
+                               <a href="/portal/account/"><img src="{{ STATIC_URL }}img/icon_user_color.png" alt="" /></a>
+                       </div>
+                       <div>
+                               <button id="logoutbtn" type="button" class="btn btn-default" data-username="{{ username }}"><span class="glyphicon glyphicon-off"></span> Logout</button>
+                       </div>
+                       <div>
+                               {% if person.last_name %}
+                                       {{person.first_name}} {{person.last_name}}<br />
                                {% endif %}
-                               </td>
-                               <td>
-                                       {% if person %}
-                                   <button id="slicerequestbtn" type="button" class="btn btn-default"><span class="glyphicon glyphicon-plus"></span> Create Slice</button>
-                                       {% endif %}
-                               </td>
-                               <td class="support">
-                                       {% if person %}
-                                   <button id="validaterequestbtn" type="button" class="btn btn-default"><span class="glyphicon glyphicon-ok"></span> Validate Requests</button>
-                                       {% endif %}
-                               </td>
-                       </tr>
-               </table>
+                       <span class="label">Username:</span> <a href='/portal/account/' title="Click here to see and edit your account details.">{{person.email}}</a>
+               </div>
+               </div>
        </div>
+       {%endif%}
+
 </div>
+{% else %}
+<div class="container-fluid home">
+       <div class="">
+               <div class="col-sm-2"></div>
+               <div class="col-sm-4 slogan">
+                       <h2>
+                               Your Easy Access to Computer Networking Testbeds:
+                       </h2>
+                       <h3>
+                               A wide variety of world class testbeds available through your one account
+                       </h3>
+               </div>
+               <div class="col-sm-5 col-sm-offset-1">
+                       <div class="row">
+                               {% widget '_widget-login-user.html' %}
+                       </div>
+               </div>
+               <div class="col-sm-1"></div>
+       </div>
+</div>
+{% endif %}
+
+
 <script type="text/javascript">
        $(document).ready(function() {
                $('a.home-tab').click(function() {
                        $('div#'+$(this).data('panel')).show();
                });
                $('button#validaterequestbtn').click(function() {
-                       window.location="/portal/validate/";
+                       window.location="/portal/institution#requests";
                });
                $('button#ticketbtn').click(function() {
                        window.location="/portal/contact/";
                $('button#slicerequestbtn').click(function() {
                        window.location="/portal/slice_request/";
                });
-/*-------
-List of slices has been moved in 
-portal/templates/base.html
-This should go into session
---------*/
+
+        myslice.loadSlices();
+        
 });
 </script>
+
 {% endblock %}
index 86071f1..985974f 100644 (file)
@@ -9,10 +9,10 @@
                         Account &nbsp;>&nbsp; <a href="/account">{{ person.email }}</a>
                 </div>
        </div>
-        {%if 'no_creds'  in user_cred %}
+        {%if 'no_creds' in user_cred %}
     <p class="command"><a href="#" style="color:red" data-toggle="modal" data-target="#myModal">NO CREDENTIALS</a> are delegated to the portal!</p>
     {%endif%}
-        {%if 'creds_expired'  in user_cred %}
+        {%if 'creds_expired' in user_cred %}
     <p class="command"><a href="#" style="color:red" data-toggle="modal" data-target="#myModal">EXPIRED CREDENTIALS</a> Please delegate again your credentials to the portal!</p>
     {%endif%}
 
     {% endfor %}
 </ul>
 {% endif %}
+
+<form id="editForm" method="post" action="account_process" enctype="multipart/form-data">
+<input type="hidden" id="button_value"  name="button_value" value="" />
+
 <div class="row">
        <div class="col-md-12">
                <ul class="nav nav-tabs nav-section">
@@ -38,7 +42,6 @@
                
                <div class="col-md-12">
 
-                       <form id="editForm" method="post" action="account_process" enctype="multipart/form-data">
                                {% csrf_token %}
                                        <table class="profile">          
                                        <tr>
                                                                                   onclick="return confirm('Are you sure? It will overwrite your current credentials and you have delegate it manually.');"/>
                                                                </span>
                                                                <div style='display:none;'> <input type='hidden'  name='dload'  /> </div> 
-                                                               <button type="submit" name="dl_pubkey" class="btn btn-default btn-xs" title="Download your public key" id="dl_file">
+                                                               <button type="submit" name="dl_pubkey" class="btn btn-default btn-xs" title="Download your public key" id="dl_pubkey" onclick="javascript:document.getElementById('button_value').value='dl_pubkey';">
                                                                        <span class="glyphicon glyphicon-download"></span> Download
                                                                </button>
                                                                <button class="btn btn-default btn-xs" id="upload_file" type="button" title="Upload a public key">
                                                 {%if 'N/A' not in user_private_key%}
                                                <td class="key">Private Key </td> <!-- Hide if priv_key doesn't exist in myslice platform   -->
                                                <td class="value">********<a href="#"></a>
-                                                       <button type="submit" name="dl_pkey" class="btn btn-default" title="Download your privaye key" id="dl_pkey">
+                                                       <button type="submit" name="dl_pkey" class="btn btn-default" title="Download your privaye key" id="dl_pkey" value="dl_pkey" onclick="javascript:document.getElementById('button_value').value='dl_pkey';">
                                                                        <span class="glyphicon glyphicon-download"></span> Download     
                                                                </button>
                                                        <input class="btn btn-danger btn-xs" id="delete" name="delete" type="submit"  value="Delete" title="Delete your private key"
-                                                                               onclick="return confirm('Are you sure? If you do so, you have to delegate your credentials manually.');"/> 
+                                                                               onclick="javascript:document.getElementById('button_value').value='delete'; return confirm('Are you sure? If you do so, you have to delegate your credentials manually.');"/> 
                                                </td>
                                                  {%else%}
                                                        <td class="key">Private Key </td> <!-- Hide if priv_key doesn't exist in myslice platform   -->
                                                        <td class="value">********<a href="#"></a>
-                                                       <button type="submit" name="dl_pkey" class="btn btn-default disabled" title="Download your privaye key" id="dl_pkey">
+                                                       <button type="submit" name="dl_pkey" class="btn btn-default disabled" title="Download your privaye key" id="dl_pkey" value="dl_pkey">
                                                                <span class="glyphicon glyphicon-download"></span> Download 
                                                        </button>
                                                        <input class="btn btn-danger btn-xs disabled" id="delete" name="delete" type="submit" title="Delete your private key" value="Delete" />
                                        <tr class="even" id="sfi_config_row">
                                                <td class="key">sfi_config </td>
                                                <td class="value">use sfi_config file with sfi.py package (pip install sfa)<a href="#"></a>
-                                                       <button type="submit" name="dl_sfi_config" class="btn btn-default btn-xs" title="Download your privaye key" id="dl_sfi_config">
+                                                       <button type="submit" name="dl_sfi_config" class="btn btn-default btn-xs" title="Download your sfi_config" id="dl_sfi_config" value="dl_sfi_config" onclick="javascript:document.getElementById('button_value').value='dl_sfi_config';">
                                                                        <span class="glyphicon glyphicon-download"></span> Download
                                                                </button>
                                                </td>
                         </tr>
+                                               <tr class="odd">
+                                                       {%if 'N/A' not in user_private_key%}
+                                                       <td class="key">Identity</td> 
+                                               <td>
+                                                               <button type="submit" name="dl_identity" class="btn btn-default btn-xs" title="You will require it to use jfed" id="dl_identity" onclick="javascript:document.getElementById('button_value').value='dl_identity';">
+                                                               <span class="glyphicon glyphicon-download"></span> Download 
+                                                               </button>
+                                                       </td>
+                                                       {%else%}
+                                                       <td class="key">Identity</td> 
+                                                       <td>
+                                                       <button type="submit" name="dl_identity" class="btn btn-default btn-xs disabled" title="You will require it to use jfed" id="dl_identity">
+                                                               <span class="glyphicon glyphicon-download"></span> Download 
+                                                       </button>
+                                                       </td>
+                                                       {%endif%} 
+                                               </tr>
 
                                                <tr class="even">
                                                <td colspan="2">
                </table>
        
                </div>
-       
 
        {%if 'Enabled'  in user_status %}
                <div class="col-md-12">
                <h3>Credentials <small>Delegated to Principal Account</small></h3>
-                       <table class="table">
-                                       <caption><b>Delegated User Credential</b></caption> 
-                           <tr class="odd"> 
-                               <th>Expiration Date</th>
-                                               <th>Download</th>
-                           </tr>
-                                       {% for row in my_users %}         
-                                       <tr class="border_bottom">
-                                       <td class="odd"> {{ row.cred_exp }} </td>
-                                               <td class="odd">
-                                                       <button class="btn btn-default btn-xs" name= "dl_user_cred" type="submit" title="Download User Credential">
-                                                               <span class="glyphicon glyphicon-download"></span> Credential
-                                                       </button>
-                                                       <button class="btn btn-default btn-xs" name= "dl_user_cert" type="submit" title="Download User Certificate">
-                                                               <span class="glyphicon glyphicon-download"></span> Certificate
-                                                       </button>
-                             <button class="btn btn-default btn-xs" name= "dl_user_p12" type="submit" title="Download User PKCS12">
-                                 <span class="glyphicon glyphicon-download"></span> PKCS p12
-                             </button>
-                                               </td>
-                                       </tr>
-                                       {%endfor%}
-                                </table>
-                               <p></p>
-                               <table class="mytable table table-bordered table-hover">
-                                       <caption><b>Delegated Slice Credentials</b></caption>  
-                               <tr class="odd"> 
-                                               <th>Slice Name</th> 
-                                       <th>Expiration Date</th>
-                                               <th>Download</th>
-                               </tr>
-                                       {% for row in my_slices %}     
-                               <tr class="border_bottom">
-                                       <td class="odd"> {{ row.slice_name }} </td>
-                                               <td class="odd"> {{ row.cred_exp }} </td>
-                                               <td class="odd"> 
-                                                       <button class="btn btn-default btn-xs" name= "dl_{{row.slice_name}}" type="submit" title="Download Slice Credentials">
-                                                               <span class="glyphicon glyphicon-download"></span> Download
-                                                       </button> 
-                                               </td>
-                               </tr>
-                               {%endfor%}
-                               </table>
-                               <p></p>
-                               <table class="mytable table table-bordered table-hover">
-                                       <caption><b>Delegated Authority Credentials</b></caption>
-                                       <tr class="odd"> 
-                                       <th>Authority Name</th> 
-                                       <th>Expiration Date</th>
-                                               <th>Download</th>
-                                       </tr>
-                                       {% for row in my_auths %}
-                                       <tr class="border_bottom">
-                                       <td class="odd"> {{ row.auth_name }} </td>
-                                       <td class="odd"> {{ row.cred_exp }} </td>
-                                               <td class="odd">
-                                                       <button class="btn btn-default btn-xs" name= "dl_{{row.auth_name}}" type="submit" title="Download Authority Credentials">
-                                                               <span class="glyphicon glyphicon-download"></span> Download
-                                                       </button>
-                                               </td>
-                                       </tr>
-                                       {%endfor%}
-                               </table>
-                               <p></p>
-                                {%if '' not in my_users%}      
-                               <p><button class="btn btn-danger btn-lg btn-block"   name= "clear_cred" type="submit" title="Clear All Credentials">Clear Credentials</button></p>
-                               {%else%}
-                               <p><button class="btn btn-danger btn-lg btn-block disabled"   name= "clear_cred" type="submit" title="Clear All Credentials">Clear Credentials</button></p>
-                               {%endif%}
+                   <table class="table">
+                               <caption><b>Delegated User Credential</b></caption> 
+                       <tr class="odd"> 
+                           <th>Expiration Date</th>
+                                       <th>Download</th>
+                       </tr>
+                               {% for row in my_users %}         
+                               <tr class="border_bottom">
+                               <td class="odd"> {{ row.cred_exp }} </td>
+                                       <td class="odd">
+                                               <button class="btn btn-default btn-xs" name= "dl_user_cred" type="submit" title="Download User Credential" onclick="javascript:document.getElementById('button_value').value='dl_user_cred';">
+                                                       <span class="glyphicon glyphicon-download"></span> Credential
+                                               </button>
+                                               <button class="btn btn-default btn-xs" name= "dl_user_cert" type="submit" title="Download User Certificate" onclick="javascript:document.getElementById('button_value').value='dl_user_cert';">
+                                                       <span class="glyphicon glyphicon-download"></span> Certificate
+                                               </button>
+                         <button class="btn btn-default btn-xs" name= "dl_user_p12" type="submit" title="Download User PKCS12" onclick="javascript:document.getElementById('button_value').value='dl_user_p12';">
+                             <span class="glyphicon glyphicon-download"></span> PKCS p12
+                         </button>
+                                       </td>
+                               </tr>
+                               {%endfor%}
+                        </table>
+                       <p></p>
+                       <table class="mytable table table-bordered table-hover">
+                               <caption><b>Delegated Slice Credentials</b></caption>  
+                       <tr class="odd"> 
+                                       <th>Slice Name</th> 
+                               <th>Expiration Date</th>
+                                       <th>Download</th>
+                       </tr>
+                               {% for row in my_slices %}     
+                       <tr class="border_bottom">
+                               <td class="odd"> {{ row.slice_name }} </td>
+                                       <td class="odd"> {{ row.cred_exp }} </td>
+                                       <td class="odd"> 
+                                               <button class="btn btn-default btn-xs" name= "dl_{{row.slice_name}}" type="submit" title="Download Slice Credentials" onclick="javascript:document.getElementById('button_value').value='dl_{{row.slice_name}}';">
+                                                       <span class="glyphicon glyphicon-download"></span> Download
+                                               </button> 
+                                       </td>
+                       </tr>
+                       {%endfor%}
+                       </table>
+                       <p></p>
+                       <table class="mytable table table-bordered table-hover">
+                               <caption><b>Delegated Authority Credentials</b></caption>
+                               <tr class="odd"> 
+                               <th>Authority Name</th> 
+                               <th>Expiration Date</th>
+                                       <th>Download</th>
+                               </tr>
+                               {% for row in my_auths %}
+                               <tr class="border_bottom">
+                               <td class="odd"> {{ row.auth_name }} </td>
+                               <td class="odd"> {{ row.cred_exp }} </td>
+                                       <td class="odd">
+                                               <button class="btn btn-default btn-xs" name= "dl_{{row.auth_name}}" type="submit" title="Download Authority Credentials" onclick="javascript:document.getElementById('button_value').value='dl_{{row.auth_name}}';">
+                                                       <span class="glyphicon glyphicon-download"></span> Download
+                                               </button>
+                                       </td>
+                               </tr>
+                               {%endfor%}
+                       </table>
+                       <p></p>
+                        {%if '' not in my_users%}      
+                       <p><button class="btn btn-danger btn-lg btn-block"   name= "clear_cred" type="submit" title="Clear All Credentials" onclick="javascript:document.getElementById('button_value').value='clear_cred';">Clear Credentials</button></p>
+                       {%else%}
+                       <p><button class="btn btn-danger btn-lg btn-block disabled"   name= "clear_cred" type="submit" title="Clear All Credentials">Clear Credentials</button></p>
+                       {%endif%}
                </div>
        </div>
 
+
        <div class="tab-pane row" id="access">
                <div class="col-md-12">
        
                 <td class="odd"> {{ row.account_type }} </td>
                                <td class="odd"> {{ row.account_reference }} </td>
                                <td class="odd">
-                               <button class="btn btn-danger" name="delete_{{row.platform_name}}" type="submit" title="Delete account from this platform">
+                               <button class="btn btn-danger" name="delete_{{row.platform_name}}" type="submit" title="Delete account from this platform" onclick="javascript:document.getElementById('button_value').value='delete_{{row.platform_name}}';">
                                                <span class="glyphicon glyphicon-minus"></span>
                                        </button>
                                </td>
             <tr class="border_bottom">
                 <td class="odd"> {{ platform.platform_no_access }} </td>
                 <td class="odd">
-                                       <button class="btn btn-success btn-sm" name= "add_{{platform.platform_no_access}}" type="submit" title="Add account to this platform">
+                                       <button class="btn btn-success btn-sm" name= "add_{{platform.platform_no_access}}" type="submit" title="Add account to this platform" onclick="javascript:document.getElementById('button_value').value='add_{{platform.platform_no_access}}';">
                                                <span class="glyphicon glyphicon-plus"></span>
                                        </button>
                                </td>
        </div>
 {%endif%} 
 </div>
-</form>
 </div>
 
+</form>
 <script>
     $(document).ready(function() {
+           {%if 'no_creds' in user_cred or 'creds_expired' in user_cred %}
+        localStorage.clear();
+        $.post("/cache/clear/", function( data ) {
+        });
+        {% endif %}
        $('.nav-tabs a').click(function (e) {
                        e.preventDefault();
                        $(this).tab('show');
                        id = $(this).attr('href').substr(1);
-               
                });
                
         $('button#createslice').click(function() {
diff --git a/portal/templates/project-request-ack-view.html b/portal/templates/project-request-ack-view.html
new file mode 100644 (file)
index 0000000..9b70c5f
--- /dev/null
@@ -0,0 +1,9 @@
+{% extends "layout.html" %}
+
+{% block content %}
+
+<h1><img src="{{ STATIC_URL }}icons/slices-xs.png" alt="Slice" />Request received</h1>
+
+We will process your request and get back to you as soon as possible.
+{% endblock %}
+
diff --git a/portal/templates/project-request-done-view.html b/portal/templates/project-request-done-view.html
new file mode 100644 (file)
index 0000000..d962afd
--- /dev/null
@@ -0,0 +1,14 @@
+{% extends "layout.html" %}
+
+{% block content %}
+
+  <h1>Success</h1>
+
+Your request to join/create project was successful.
+<script>
+$(document).ready(function() {
+    localStorage.clear();
+});
+</script>
+{% endblock %}
+
index 4d09858..6c04487 100644 (file)
@@ -57,7 +57,6 @@
                 </select>
                 </div>
                                <p></p>
-                               <p>Organization not listed? <a href="/portal/join">Request its addition now.</a></p>
                        </div>
        </div>
 </div>
index 93285e1..3fefedf 100644 (file)
@@ -54,9 +54,7 @@ $(document).ready(function() {
                        <ul class="nav nav-tabs">
                          <li class="active"><a href="#resourcelist" role="tab" data-toggle="tab">Table</a></li>
                          <li> <a href="#resourcemap" role="tab" data-toggle="tab">Map</a></li>
-              <!-- <li> <a href="#openflowcontroller" role="tab" data-toggle="tab">OpenFlow Controller</a></li>
-              <li> <a href="#resourceflowspace" role="tab" data-toggle="tab">Flowspace</a></li>
-                         <li> <a href="#resourcescheduler" role="tab" data-toggle="tab">Scheduler</a></li> -->
+                         <li> <a href="#resourcescheduler" role="tab" data-toggle="tab">Scheduler</a></li>
                        </ul>
                        </div>
                </div>
@@ -92,24 +90,6 @@ $(document).ready(function() {
                                <div class="tab-pane" id="resourcemap">
                        {{map_resources}}
                                </div>
-                <div class="tab-pane" id="openflowcontroller">
-                    <p>{{vms_list}}</p>
-                    <p>{{vm_form}}</p>
-
-                    <p>{{below_table}}</p>
-                </div>
-
-                <div class="tab-pane" id="resourceflowspace">
-                    <p>{{welcome}}</p>
-                    <p>{{flowspaces}}</p>
-                    <p>{{flowspaces_form}}</p>
-                    <p>{{oflowspaces_form}}</p>
-                    <p>{{topology}}</p>
-                    <p>{{resources}}</p>
-
-                    <p>{{below_table}}</p>
-                </div>
-
                                <div class="tab-pane" id="resourcescheduler">
                        {{scheduler}}
                                </div>
index ce97efa..e10c88f 100644 (file)
@@ -16,7 +16,6 @@
        {%endfor%}
        </p>
        <p><strong>NOTE:</strong> Your original slicename <b>{{slicename}}</b> has been converted to PlanetLab specific format <b>{{ple_slicename}}</b> in order to do SSH.</p>
-       <p>Please note that the first '.' is replaced by number 8 and the rest of the dot/s are replaced by underscore/s.</p>
        <p>
                Be aware that after you reserve a PlanetLab Europe resource your slice will be deployed with a delay of about 15 minutes, 
                after witch you will be able to access the resource.
@@ -74,7 +73,7 @@
                the following command:
        </p>
        <p class="command">
-               ssh {{iot_login}}@fit3-dev.inrialpes.fr
+               ssh {{iot_login}}@grenoble.iot-lab.info
        </p>
        {% endif %}
        {% if nitos_resources or nitos_paris_resources %}
        {% if nitos_resources %}        
        <h4>NITLab</h4>
        <p class="command">
-       $ ssh {{slicename}}@nitlab.inf.uth.gr
-       </p>
+           $ ssh {{slicename}}@nitlab.inf.uth.gr #nodes 001-040<br>
+        $ ssh {{slicename}}@nitlab2.inf.uth.gr #nodes 041-049<br>
+        $ ssh {{slicename}}@nitlab3.inf.uth.gr #nodes > 049
+    </p>
        
-       <p>For each of the reserved nodes, follo the steps given below:</p>
+       <p>Loading an OMF-compatible image on your resource:</p>
        <p class="command">
        {%for resource in nitos_resources %}
                <b>Resource</b><br>
-       $ omf load -i baseline_grid.ndz -t {{resource}}  #loading OMF image on the node<br>
-               $ omf tell -a on -t {{resource}}  #turn on the node <br>
-               $ ssh root@{{resource}}  #ssh to the node<br><br>
+        $ omf6 stat -t {{resource}} #check the status of the node<br>
+        $ omf6 tell -a on -t {{resource}}  #turn on/off the node <br>
+       $ omf6 load -i baseline.ndz -t {{resource}}  #for orbit-like node (002-009) use "baseline_orbit.ndz"<br>
+               $ ssh root@{{resource}}  #ssh to the node<br>
        {%endfor%}
        </p>
+    <p><b>NOTE:</b> Nodes 002-009 are orbit-like nodes. For these nodes use "baseline_orbit.ndz". All these images come with OMF5.4 resource controller. To do OMF6 experiments use "baseline_omf6_1_1.ndz" and  "baseline_orbit_omf6_1_1.ndz" for grid nodes and orbit nodes respectively. </p>
        {% endif %}
 
        {% if nitos_paris_resources %}
        {%endif%}
 
        <p>
-               On the node itself you will have to modify the file /etc/omf-resctl-5.3/omf-resctl.yaml according to your slice settings and then
+               On the node itself you will have to modify the file /etc/omf-resctl-5.3/omf-resctl.yaml (OMF5.4 only) according to your slice settings and then
                restart the OMF Resource Controller and finally execute the experiment:
        </p>
        <p class="command">
                $ omf exec --slice {{slicename}} your_exp.rb
        </p>
        <p>
-       The complete tutorial is available at the following address:
+       The complete tutorial on NITOS nodes:
        <a target="_blank" href="http://nitlab.inf.uth.gr/NITlab/index.php/testbed/instructions/basic-tutorial">NITOS basic tutorial</a>
        </p>
-       <p>To learn more about OMF6, please click <a href="http://omf.mytestbed.net/projects/omf6/wiki/Wiki" target="_blank">here.</a></p>
+    <p>OMF based experiments' tutorials are available <a href="http://nitlab.inf.uth.gr/NITlab/index.php/testbed/instructions/omf-tutorials-scenarios" target="_blank">here.</a></p> 
+       <p>To learn more about OMF, please click <a href="http://omf.mytestbed.net/projects/omf/wiki/OMF_Main_Page" target="_blank">here.</a></p>
 
        {% endif %}
        
index 199444a..985974f 100644 (file)
@@ -1,15 +1,20 @@
 {% extends "layout.html" %}
+{% load portal_filters %}
 {% block content %}
-
+{% widget "_widget-no_credentials.html" %}
+{% widget "_widget-tradeoff.html" %}
 <div class="row">
        <div class="col-md-12">
                 <div class="breadcrumbs">
                         Account &nbsp;>&nbsp; <a href="/account">{{ person.email }}</a>
                 </div>
        </div>
-        {%if 'no_creds'  in user_cred %}
+        {%if 'no_creds' in user_cred %}
     <p class="command"><a href="#" style="color:red" data-toggle="modal" data-target="#myModal">NO CREDENTIALS</a> are delegated to the portal!</p>
-{%endif%}
+    {%endif%}
+        {%if 'creds_expired' in user_cred %}
+    <p class="command"><a href="#" style="color:red" data-toggle="modal" data-target="#myModal">EXPIRED CREDENTIALS</a> Please delegate again your credentials to the portal!</p>
+    {%endif%}
 
 </div>
 {% if messages %}
     {% endfor %}
 </ul>
 {% endif %}
+
+<form id="editForm" method="post" action="account_process" enctype="multipart/form-data">
+<input type="hidden" id="button_value"  name="button_value" value="" />
+
 <div class="row">
        <div class="col-md-12">
                <ul class="nav nav-tabs nav-section">
@@ -33,7 +42,6 @@
                
                <div class="col-md-12">
 
-                       <form id="editForm" method="post" action="account_process" enctype="multipart/form-data">
                                {% csrf_token %}
                                        <table class="profile">          
                                        <tr>
                                                                                   onclick="return confirm('Are you sure? It will overwrite your current credentials and you have delegate it manually.');"/>
                                                                </span>
                                                                <div style='display:none;'> <input type='hidden'  name='dload'  /> </div> 
-                                                               <button type="submit" name="dl_pubkey" class="btn btn-default btn-xs" title="Download your public key" id="dl_file">
+                                                               <button type="submit" name="dl_pubkey" class="btn btn-default btn-xs" title="Download your public key" id="dl_pubkey" onclick="javascript:document.getElementById('button_value').value='dl_pubkey';">
                                                                        <span class="glyphicon glyphicon-download"></span> Download
                                                                </button>
                                                                <button class="btn btn-default btn-xs" id="upload_file" type="button" title="Upload a public key">
                                                 {%if 'N/A' not in user_private_key%}
                                                <td class="key">Private Key </td> <!-- Hide if priv_key doesn't exist in myslice platform   -->
                                                <td class="value">********<a href="#"></a>
-                                                       <button type="submit" name="dl_pkey" class="btn btn-default" title="Download your privaye key" id="dl_pkey">
+                                                       <button type="submit" name="dl_pkey" class="btn btn-default" title="Download your privaye key" id="dl_pkey" value="dl_pkey" onclick="javascript:document.getElementById('button_value').value='dl_pkey';">
                                                                        <span class="glyphicon glyphicon-download"></span> Download     
                                                                </button>
                                                        <input class="btn btn-danger btn-xs" id="delete" name="delete" type="submit"  value="Delete" title="Delete your private key"
-                                                                               onclick="return confirm('Are you sure? If you do so, you have to delegate your credentials manually.');"/> 
+                                                                               onclick="javascript:document.getElementById('button_value').value='delete'; return confirm('Are you sure? If you do so, you have to delegate your credentials manually.');"/> 
                                                </td>
                                                  {%else%}
                                                        <td class="key">Private Key </td> <!-- Hide if priv_key doesn't exist in myslice platform   -->
                                                        <td class="value">********<a href="#"></a>
-                                                       <button type="submit" name="dl_pkey" class="btn btn-default disabled" title="Download your privaye key" id="dl_pkey">
+                                                       <button type="submit" name="dl_pkey" class="btn btn-default disabled" title="Download your privaye key" id="dl_pkey" value="dl_pkey">
                                                                <span class="glyphicon glyphicon-download"></span> Download 
                                                        </button>
                                                        <input class="btn btn-danger btn-xs disabled" id="delete" name="delete" type="submit" title="Delete your private key" value="Delete" />
                                                        </td>
                                                 {%endif%}              
                                                </tr>
+                                       <tr class="even" id="sfi_config_row">
+                                               <td class="key">sfi_config </td>
+                                               <td class="value">use sfi_config file with sfi.py package (pip install sfa)<a href="#"></a>
+                                                       <button type="submit" name="dl_sfi_config" class="btn btn-default btn-xs" title="Download your sfi_config" id="dl_sfi_config" value="dl_sfi_config" onclick="javascript:document.getElementById('button_value').value='dl_sfi_config';">
+                                                                       <span class="glyphicon glyphicon-download"></span> Download
+                                                               </button>
+                                               </td>
+                        </tr>
+                                               <tr class="odd">
+                                                       {%if 'N/A' not in user_private_key%}
+                                                       <td class="key">Identity</td> 
+                                               <td>
+                                                               <button type="submit" name="dl_identity" class="btn btn-default btn-xs" title="You will require it to use jfed" id="dl_identity" onclick="javascript:document.getElementById('button_value').value='dl_identity';">
+                                                               <span class="glyphicon glyphicon-download"></span> Download 
+                                                               </button>
+                                                       </td>
+                                                       {%else%}
+                                                       <td class="key">Identity</td> 
+                                                       <td>
+                                                       <button type="submit" name="dl_identity" class="btn btn-default btn-xs disabled" title="You will require it to use jfed" id="dl_identity">
+                                                               <span class="glyphicon glyphicon-download"></span> Download 
+                                                       </button>
+                                                       </td>
+                                                       {%endif%} 
+                                               </tr>
+
                                                <tr class="even">
                                                <td colspan="2">
-                                                       <p class="message" id="pkey_del_msg"><b> Tradeoff:</b> Ease-of-use vs Security.<br>
-                                                                       <b>Ease-of-use:</b> Automatic account delegation. Don't delete private key.<br>
-                                                                       <b>Security:</b> Manual account delegation. Download & Delete private key.
+                                                               <p class="command">
+                                                                       <a href="#" style="color:green" data-toggle="modal" data-target="#tradeoffmodal">Automatic vs. Manual delegation of credentials:</a>
+                                                                       Trade-off between ease-of-use & security</p>
                                                                </p>
                                                </td>
                                                </tr>
                </table>
        
                </div>
-       
 
        {%if 'Enabled'  in user_status %}
                <div class="col-md-12">
                <h3>Credentials <small>Delegated to Principal Account</small></h3>
-                       <table class="table">
-                                       <caption><b>Delegated User Credential</b></caption> 
-                           <tr class="odd"> 
-                               <th>Expiration Date</th>
-                                               <th>Download</th>
-                           </tr>
-                                       {% for row in my_users %}         
-                                       <tr class="border_bottom">
-                                       <td class="odd"> {{ row.cred_exp }} </td>
-                                               <td class="odd">
-                                                       <button class="btn btn-default btn-xs" name= "dl_user_cred" type="submit" title="Download User Credential">
-                                                               <span class="glyphicon glyphicon-download"></span> Credential
-                                                       </button>
-                                                       <button class="btn btn-default btn-xs" name= "dl_user_cert" type="submit" title="Download User Certificate">
-                                                               <span class="glyphicon glyphicon-download"></span> Certificate
-                                                       </button>
-                             <button class="btn btn-default btn-xs" name= "dl_user_p12" type="submit" title="Download User PKCS12">
-                                 <span class="glyphicon glyphicon-download"></span> PKCS p12
-                             </button>
-                                               </td>
-                                       </tr>
-                                       {%endfor%}
-                                </table>
-                               <p></p>
-                               <table class="mytable table table-bordered table-hover">
-                                       <caption><b>Delegated Slice Credentials</b></caption>  
-                               <tr class="odd"> 
-                                               <th>Slice Name</th> 
-                                       <th>Expiration Date</th>
-                                               <th>Download</th>
-                               </tr>
-                                       {% for row in my_slices %}     
-                               <tr class="border_bottom">
-                                       <td class="odd"> {{ row.slice_name }} </td>
-                                               <td class="odd"> {{ row.cred_exp }} </td>
-                                               <td class="odd"> 
-                                                       <button class="btn btn-default btn-xs" name= "dl_{{row.slice_name}}" type="submit" title="Download Slice Credentials">
-                                                               <span class="glyphicon glyphicon-download"></span> Download
-                                                       </button> 
-                                               </td>
-                               </tr>
-                               {%endfor%}
-                               </table>
-                               <p></p>
-                               <table class="mytable table table-bordered table-hover">
-                                       <caption><b>Delegated Authority Credentials</b></caption>
-                                       <tr class="odd"> 
-                                       <th>Authority Name</th> 
-                                       <th>Expiration Date</th>
-                                               <th>Download</th>
-                                       </tr>
-                                       {% for row in my_auths %}
-                                       <tr class="border_bottom">
-                                       <td class="odd"> {{ row.auth_name }} </td>
-                                       <td class="odd"> {{ row.cred_exp }} </td>
-                                               <td class="odd">
-                                                       <button class="btn btn-default btn-xs" name= "dl_{{row.auth_name}}" type="submit" title="Download Authority Credentials">
-                                                               <span class="glyphicon glyphicon-download"></span> Download
-                                                       </button>
-                                               </td>
-                                       </tr>
-                                       {%endfor%}
-                               </table>
-                               <p></p>
-                                {%if '' not in my_users%}      
-                               <p><button class="btn btn-danger btn-lg btn-block"   name= "clear_cred" type="submit" title="Clear All Credentials">Clear Credentials</button></p>
-                               {%else%}
-                               <p><button class="btn btn-danger btn-lg btn-block disabled"   name= "clear_cred" type="submit" title="Clear All Credentials">Clear Credentials</button></p>
-                               {%endif%}
+                   <table class="table">
+                               <caption><b>Delegated User Credential</b></caption> 
+                       <tr class="odd"> 
+                           <th>Expiration Date</th>
+                                       <th>Download</th>
+                       </tr>
+                               {% for row in my_users %}         
+                               <tr class="border_bottom">
+                               <td class="odd"> {{ row.cred_exp }} </td>
+                                       <td class="odd">
+                                               <button class="btn btn-default btn-xs" name= "dl_user_cred" type="submit" title="Download User Credential" onclick="javascript:document.getElementById('button_value').value='dl_user_cred';">
+                                                       <span class="glyphicon glyphicon-download"></span> Credential
+                                               </button>
+                                               <button class="btn btn-default btn-xs" name= "dl_user_cert" type="submit" title="Download User Certificate" onclick="javascript:document.getElementById('button_value').value='dl_user_cert';">
+                                                       <span class="glyphicon glyphicon-download"></span> Certificate
+                                               </button>
+                         <button class="btn btn-default btn-xs" name= "dl_user_p12" type="submit" title="Download User PKCS12" onclick="javascript:document.getElementById('button_value').value='dl_user_p12';">
+                             <span class="glyphicon glyphicon-download"></span> PKCS p12
+                         </button>
+                                       </td>
+                               </tr>
+                               {%endfor%}
+                        </table>
+                       <p></p>
+                       <table class="mytable table table-bordered table-hover">
+                               <caption><b>Delegated Slice Credentials</b></caption>  
+                       <tr class="odd"> 
+                                       <th>Slice Name</th> 
+                               <th>Expiration Date</th>
+                                       <th>Download</th>
+                       </tr>
+                               {% for row in my_slices %}     
+                       <tr class="border_bottom">
+                               <td class="odd"> {{ row.slice_name }} </td>
+                                       <td class="odd"> {{ row.cred_exp }} </td>
+                                       <td class="odd"> 
+                                               <button class="btn btn-default btn-xs" name= "dl_{{row.slice_name}}" type="submit" title="Download Slice Credentials" onclick="javascript:document.getElementById('button_value').value='dl_{{row.slice_name}}';">
+                                                       <span class="glyphicon glyphicon-download"></span> Download
+                                               </button> 
+                                       </td>
+                       </tr>
+                       {%endfor%}
+                       </table>
+                       <p></p>
+                       <table class="mytable table table-bordered table-hover">
+                               <caption><b>Delegated Authority Credentials</b></caption>
+                               <tr class="odd"> 
+                               <th>Authority Name</th> 
+                               <th>Expiration Date</th>
+                                       <th>Download</th>
+                               </tr>
+                               {% for row in my_auths %}
+                               <tr class="border_bottom">
+                               <td class="odd"> {{ row.auth_name }} </td>
+                               <td class="odd"> {{ row.cred_exp }} </td>
+                                       <td class="odd">
+                                               <button class="btn btn-default btn-xs" name= "dl_{{row.auth_name}}" type="submit" title="Download Authority Credentials" onclick="javascript:document.getElementById('button_value').value='dl_{{row.auth_name}}';">
+                                                       <span class="glyphicon glyphicon-download"></span> Download
+                                               </button>
+                                       </td>
+                               </tr>
+                               {%endfor%}
+                       </table>
+                       <p></p>
+                        {%if '' not in my_users%}      
+                       <p><button class="btn btn-danger btn-lg btn-block"   name= "clear_cred" type="submit" title="Clear All Credentials" onclick="javascript:document.getElementById('button_value').value='clear_cred';">Clear Credentials</button></p>
+                       {%else%}
+                       <p><button class="btn btn-danger btn-lg btn-block disabled"   name= "clear_cred" type="submit" title="Clear All Credentials">Clear Credentials</button></p>
+                       {%endif%}
                </div>
        </div>
-<!-- Modal- No credentials -->
-<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
-            <div class="modal-dialog">
-                <div class="modal-content">
-                    <div class="modal-header">
-                        <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
-                            <h4 class="modal-title" id="myModalLabel">No credentials are delegated to the portal</h4>
-                    </div>
-                    <div class="modal-body">
-                                       <p>You may get this message for several reasons.</p>
-                                       <h3>Account Delegation: Automatic</h3>
-                                       <ul>
-                                               <li>If your account is not yet validated</li>
-                                               <li>If you press the "Clear Credentials" button</li>
-                                               <li>If you "Generate a new key pair"</li>
-                                               <li>If a new slice is added to your account</li>
-                                       </ul>
-                                       <p>In all the above mentioned cases, it is sufficient to refresh the page or go back to home page. The portal will regenrate your credentials.
-                                        In some cases it may take more time than usual. If nothing works, then please logout and login again to the portal.</p>
-                                       <h3>Account Delegation: Manual</h3>
-                                               <p>First of all your account needs to be validated by the manager of your organization.</p>
-                                               <p>As you have uploaded your own public key, the portal can no longer generate your credentials automatically.</p>
-                                               <p>In order for the portal to contact testbeds on your behalf, so as to list and reserve resources, you will need to
-                                               <a href="/portal/manual_delegation" target="_blank">delegate your credentials to the portal.</a>
-                                       </p>
-                                       <h5>Contact support</h5>
-                                       <p>If you don't have the above mentioned cases and still have this message, please  <a href="/contact/" target="_blank">contact us</a>.</p>
-                    </div>
-                    <div class="modal-footer">
-                        <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
-                    </div>
-                </div>
-            </div>
-</div>
 
 
        <div class="tab-pane row" id="access">
                 <td class="odd"> {{ row.account_type }} </td>
                                <td class="odd"> {{ row.account_reference }} </td>
                                <td class="odd">
-                               <button class="btn btn-danger" name="delete_{{row.platform_name}}" type="submit" title="Delete account from this platform">
+                               <button class="btn btn-danger" name="delete_{{row.platform_name}}" type="submit" title="Delete account from this platform" onclick="javascript:document.getElementById('button_value').value='delete_{{row.platform_name}}';">
                                                <span class="glyphicon glyphicon-minus"></span>
                                        </button>
                                </td>
             <tr class="border_bottom">
                 <td class="odd"> {{ platform.platform_no_access }} </td>
                 <td class="odd">
-                                       <button class="btn btn-success btn-sm" name= "add_{{platform.platform_no_access}}" type="submit" title="Add account to this platform">
+                                       <button class="btn btn-success btn-sm" name= "add_{{platform.platform_no_access}}" type="submit" title="Add account to this platform" onclick="javascript:document.getElementById('button_value').value='add_{{platform.platform_no_access}}';">
                                                <span class="glyphicon glyphicon-plus"></span>
                                        </button>
                                </td>
        </div>
 {%endif%} 
 </div>
-</form>
 </div>
 
+</form>
 <script>
     $(document).ready(function() {
+           {%if 'no_creds' in user_cred or 'creds_expired' in user_cred %}
+        localStorage.clear();
+        $.post("/cache/clear/", function( data ) {
+        });
+        {% endif %}
        $('.nav-tabs a').click(function (e) {
                        e.preventDefault();
                        $(this).tab('show');
                        id = $(this).attr('href').substr(1);
-               
                });
                
         $('button#createslice').click(function() {
diff --git a/portal/templates/smartfire/smartfire_activate_user.html b/portal/templates/smartfire/smartfire_activate_user.html
new file mode 100644 (file)
index 0000000..48e0142
--- /dev/null
@@ -0,0 +1,29 @@
+<img src="http://eukorea-fire.eu/wp-content/uploads/2014/02/SmartFIRE_logo.png">
+<br>
+<p>We have received a user signup request for your email address at {{current_site}}</p>
+<p>You have the following user details:</p>
+
+Organization: {{organization}}<br>
+First name: {{first_name}}<br>
+Last name: {{last_name}}<br>
+Email: {{email}}<br>
+
+<p></p>
+<p>
+You may now <a href="http://{{current_site}}">log</a> in to the portal using your email address and the password that you provided, but your access will be limited. To gain full access, two steps are required:
+</p>
+
+<ul style="list-style-type:decimal;">
+<li>
+You must confirm that you have indeed made this request by clicking on the following link: <br>
+       <a href={{validation_link}}>{{validation_link}}</a> 
+       <ul><li>If you did not make this request, we apologise. You may disregard this email or you may advise us the error by replying to this email.</li></ul>
+</li>
+<li>
+A manager from your organization must also validate your request. Upon confirmation of your signup request, we will send an email to the managers at your organization with a validation request.
+</li>
+</ul>
+<p>
+We look forward to welcoming you to SmartFIRE. You will find answers to frequently asked questions <a href="http://{{current_site}}/support/">here</a>. 
+Please don't hesitate to <a href="http://{{current_site}}/contact/">contact us</a> with any additional questions that you might have.
+</p>
diff --git a/portal/templates/smartfire/smartfire_activate_user.txt b/portal/templates/smartfire/smartfire_activate_user.txt
new file mode 100644 (file)
index 0000000..ac84bc3
--- /dev/null
@@ -0,0 +1,24 @@
+We have received a user signup request for your email address at {{current_site}}
+
+You have the following user details:
+
+Organization: {{organization}}
+First name: {{first_name}}
+Last name: {{last_name}}
+Email: {{email}}
+
+You may now log in to the portal using your email address and the password that you provided, but your access will be limited. To gain full access, two steps are required:
+
+       1. You must confirm that you have indeed made this request by clicking on the following link:
+
+               {{validation_link}}
+
+               If you did not make this request, we apologise. You may disregard this email or you may advise us the error by replying to this email.
+
+       2. A manager from your organization must also validate your request. Upon confirmation of your signup request, we will send an email to the managers at your organization with a validation request.
+
+We look forward to welcoming you to SmartFIRE portal. 
+Please don't hesitate to contact us at support@onelab.eu with any additional questions that you might have.
+
+
+
diff --git a/portal/templates/smartfire/smartfire_authority_request_denied.html b/portal/templates/smartfire/smartfire_authority_request_denied.html
new file mode 100644 (file)
index 0000000..e4da271
--- /dev/null
@@ -0,0 +1,20 @@
+<img src="http://eukorea-fire.eu/wp-content/uploads/2014/02/SmartFIRE_logo.png">
+<br>
+<p>Dear SmartFIRE user,</p>
+<p></p>
+<p>You have recently requested an addition of the following authority in the SmartFIRE portal ({{portal_url}}):</p> 
+<p></p>
+<b>Name of organization:</b> {{site_name}}<br>
+<b>Short name:</b> {{short_name}}<br>
+<b>Url:</b> {{url}}<br>
+<b>City:</b> {{city}}<br>
+<b>Country:</b> {{country}}<br>
+<p></p>
+</p>After verifying your request, we regret to inform you that, we are unable to validate your request.</p>
+<p>For any queries, contact us by replying to this email.</p>
+<br>
+<p>We wish you all the best.</p>
+<br>
+<p>Yours sincerely,</p>
+<p>The SmartFIRE team</p>
+
diff --git a/portal/templates/smartfire/smartfire_authority_request_denied.txt b/portal/templates/smartfire/smartfire_authority_request_denied.txt
new file mode 100644 (file)
index 0000000..44d522b
--- /dev/null
@@ -0,0 +1,18 @@
+Dear SmartFIRE user,
+
+You have recently requested an addition of the following authority in the SmartFIRE portal ({{portal_url}}): 
+
+Name of organization: {{site_name}}
+Short name: {{short_name}}
+Url: {{url}}
+City: {{city}}
+Country: {{country}}
+
+
+After verifying your request, we regret to inform you that, we are unable to validate your request.
+For any queries, contact us by replying to this email.
+
+We wish you all the best.
+
+Yours sincerely,
+The SmartFIRE team
diff --git a/portal/templates/smartfire/smartfire_authority_request_email.html b/portal/templates/smartfire/smartfire_authority_request_email.html
new file mode 100644 (file)
index 0000000..72af5a7
--- /dev/null
@@ -0,0 +1,22 @@
+<img src="http://eukorea-fire.eu/wp-content/uploads/2014/02/SmartFIRE_logo.png">
+<br>
+<h1>NEW AUTHORITY REQUEST</h1>
+<br>
+<p>This email is only for SmartFIRE admins</p>
+<br>
+<h2>{{site_name}}</h2>             
+<b>Authority hrn    :</b> {{authority_hrn}}<br>         
+<b>Abreviated name  :</b> {{site_abbreviated_name}}<br>
+<b>URL              :</b> {{site_url}}<br>              
+<b>City             :</b> {{address_city}}<br>          
+<b>Country          :</b> {{address_country}}<br>  
+
+<br><br>
+
+<h2>PI for this Authority</h2>     
+<b>First Name   :</b> {{first_name}}<br>
+<b>Last Name    :</b> {{last_name}}<br>
+<b>Authority hrn:</b> {{authority_hrn}}<br>
+<b>Public key   :</b> {{public_key}}<br>
+<b>Email        :</b> {{email}}<br>
+<b>User Hrn     :</b> {{user_hrn}}<br>
diff --git a/portal/templates/smartfire/smartfire_authority_request_email.txt b/portal/templates/smartfire/smartfire_authority_request_email.txt
new file mode 100644 (file)
index 0000000..93daae0
--- /dev/null
@@ -0,0 +1,22 @@
+This email is only for SmartFIRE admins.
+
+NEW AUTHORITY REQUEST
+
+Site             : {{site_name}}             
+
+Authority hrn    : {{authority_hrn}}         
+Abreviated name  : {{site_abbreviated_name}} 
+URL              : {{site_url}}              
+
+
+City             : {{address_city}}          
+Country          : {{address_country}}  
+
+
+PI for this Authority     
+First Name   : {{first_name}}
+Last Name    : {{last_name}}
+Authority hrn: {{authority_hrn}}
+Public key   : {{public_key}}
+Email        : {{email}}
+User Hrn     : {{user_hrn}}
diff --git a/portal/templates/smartfire/smartfire_authority_request_email_subject.txt b/portal/templates/smartfire/smartfire_authority_request_email_subject.txt
new file mode 100644 (file)
index 0000000..1366a27
--- /dev/null
@@ -0,0 +1 @@
+SmartFIRE new Authority request submitted
diff --git a/portal/templates/smartfire/smartfire_contact_support_email.html b/portal/templates/smartfire/smartfire_contact_support_email.html
new file mode 100644 (file)
index 0000000..edd8534
--- /dev/null
@@ -0,0 +1,10 @@
+<img src="http://eukorea-fire.eu/wp-content/uploads/2014/02/SmartFIRE_logo.png">
+<br>
+<h1>User details</h1>
+<br>
+<b>Email        :</b> {{email}}
+
+<h1>Query details</h1>
+
+<b>Subject             :</b> {{subject}}
+<b>Query               :</b> {{description}}
diff --git a/portal/templates/smartfire/smartfire_contact_support_email.txt b/portal/templates/smartfire/smartfire_contact_support_email.txt
new file mode 100644 (file)
index 0000000..536d1b2
--- /dev/null
@@ -0,0 +1,9 @@
+User details: 
+
+email           : {{email}}
+
+Query Details:
+
+Subject         : {{subject}}
+Description     : {{description}}
+
diff --git a/portal/templates/smartfire/smartfire_contact_support_email_subject.txt b/portal/templates/smartfire/smartfire_contact_support_email_subject.txt
new file mode 100644 (file)
index 0000000..7d15d8d
--- /dev/null
@@ -0,0 +1 @@
+SmartFIRE support: user ticket
diff --git a/portal/templates/smartfire/smartfire_email_activation.html b/portal/templates/smartfire/smartfire_email_activation.html
new file mode 100644 (file)
index 0000000..124f32a
--- /dev/null
@@ -0,0 +1,25 @@
+{% extends "layout.html" %}
+
+{% block content %}
+
+<div class="row">
+       <h1><img src="{{ STATIC_URL }}img/icon_user_small.png" alt="User Registration" />User sign-up</h1>
+</div>
+<div class="row">
+       {% if activation_status == 'success' %}
+               <h3>Signup request confirmed.</h3>
+               <p>You are currently able to log in to the portal using your email address and the password that you have provided; however, your access is still limited.</p> 
+               <p>You will have full access as soon as your account is validated by a manager at your organization. We have sent an email to your organisation's managers with a validation request.</p>
+    {% elif activation_status == 'validated' %}
+               <h3>Account validated.</h3>
+               <p>We have identified you as a valid PLE user. Your SmartFIRE account has automatically been approved.</p>
+        <p>You have a full access to SmartFIRE testbeds.</p>
+       {%else%}
+               <h3>Signup confirmation failed.</h3>
+               <p>You have probably arrived at this page by clicking a confirmation link in an email that we have sent to you. 
+               We have been unable to match the link that you have clicked to a signup request in our database.</p>
+               <p>Please <a href="/portal/contact/">contact support</a> so that we may help you complete the signup process.</p>
+       {%endif%}
+ </div>
+
+{% endblock %}
diff --git a/portal/templates/smartfire/smartfire_email_default_recipients.txt b/portal/templates/smartfire/smartfire_email_default_recipients.txt
new file mode 100644 (file)
index 0000000..df7e93a
--- /dev/null
@@ -0,0 +1 @@
+SmartFIRE Support <support@onelab.eu>
diff --git a/portal/templates/smartfire/smartfire_email_default_sender.txt b/portal/templates/smartfire/smartfire_email_default_sender.txt
new file mode 100644 (file)
index 0000000..df7e93a
--- /dev/null
@@ -0,0 +1 @@
+SmartFIRE Support <support@onelab.eu>
index 8236fc5..89fdf64 100644 (file)
@@ -6,9 +6,17 @@
 {% widget '_widget-news.html' %}
 </div> -->
 {% if username %}
+{% widget "_widget-no_credentials.html" %}
 <div class="container dashboard">
+       {%if 'no_creds'  in user_cred %}
+        <p class="command"><a href="#" style="color:red" data-toggle="modal" data-target="#myModal">NO CREDENTIALS</a> are delegated to the portal!</p>
+    {%endif%}
+       {%if 'creds_expired'  in user_cred %}
+        <p class="command"><a href="#" style="color:red" data-toggle="modal" data-target="#myModal">EXPIRED CREDENTIALS</a> Please delegate again your credentials to the portal!</p>
+    {%endif%}
+
        <div class="row">
-               {%if 'is_pi'  in pi %}
+               {% if pi %}
                <div class="col-md-3">
                        <h3>
                                EXPERIMENT
@@ -22,9 +30,7 @@
                        <div>
                                <p><strong>Your slices </strong>
                                        <span title="A slice is a set of testbed resources on which you can conduct an experiment. 
-                                       Either ask your colleagues to give you access to an existing slice or request a new slice by clicking 'Request Slice'. 
-                                       However, on the OneLab portal, you will only see slices that you have created through OneLab. If you have created slices elsewhere, 
-                                       such as on the PlanetLab Europe portal, those slices will not appear here."
+                                       Either ask your colleagues to give you access to an existing slice or request a new slice by clicking 'Request Slice'." 
                                        class="glyphicon glyphicon-info-sign">
                                </span>
 
@@ -88,9 +94,7 @@
                        <div>
                                <p><strong>Your slices </strong>
                                <span title="A slice is a set of testbed resources on which you can conduct an experiment. 
-                                       Either ask your colleagues to give you access to an existing slice or request a new slice by clicking 'Request Slice'. 
-                                       However, on the OneLab portal, you will only see slices that you have created through OneLab. If you have created slices elsewhere, 
-                                       such as on the PlanetLab Europe portal, those slices will not appear here."
+                                       Either ask your colleagues to give you access to an existing slice or request a new slice by clicking 'Request Slice'."
                                        class="glyphicon glyphicon-info-sign">
                                </span>
                                </p>
                        <div>   
                                <div id="home-slice-list"><img src="{{ STATIC_URL }}img/loading.gif" alt="Loading Slices" /></div>
                        </div>
+                       {% if pending_slices %}
+                       <p><strong>Pending slices</strong>
+                       <span title="Slices that you have requested and are pending for validation by the contact person of your organization."
+                               class="glyphicon glyphicon-info-sign">
+                       <ul>
+                       {% for slices in pending_slices %}
+                       <li>{{slices}}</li>
+                       {% endfor %}
+                       </ul>
+                       </span>
+                       </p>
+                       {%endif%}       
                </div>
                <div class="col-md-4">
                        <h3>
                <div class="col-sm-2"></div>
                <div class="col-sm-4 slogan">
                        <h2>
-                               SmartFIRE
+                               Your Easy Access to Computer Networking Testbeds:
                        </h2>
                        <h3>
-                               EU-South Korea Cooperation<br>
-                               On Future Internet Infrastructure
+                               A wide variety of world class testbeds available through your one account
                        </h3>
                </div>
                <div class="col-sm-5 col-sm-offset-1">
                $('button#slicerequestbtn').click(function() {
                        window.location="/portal/slice_request/";
                });
-/*-------
-List of slices has been moved in 
-portal/templates/base.html
-This should go into session
---------*/
+
+        myslice.loadSlices();
+        
 });
 </script>
-{# widget "_widget-monitor.html" #}
-{# widget "_widget-stats-top-slices.html" #}
 
 {% endblock %}
diff --git a/portal/templates/smartfire/smartfire_slice_request_denied.html b/portal/templates/smartfire/smartfire_slice_request_denied.html
new file mode 100644 (file)
index 0000000..6c7d595
--- /dev/null
@@ -0,0 +1,17 @@
+<img src="http://eukorea-fire.eu/wp-content/uploads/2014/02/SmartFIRE_logo.png">
+<br>
+<p>Dear SmartFIRE user,</p>
+<p></p>
+<p>You have recently requested the following slice on the SmartFIRE portal({{portal_url}}):</p> 
+<br>
+<b>Slice name   :</b> {{slice_name}}<br>
+<b>URL          :</b> {{url}}<br>
+<b>Purpose      :</b> {{purpose}}<br>
+<br>
+<p>We regret to inform you that, a manager of your institution has not confirmed your request. Please contact the manager of your institution for further information. 
+For any other queries, please contact us by replying to this email.</p>
+<br>
+<p>We wish you a fruitful user experience on SmartFIRE.</p>
+<br>
+<p>Yours sincerely,</p>
+<p>The SmartFIRE team</p>
diff --git a/portal/templates/smartfire/smartfire_slice_request_denied.txt b/portal/templates/smartfire/smartfire_slice_request_denied.txt
new file mode 100644 (file)
index 0000000..e4b4990
--- /dev/null
@@ -0,0 +1,14 @@
+Dear SmartFIRE user,
+
+You have recently requested the following slice on the SmartFIRE portal({{portal_url}}):
+
+Slice name   : {{slice_name}}
+URL          : {{url}}
+Purpose      : {{purpose}}
+We regret to inform you that, a manager of your institution has not confirmed your request. Please contact the manager of your institution for further information. For any other queries, please contact us by replying to this email.
+
+We wish you a fruitful user experience on SmartFIRE.
+
+Yours sincerely,
+The SmartFIRE team
diff --git a/portal/templates/smartfire/smartfire_slice_request_email_subject.txt b/portal/templates/smartfire/smartfire_slice_request_email_subject.txt
new file mode 100644 (file)
index 0000000..e3988df
--- /dev/null
@@ -0,0 +1 @@
+Slice request submitted 
diff --git a/portal/templates/smartfire/smartfire_slice_request_validated.html b/portal/templates/smartfire/smartfire_slice_request_validated.html
new file mode 100644 (file)
index 0000000..2c96a1d
--- /dev/null
@@ -0,0 +1,21 @@
+<img src="http://eukorea-fire.eu/wp-content/uploads/2014/02/SmartFIRE_logo.png">
+<br>
+<p>Dear SmartFIRE user,</p>
+<p></p>
+<p>You have recently requested a slice in the SmartFIRE portal.</p>
+<br>
+<b>Slice name   :</b> {{slice_name}}<br>
+<b>URL          :</b> {{number_of_nodes}}<br>
+<b>Purpose      :</b> {{purpose}}<br>
+<p></p>
+<p>
+       We are pleased to inform you that a manager from your institution has validated your slice request on the SmartFIRE portal. 
+       You can now add resources to you slice and start experimenting.
+</p>
+<p></p>
+<p>We wish you a fruitful user experience with the SmartFIRE portal.</p>
+<p></p>
+<p>Yours sincerely,</p>
+<p>The SmartFIRE team</p>
+
+
diff --git a/portal/templates/smartfire/smartfire_slice_request_validated.txt b/portal/templates/smartfire/smartfire_slice_request_validated.txt
new file mode 100644 (file)
index 0000000..571a3e4
--- /dev/null
@@ -0,0 +1,16 @@
+Dear SmartFIRE user,
+
+You have recently requested a slice in the SmartFIRE portal.
+
+Slice name      : {{slice_name}}
+URL             : {{number_of_nodes}}
+Purpose         : {{purpose}}
+
+
+We are pleased to inform you that a manager from your institution has validated your slice request on the SmartFIRE portal. You can now add resources to you slice and start experimenting.
+
+We wish you a fruitful user experience with the SmartFIRE portal.
+
+Yours sincerely,
+The SmartFIRE team
+
diff --git a/portal/templates/smartfire/smartfire_user_request_denied.html b/portal/templates/smartfire/smartfire_user_request_denied.html
new file mode 100644 (file)
index 0000000..64678e3
--- /dev/null
@@ -0,0 +1,11 @@
+<img src="http://eukorea-fire.eu/wp-content/uploads/2014/02/SmartFIRE_logo.png">
+<br>
+<p>Dear {{first_name}} {{last_name}},</p>
+<p></p>
+<p>You have recently registered as a user to SmartFIRE portal. We are sorry to inform you that, a manager of your institution has rejected your request. Please contact the manager of your institution for further information. For any other queries, contact us by replying to this email.</p>
+<p></p>
+<p>We wish you all the best.</p>
+<p></p>
+<p>Yours sincerely,</p>
+<p>The SmartFIRE team</p>
+
diff --git a/portal/templates/smartfire/smartfire_user_request_denied.txt b/portal/templates/smartfire/smartfire_user_request_denied.txt
new file mode 100644 (file)
index 0000000..29edc21
--- /dev/null
@@ -0,0 +1,8 @@
+Dear {{first_name}} {{last_name}},
+
+You have recently registered as a user to SmartFIRE portal. We are sorry to inform you that, a manager of your institution has rejected your request. Please contact the manager of your institution for further information. For any other queries, contact us by replying to this email.
+
+We wish you all the best.
+
+Yours sincerely,
+The SmartFIRE team
diff --git a/portal/templates/smartfire/smartfire_user_request_email.html b/portal/templates/smartfire/smartfire_user_request_email.html
new file mode 100644 (file)
index 0000000..ae8952c
--- /dev/null
@@ -0,0 +1,16 @@
+<img src="http://eukorea-fire.eu/wp-content/uploads/2014/02/SmartFIRE_logo.png">
+<br>
+<h1>NEW USER REQUEST</h1>
+<br>
+<b>First name   :</b> {{first_name}}<br>
+<b>Last name    :</b> {{last_name}}<br>
+<b>Organization :</b> {{organization}}<br>
+<b>Authority hrn:</b> {{authority_hrn}}<br>
+<b>Public key   :</b> {{public_key}}<br>
+<b>Email        :</b> {{email}}<br>
+<b>User hrn     :</b> {{user_hrn}}<br>
+<b>Portal url  :</b> {{ current_site }}<br>
+<p></p>
+<p>You can validate the user <a href="http://{{current_site}}/portal/validate">here</a>.<p>
+<br>
+<p>Please note that the validation request will only become visible once the user has confirmed his/her email address.</p>
diff --git a/portal/templates/smartfire/smartfire_user_request_email.txt b/portal/templates/smartfire/smartfire_user_request_email.txt
new file mode 100644 (file)
index 0000000..17ce184
--- /dev/null
@@ -0,0 +1,14 @@
+NEW USER REQUEST
+
+First name   : {{first_name}}
+Last name    : {{last_name}} 
+Organization :{{organization}}
+Authority hrn: {{authority_hrn}}
+Public key   : {{public_key}}
+Email        : {{email}}
+User hrn     : {{user_hrn}}
+Portal url   : {{ current_site }}
+
+Please note that the validation request will only become visible once the user has confirmed his/her email address.
+
+
diff --git a/portal/templates/smartfire/smartfire_user_request_email_subject.txt b/portal/templates/smartfire/smartfire_user_request_email_subject.txt
new file mode 100644 (file)
index 0000000..a373b60
--- /dev/null
@@ -0,0 +1 @@
+User request submitted
diff --git a/portal/templates/smartfire/smartfire_user_request_validated.html b/portal/templates/smartfire/smartfire_user_request_validated.html
new file mode 100644 (file)
index 0000000..7997a18
--- /dev/null
@@ -0,0 +1,14 @@
+<img src="http://eukorea-fire.eu/wp-content/uploads/2014/02/SmartFIRE_logo.png">
+<br>
+<p>Dear {{first_name}} {{last_name}},</p>
+<p></p>
+<p>It is my pleasure to welcome you as a fully signed-up user of the SmartFIRE experimental facility. SmartFIRE provides you with access to world class computer networking testbeds. Our aim at SmartFIRE is to promote the use of these testbeds for pre-commercial research and development by industry, for scientific research, and for university level laboratory exercises.</p>
+<p></p>
+</p>
+Your entry point for access to the testbeds is the SmartFIRE portal, which provides a web-based interface for browsing and reserving resources on the various testbeds. To run an experiment using those resources, you may log in to the testbed and/or individual nodes on the testbed with your SmartFIRE public/private key pair, or you may use an experiment control tool such as as OMF. The SmartFIRE  operations team is standing by at support@onelab.eu to provide you with help regarding the portal and to refer your testbed- and tool-specific queries to those best able to answer them.
+</p>
+<p></p>
+<p>We wish you a fruitful user experience with the SmartFIRE portal.</p>
+<p></p>
+<p>Yours sincerely,</p>
+<p>The SmartFIRE team</p>
diff --git a/portal/templates/smartfire/smartfire_user_request_validated.txt b/portal/templates/smartfire/smartfire_user_request_validated.txt
new file mode 100644 (file)
index 0000000..b546b19
--- /dev/null
@@ -0,0 +1,10 @@
+Dear {{first_name}} {{last_name}},
+
+It is our pleasure to welcome you as a fully signed-up user of the SmartFIRE experimental facility. SmartFIRE provides you with access to world class computer networking testbeds.. Our aim at SmartFIRE is to promote the use of these testbeds for pre-commercial research and development by industry, for scientific research, and for university level laboratory exercises.
+
+Your entry point for access to the testbeds is the SmartFIRE portal, which provides a web-based interface for browsing and reserving resources on the various testbeds. To run an experiment using those resources, you may log in to the testbed and/or to individual nodes on the testbed with your SmartFIRE public/private key pair, or you may use an experiment control tool such as as  OMF. The SmartFIRE operations team is standing by at support@onelab.eu to provide you with help regarding the portal and to refer your testbed- and tool-specific queries to those best able to answer them.
+
+We wish you a fruitful user experience with the SmartFIRE portal.
+
+Yours sincerely,
+The SmartFIRE team
index 7529c61..eaa5c2a 100644 (file)
        <div class="login-submit">
                <input type="submit" class="btn btn-onelab" value="Sign In" />
                <span class="lost-password">&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;<a href="/portal/pass_reset/">Can't access your account?</a></span>
-       </div>
-       <div class="login-signup">
-               <!-- You don't have yet an account? 
-               
-               <a href="/register">Sign Up!</a> -->
+       <p></p>
+       <p style="color:white;">Don't have an account? <a href="/register">Sign Up!</a></p>
        </div>
        </form>
 </div>
index 738075f..de34e32 100644 (file)
@@ -19,7 +19,7 @@
                                                        </ul>
                                        </div>
                                </li>
-                               {%if 'is_pi'  in pi %}  
+                               {%if pi %}      
                                <li id="nav-institution" class=""><a href="/institution">MANAGEMENT</a></li>
                                 {%endif%}
                                <li><a href="/support/">SUPPORT</a></li>
diff --git a/portal/templates/user_register_email.txt b/portal/templates/user_register_email.txt
deleted file mode 100644 (file)
index dc34c21..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-Your have registered for an account in {{site}}.
-
-Your activation key is :{{activation_key}}; it will expire in {{expiration_days}} days.
-
diff --git a/portal/templates/user_register_email_subject.txt b/portal/templates/user_register_email_subject.txt
deleted file mode 100644 (file)
index 6ec4cc2..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Onelab New User request submitted
index e385baf..676d108 100755 (executable)
@@ -3,10 +3,16 @@ from django.conf.urls import patterns, url, include
 from sla import slicetabsla
 
 urlpatterns = patterns('',
-       url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')),
-       url(r'^testbeds/', slicetabsla.Testbeds.as_view(), name="testbeds"),
-       url(r'^(?P<slicename>[^/]+)/?$', slicetabsla.SLAView.as_view(), name="agreements_summary"),
-       url(r'^agreements/(?P<agreement_id>[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12})/detail$', slicetabsla.agreement_details, name='agreement_details'),
-       url(r'^agreements/(?P<agreement_id>[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12})/guarantees/(?P<guarantee_name>\w+)/violations$', slicetabsla.agreement_term_violations, name='agreement_term_violations'),
-       url(r'^agreements/simplecreate/?$', slicetabsla.AgreementSimple.as_view(), name="agreementsimple"),
-)
\ No newline at end of file
+       url(r'^api-auth/',
+            include('rest_framework.urls', namespace='rest_framework')),
+       url(r'^testbeds/',
+            slicetabsla.Testbeds.as_view(), name="testbeds"),
+       url(r'^(?P<slicename>[^/]+)/?$',
+            slicetabsla.SLAView.as_view(), name="agreements_summary"),
+       url(r'^agreements/(?P<agreement_id>[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12})/detail$',
+            slicetabsla.agreement_details, name='agreement_details'),
+       url(r'^agreements/(?P<agreement_id>[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12})/guarantees/(?P<guarantee_name>\w+)/violations$',
+            slicetabsla.agreement_term_violations, name='agreement_term_violations'),
+       url(r'^agreements/simplecreate/?$',
+            slicetabsla.AgreementSimple.as_view(), name="agreementsimple"),
+)