Merge branch 'master' of git://git.onelab.eu/myslice
authorLoic Baron <loic.baron@lip6.fr>
Thu, 26 Sep 2013 10:16:07 +0000 (12:16 +0200)
committerLoic Baron <loic.baron@lip6.fr>
Thu, 26 Sep 2013 10:16:07 +0000 (12:16 +0200)
Conflicts:
portal/registrationview.py

15 files changed:
myslice.spec
plugins/resources_selected/static/css/resources_selected.css
plugins/resources_selected/static/js/resources_selected.js
plugins/resources_selected/templates/resources_selected.html
plugins/tabs/static/js/tabs.js
portal/dashboardview.py
portal/platformsview.py
portal/registrationview.py
portal/sliceview.py
portal/static/js/my_account.register.js
portal/templates/dashboard.html
portal/templates/platforms.html
portal/templates/registration_view.html
views/static/img/myslice-icon.png [new file with mode: 0644]
views/templates/base.html

index 1c7bf54..e0504ea 100644 (file)
@@ -1,6 +1,6 @@
 %define name myslice
 %define version 0.2
-%define taglevel 3
+%define taglevel 4
 
 %define release %{taglevel}%{?pldistro:.%{pldistro}}%{?date:.%{date}}
 
@@ -47,6 +47,12 @@ rm -rf $RPM_BUILD_ROOT
 %{_datadir}/myslice/*
 
 %changelog
+* Wed Sep 25 2013 Thierry Parmentelat <thierry.parmentelat@sophia.inria.fr> - myslice-0.2-4
+- move to bootstrap v3 complete - hopefully
+- static files directory is now plain static/
+- templates files directory is now plain templates/
+- packaging for debian should be working fine, using apache+wsgi
+
 * Fri Sep 20 2013 Thierry Parmentelat <thierry.parmentelat@sophia.inria.fr> - myslice-0.2-3
 - checkpoint for deployment on test.myslice.info
 
index a9a0bda..1759ad2 100644 (file)
@@ -16,16 +16,6 @@ tr.remove td{
     cursor: pointer;
 }
 
-input.myslice_action {
-   font-size:13px;
-   font-family:Arial,sans-serif;
-   font-weight:bold;
-   color:#0066CC;
-   width:100px;
-   height:30px;
-   background-color:#FF9933;
-}
-
 .ResourcesSelected .added {
     background-color: #E3F6CE;
 }
index fb498c2..d8705c4 100644 (file)
@@ -32,7 +32,7 @@
             var self = this;
             this.table = this.elmt('table').dataTable({
                 //sPaginationType: 'full_numbers',  // Use pagination
-                sPaginationType: 'bootstrap',
+                sPaginationType: 'full_numbers',
                 //bJQueryUI      : true,
                 //bRetrieve      : true,
                 sScrollX       : '100%',                 // Horizontal scrolling 
index aa5e485..e1e56bc 100644 (file)
@@ -8,8 +8,10 @@
       <th>+/-</th>
     </tr>
   </thead>
+  <tbody></tbody>
 </table>
-<input id="{{domid}}__update" type=button value="Update" />
-<input id="{{domid}}__refresh" type=button value="Refresh" />
-<input id="{{domid}}__reset" type=button value="Reset" />
-<input id="{{domid}}__clear_annotations" type=button value="Clear annotations" />
+<button type="button" id="{{domid}}__update"  class="btn btn-default">"Update"</button>
+<button type="button" id="{{domid}}__refresh"  class="btn btn-default">"Refresh"</button>
+<button type="button" id="{{domid}}__reset"  class="btn btn-default">"Reset"</button>
+<button type="button" id="{{domid}}__clear_annotations"  class="btn btn-default">"Clear Annotations"</button>
+
index b5b1cd0..64c6921 100644 (file)
@@ -2,7 +2,9 @@
 
     $.fn.Tabs = function( method ) {
 
-        $('a[data-toggle="tab"]').on('shown', function (e) {
+        // In Bootstrap 3, we need shown.bs.tab instrad of shown.
+        // see: http://bootply.com/bootstrap-3-migration-guide
+        $('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
           // find the plugin object inside the tab content referenced by the current tabs
           $('.plugin', $($(e.target).attr('href'))).trigger('show');
         });
index a6dc46d..bbd1941 100644 (file)
@@ -53,7 +53,7 @@ class DashboardView (LoginRequiredAutoLogoutView):
 
         # XXX This is repeated in all pages
         # more general variables expected in the template
-        context['title'] = 'Test view that combines various plugins'
+        context['title'] = 'Dashboard'
         # the menu items on the top
         context['topmenu_items'] = topmenu_items('Dashboard', self.request) 
         # so we can sho who is logged
index 7c83d94..7101164 100644 (file)
@@ -14,39 +14,30 @@ class PlatformsView(TemplateView):
     def get_context_data(self, **kwargs):
         page = Page(self.request)
 
-        #network_query  = Query().get('local:platform').filter_by('disabled', '==', '0').select('platform','platform_longname','gateway_type')
-        network_query  = Query().get('local:platform').select('platform','platform_longname','gateway_type')
-        page.enqueue_query(network_query)
+        #platform_query  = Query().get('local:platform').filter_by('disabled', '==', '0').select('platform','platform_longname','gateway_type')
+        platform_query  = Query().get('local:platform').select('platform','platform_longname','gateway_type')
+        page.enqueue_query(platform_query)
 
         page.expose_js_metadata()
         page.expose_queries()
-        networklist = Hazelnut(
+        platformlist = Hazelnut(
             page  = page,
             title = 'List',
             domid = 'checkboxes',
             # this is the query at the core of the slice list
-            query = network_query,
-            query_all = network_query,
+            query = platform_query,
+            query_all = platform_query,
             checkboxes = False,
-            datatables_options = {
-            # for now we turn off sorting on the checkboxes columns this way
-            # this of course should be automatic in hazelnut
-            'aoColumns'      : [None, None, None, None, {'bSortable': False}],
-            'iDisplayLength' : 25,
-            'bLengthChange'  : True,
-            },
+            datatables_options = { 
+                'iDisplayLength': 10,
+                'bLengthChange' : True,
+                'bAutoWidth'    : True,
+                },
         )
-#
-#        networklist = SimpleList(
-#            title = None,
-#            page  = page,
-#            key   = 'platform',
-#            query = network_query,
-#        )
 
         context = super(PlatformsView, self).get_context_data(**kwargs)
         context['person']   = self.request.user
-        context['networks'] = networklist.render(self.request)
+        context['platforms'] = platformlist.render(self.request)
 
         # XXX This is repeated in all pages
         # more general variables expected in the template
index 9867c36..c731746 100644 (file)
@@ -6,6 +6,7 @@ from django.views.generic       import View
 from django.template.loader     import render_to_string
 from django.shortcuts           import render
 
+from unfold.page                import Page
 from myslice.viewutils          import topmenu_items
 
 from manifold.manifoldapi       import execute_query
@@ -24,76 +25,75 @@ from portal.actions             import authority_get_pi_emails
 
 class RegistrationView (View):
 
-  def dispatch (self, request):
-
-    errors = []
-
-    #authorities_query = Query.get('authority').filter_by('authority_hrn', 'included', ['ple.inria', 'ple.upmc']).select('name', 'authority_hrn')
-    authorities_query = Query.get('authority').select('authority_hrn')
-    authorities = execute_query(request, authorities_query)
-    authorities = sorted(authorities)
-
-    if request.method == 'POST':
-        # 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()
-        
-        #POST value validation  
-        if (re.search(r'^[\w+\s.@+-]+$', reg_fname)==None):
-            errors.append('First Name may contain only letters, numbers, spaces and @/./+/-/_ characters.')
-            #return HttpResponse("Only Letters, Numbers, - and _ allowd in First Name")
-            #return render(request, 'registration_view.html')
-        if (re.search(r'^[\w+\s.@+-]+$', reg_lname) == None):
-            errors.append('Last Name may contain only letters, numbers, spaces and @/./+/-/_ characters.')
-            #return HttpResponse("Only Letters, Numbers, - and _ is allowed in Last name")
-            #return render(request, 'registration_view.html')
-#        if (re.search(r'^[\w+\s.@+-]+$', reg_aff) == None):
-#            errors.append('Affiliation may contain only letters, numbers, spaces and @/./+/-/_ characters.')
-            #return HttpResponse("Only Letters, Numbers and _ is allowed in Affiliation")
-            #return render(request, 'registration_view.html')
-        # XXX validate authority hrn !!
-        if PendingUser.objects.filter(email__iexact=reg_email):
-            errors.append('Email already registered.Please provide a new email address.')
-            #return HttpResponse("Email Already exists")
-            #return render(request, 'registration_view.html')
-        if 'generate' in request.POST['question']:
-            # Generate public and private keys using SFA Library
-            from sfa.trust.certificate  import Keypair
-            k = Keypair(create=True)
-            public_key = k.get_pubkey_string()
-            private_key = k.as_pem()
-            private_key = ''.join(private_key.split())
-            public_key = "ssh-rsa " + public_key
-            # Saving to DB
-            keypair = '{"user_public_key":"'+ public_key + '", "user_private_key":"'+ private_key + '"}'
-#            keypair = re.sub("\r", "", keypair)
-#            keypair = re.sub("\n", "\\n", keypair)
-#            #keypair = keypair.rstrip('\r\n')
-#            keypair = ''.join(keypair.split())
-        else:
-            up_file = request.FILES['user_public_key']
-            file_content =  up_file.read()
-            file_name = up_file.name
-            file_extension = os.path.splitext(file_name)[1]
-            allowed_extension =  ['.pub','.txt']
-            if file_extension in allowed_extension and re.search(r'ssh-rsa',file_content):
-                keypair = '{"user_public_key":"'+ file_content +'"}'
-                keypair = re.sub("\r", "", keypair)
-                keypair = re.sub("\n", "\\n",keypair)
-                keypair = ''.join(keypair.split())
-            else:
-                errors.append('Please upload a valid RSA public key [.txt or .pub].')
-
-        #b = PendingUser(first_name=reg_fname, last_name=reg_lname, affiliation=reg_aff, 
-        #                email=reg_email, password=request.POST['password'], keypair=keypair)
-        #b.save()
-        if not errors:
-            b = PendingUser(
+    def dispatch (self, request):
+
+        errors = []
+
+        authorities_query = Query.get('authority').\
+            filter_by('authority_hrn', 'included', ['ple.inria', 'ple.upmc']).\
+            select('name', 'authority_hrn')
+        #authorities_query = Query.get('authority').select('authority_hrn')
+        authorities = execute_query(request, authorities_query)
+        # xxx tocheck - if authorities is empty, it's no use anyway
+        # (users won't be able to validate the form anyway)
+
+        page = Page(request)
+        page.add_js_files  ( [ "js/jquery.validate.js", "js/my_account.register.js" ] )
+        page.add_css_files ( [ "css/onelab.css", "css/registration.css" ] )
+
+        print 'registration view, method',request.method
+
+        if request.method == 'POST':
+            # 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()
+      
+            #POST value validation  
+            if (re.search(r'^[\w+\s.@+-]+$', reg_fname)==None):
+                errors.append('First Name may contain only letters, numbers, spaces and @/./+/-/_ characters.')
+            if (re.search(r'^[\w+\s.@+-]+$', reg_lname) == None):
+                errors.append('Last Name may contain only letters, numbers, spaces and @/./+/-/_ characters.')
+            # XXX validate authority hrn !!
+            if PendingUser.objects.filter(email__iexact=reg_email):
+                errors.append('Email already registered.Please provide a new email address.')
+            if 'generate' in request.POST['question']:
+                # Generate public and private keys using SFA Library
+                from sfa.trust.certificate  import Keypair
+                k = Keypair(create=True)
+                public_key = k.get_pubkey_string()
+                private_key = k.as_pem()
+                private_key = ''.join(private_key.split())
+                public_key = "ssh-rsa " + public_key
+                # Saving to DB
+                keypair = '{"user_public_key":"'+ public_key + '", "user_private_key":"'+ private_key + '"}'
+                #keypair = re.sub("\r", "", keypair)
+                #keypair = re.sub("\n", "\\n", keypair)
+                #keypair = keypair.rstrip('\r\n')
+                #keypair = ''.join(keypair.split())
+            else: 
+                up_file = request.FILES['user_public_key']
+                file_content =  up_file.read()
+                file_name = up_file.name
+                file_extension = os.path.splitext(file_name)[1]
+                allowed_extension =  ['.pub','.txt']
+                if file_extension in allowed_extension and re.search(r'ssh-rsa',file_content):
+                    keypair = '{"user_public_key":"'+ file_content +'"}'
+                    keypair = re.sub("\r", "", keypair)
+                    keypair = re.sub("\n", "\\n",keypair)
+                    keypair = ''.join(keypair.split())
+                else:
+                    errors.append('Please upload a valid RSA public key [.txt or .pub].')
+
+            #b = PendingUser(first_name=reg_fname, last_name=reg_lname, affiliation=reg_aff, 
+            #                email=reg_email, password=request.POST['password'], keypair=keypair)
+            #b.save()
+            if not errors:
+              b = PendingUser(
                 first_name=reg_fname, 
                 last_name=reg_lname, 
                 #affiliation=reg_aff,
@@ -101,36 +101,38 @@ class RegistrationView (View):
                 email=reg_email, 
                 password=request.POST['password'],
                 keypair=keypair
-            )
-            b.save()
+                )
+              b.save()
 
-            # Send email
-            ctx = {
+              # Send email
+              ctx = {
                 'first_name'   : reg_fname, 
                 'last_name'    : reg_lname, 
                 'authority_hrn': reg_auth,
                 'email'        : reg_email, 
                 'keypair'      : keypair,
                 'cc_myself'    : True # form.cleaned_data['cc_myself']
-            }
+                }
 
-            recipients = authority_get_pi_emails(request,reg_auth)
-            if ctx['cc_myself']:
-                recipients.append(ctx['email'])
+              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)
             send_mail("Onelab New User request for %s submitted"%reg_email, msg, reg_email, recipients)
 
             return render(request, 'user_register_complete.html')
 
-    return render(request, 'registration_view.html',{
-        'topmenu_items': topmenu_items('Register', request),
-        'errors': errors,
-        'firstname': request.POST.get('firstname', ''),
-        'lastname': request.POST.get('lastname', ''),
-        #'affiliation': request.POST.get('affiliation', ''),
-        'authority_hrn': request.POST.get('authority_hrn', ''),
-        'email': request.POST.get('email', ''),
-        'password': request.POST.get('password', ''),           
-        'authorities': authorities,
-    })        
+        template_env = {
+          'topmenu_items': topmenu_items('Register', request),
+          'errors': errors,
+          'firstname': request.POST.get('firstname', ''),
+          'lastname': request.POST.get('lastname', ''),
+          #'affiliation': request.POST.get('affiliation', ''),
+          'authority_hrn': request.POST.get('authority_hrn', ''),
+          'email': request.POST.get('email', ''),
+          'password': request.POST.get('password', ''),           
+          'authorities': authorities,
+          }
+        template_env.update(page.prelude_env ())
+        return render(request, 'registration_view.html',template_env)
index 97802f6..4f66dfd 100644 (file)
@@ -139,7 +139,7 @@ class SliceView (LoginRequiredAutoLogoutView):
                 'aoColumns'     : [None, None, None, None, {'bSortable': False}],
                 'iDisplayLength': 25,
                 'bLengthChange' : True,
-                'bAutiWidth'    : True,
+                'bAutoWidth'    : True,
                 },
             )
 
@@ -207,11 +207,9 @@ class SliceView (LoginRequiredAutoLogoutView):
                 query_all  = query_user_all,
                 checkboxes  = True,
                 datatables_options = { 
-                    # for now we turn off sorting on the checkboxes columns this way
-                    # this of course should be automatic in hazelnut
-                    'aoColumns'      : [None, None, None, None, {'bSortable': False}],
                     'iDisplayLength' : 25,
                     'bLengthChange'  : True,
+                    'bAutoWidth'     : True,
                 },
             ))
     
@@ -237,11 +235,9 @@ class SliceView (LoginRequiredAutoLogoutView):
             query       = sq_measurement,
             checkboxes  = True,
             datatables_options = { 
-                # for now we turn off sorting on the checkboxes columns this way
-                # this of course should be automatic in hazelnut
-                'aoColumns'      : [None, None, None, None, {'bSortable': False}],
                 'iDisplayLength' : 25,
                 'bLengthChange'  : True,
+                'bAutoWidth'     : True,
             },
         ))
     
index bb7fba4..73b76ac 100644 (file)
@@ -8,7 +8,7 @@ Copyright 2013, UPMC Sorbonne Universités / LIP6
 */
 jQuery(document).ready(function(){
     
-    jQuery("#commentForm").validate({
+    jQuery("#registrationForm").validate({
         rules: {
           password: { 
                 required: true
@@ -19,7 +19,7 @@ jQuery(document).ready(function(){
         }
     });
     // upload button
-    jQuery("#question").change(function(){
+    jQuery("#key-policy").change(function(){
         if(this.value=="upload"){
             jQuery("#upload_key").show();
         }else{
index cb9264b..c80da1a 100644 (file)
@@ -20,7 +20,7 @@
            {% if person.last_name %} <li><span id='username'>{{person.first_name}} {{person.last_name}}</span></li> {% endif %}
            <li><b>Email: </b><a href='mailto:#'>{{person.email}}</a></li>
          </ul>
-         <button id="account" onclick="location.href='{{URL}}/portal/account'" class="btn btn-default">Modify</button>
+         <button id="account" onclick="location.href='/portal/account/'" class="btn btn-default">Modify</button>
        </div>
       </div>
 
index 33fb0b3..2234066 100644 (file)
@@ -7,5 +7,5 @@
 {% block unfold1_main %}
 
 <h1>Platforms</h1>
-{{networks}}
+{{platforms}}
 {% endblock %}
index 71ef1b8..039a07a 100644 (file)
@@ -1,13 +1,5 @@
 {% extends "layout-unfold1.html" %}
 
-{% block head %}
-<link rel="stylesheet" type="text/css" href="{{STATIC_URL}}/css/onelab.css" />
-<!-- xxx ideally only onelab.css but ... xxx -->
-<link rel="stylesheet" type="text/css" href="{{STATIC_URL}}/css/registration.css" />
-<script type="text/javascript" src="{{STATIC_URL}}/js/jquery.validate.js"></script> 
-<script type="text/javascript" src="{{STATIC_URL}}/js/my_account.register.js"></script>
-{% endblock %}                              
-                                    
 {% block unfold1_main %}        
 
 <div class="onelab-title well well-lg">
diff --git a/views/static/img/myslice-icon.png b/views/static/img/myslice-icon.png
new file mode 100644 (file)
index 0000000..05c10b9
Binary files /dev/null and b/views/static/img/myslice-icon.png differ
index 3ee9ba2..4a05bad 100644 (file)
@@ -2,6 +2,7 @@
 <html lang="en"> <head>
 <title> MySlice - {{ title }} </title>
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
+<link rel="shortcut icon" href="/static/img/myslice-icon.png">
 {# 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>