encoding//portal/django_passresetview.py=utf-8
encoding//portal/forms.py=utf-8
encoding//portal/migrations/0002_extend_slice.py=utf-8
++encoding//portal/migrations/0005_extend_user.py=utf-8
++encoding//portal/migrations/0008_extend_user.py=utf-8
++encoding//portal/migrations/0009_initial.py=utf-8
++encoding//portal/migrations/0010_project.py=utf-8
encoding//portal/models.py=utf-8
encoding//portal/urls.py=utf-8
encoding//portal/validationview.py=utf-8
--encoding//portal/views.py=utf-8
# assume we have ./static present already
HTTPROOT="/var/myslice-f4f"
# the place to store local data, like e.g. the sqlite db
--DATAROOT="/var/unfold"
++DATAROOT="/Users/moray/Sites/upmc/myslice"
# if not there, then we assume it's from a devel tree
if not os.path.isdir (os.path.join(HTTPROOT,"static")):
HTTPROOT=ROOT
- from django.http import HttpResponse
- from manifold.core.query import Query
- from manifoldapi.manifoldapi import execute_query,execute_admin_query
- from portal.models import PendingUser, PendingSlice, PendingAuthority, PendingProject
+ from django.http import HttpResponse
+ from manifold.core.query import Query
+ from manifoldapi.manifoldapi import execute_query,execute_admin_query
-from portal.models import PendingUser, PendingSlice, PendingAuthority
++from portal.models import PendingUser, PendingSlice, PendingAuthority, PendingProject
+ from unfold.page import Page
+
import json
- from django.contrib.auth.models import User
- from django.contrib.sites.models import Site
- from django.contrib.auth import get_user_model
- from django.template.loader import render_to_string
- from django.core.mail import EmailMultiAlternatives, send_mail
+ from django.contrib.auth.models import User
+ from django.contrib.sites.models import Site
+ from django.contrib.auth import get_user_model
+ from django.template.loader import render_to_string
+ from django.core.mail import EmailMultiAlternatives, send_mail
- from myslice.theme import ThemeView
- from myslice.configengine import ConfigEngine
+ from myslice.theme import ThemeView
+ from myslice.configengine import ConfigEngine
theme = ThemeView()
type_of_nodes = models.TextField(default='NA')
purpose = models.TextField(default='NA')
created = models.DateTimeField(auto_now_add = True)
++
++class PendingProject(models.Model):
++ project_name = models.TextField()
++ user_hrn = models.TextField()
++ authority_hrn = models.TextField(null=True)
++ purpose = models.TextField(default='NA')
++ created = models.DateTimeField(auto_now_add = True)
from django.shortcuts import render
from django.contrib.sites.models import Site
--
--from unfold.page import Page
--
from manifold.core.query import Query
from manifoldapi.manifoldapi import execute_admin_query, execute_query
--from portal.actions import is_pi, create_slice, create_pending_slice, clear_user_creds
--#from portal.forms import SliceRequestForm
from unfold.loginrequired import LoginRequiredAutoLogoutView
--from ui.topmenu import topmenu_items_live, the_user
++
++from portal.actions import create_pending_project
++
++from portal.models import PendingProject
from myslice.theme import ThemeView
import json, time, re
--import activity.user
--
--class ProjectRequestView (LoginRequiredAutoLogoutView, ThemeView):
++class ProjectRequestView(LoginRequiredAutoLogoutView, ThemeView):
template_name = 'projectrequest_view.html'
-- # because we inherit LoginRequiredAutoLogoutView that is implemented by redefining 'dispatch'
-- # we cannot redefine dispatch here, or we'd lose LoginRequired and AutoLogout behaviours
-- def post (self, request):
-- return self.get_or_post (request, 'POST')
++ def getAuthorities(self, request):
++ authorities_query = Query.get('authority').select('name', 'authority_hrn')
++ authorities = execute_admin_query(request, authorities_query)
++ if authorities is not None:
++ authorities = sorted(authorities, key=lambda k: k['authority_hrn'])
++ authorities = sorted(authorities, key=lambda k: k['name'])
++ return authorities
++
++ def getUserAuthority(self, request):
++ # Get user_email (XXX Would deserve to be simplified)
++ user_query = Query().get('local:user').select('email','config')
++ user_details = execute_query(request, user_query)
++ for user_detail in user_details:
++ user_config = json.loads(user_detail['config'])
++ user_authority = user_config.get('authority','N/A')
++ return user_authority
++
++ def getUserHrn(self, request):
++ user_hrn = None
++
++ account_query = Query().get('local:account').select('user_id','platform_id','auth_type','config')
++ account_details = execute_query(request, account_query)
++
++ platform_query = Query().get('local:platform').select('platform_id','platform','gateway_type','disabled')
++ platform_details = execute_query(request, platform_query)
++
++ # getting user_hrn from local:account
++ for account_detail in account_details:
++ for platform_detail in platform_details:
++ if platform_detail['platform_id'] == account_detail['platform_id']:
++ # taking user_hrn only from myslice account
++ # NOTE: we should later handle accounts filter_by auth_type= managed OR user
++ if 'myslice' in platform_detail['platform']:
++ account_config = json.loads(account_detail['config'])
++ user_hrn = account_config.get('user_hrn','N/A')
++ return user_hrn
++
++ def post(self, request):
++ return self.handle_request(request, 'POST')
-- def get (self, request):
-- return self.get_or_post (request, 'GET')
++ def get(self, request):
++ return self.handle_request(request, 'GET')
-- def get_or_post (self, wsgi_request, method):
++ def handle_request(self, wsgi_request, method):
++ errors = []
++ authority_hrn = None
++ authority_name = None
++
++ user_hrn = self.getUserHrn(wsgi_request)
++
++ authorities = self.getAuthorities(wsgi_request)
++
++ user_authority = self.getUserAuthority(wsgi_request)
++
++ # getting the org from authority
++ for authority in authorities:
++ if authority['authority_hrn'] == user_authority:
++ authority_name = authority['name']
++
++ if method == 'POST' :
++
++ post = {
++ 'user_hrn' : user_hrn,
++ 'authority_hrn' : wsgi_request.POST.get('authority_name', ''),
++ 'project_name' : wsgi_request.POST.get('project_name', ''),
++ 'purpose' : wsgi_request.POST.get('purpose', ''),
++ }
++
++# # create slice_hrn based on authority_hrn and slice_name
++# # slice_name = slice_request['slice_name']
++# req_slice_hrn = authority_hrn + '.' + slice_name
++# # comparing requested slice_hrn with the existing slice_hrn
++# slice_query = Query().get('myslice:slice').select('slice_hrn','parent_authority').filter_by('parent_authority','==',authority_hrn)
++# slice_details_sfa = execute_admin_query(wsgi_request, slice_query)
++# for _slice in slice_details_sfa:
++# if _slice['slice_hrn'] == req_slice_hrn:
++# errors.append('Slice already exists. Please use a different slice name.')
++
++
++ # What kind of slice name is valid?
++ if (post['project_name'] is None or post['project_name'] == ''):
++ errors.append('Project name 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.')
++
++ if (post['authority_hrn'] is None or post['authority_hrn'] == ''):
++ errors.append('Organization is mandatory')
++
++ if (post['purpose'] is None or post['purpose'] == ''):
++ errors.append('Experiment purpose is mandatory')
++
++ if not errors:
++ create_pending_project(wsgi_request, post)
++
++ # retrieves the pending projects list
++ pending_projects = PendingProject.objects.all().filter(user_hrn=user_hrn)
++
++ env = {
++ 'errors': errors,
++ 'username': wsgi_request.user,
++ 'theme': self.theme,
++ 'authorities': authorities,
++ 'authority_hrn': user_authority,
++ 'pending_projects': pending_projects,
++ }
++ return render(wsgi_request, self.template, env)
++
++
++
"""
"""
errors = []
#
platform_query = Query().get('local:platform').select('platform_id','platform','gateway_type','disabled')
platform_details = execute_query(wsgi_request, platform_query)
++
user_hrn = None
# getting user_hrn from local:account
for account_detail in account_details:
# Page rendering
-- page = Page(wsgi_request)
-- page.add_js_files ( [ "js/jquery.validate.js", "js/jquery-ui.js" ] )
-- page.add_css_files ( [ "https://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" ] )
-- page.expose_js_metadata()
++# page = Page(wsgi_request)
++# page.add_js_files ( [ "js/jquery.validate.js", "js/jquery-ui.js" ] )
++# page.add_css_files ( [ "https://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" ] )
++# page.expose_js_metadata()
if method == 'POST':
# The form has been submitted
# get the domain url
-- current_site = Site.objects.get_current()
-- current_site = current_site.domain
++# current_site = Site.objects.get_current()
++# current_site = current_site.domain
# getting the authority_hrn from the selected organization
for authority in authorities:
}
# create slice_hrn based on authority_hrn and slice_name
-- slice_name = slice_request['slice_name']
++# slice_name = slice_request['slice_name']
req_slice_hrn = authority_hrn + '.' + slice_name
# comparing requested slice_hrn with the existing slice_hrn
slice_query = Query().get('myslice:slice').select('slice_hrn','parent_authority').filter_by('parent_authority','==',authority_hrn)
template_env = {
'username': wsgi_request.user.email,
-- 'topmenu_items': topmenu_items_live('Request a slice', page),
'errors': errors,
'slice_name': slice_name,
'purpose': purpose,
color:#201E62;
}
++input[type=text], input[type=password], input[type=email], input[type=tel], input[type=number] {
++ min-width:260px;
++ padding:6px;
++ border:1pt solid #CCCCCC;
++ vertical-align:bottom;
++ border-radius:0;
++}
++
++textarea {
++ padding:6px;
++ border:1pt solid #CCCCCC !important;
++ border-radius:0 !important;
++}
++
div.wrapper {
width:980px;
margin:0 auto;
}
},
- loadProjects: function(fn) {
- var u = localStorage.getItem('user');
- if (u !== 'undefined') {
- var user = JSON.parse(u);
- var projects = localStorage.getItem('projects');
- if($.isEmptyObject(projects)){
- if($.isEmptyObject(user) || $.isEmptyObject(user.parent_authority)){
- $.post("/rest/myslice:user/",{'filters':{'user_hrn':'$user_hrn'},'fields':['parent_authority']}, function( data ) {
- parent_authority = data[0].parent_authority;
-
- });
- }else{
- parent_authority = user.parent_authority;
- }
- // REGISTRY ONLY TO BE REMOVED WITH MANIFOLD-V2
- $.post("/rest/myslice:authority/",{'fields':['authority_hrn'],'filters':{'authority_hrn':'CONTAINS'+parent_authority}}, function( data ) {
- localStorage.setItem('projects', JSON.stringify(data));
- if(isFunction(fn)){
- fn();
- }
- });
- }else{
- if(isFunction(fn)){
- fn();
- }
- }
- }
- },
+
getSlices: function(name) {
},
<li><a href="/slice/{{ slice }}#testbeds">Testbeds</a></li>
<li class="active"><a class="link" href="/resources/{{ slice }}">Resources</a></li>
<li><a href="/slice/{{ slice }}#users">Users</a></li>
-- <!--<li><a href="/slice/{{ slice }}#statistics">Statistics</a></li> -->
++ <li><a href="/slice/{{ slice }}#statistics">Statistics</a></li>
<li><a href="/slice/{{ slice }}#measurements">Measurements</a></li>
<li><a href="/slice/{{ slice }}#experiment" data-toggle="tab">Experiment</a></li>
<li><a href="/slice/{{ slice }}#sla">SLA</a></li>
<li class="testbeds"><a href="#testbeds">Testbeds</a></li>
<li><a class="link" href="/resources/{{ slice }}">Resources</a></li>
<li class="users"><a href="#users">Users</a></li>
--<!-- <li class="statistics"><a href="#statistics">Statistics</a></li> -->
++ <li class="statistics"><a href="#statistics">Statistics</a></li>
<li class="measurements"><a href="#measurements">Measurements</a></li>
<li class="experiment"><a href="#experiment" data-toggle="tab">Experiment</a></li>
<li class="sla"><a href="#sla" data-toggle="tab">SLA</a></li>
{% load i18n %}
{% block content %}
-- <div class="row">
-- <div class="col-md-12">
-- <div class="breadcrumbs">
-- Experiment > Request a new Project or Join an existing one
-- </div>
-- </div>
-- </div>
++<br />
++<div class="row">
++ <div class="col-md-12">
++ <ul class="nav nav-tabs nav-section">
++ <li class="active"><a href="#existing">Join existing Project</a></li>
++ <li><a href="#new">Create new Project</a></li>
++
++ </ul>
++ </div>
++</div>
-- {% if errors %}
-- <div class="row">
-- <div class="col-md-12">
-- <ul class="error">
-- {% for error in errors %}
-- <li>{{ error }}</li>
-- {% endfor %}
-- </ul>
-- </div>
-- </div>
-- {% endif %}
--
-- <div class="row">
-- <div class="col-md-8 el">
-- <form role="form" method="post">
-- {% csrf_token %}
-- <div class="form-group" style="display:none">
-- <input type="email" class="form-control" id="email" style="width:300px" value="{{ email }}" readonly="readonly">
-- </div>
-- <div class="form-group">
-- <select id="org_name" name="org_name" class="form-control" style="width:590px" value="{{ organization }}" required>
-- {% if authorities %}
-- {% for authority in authorities %}
-- {% if authority.name %}
-- <option value="{{ authority.authority_hrn }}">{{authority.name}}</option>
-- {% else %}
-- <option value="{{ authority.authority_hrn }}">{{authority.authority_hrn}}</option>
-- {% endif %}
-- {% endfor %}
-- {% endif %}
-- </select>
-- </div>
-- <div class="form-group">
-- <input type="text">New Project</input>
-- </div>
-- <div class="form-group">
-- <input type="text">Existing Project</input>
-- </div>
-- <div class="form-group">
-- <textarea id="purpose" name="purpose" class="form-control" rows="6" placeholder="Project purpose" style="width:300px"
-- title="Purpose of your project (informative)" required="required">{{ purpose }}</textarea>
-- </div>
-- {%if 'is_pi' in pi %}
-- <button type="submit" id=submit_pi class="btn btn-onelab"><span class="glyphicon glyphicon-plus"></span> Create slice</button>
-- {%else%}
-- <button type="submit" class="btn btn-onelab"><span class="glyphicon glyphicon-plus"></span> Request slice</button>
-- {%endif%}
-- </form>
--
-- </div>
-- </div>
++{% if errors %}
++<div class="row">
++ <div class="col-md-12">
++ <ul class="error">
++ {% for error in errors %}
++ <li>{{ error }}</li>
++ {% endfor %}
++ </ul>
++ </div>
++</div>
++{% endif %}
++
++<div class="container tab-content">
++
++ <div class="tab-pane active" id="existing">
++ <div class="row">
++ <div class="col-md-6">
++ <h3>Join an existing Project</h3>
++ </div>
++ <div class="col-md-6">
++ <h3>List of projects you are part of</h3>
++ </div>
++ </div>
++ <div class="row">
++ <div class="col-md-6">
++ <form role="form" method="post">
++ {% csrf_token %}
++ <select id="projects"></select> <button type="submit" class="btn">Join</button>
++ </form>
++ </div>
++ <div class="col-md-6">
++ <table class="table project-list">
++ {% for pending in pending_projects %}
++ <tr><td>(PENDING) {{ pending.project_name }}</td><td>{{ pending.authority_hrn }}</td><td>{{ pending.created|date:"d/m/Y" }}</td></tr>
++ {% endfor %}
++ </table>
++ </div>
++ </div>
++ </div>
++
++ <div class="tab-pane" id="new">
++ <div class="row">
++ <div class="col-md-12">
++ <h3>Create a new Project</h3>
++ </div>
++ </div>
++
++
++ <div class="row">
++ <div class="col-md-12">
++ <form role="form" method="post" action="/portal/project_request">
++ {% csrf_token %}
++ <div class="form-group">
++ <input type="text" name="project_name" value="" placeholder="Name" required>
++ </div>
++ <div class="form-group">
++ <select id="org_name" name="authority_name" class="form-control" style="width:590px" value="{{ organization }}" required>
++ {% if authorities %}
++ {% for authority in authorities %}
++ {% if authority.name %}
++ <option value="{{ authority.authority_hrn }}">{{authority.name}}</option>
++ {% else %}
++ <option value="{{ authority.authority_hrn }}">{{authority.authority_hrn}}</option>
++ {% endif %}
++ {% endfor %}
++ {% endif %}
++ </select>
++ </div>
++
++
++ <div class="form-group">
++ <textarea id="purpose" name="purpose" class="form-control" rows="6" placeholder="Description" style="width:300px" title="Purpose of your project (informative)" required="required"></textarea>
++ </div>
++ <button type="submit" class="btn btn-onelab"><span class="glyphicon glyphicon-plus"></span> Send Request</button>
++ </form>
++
++ </div>
++ </div>
++ </div>
++
++</div>
<script>
--jQuery(document).ready(function(){
++$(document).ready(function() {
++ var myprojects = localStorage.getItem('projects');
++ console.log(myprojects);
++ if (myprojects) {
++
++ } else {
++ $('.project-list').html('<tr><td>no projetcs</td></tr>');
++ }
++
++ $('.nav-tabs a').click(function (e) {
++ e.preventDefault();
++ $(this).tab('show');
++ });
++ $.post("/rest/myslice:authority/",{'fields':['authority_hrn','pi_users'],'filters':{'authority_hrn':'CONTAINS{{ authority_hrn }}' }}, function( data ) {
++
++ var projects = [];
++ project_row = "<option value=''> - </option>";
++ projects.push(project_row);
++
++ $.each( data, function( key, val ) {
++ console.log(val);
++ project_row = "<option value='"+val.authority_hrn+"'>"+val.authority_hrn+"</option>";
++ projects.push(project_row);
++ });
++ $("#projects").html(projects.join( "" ));
++ });
/*
$("#authority_hrn").load("/rest/user/", {"fields" : ["parent_authority"], "filters": {"user_hrn": "{{ user_hrn }}"}}, function(data) {
localStorage.clear();
});
// auto-complete the form
-- jQuery("#org_name").combobox();
++ //jQuery("#org_name").combobox();
});
</script>
<b>{{request.first_name}} {{request.last_name}}</b> <<a href="mailto:{{request.email}}">{{request.email}}</a>>
{% elif request.type == 'slice' %}
<b>{{request.slice_name}}</b> -- Number of nodes: {{request.number_of_nodes}} -- Type of nodes: {{request.type_of_nodes}} -- Purpose: {{request.purpose}}
++ {% elif request.type == 'project' %}
++ <b>{{request.project_name}}</b> -- {{ request.user_hrn }} -- Purpose: {{request.purpose}}
{% else %}
<b>{{request.site_name}}</b> ({{request.site_authority}}) -- {{request.address_city}}, {{request.address_country}}
{% endif %}
{% else %}
{% if request.type == 'slice' %}
Slice name: {{request.slice_name}} -- Number of nodes: {{request.number_of_nodes}} -- Type of nodes: {{request.type_of_nodes}} -- Purpose: {{request.purpose}}
++ {% elif request.type == 'project' %}
++ <b>{{request.project_name}}</b> -- {{ request.user_hrn }} -- Purpose: {{request.purpose}}
{% else %} {# authority #}
Authority name: {{request.site_name}} -- authority_hrn: {{request.site_authority}} -- City: {{request.address_city}} -- Country: {{request.address_country}}
{% endif %}
{% else %}
{% if request.type == 'slice' %}
Slice name: {{request.slice_name}} -- Number of nodes: {{request.number_of_nodes}} -- Type of nodes: {{request.type_of_nodes}} -- Purpose: {{request.purpose}}
++ {% elif request.type == 'project' %}
++ <b>{{request.project_name}}</b> -- {{ request.user_hrn }} -- Purpose: {{request.purpose}}
{% else %} {# authority #}
Authority name: {{request.site_name}} -- authority_hrn: {{request.site_authority}} -- City: {{request.address_city}} -- Country: {{request.address_country}}
{% endif %}
<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="#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>