Merge branch 'master' of ssh://git.onelab.eu/git/myslice
authorCiro Scognamiglio <ciro.scognamiglio@cslash.net>
Fri, 25 Oct 2013 17:22:40 +0000 (19:22 +0200)
committerCiro Scognamiglio <ciro.scognamiglio@cslash.net>
Fri, 25 Oct 2013 17:22:40 +0000 (19:22 +0200)
Conflicts:
portal/sliceview.py

26 files changed:
README.remove_columns [new file with mode: 0644]
manifold/manifoldapi.py
myslice/config.py
myslice/myslice.ini.localhost
plugins/hazelnut/static/js/hazelnut.js
plugins/slicestat/__init__.py
plugins/slicestat/static/js/slicestat.js
portal/actions.py
portal/migrations/0001_initial.py
portal/migrations/0002_extend_slice.py
portal/migrations/0003_extend_slice.py
portal/migrations/0004_extend_user.py [new file with mode: 0644]
portal/migrations/0005_extend_user.py [new file with mode: 0644]
portal/migrations/0006_extend_slice.py [new file with mode: 0644]
portal/models.py
portal/registrationview.py
portal/resourceview.py
portal/slicerequestview.py
portal/sliceview.py
portal/templates/registration_view.html
portal/templates/resource.html
portal/templates/validate_pending.html
portal/urls.py
trash/sampleviews.py
unfold/page.py
unfold/static/css/onelab_marko.css [new file with mode: 0644]

diff --git a/README.remove_columns b/README.remove_columns
new file mode 100644 (file)
index 0000000..32d5981
--- /dev/null
@@ -0,0 +1,7 @@
+sqlite> CREATE TEMPORARY TABLE portal_pendinguser_backup(id,first_name,last_name,email,password,keypair,authority_hrn);
+sqlite> INSERT INTO portal_pendinguser_backup SELECT id,first_name,last_name,email,password,keypair,authority_hrn FROM portal_pendinguser;
+sqlite> DROP TABLE portal_pendinguser;
+sqlite> CREATE TABLE portal_pendinguser(id,first_name,last_name,email,password,keypair,authority_hrn);
+sqlite> INSERT INTO portal_pendinguser SELECT id,first_name,last_name,email,password,keypair,authority_hrn FROM portal_pendinguser_backup;
+sqlite> DROP TABLE portal_pendinguser_backup;
+sqlite> COMMIT;
index e7c6ce9..35fd3d7 100644 (file)
@@ -87,6 +87,10 @@ def _execute_query(request, query, manifold_api_session_auth):
     result = manifold_api.forward(query.to_dict())
     if result['code'] == 2:
         raise Exception, 'Error running query: %r' % result
+    
+    if result['code'] == 1:
+        print "WARNING" 
+        print result['description']
 
     # XXX Handle errors
     #Error running query: {'origin': [0, 'XMLRPCAPI'], 'code': 2, 'description': 'No such session: No row was found for one()', 'traceback': 'Traceback (most recent call last):\n  File "/usr/local/lib/python2.7/dist-packages/manifold/core/xmlrpc_api.py", line 68, in xmlrpc_forward\n    user = Auth(auth).check()\n  File "/usr/local/lib/python2.7/dist-packages/manifold/auth/__init__.py", line 245, in check\n    return self.auth_method.check()\n  File "/usr/local/lib/python2.7/dist-packages/manifold/auth/__init__.py", line 95, in check\n    raise AuthenticationFailure, "No such session: %s" % e\nAuthenticationFailure: No such session: No row was found for one()\n', 'type': 2, 'ts': None, 'value': None}
index 61c2281..53295c4 100644 (file)
@@ -24,7 +24,7 @@ class Config(object):
     # the INRIA setup is with "http://manifold.pl.sophia.inria.fr:7080/"
 
     default_manifold_admin_user     = 'admin'
-    default_manifold_admin_password = 'admin'
+    default_manifold_admin_password = 'demo'
 
 
     def __init__ (self):
index 325191d..c22836e 100644 (file)
@@ -1,4 +1,4 @@
 [manifold]
 url = http://localhost:7080
 admin_user = admin
-admin_password = demo
+admin_password = admin
index 21b23f5..dcd4e1f 100644 (file)
         on_filter_added: function(filter)
         {
             // XXX
+            console.log(filter);
             this.redraw_table();
         },
 
index d601663..d5990a8 100644 (file)
@@ -1,6 +1,6 @@
 from unfold.plugin import Plugin
 
-class Slicestat(Plugin):
+class SliceStat(Plugin):
     
     def __init__ (self, query, **settings):
         Plugin.__init__ (self, **settings)
index 5c1920a..0e3dc53 100644 (file)
@@ -13,7 +13,7 @@
 
 (function($){
 
-    var Slicestat = Plugin.extend({
+    var SliceStat = Plugin.extend({
 
         /** XXX to check
          * @brief Plugin constructor
     });
 
     /* Plugin registration */
-    $.plugin('Slicestat', Slicestat);
+    $.plugin('SliceStat', SliceStat);
 
     // TODO Here use cases for instanciating plugins in different ways like in the pastie.
 
index c66b10a..5699562 100644 (file)
@@ -4,6 +4,10 @@ from manifold.manifoldapi        import execute_query
 from portal.models               import PendingUser, PendingSlice
 import json
 
+# XXX sfa dependency, should be moved to SFA gateway
+from sfa.util.xrn                import Xrn 
+
+
 # Get the list of authorities
 
 def authority_get_pis(request, authority_hrn):
@@ -17,35 +21,38 @@ def authority_get_pis(request, authority_hrn):
     #return result['pi_users']
     return results
 
-def authority_get_pi_emails(request,authority_hrn):
+def authority_get_pi_emails(request, authority_hrn):
+    return ['jordan.auge@lip6.fr', 'loic.baron@lip6.fr']
+
     pi_users = authority_get_pis(request,authority_hrn)
     pi_user_hrns = [ hrn for x in pi_users for hrn in x['pi_users'] ]
     query = Query.get('user').filter_by('user_hrn', 'included', pi_user_hrns).select('email')
-    results = execute_query(request,query)
+    results = execute_query(request, query)
     print "mails",  [result['email'] for result in results]
     return [result['email'] for result in results]
 
 # SFA add record (user, slice)
 
-def sfa_add_user(user_params):
-    # sfi.py add --xrn=fed4fire.upmc.timur_friedman --type=user --key=/root/.sfi/timur.pub --email=timur.friedman@lip6.fr --extra=first_name=Timur --extra=last_name=Friedman --extra=enabled=true
-    # user_params: xrn type key email + first_name last_name enabled
+def sfa_add_user(request, user_params):
     query = Query.create('user').set(user_params).select('user_hrn')
-    results = execute_query(query)
+    results = execute_query(request, query)
     if not results:
-        raise Exception, "Failed creating SFA user: %s" % user_params['user_hrn']
-    result, = results
-    return result['user_hrn']
+        raise Exception, "Could not create %s. Already exists ?" % user_params['hrn']
+    return results
 
-def sfa_add_slice(slice_params):
-    pass
+def sfa_add_slice(request, slice_params):
+    query = Query.create('slice').set(slice_params).select('slice_hrn')
+    results = execute_query(request, query)
+    if not results:
+        raise Exception, "Could not create %s. Already exists ?" % slice_params['hrn']
+    return results
 
 # Propose hrn
 
 def manifold_add_user(request, user_params):
     # user_params: email, password e.g., user_params = {'email':'aa@aa.com','password':'demo'}
     query = Query.create('local:user').set(user_params).select('email')
-    results = execute_query(request,query)
+    results = execute_query(request, query)
     if not results:
         raise Exception, "Failed creating manifold user: %s" % user_params['email']
     result, = results
@@ -84,21 +91,24 @@ def manifold_update_account(request,account_params):
 
 def make_request_user(user):
     request = {}
-    request['type'] = 'user'
-    request['id'] = user.id
-    request['timestamp'] = 'TODO' # XXX in DB ?
+    request['type']          = 'user'
+    request['id']            = user.id
+    request['timestamp']     = user.created # XXX in DB ?
     request['authority_hrn'] = user.authority_hrn
-    request['first_name'] = user.first_name
-    request['last_name'] = user.last_name
-    request['email'] = user.email
+    request['first_name']    = user.first_name
+    request['last_name']     = user.last_name
+    request['email']         = user.email
+    request['login']         = user.login
+    request['keypair']       = user.keypair
     return request
 
 def make_request_slice(slice):
     request = {}
     request['type'] = 'slice'
     request['id'] = slice.id
-    request['timestamp'] = 'TODO' # XXX in DB ?
+    request['timestamp'] = slice.created
     request['authority_hrn'] = slice.authority_hrn
+    request['slice_name'] = slice.slice_name
     request['number_of_nodes'] = slice.number_of_nodes
     request['type_of_nodes'] = slice.type_of_nodes
     request['purpose'] = slice.purpose
@@ -140,12 +150,9 @@ def get_request_by_authority(authority_hrns):
 
     return make_requests(pending_users, pending_slices)
     
-SFA_USER_KEYS         = ['xrn', 'type', 'key', 'first_name', 'last_name', 'email']
-SFA_SLICE_KEYS        = []
-MANIFOLD_USER_KEYS    = ['email', 'password']
-MANIFOLD_ACCOUNT_KEYS = []
+# XXX Is it in sync with the form fields ?
 
-def portal_validate_request(request_ids):
+def portal_validate_request(wsgi_request, request_ids):
     status = {}
 
     if not isinstance(request_ids, list):
@@ -160,45 +167,85 @@ def portal_validate_request(request_ids):
         
         request_status = {}
 
+        print "REQUEST", request
         if request['type'] == 'user':
+
             try:
-                sfa_user_params = { key: request[key] for key in SFA_USER_KEYS }
-                sfa_user_params['enabled'] = True
-                # XXX # sfa_add_user(sfa_user_params)
+                hrn = "%s.%s" % (request['authority_hrn'], request['login'])
+                urn = Xrn(hrn, request['type']).get_urn()
+
+                sfa_user_params = {
+                    'hrn'        : hrn, 
+                    'urn'        : urn,
+                    'type'       : request['type'],
+                    'keys'       : [json.loads(request['keypair'])['user_public_key']],
+                    'first_name' : request['first_name'],
+                    'last_name'  : request['last_name'],
+                    'email'      : request['email'],
+                    #'slices'    : None,
+                    #'researcher': None,
+                    #'pi'        : None,
+                    'enabled'    : True
+                }
+                # ignored in request: id, timestamp, password
+
+                sfa_add_user(wsgi_request, sfa_user_params)
+
+                # XXX Remove from database
+
+
                 request_status['SFA user'] = {'status': True }
+
             except Exception, e:
                 request_status['SFA user'] = {'status': False, 'description': str(e)}
 
-            try:
-                manifold_user_params = { key: request[key] for key in MANIFOLD_USER_KEYS }
-                # XXX # manifold_add_user(manifold_user_params)
-                request_status['MySlice user'] = {'status': True }
-            except Exception, e:
-                request_status['MySlice user'] = {'status': False, 'description': str(e)}
+            # MANIFOLD user should be added beforehand, during registration
+            #try:
+            #    manifold_user_params = { key: request[key] for key in MANIFOLD_USER_KEYS }
+            #    # XXX # manifold_add_user(manifold_user_params)
+            #    request_status['MySlice user'] = {'status': True }
+            #except Exception, e:
+            #    request_status['MySlice user'] = {'status': False, 'description': str(e)}
 
             # XXX
             #manifold_account_params = { key: request[key] for key in MANIFOLD_ACCOUNT_KEYS }
             #manifold_add_account(manifold_account_params)
-            request_status['MySlice testbed accounts'] = {'status': False }
+            #request_status['MySlice testbed accounts'] = {'status': False }
 
         elif request['type'] == 'slice':
             try:
-                sfa_slice_params = { key: request[key] for key in SFA_SLICE_KEYS }
-                # XXX # sfa_add_slice(sfa_slice_params)
+                hrn = "%s.%s" % (request['authority_hrn'], request['slice_name'])
+                urn = Xrn(hrn, request['type']).get_urn()
+
+                sfa_slice_params = {
+                    'hrn'        : hrn, 
+                    'urn'        : urn,
+                    'type'       : request['type'],
+                    #'slices'    : None,
+                    #'researcher': None,
+                    #'pi'        : None,
+                    'enabled'    : True
+                }
+                # ignored in request: id, timestamp,  number_of_nodes, type_of_nodes, purpose
+
+                sfa_add_slice(wsgi_request, sfa_slice_params)
+
+                # XXX Remove from database
+
+            
                 request_status['SFA slice'] = {'status': True }
+
             except Exception, e:
                 request_status['SFA slice'] = {'status': False, 'description': str(e)}
 
         status['%s__%s' % (request['type'], request['id'])] = request_status
 
-    # XXX remove from database succeeded actions
-
     return status
 
 
-def validate_action(*args, **kwargs):
+def validate_action(request, **kwargs):
     ids = filter(None, kwargs['id'].split('/'))
-    status = portal_validate_request(ids)
+    status = portal_validate_request(request, ids)
     json_answer = json.dumps(status)
     return HttpResponse (json_answer, mimetype="application/json")
 
index 24960f3..2c1fd6d 100644 (file)
@@ -20,7 +20,6 @@ class Migration(SchemaMigration):
             (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
             ('first_name', self.gf('django.db.models.fields.TextField')()),
             ('last_name', self.gf('django.db.models.fields.TextField')()),
-            ('affiliation', self.gf('django.db.models.fields.TextField')()),
             ('email', self.gf('django.db.models.fields.EmailField')(max_length=75)),
             ('password', self.gf('django.db.models.fields.TextField')()),
             ('keypair', self.gf('django.db.models.fields.TextField')()),
@@ -60,7 +59,6 @@ class Migration(SchemaMigration):
         },
         u'portal.pendinguser': {
             'Meta': {'object_name': 'PendingUser'},
-            'affiliation': ('django.db.models.fields.TextField', [], {}),
             'authority_hrn': ('django.db.models.fields.TextField', [], {}),
             'email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}),
             'first_name': ('django.db.models.fields.TextField', [], {}),
@@ -71,4 +69,4 @@ class Migration(SchemaMigration):
         }
     }
 
-    complete_apps = ['portal']
\ No newline at end of file
+    complete_apps = ['portal']
index 633006a..c6de6c5 100644 (file)
@@ -33,7 +33,6 @@ class Migration(SchemaMigration):
         },
         u'portal.pendinguser': {
             'Meta': {'object_name': 'PendingUser'},
-            'affiliation': ('django.db.models.fields.TextField', [], {}),
             'authority_hrn': ('django.db.models.fields.TextField', [], {}),
             'email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}),
             'first_name': ('django.db.models.fields.TextField', [], {}),
@@ -44,4 +43,4 @@ class Migration(SchemaMigration):
         }
     }
 
-    complete_apps = ['portal']
\ No newline at end of file
+    complete_apps = ['portal']
index 2437098..10fe0fa 100644 (file)
@@ -52,7 +52,6 @@ class Migration(SchemaMigration):
         },
         u'portal.pendinguser': {
             'Meta': {'object_name': 'PendingUser'},
-            'affiliation': ('django.db.models.fields.TextField', [], {}),
             'authority_hrn': ('django.db.models.fields.TextField', [], {}),
             'email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}),
             'first_name': ('django.db.models.fields.TextField', [], {}),
@@ -63,4 +62,4 @@ class Migration(SchemaMigration):
         }
     }
 
-    complete_apps = ['portal']
\ No newline at end of file
+    complete_apps = ['portal']
diff --git a/portal/migrations/0004_extend_user.py b/portal/migrations/0004_extend_user.py
new file mode 100644 (file)
index 0000000..50be2b9
--- /dev/null
@@ -0,0 +1,50 @@
+# -*- coding: utf-8 -*-
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+
+class Migration(SchemaMigration):
+
+    def forwards(self, orm):
+        # Adding field 'PendingUser.login'
+        db.add_column(u'portal_pendinguser', 'login',
+                      self.gf('django.db.models.fields.TextField')(default='dummy'),
+                      keep_default=False)
+
+
+    def backwards(self, orm):
+        # Deleting field 'PendingUser.login'
+        db.delete_column(u'portal_pendinguser', 'login')
+
+
+    models = {
+        u'portal.institution': {
+            'Meta': {'object_name': 'Institution'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.TextField', [], {})
+        },
+        u'portal.pendingslice': {
+            'Meta': {'object_name': 'PendingSlice'},
+            'authority_hrn': ('django.db.models.fields.TextField', [], {'null': 'True'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'number_of_nodes': ('django.db.models.fields.TextField', [], {'default': '0'}),
+            'purpose': ('django.db.models.fields.TextField', [], {'default': "'NA'"}),
+            'slice_name': ('django.db.models.fields.TextField', [], {}),
+            'type_of_nodes': ('django.db.models.fields.TextField', [], {'default': "'NA'"})
+        },
+        u'portal.pendinguser': {
+            'Meta': {'object_name': 'PendingUser'},
+            'authority_hrn': ('django.db.models.fields.TextField', [], {}),
+            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}),
+            'first_name': ('django.db.models.fields.TextField', [], {}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'keypair': ('django.db.models.fields.TextField', [], {}),
+            'last_name': ('django.db.models.fields.TextField', [], {}),
+            'login': ('django.db.models.fields.TextField', [], {}),
+            'password': ('django.db.models.fields.TextField', [], {})
+        }
+    }
+
+    complete_apps = ['portal']
\ No newline at end of file
diff --git a/portal/migrations/0005_extend_user.py b/portal/migrations/0005_extend_user.py
new file mode 100644 (file)
index 0000000..c3725b1
--- /dev/null
@@ -0,0 +1,51 @@
+# -*- coding: utf-8 -*-
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+
+class Migration(SchemaMigration):
+
+    def forwards(self, orm):
+        # Adding field 'PendingUser.created'
+        db.add_column(u'portal_pendinguser', 'created',
+                      self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, default=datetime.datetime(2013, 10, 25, 0, 0), blank=True),
+                      keep_default=False)
+
+
+    def backwards(self, orm):
+        # Deleting field 'PendingUser.created'
+        db.delete_column(u'portal_pendinguser', 'created')
+
+
+    models = {
+        u'portal.institution': {
+            'Meta': {'object_name': 'Institution'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.TextField', [], {})
+        },
+        u'portal.pendingslice': {
+            'Meta': {'object_name': 'PendingSlice'},
+            'authority_hrn': ('django.db.models.fields.TextField', [], {'null': 'True'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'number_of_nodes': ('django.db.models.fields.TextField', [], {'default': '0'}),
+            'purpose': ('django.db.models.fields.TextField', [], {'default': "'NA'"}),
+            'slice_name': ('django.db.models.fields.TextField', [], {}),
+            'type_of_nodes': ('django.db.models.fields.TextField', [], {'default': "'NA'"})
+        },
+        u'portal.pendinguser': {
+            'Meta': {'object_name': 'PendingUser'},
+            'authority_hrn': ('django.db.models.fields.TextField', [], {}),
+            'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}),
+            'first_name': ('django.db.models.fields.TextField', [], {}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'keypair': ('django.db.models.fields.TextField', [], {}),
+            'last_name': ('django.db.models.fields.TextField', [], {}),
+            'login': ('django.db.models.fields.TextField', [], {}),
+            'password': ('django.db.models.fields.TextField', [], {})
+        }
+    }
+
+    complete_apps = ['portal']
\ No newline at end of file
diff --git a/portal/migrations/0006_extend_slice.py b/portal/migrations/0006_extend_slice.py
new file mode 100644 (file)
index 0000000..b2c593d
--- /dev/null
@@ -0,0 +1,52 @@
+# -*- coding: utf-8 -*-
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+
+class Migration(SchemaMigration):
+
+    def forwards(self, orm):
+        # Adding field 'PendingSlice.created'
+        db.add_column(u'portal_pendingslice', 'created',
+                      self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, default=datetime.datetime(2013, 10, 25, 0, 0), blank=True),
+                      keep_default=False)
+
+
+    def backwards(self, orm):
+        # Deleting field 'PendingSlice.created'
+        db.delete_column(u'portal_pendingslice', 'created')
+
+
+    models = {
+        u'portal.institution': {
+            'Meta': {'object_name': 'Institution'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.TextField', [], {})
+        },
+        u'portal.pendingslice': {
+            'Meta': {'object_name': 'PendingSlice'},
+            'authority_hrn': ('django.db.models.fields.TextField', [], {'null': 'True'}),
+            'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'number_of_nodes': ('django.db.models.fields.TextField', [], {'default': '0'}),
+            'purpose': ('django.db.models.fields.TextField', [], {'default': "'NA'"}),
+            'slice_name': ('django.db.models.fields.TextField', [], {}),
+            'type_of_nodes': ('django.db.models.fields.TextField', [], {'default': "'NA'"})
+        },
+        u'portal.pendinguser': {
+            'Meta': {'object_name': 'PendingUser'},
+            'authority_hrn': ('django.db.models.fields.TextField', [], {}),
+            'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}),
+            'first_name': ('django.db.models.fields.TextField', [], {}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'keypair': ('django.db.models.fields.TextField', [], {}),
+            'last_name': ('django.db.models.fields.TextField', [], {}),
+            'login': ('django.db.models.fields.TextField', [], {}),
+            'password': ('django.db.models.fields.TextField', [], {})
+        }
+    }
+
+    complete_apps = ['portal']
\ No newline at end of file
index 61feba3..1569146 100644 (file)
@@ -56,14 +56,14 @@ class Institution(models.Model):
 class PendingUser(models.Model):
     # NOTE We might consider migrating the fields to CharField, which would
     # simplify form creation in forms.py
-    first_name  = models.TextField()
-    last_name   = models.TextField()
-#    affiliation = models.TextField()
-    email       = models.EmailField() #validators=[validate_email])
-    password    = models.TextField()
-    keypair     = models.TextField()
-    # institution
+    first_name    = models.TextField()
+    last_name     = models.TextField()
+    email         = models.EmailField() #validators=[validate_email])
+    password      = models.TextField()
+    keypair       = models.TextField()
     authority_hrn = models.TextField()
+    login         = models.TextField()
+    created       = models.DateTimeField(auto_now_add = True)
     # models.ForeignKey(Institution)
 
 class PendingSlice(models.Model):
@@ -72,3 +72,4 @@ class PendingSlice(models.Model):
     number_of_nodes = models.TextField(default=0)
     type_of_nodes   = models.TextField(default='NA')
     purpose         = models.TextField(default='NA')
+    created         = models.DateTimeField(auto_now_add = True)
index ba73700..2322081 100644 (file)
@@ -27,15 +27,13 @@ from portal.actions             import authority_get_pi_emails
 class RegistrationView (View):
 
     def dispatch (self, request):
-
         errors = []
 
         authorities_query = Query.get('authority').\
             select('name', 'authority_hrn')
         
-        onelab_enabled_query = Query.get('local:platform').filter_by('platform', '==', 'ple-onelab').filter_by('disabled', '==', 'False')
-        #onelab_enabled = not not execute_admin_query(request, onelab_enabled_query)
-        onelab_enabled = True
+        onelab_enabled_query = Query.get('local:platform').filter_by('platform', '==', 'ple').filter_by('disabled', '==', 'False')
+        onelab_enabled = not not execute_admin_query(request, onelab_enabled_query)
         if onelab_enabled:
             print "ONELAB ENABLED"
             authorities_query = authorities_query.filter_by('authority_hrn', 'included', ['ple.inria', 'ple.upmc', 'ple.ibbtple'])
@@ -56,11 +54,12 @@ class RegistrationView (View):
             # We shall use a form here
 
             #get_email = PendingUser.objects.get(email)
-            reg_fname = request.POST.get('firstname', '')
-            reg_lname = request.POST.get('lastname', '')
-            #reg_aff = request.POST.get('affiliation','')
-            reg_auth = request.POST.get('authority_hrn', '')
-            reg_email = request.POST.get('email','').lower()
+            reg_fname  = request.POST.get('firstname', '')
+            reg_lname  = request.POST.get('lastname', '')
+            #reg_aff   = request.POST.get('affiliation','')
+            reg_auth   = request.POST.get('authority_hrn', '')
+            reg_login  = request.POST.get('login', '')
+            reg_email  = request.POST.get('email','').lower()
       
             #POST value validation  
             if (re.search(r'^[\w+\s.@+-]+$', reg_fname)==None):
@@ -113,14 +112,15 @@ class RegistrationView (View):
             #b.save()
             if not errors:
                 b = PendingUser(
-                    first_name=reg_fname, 
-                    last_name=reg_lname, 
-                    #affiliation=reg_aff,
-                    authority_hrn=reg_auth,
-                    email=reg_email, 
-                    password=request.POST['password'],
-                    keypair=keypair
-                    )
+                    first_name    = reg_fname, 
+                    last_name     = reg_lname, 
+                    #affiliation  = reg_aff,
+                    authority_hrn = reg_auth,
+                    login         = reg_login,
+                    email         = reg_email, 
+                    password      = request.POST['password'],
+                    keypair       = keypair,
+                )
                 b.save()
 
                 # Send email
@@ -132,15 +132,13 @@ class RegistrationView (View):
                     'keypair'       : 'Public Key :' + public_key,
                     'cc_myself'     : True # form.cleaned_data['cc_myself']
                     }
-                #not working
-                #recipients = authority_get_pi_emails(request,reg_auth)
-                recipients = ['devel@myslice.info']
+
+                recipients = authority_get_pi_emails(request,reg_auth)
+
                 if ctx['cc_myself']:
                     recipients.append(ctx['email'])
 
                 msg = render_to_string('user_request_email.txt', ctx)
-                print "tesing msg"
-                print msg
                 send_mail("Onelab New User request for %s submitted"%reg_email, msg, reg_email, recipients)
 
                 return render(request, 'user_register_complete.html')
index 1191b6f..0ba8a26 100644 (file)
@@ -8,7 +8,7 @@ from ui.topmenu                  import topmenu_items, the_user
 from plugins.googlemap           import GoogleMap
 from plugins.hazelnut            import Hazelnut
 from plugins.lists.simplelist    import SimpleList
-from plugins.slicestat           import Slicestat
+from plugins.slicestat           import SliceStat
 
 # View for 1 platform and its details
 class ResourceView(TemplateView):
@@ -66,7 +66,7 @@ class ResourceView(TemplateView):
 #            query = resource_query,
 #        )
 
-        resource_stats = Slicestat(
+        resource_stats = SliceStat(
             title = None,
             page  = page,
             stats = 'node',
index e8c80d8..da8e667 100644 (file)
@@ -18,8 +18,7 @@ class SliceRequestView (LoginRequiredAutoLogoutView):
             select('name', 'authority_hrn')
         
         onelab_enabled_query = Query.get('local:platform').filter_by('platform', '==', 'ple-onelab').filter_by('disabled', '==', 'False')
-        #onelab_enabled = not not execute_admin_query(request, onelab_enabled_query)
-        onelab_enabled = True
+        onelab_enabled = not not execute_admin_query(request, onelab_enabled_query)
         if onelab_enabled:
             authorities_query = authorities_query.filter_by('authority_hrn', 'included', ['ple.inria', 'ple.upmc', 'ple.ibbtple'])
 
@@ -59,8 +58,8 @@ class SliceRequestView (LoginRequiredAutoLogoutView):
             cc_myself = form.cleaned_data['cc_myself']
 
             # The recipients are the PI of the authority
-            recipients = authority_get_pi_emails(request,authority_hrn)
-            #recipients = ['yasin.upmc@gmail.com','jordan.auge@lip6.fr']
+            recipients = authority_get_pi_emails(request, authority_hrn)
+
             if cc_myself:
                 recipients.append(email)
             msg = render_to_string('slice-request-email.txt', form.cleaned_data)
index 8767e8b..44effc9 100644 (file)
@@ -27,7 +27,8 @@ from myslice.config                  import Config
 tmp_default_slice='ple.upmc.myslicedemo'
 
 # temporary : turn off the users part to speed things up
-do_query_users=True
+#do_query_users=True
+do_query_users=False
 
 class SliceView (LoginRequiredAutoLogoutView):
 
@@ -234,6 +235,7 @@ class SliceView (LoginRequiredAutoLogoutView):
         # --------------------------------------------------------------------------
         # USERS
     
+<<<<<<< HEAD
         if do_query_users:
             tab_users = Tabs(
                 page                = page,
@@ -263,6 +265,35 @@ class SliceView (LoginRequiredAutoLogoutView):
             ))
             
         
+=======
+        if do_query_users:
+            tab_users = Tabs(
+                page                = page,
+                domid               = 'users',
+                outline_complete    = True,
+                togglable           = True,
+                title               = 'Users',
+                active_domid        = 'users-list',
+                )
+            main_stack.insert(tab_users)
+    
+            tab_users.insert(Hazelnut( 
+                page        = page,
+                title       = 'Users List',
+                domid       = 'users-list',
+                # tab's sons preferably turn this off
+                togglable   = False,
+                # this is the query at the core of the slice list
+                query       = sq_user,
+                query_all  = query_user_all,
+                checkboxes  = True,
+                datatables_options = { 
+                    'iDisplayLength' : 25,
+                    'bLengthChange'  : True,
+                    'bAutoWidth'     : True,
+                },
+            ))
+>>>>>>> 0c8a634162f3271018102e75a3934c5db5e48f59
 # DEMO    
         # --------------------------------------------------------------------------
         # MEASUREMENTS
index 6f709f4..3d1010c 100644 (file)
       </div>
       <div class="col-xs-4"><p class="form-hint">Please select an authority responsible for vetting your account</p></div>
     </div>
+
+       <!-- LOGIN
+       TODO: Login should be suggested from user email or first/last name, and
+       checked for existence. In addition, the full HRN should be shown to the
+       user.
+       -->
+    <div class="form-group">
+      <label for="login" class="col-xs-4 control-label">Login</label>
+      <div class="col-xs-4">
+         <input type="text" name="login" size="25" class="form-control" minlength="2" value="{{ login }}" placeholder="Login" required />
+      </div>
+      <div class="col-xs-4"><p class="form-hint">Enter your login</p></div>
+    </div>
     
     <div class="form-group">
       <label for="email" class="col-xs-4 control-label">Email</label>
index 5bdfdc9..27089a7 100644 (file)
@@ -8,6 +8,6 @@
 
 <h1>Resource</h1>
 {{resource}}
-{{resource_stats}}
 {{resource_as_map}}
+{{resource_stats}}
 {% endblock %}
index 74176ea..e21cac8 100644 (file)
@@ -6,7 +6,7 @@
        function on_click_event() {
                var ids = []; 
                $('.portal__validate__checkbox').each(function(i, el) {
-                       if ($(el).attr('checked')) {
+                       if ($(el).prop('checked')) {
                                // portal__validate__checkbox__slice__2
                                var id_array = $(el).attr('id').split('__');
                                // push(slice__2)
                                                                status_str += ' -- ';
 
                                                        if (result.status) {
-                                                               status_str += '<font color="green">' + name + '</font>';
+                                                               status_str += '<font color="green">OK</font>';
                                                                $('#portal__validate__checkbox__' + request_type__id).hide();
                                                        } else {
-                                                               status_str += '<font color="red">' + name + ' (' + result.description + ')</font>';
+                                                               status_str += '<font color="red">ERROR: ' + result.description + '</font>';
                                                        }
                                                });
                                                $('#portal__status__' + request_type__id).html(status_str)
index ef90018..5659386 100644 (file)
@@ -71,7 +71,7 @@ urlpatterns = patterns('',
     url(r'^validate/?$', ValidatePendingView.as_view()),
     # http://stackoverflow.com/questions/2360179/django-urls-how-to-pass-a-list-of-items-via-clean-urls
     # (r'^validate_action/(?P<constraints>[^/]+)/(?P<id>\w+)/?$', 'portal.views.pres_view_static'),
-     (r'^validate_action(?P<id>(?:/\w+)+)/?$', 'portal.actions.validate_action'),
+    url(r'^validate_action(?P<id>(?:/\w+)+)/?$', 'portal.actions.validate_action'),
 
     url(r'^pres_view/?$', PresViewView.as_view(), name='pres_view'),
     (r'^methods/(?P<type>\w+)/?$', 'portal.views.pres_view_methods'),
index ad8571d..5d257a4 100644 (file)
@@ -12,6 +12,8 @@ from trash.trashutils import lorem, hard_wired_slice_names
 
 @login_required
 def tab_view (request):
+    print "request", request.__class__
+    print request
     prelude=Prelude( js_files='js/bootstrap.js', css_files='css/bootstrap.css')
     prelude_env = prelude.prelude_env()
 
index 3627e16..5922ae7 100644 (file)
@@ -34,6 +34,7 @@ class Page:
         self._queue=[]
         # global prelude object
         self.prelude=Prelude(css_files='css/plugin.css')
+        self.prelude=Prelude(css_files='css/onelab_marko.css')
 
     # record known plugins hashed on their domid
     def record_plugin (self, plugin):
diff --git a/unfold/static/css/onelab_marko.css b/unfold/static/css/onelab_marko.css
new file mode 100644 (file)
index 0000000..b31174c
--- /dev/null
@@ -0,0 +1,410 @@
+/* @override 
+       http://test.myslice.info/static/css/plugin.css
+*/
+
+
+
+/*-------------------------------- MARKO'S STYLES -----*/
+
+
+/* GENERAL */
+
+.container {
+       padding: 0 !important;
+       color: #fff;
+}
+
+.container h1 {
+       color: #fff !important;
+       font-family: Ubuntu;
+       margin-top: 60px;
+}
+
+div.plugin-outline-complete, 
+div.plugin-outline-body {
+    border: 0px solid;
+    border-radius: 0;
+    border-color: #ccc;
+    -webkit-transition: padding 200ms ease-out;
+    -moz-transition: padding 200ms ease-out;
+    -o-transition: padding 200ms ease-out;
+    transition: padding 0.2s ease-out;
+    padding: 20px;
+    margin: 0;
+}
+/*
+div.plugin-outline-complete:hover, 
+div.plugin-outline-body:hover {
+    padding: 80px 80px 120px 80px; 
+}
+*/
+a.plugin-tooltip { 
+    font-size: 130%;
+    font-style: normal;
+    font-weight: bold;
+    padding: 5px;
+    color: #333;
+    font-family: Ubuntu, Arial, sans-serif;
+    text-transform: uppercase;
+}
+
+a.plugin-tooltip:hover { 
+    color: #fff; 
+    text-decoration: none;
+}
+
+
+
+/* LIST VIEW */
+
+h2.well.well-lg {
+       border-radius:0;
+       border: 0;
+       font-family: Ubuntu, arial, sans-serif;
+       text-transform: ;
+       font-weight: normal;
+       font-size: 40px;
+       /* color: #30196d; */
+    color: white;
+       margin-bottom: 0px;
+       margin-top: 0;
+       padding: 30px;
+       opacity: 1;
+       text-align: center;
+       background-color: #30196d;
+}
+
+#complete-resources {
+/*    background-color: #92f79e !important; */
+    background-color: #B8B2FF !important;
+}
+
+#complete-filters {
+/*    background-color: #4af25d; */
+    background-color: #add7ff;
+}
+
+#complete-users {
+/*    background-color: #ff7394 !important; */
+    background-color: #add7ff !important;
+}
+
+#complete-measurements {
+    background-color: !important;
+}
+
+#complete-pending {
+/*    background-color: #add7ff !important; */
+    background-color: #B8B2FF !important;
+
+}
+
+#complete-customize-resources {
+    background-color: #efdfdf;
+}
+
+#complete-msgs-pre {
+    background-color: #ccc;
+}
+
+#complete-resources, 
+#complete-filters, 
+#complete-users, 
+#complete-measurements,
+#complete-pending,
+#complete-customize-resources,
+#complete-msgs-pre {
+       opacity: 1;
+       text-align: center;
+       color: #333;
+}
+
+#complete-resources:hover, 
+#complete-filters:hover, 
+#complete-users:hover, 
+#complete-measurements:hover,
+#complete-pending:hover,
+#complete-customize-resources:hover,
+#complete-msgs-pre:hover {
+       opacity: 1;
+}
+
+.nav.nav-tabs {
+       font-family: Ubuntu, Arial, sans-serif;
+       border: 0 !important;
+       border-bottom: 3px solid #fff !important;
+       margin-bottom: 40px;
+}
+
+.nav.nav-tabs li.active a {
+       color: #572bc9;
+       border-left: 0px solid #572bc9;
+       border-top: 0px solid #572bc9;
+       border-right: 0px solid #572bc9;
+}
+
+.nav.nav-tabs li a {
+       color: #333;
+       border: 0 !important;
+       margin-right: 5px;
+}
+
+.nav.nav-tabs li a:hover {
+       color: #333;
+       background: #572bc9;
+       color: #fff;
+       border: 0 !important;
+}
+
+
+
+
+
+/* TOPMENU.CSS */
+
+body {
+       background: #30196d !important;
+    padding-top: 60px;
+    padding-bottom: 0px;
+}
+
+div.topmenu { 
+       padding-top: 0px;
+       font-family: Ubuntu, Arial, sans-serif;
+       font-weight: bold;
+       text-transform: ;
+       background: #fff;
+       -webkit-box-shadow: 0px 10px 10px rgba(50, 50, 50, 0.44);
+       -moz-box-shadow:    0px 10px 10px rgba(50, 50, 50, 0.44);
+       box-shadow:         0px 10px 10px rgba(50, 50, 50, 0.44);
+}
+
+.navbar-nav li a,
+.navbar-nav li.other a {
+       padding-top: 25px;
+       padding-bottom: 20px;
+}
+
+.navbar-nav li a:hover {
+       color: #572bc9 !important;
+}
+
+.navbar-nav li.active a {
+.navbar-nav li.active a {
+       background: #eee !important;
+}
+
+ul.logged-in { 
+    padding-top: 25px; 
+}
+button.logged-in { 
+    font-size: 1em;
+    font-weight: bold; 
+    margin-left: 5px;
+    margin-top: -5px;
+    background: #572bc9;
+    border: 2px solid #572bc9;
+    color: #eee;
+    padding: 5px 15px;
+    border-radius:5px;
+}
+
+button.logged-in:hover { 
+    background: #4af25d;
+    border: 2px solid #4af25d;
+    color: #333;
+}
+li.username {
+    margin-bottom: 10px;
+    font-size: 0.8em;
+    text-transform: none;
+    font-weight: normal; 
+    color: #999;
+}
+
+
+/* BOOTSTRAP */
+
+
+ul.pagination li a {
+       background: ;
+       color: #572bc9;
+       font-family: Ubuntu, Arial, sans-serif;
+}
+
+ul.pagination li.active a {
+       background: #572bc9;
+       border: 1px solid #572bc9;
+}
+
+.btn.btn-default {
+       background: #572bc9;
+       color: #ccc;
+       font-family: Ubuntu, Arial, sans-serif;
+       font-weight: bold;
+       border: 0px;
+}
+
+.btn.btn-default:hover {
+       background: #4af25d;
+       color: #333;
+       font-family: Ubuntu, Arial, sans-serif;
+       font-weight: bold;
+       border: 0px;
+}
+
+input {
+       border-radius: 3px;
+       border: none;
+       border: 1px solid #ccc;
+}
+
+
+div.dataTables_length label, 
+div.dataTables_filter label,
+div.dataTables_info {
+       font-family: Ubuntu, Arial, sans-serif !important;
+}
+
+
+
+
+/* HAZELNUT */
+
+div.Hazelnut table.dataTable th {
+    font: bold 12px/22px Ubuntu, Arial, sans-serif;
+    color: #333 !important;
+    border-right: 0px solid #333 !important;
+    border-bottom: 0px solid #C1DAD7 !important;
+    border-top: 0px solid #C1DAD7 !important;
+    letter-spacing: 1px;
+    text-transform: uppercase;
+    text-align: left;
+    padding: 8px 12px 4px 20px;
+    vertical-align:middle;
+    background: # url(../img/tablesort-header.jpg) no-repeat !important; 
+}
+
+div.Hazelnut table.dataTable td, div.Hazelnut table.dataTable textarea, div.Hazelnut table.dataTable input [type="text"] {
+    font: normal 12px Ubuntu, Arial, Helvetica, sans-serif;
+    border-right: 0px solid #fff !important;
+    border-bottom: 1px solid #fff !important;
+}
+
+div.Hazelnut table.dataTable thead { 
+    background: url('../img/tablesort-header.png') repeat-x !important;
+    background-color: #caebea;
+}
+
+div.Hazelnut table.dataTable tfoot { 
+    background: url('../img/tablesort-header.png') repeat-x !important;
+    background-color: # !important;
+}
+
+
+/* QUERY EDITOR */
+
+table.query-editor {
+    margin: 40px auto !important;
+    clear: both;
+    /* width: 80%;*/
+    width: 100% !important;
+    font-family: Ubuntu;
+}
+
+.query-editor-spacer,
+.plugin.ResourcesSelected,
+.plugin.Tabs {
+    margin-top: 60px !important;
+}
+
+table.query-editor td {
+    padding: 5px 5px !important;
+    font: normal 12px Ubuntu, Arial, sans-serif !important;
+}
+
+
+
+/* DASHBOARD */
+
+#ms-dashboard-profile,
+#ms-dashboard-testbeds,
+#ms-dashboard-slices {
+       -webkit-transition: all 50ms ease-out;
+    -moz-transition: all 50ms ease-out;
+    -o-transition: all 50ms ease-out;
+    transition: all 0.05s ease-out;
+       padding-top: 140px;
+       padding-bottom: 60px;
+       margin-top: 60px;
+       color: #fff;
+       font-family: Ubuntu, Arial, sans-serif;
+       text-align: center;
+       
+}
+
+#ms-dashboard-profile:hover,
+#ms-dashboard-testbeds:hover,
+#ms-dashboard-slices:hover {
+       margin-top: 65px;
+}
+
+#ms-dashboard-profile {
+       background: url("../img/icon_users_color.png") top center no-repeat;
+       
+}
+
+#ms-dashboard-testbeds {
+       background: url("../img/icon_testbed_color.png") top center no-repeat;
+}
+
+#ms-dashboard-slices {
+       background: url("../img/icon_slices_color.png") top center no-repeat;
+}
+
+.ms-dashboard-content ul {
+       list-style-type: none !important;
+       padding-left: 0;
+       text-align: center !important;
+}
+
+.ms-dashboard-content {
+       padding: 0 !important;
+}
+
+.ms-dashboard-content a {
+       color: /*#572bc9*/ #ff7394 !important;
+}
+
+.ms-dashboard-caption h2 {
+       font-family: Ubuntu, Arial, sans-serif;
+       border-bottom: 0 !important;
+       text-transform: uppercase;
+}
+
+#ms-dashboard-profile>div.ms-dashboard-caption {
+    background: no-repeat url(#) !important;
+    padding-left: 0 !important;
+}   
+
+#ms-dashboard-testbeds>div.ms-dashboard-caption {
+    background: no-repeat url(#) !important;
+    padding-left: 0 !important;
+}   
+
+#ms-dashboard-slices>div.ms-dashboard-caption {
+    background: no-repeat url(#) !important;
+    padding-left: 0 !important;
+}   
+
+.simplelist {
+       font-size: 100%;
+       text-align: center !important;
+       margin: 0 auto;
+}
+
+
+
+
+
+