dashboard now uses variables for displaying user slices
[myslice.git] / portal / views.py
1 # -*- coding: utf-8 -*-
2 #
3 # portal/views.py: views for the portal application
4 # This file is part of the Manifold project.
5 #
6 # Authors:
7 #   Jordan AugĂ© <jordan.auge@lip6.fr>
8 #   Mohammed Yasin Rahman <mohammed-yasin.rahman@lip6.fr>
9 # Copyright 2013, UPMC Sorbonne UniversitĂ©s / LIP6
10 #
11 # This program is free software; you can redistribute it and/or modify it under
12 # the terms of the GNU General Public License as published by the Free Software
13 # Foundation; either version 3, or (at your option) any later version.
14
15 # This program is distributed in the hope that it will be useful, but WITHOUT
16 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17 # FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
18 # details.
19
20 # You should have received a copy of the GNU General Public License along with
21 # this program; see the file COPYING.  If not, write to the Free Software
22 # Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23
24 from django.conf                 import settings
25 from django.contrib.sites.models import Site, RequestSite
26 from django.contrib              import messages
27 from django.views.generic        import View
28 from django.views.generic.base   import TemplateView
29 from django.shortcuts            import render
30
31 from plugins.lists.simplelist    import SimpleList
32
33 from plugins.pres_view           import PresView
34 from portal.event import Event
35 import json
36
37 from portal                      import signals
38 from portal.forms                import UserRegisterForm, SliceRequestForm, ContactForm
39 from portal.util                 import RegistrationView, ActivationView
40 from portal.models               import PendingUser, PendingSlice
41 from manifold.core.query         import Query
42 from unfold.page                 import Page
43 from myslice.viewutils           import topmenu_items, the_user
44 from django.http                 import HttpResponseRedirect, HttpResponse
45 import os.path, re
46
47 class DashboardView(TemplateView):
48     template_name = "dashboard.html"
49
50     def get_context_data(self, **kwargs):
51         # We might have slices on different registries with different user accounts 
52         # We note that this portal could be specific to a given registry, to which we register users, but i'm not sure that simplifies things
53         # Different registries mean different identities, unless we identify via SFA HRN or have associated the user email to a single hrn
54
55         #messages.info(self.request, 'You have logged in')
56         page = Page(self.request)
57
58         # Slow...
59         #slice_query = Query().get('slice').filter_by('user.user_hrn', 'contains', user_hrn).select('slice_hrn')
60         slice_query = Query().get('user').filter_by('user_hrn', '==', '$user_hrn').select('user_hrn', 'slice.slice_hrn')
61         auth_query  = Query().get('network').select('network_hrn')
62         page.enqueue_query(slice_query)
63         page.enqueue_query(auth_query)
64
65         page.expose_queries()
66
67         slicelist = SimpleList(
68             title = None,
69             page  = page,
70             key   = 'slice.slice_hrn',
71             query = slice_query,
72         )
73          
74         authlist = SimpleList(
75             title = None,
76             page  = page,
77             key   = 'network_hrn',
78             query = auth_query,
79         )
80
81         context = super(DashboardView, self).get_context_data(**kwargs)
82         context['person']   = self.request.user
83         context['networks'] = authlist.render(self.request) 
84         context['slices']   = slicelist.render(self.request)
85
86         # XXX This is repeated in all pages
87         # more general variables expected in the template
88         context['title'] = 'Test view that combines various plugins'
89         # the menu items on the top
90         context['topmenu_items'] = topmenu_items('Dashboard', self.request) 
91         # so we can sho who is logged
92         context['username'] = the_user(self.request) 
93
94         context.update(page.prelude_env())
95
96         return context
97
98 class UserRegisterView(RegistrationView):
99     """
100     A registration backend which follows a simple workflow:
101
102     1. User signs up, inactive account is created.
103
104     2. Email is sent to user with activation link.
105
106     3. User clicks activation link, account is now active.
107
108     Using this backend requires that
109
110     * ``registration`` be listed in the ``INSTALLED_APPS`` setting
111       (since this backend makes use of models defined in this
112       application).
113
114     * The setting ``ACCOUNT_ACTIVATION_DAYS`` be supplied, specifying
115       (as an integer) the number of days from registration during
116       which a user may activate their account (after that period
117       expires, activation will be disallowed).
118
119     * The creation of the templates
120       ``registration/activation_email_subject.txt`` and
121       ``registration/activation_email.txt``, which will be used for
122       the activation email. See the notes for this backends
123       ``register`` method for details regarding these templates.
124
125     Additionally, registration can be temporarily closed by adding the
126     setting ``REGISTRATION_OPEN`` and setting it to
127     ``False``. Omitting this setting, or setting it to ``True``, will
128     be interpreted as meaning that registration is currently open and
129     permitt ed.
130
131     Internally, this is accomplished via storing an activation key in
132     an instance of ``registration.models.RegistrationProfile``. See
133     that model and its custom manager for full documentation of its
134     fields and supported operations.
135     
136     """
137     form_class = UserRegisterForm
138     
139     def register(self, request, **cleaned_data):
140         """
141         Given a username, email address and password, register a new
142         user account, which will initially be inactive.
143
144         Along with the new ``User`` object, a new
145         ``registration.models.RegistrationProfile`` will be created,
146         tied to that ``User``, containing the activation key which
147         will be used for this account.
148
149         An email will be sent to the supplied email address; this
150         email should contain an activation link. The email will be
151         rendered using two templates. See the documentation for
152         ``RegistrationProfile.send_activation_email()`` for
153         information about these templates and the contexts provided to
154         them.
155
156         After the ``User`` and ``RegistrationProfile`` are created and
157         the activation email is sent, the signal
158         ``registration.signals.user_registered`` will be sent, with
159         the new ``User`` as the keyword argument ``user`` and the
160         class of this backend as the sender.
161
162         """
163         first_name = cleaned_data['first_name']
164         last_name  = cleaned_data['last_name']
165         affiliation= cleaned_data['affiliation']
166         email      = cleaned_data['email']
167         password   = cleaned_data['password1']
168         
169         #password2  = cleaned_data['password2']
170         keypair    = cleaned_data['keypair']
171
172         #if Site._meta.installed:
173         #    site = Site.objects.get_current()
174         #else:
175         #    site = RequestSite(request) 
176         site = None
177
178         new_user = PendingUser.objects.create_inactive_user(first_name, last_name, email, password, site)
179         signals.user_registered.send(sender=self.__class__,
180                                      user=new_user,
181                                      request=request)
182         return new_user
183
184     def get_context_data(self, **kwargs):
185         context = super(UserRegisterView, self).get_context_data(**kwargs)
186         context['topmenu_items'] = topmenu_items('Register', self.request)
187         context['username'] = the_user (self.request)
188         return context
189
190     def registration_allowed(self, request):
191         """
192         Indicate whether account registration is currently permitted,
193         based on the value of the setting ``REGISTRATION_OPEN``. This
194         is determined as follows:
195
196         * If ``REGISTRATION_OPEN`` is not specified in settings, or is
197           set to ``True``, registration is permitted.
198
199         * If ``REGISTRATION_OPEN`` is both specified and set to
200           ``False``, registration is not permitted.
201         
202         """
203         return getattr(settings, 'REGISTRATION_OPEN', True)
204
205     def get_success_url(self, request, user):
206         """
207         Return the name of the URL to redirect to after successful
208         user registration.
209         
210         """
211         return ('user_register_complete', (), {})
212
213
214 class UserValidateView(ActivationView):
215     def activate(self, request, activation_key):
216         """
217         Given an an activation key, look up and activate the user
218         account corresponding to that key (if possible).
219
220         After successful activation, the signal
221         ``registration.signals.user_activated`` will be sent, with the
222         newly activated ``User`` as the keyword argument ``user`` and
223         the class of this backend as the sender.
224         
225         """
226         activated_user = RegistrationProfile.objects.activate_user(activation_key)
227         if activated_user:
228             signals.user_activated.send(sender=self.__class__,
229                                         user=activated_user,
230                                         request=request)
231         return activated_user
232
233     def get_success_url(self, request, user):
234         return ('registration_activation_complete', (), {})
235
236
237 # DEPRECATED #from portal.portalpage  import PortalPage
238 # DEPRECATED #from plugins.wizard     import Wizard
239 # DEPRECATED #from plugins.form       import CreateForm
240 # DEPRECATED #from plugins.raw.raw    import Raw          # XXX
241 # DEPRECATED #
242 # DEPRECATED #from myslice.viewutils  import the_user
243 # DEPRECATED #
244 # DEPRECATED #from django.template.loader import render_to_string
245 # DEPRECATED #from django.template import RequestContext
246 # DEPRECATED #from django.views import generic
247 # DEPRECATED #
248 # DEPRECATED #from django.contrib.formtools.wizard.views import NamedUrlSessionWizardView
249 # DEPRECATED ##from django.core.files.storage import FileSystemStorage
250 # DEPRECATED #from django.core.files.storage import default_storage
251 # DEPRECATED #
252 # DEPRECATED ##class MerlinWizard(NamedUrlSessionWizardView):
253 # DEPRECATED ##
254 # DEPRECATED ##    ...
255 # DEPRECATED ##    ...
256 # DEPRECATED ##
257 # DEPRECATED ##    @classonlymethod
258 # DEPRECATED ##    def as_view(cls, *args, **kwargs):
259 # DEPRECATED ##        kwargs.update({
260 # DEPRECATED ##            'form_list': [
261 # DEPRECATED ##                NameForm,
262 # DEPRECATED ##                QuestForm,
263 # DEPRECATED ##                ColorForm,
264 # DEPRECATED ##            ],
265 # DEPRECATED ##            'url_name': 'merlin_wizard'
266 # DEPRECATED ##        })
267 # DEPRECATED ##        return super(MerlinWizard, cls).as_view(*args, **kwargs)
268 # DEPRECATED #
269 # DEPRECATED #class UserRegisterWizardView(NamedUrlSessionWizardView):
270 # DEPRECATED ##class UserRegisterWizardView(LoginRequiredMixin, NamedUrlSessionWizardView):
271 # DEPRECATED #    # Notice that I specify a file storage instance. If you don't specify this,
272 # DEPRECATED #    # and you need to support FileField or ImageField in your forms, you'll get
273 # DEPRECATED #    # errors from Django. This is something else I think could be handled by
274 # DEPRECATED #    # the views better. Seems to me that it should just use whatever the
275 # DEPRECATED #    # default/specified storage is for the rest of your project/application.
276 # DEPRECATED #    file_storage = default_storage # FileSystemStorage()
277 # DEPRECATED #    template_name = "register_user_wizard.html"
278 # DEPRECATED #
279 # DEPRECATED #    def done(self, form_list, **kwargs):
280 # DEPRECATED #        step1_form = form_list[0]
281 # DEPRECATED #        step2_form = form_list[1]
282 # DEPRECATED #
283 # DEPRECATED #        productext = self.create_product(product_form)
284 # DEPRECATED #        shippings = self.create_shippings(productext, shipping_forms)
285 # DEPRECATED #        images = self.create_images(productext, image_forms)
286 # DEPRECATED #
287 # DEPRECATED #        if all([productext, shippings, images]):
288 # DEPRECATED #            del self.request.session["wizard_product_wizard_view"]
289 # DEPRECATED #
290 # DEPRECATED #            messages.success(self.request,
291 # DEPRECATED #                _("Your product has been created."))
292 # DEPRECATED #            return HttpResponseRedirect(self.get_success_url(productext))
293 # DEPRECATED #
294 # DEPRECATED #        messages.error(self.request, _("Something went wrong creating your "
295 # DEPRECATED #            "product. Please try again or contact support."))
296 # DEPRECATED #        return HttpResponseRedirect(reverse("register_wizard"))
297 # DEPRECATED #
298 # DEPRECATED #    #def get_form_kwargs(self, step):
299 # DEPRECATED #    #    if step == "product":
300 # DEPRECATED #    #        return {"user": self.request.user}
301 # DEPRECATED #    #    return {}
302 # DEPRECATED #
303 # DEPRECATED ## The portal should hook the slice and user creation pages
304 # DEPRECATED #
305 # DEPRECATED #def register_user(request):
306 # DEPRECATED #    
307 # DEPRECATED #    if request.method == 'POST':
308 # DEPRECATED #        form = UserRegisterForm(request.POST) # Nous reprenons les donnĂ©es
309 # DEPRECATED #        if form.is_valid():
310 # DEPRECATED #            first_name = form.cleaned_data['first_name']
311 # DEPRECATED #            last_name  = form.cleaned_data['last_name']
312 # DEPRECATED #            email      = form.cleaned_data['email']
313 # DEPRECATED #            password   = form.cleaned_data['password']
314 # DEPRECATED #            password2  = form.cleaned_data['password2']
315 # DEPRECATED #            keypair    = form.cleaned_data['keypair']
316 # DEPRECATED #            ## Ici nous pouvons traiter les donnĂ©es du formulaire
317 # DEPRECATED #            #sujet = form.cleaned_data['sujet']
318 # DEPRECATED #            #message = form.cleaned_data['message']
319 # DEPRECATED #            #envoyeur = form.cleaned_data['envoyeur']
320 # DEPRECATED #            #renvoi = form.cleaned_data['renvoi']
321 # DEPRECATED #            ## Nous pourrions ici envoyer l'e-mail grâce aux donnĂ©es que nous venons de rĂ©cupĂ©rer
322 # DEPRECATED #            #envoi = True
323 # DEPRECATED #    else:
324 # DEPRECATED #        form = UserRegisterForm()
325 # DEPRECATED #    return render(request, 'register_user.html', locals())
326 # DEPRECATED #
327 # DEPRECATED #def index(request):
328 # DEPRECATED #
329 # DEPRECATED #    WIZARD_TITLE = 'User registration'
330 # DEPRECATED #    STEP1_TITLE  = 'Enter your details'
331 # DEPRECATED #    STEP2_TITLE  = 'Select your institution'
332 # DEPRECATED #    STEP3_TITLE  = 'Authentication'
333 # DEPRECATED #    STEP4_TITLE  = 'Request a slice (optional)'
334 # DEPRECATED #    STEP5_TITLE  = 'Waiting for validation'
335 # DEPRECATED #    STEP6_TITLE  = 'Account validated'
336 # DEPRECATED #
337 # DEPRECATED #    STEP0 = render_to_string('account_validated.html', context_instance=RequestContext(request))
338 # DEPRECATED #    STEP2_HTML   = """
339 # DEPRECATED #    coucou
340 # DEPRECATED #    """
341 # DEPRECATED #    STEP4 = """
342 # DEPRECATED #    mede
343 # DEPRECATED #    """
344 # DEPRECATED #    STEP5 = render_to_string('account_validated.html', context_instance=RequestContext(request))
345 # DEPRECATED #
346 # DEPRECATED #    p = PortalPage(request)
347 # DEPRECATED #
348 # DEPRECATED #    # This is redundant with the Wizard title
349 # DEPRECATED #    p << "<h3>User registration</h3>"
350 # DEPRECATED #
351 # DEPRECATED #    sons = []
352 # DEPRECATED #    start_step = 1
353 # DEPRECATED #
354 # DEPRECATED #    # STEP 1
355 # DEPRECATED #    # If the user already exists (is logged), let's display a summary of his account details
356 # DEPRECATED #    # Otherwise propose a form to fill in
357 # DEPRECATED #    if the_user(request):
358 # DEPRECATED #        # Fill a disabled form with user info
359 # DEPRECATED #        # Please logout to register another user
360 # DEPRECATED #        sons.append(Raw(page=p, title=STEP1_TITLE, togglable=False, html=STEP0))
361 # DEPRECATED #        start_step += 1
362 # DEPRECATED #    else:
363 # DEPRECATED #        # We could pass a list of fields also, instead of retrieving them from metadata
364 # DEPRECATED #        # Otherwise we need some heuristics to display nice forms
365 # DEPRECATED #        # XXX Could we log the user in after the form is validated ?
366 # DEPRECATED #        # XXX Explain the password is for XXX
367 # DEPRECATED #        field_list = [{
368 # DEPRECATED #            'name'        : 'First name',
369 # DEPRECATED #            'field'       : 'firstname',
370 # DEPRECATED #            'type'        : 'text',
371 # DEPRECATED #            'validate_rx' : '^[a-zA-Z -]+$',
372 # DEPRECATED #            'validate_err': 'Your first name must be comprised of letters only',
373 # DEPRECATED #            'description' : 'Enter your first name',
374 # DEPRECATED #        }, {
375 # DEPRECATED #            'name'        : 'Last name',
376 # DEPRECATED #            'field'       : 'lastname',
377 # DEPRECATED #            'type'        : 'text',
378 # DEPRECATED #            'validate_rx' : '^[a-zA-Z -]+$',
379 # DEPRECATED #            'validate_err': 'Your last name must be comprised of letters only',
380 # DEPRECATED #            'description' : 'Enter your last name',
381 # DEPRECATED #        }, { 
382 # DEPRECATED #            'name'        : 'Email',
383 # DEPRECATED #            'field'       : 'email',
384 # DEPRECATED #            'type'        : 'text',
385 # DEPRECATED #            'description' : 'Enter your email address',
386 # DEPRECATED #        }, {
387 # DEPRECATED #            'name'        : 'Password',
388 # DEPRECATED #            'field'       : 'password',
389 # DEPRECATED #            'type'        : 'password',
390 # DEPRECATED #            'description' : 'Enter your password',
391 # DEPRECATED #        }, {
392 # DEPRECATED #            'name'        : 'Confirm password',
393 # DEPRECATED #            'field'       : 'password2',
394 # DEPRECATED #            'type'        : 'password',
395 # DEPRECATED #            'description' : 'Enter your password again',
396 # DEPRECATED #        }]
397 # DEPRECATED #        sons.append(CreateForm(page = p, title = STEP1_TITLE, togglable = False, object = 'local:user', fields = field_list))
398 # DEPRECATED #
399 # DEPRECATED #    # STEP 2
400 # DEPRECATED #    # If the user already exists (is logged), let's display a summary of its institution
401 # DEPRECATED #    # Otherwise propose a form to fill in (we should base our selection on the email)
402 # DEPRECATED #    if the_user(request):
403 # DEPRECATED #        # Fill a disabled form with institution
404 # DEPRECATED #        # Please logout to register another user
405 # DEPRECATED #        sons.append(Raw(page=p, title=STEP2_TITLE, togglable=False, html="User created"))
406 # DEPRECATED #        start_step += 1
407 # DEPRECATED #    else:
408 # DEPRECATED #        sons.append(CreateForm(page = p, title = STEP2_TITLE, togglable = False, object = 'slice')) #institution'))
409 # DEPRECATED #
410 # DEPRECATED #    # STEP3
411 # DEPRECATED #    # Please should your prefered authentication method
412 # DEPRECATED #    # This step should allow the user to either choose the user or managed mode in MySlice
413 # DEPRECATED #    sons.append(Raw(page = p, title = STEP3_TITLE, togglable = False, html = STEP2_HTML))
414 # DEPRECATED #
415 # DEPRECATED #    # Step 4: Request a slice (optional)
416 # DEPRECATED #    sons.append(CreateForm(page = p, title = STEP4_TITLE, togglable = False, object = 'slice'))
417 # DEPRECATED #
418 # DEPRECATED #    # Step 5: Your request is waiting for validation
419 # DEPRECATED #    # Periodic refresh
420 # DEPRECATED #    sons.append(Raw(page = p, title = STEP5_TITLE, togglable = False, html = STEP4))
421 # DEPRECATED #
422 # DEPRECATED #    # Step 6: Account validation  = welcome for newly validated users
423 # DEPRECATED #    # . delegation
424 # DEPRECATED #    # . platforms
425 # DEPRECATED #    # . slice
426 # DEPRECATED #    # . pointers
427 # DEPRECATED #    sons.append(Raw(page = p, title = STEP6_TITLE, togglable = False, html = STEP5))
428 # DEPRECATED #
429 # DEPRECATED #    wizard = Wizard(
430 # DEPRECATED #        page       = p,
431 # DEPRECATED #        title      = WIZARD_TITLE,
432 # DEPRECATED #        togglable  = False,
433 # DEPRECATED #        sons       = sons,
434 # DEPRECATED #        start_step = start_step,
435 # DEPRECATED #    )
436 # DEPRECATED #
437 # DEPRECATED #    p << wizard.render(request) # in portal page if possible
438 # DEPRECATED #
439 # DEPRECATED #    return p.render()
440
441
442 # DEPRECATED ## view for my_account
443 # DEPRECATED # class MyAccountView(TemplateView):
444 # DEPRECATED #    template_name = "my_account.html"
445 # DEPRECATED #    
446 # DEPRECATED #    def from_process(self, request, **cleaned_data): 
447 # DEPRECATED #        #if request.method == 'POST':
448 # DEPRECATED #         #       if request.POST['submit_name']:
449 # DEPRECATED #        if 'fname' in request.POST:            
450 # DEPRECATED #                messsag= "Got Name"
451 # DEPRECATED #                #return render(request, 'portal/my_account.html')
452 # DEPRECATED #                #response = HttpResponse("Here's the text of the Web page.")    
453 # DEPRECATED #                return HttpResponse(message)
454 # DEPRECATED #            
455 # DEPRECATED #    def get_context_data(self, **kwargs):
456 # DEPRECATED #        page = Page(self.request)
457 # DEPRECATED #        context = super(MyAccountView, self).get_context_data(**kwargs)
458 # DEPRECATED #        context['person']   = self.request.user
459 # DEPRECATED #        # XXX This is repeated in all pages
460 # DEPRECATED #        # more general variables expected in the template
461 # DEPRECATED #        context['title'] = 'User Profile Page'
462 # DEPRECATED #        # the menu items on the top
463 # DEPRECATED #        context['topmenu_items'] = topmenu_items('my_account', self.request)
464 # DEPRECATED #        # so we can sho who is logged
465 # DEPRECATED #        context['username'] = the_user(self.request)
466 # DEPRECATED #        context.update(page.prelude_env())
467 # DEPRECATED #        return context
468
469
470
471 # View for my_account form
472 def my_account(request):
473     return render(request, 'my_account.html')
474
475 #my_acc form value processing
476 def acc_process(request):
477     # getting the user_id from the session [now hardcoded]
478     get_user = PendingUser.objects.get(id='1') # here we will get the id/email from session e.g., person.email
479     if 'submit_name' in request.POST:
480         edited_first_name =  request.POST['fname']
481         edited_last_name =  request.POST['lname']
482         #email = 'test_email@gmail.com'
483         #password = 'test_pp'
484         #message = 'F_Name: %s L_name: %s dummy_pp: %s' % (first_name, last_name, password)
485         #site = None
486         
487         # insert into DB [needed for registration page]
488         #approach borrowed from register view     
489         #new_user = PendingUser.objects.create_inactive_user(edited_first_name, edited_last_name, email,  password, site) 
490         #conventional approach
491         #b = PendingUser(first_name=edited_first_name, edited_last_name=last_name)
492         #b.save()
493         
494         # select and update [will be used throughout this view]
495         # select the logged in user [for the moment hard coded]
496         #get_user = PendingUser.objects.get(id='1') # here we will get the id/email from session e.g., person.email
497         # update first and last name
498         get_user.first_name = edited_first_name
499         get_user.last_name = edited_last_name
500         get_user.save() 
501
502         return HttpResponse('Success: Name Updated!!')       
503     elif 'submit_pass' in request.POST:
504         edited_password = request.POST['password']
505         # select the logged in user [for the moment hard coded]
506         #get_user = PendingUser.objects.get(id='1') # here we will get the id/email from session e.g., person.email
507         # update password
508         get_user.password = edited_password
509         get_user.save()
510         return HttpResponse('Success: Password Changed!!')
511     elif 'generate' in request.POST:
512         a =2
513         message = 'Here will generate ssh-rsa keys :D %d' %a
514         return HttpResponse(message)
515     elif 'upload_key' in request.POST:
516         up_file = request.FILES['pubkey']
517         file_content =  up_file.read()
518         file_name = up_file.name
519         file_extension = os.path.splitext(file_name)[1] 
520         allowed_extension =  ['.pub','.txt']
521         if file_extension in allowed_extension:
522             file_content = '{user_public_key:'+ file_content +'}'
523             file_content = re.sub("\r", "", file_content)
524             file_content = re.sub("\n", "\\n",file_content)
525             get_user.keypair = file_content
526             get_user.save()
527             return HttpResponse('Success: Publickey uploaded! Old records overwritten')
528         else:
529             return HttpResponse('Please upload a valid public key.')    
530         
531     else:
532         message = 'You submitted an empty form.'
533         return HttpResponse(message)
534
535
536
537 # view for contact form
538 def contact(request):
539     if request.method == 'POST': # If the form has been submitted...
540         form = ContactForm(request.POST) # A form bound to the POST data
541         if form.is_valid(): # All validation rules pass
542             # Process the data in form.cleaned_data
543             first_name = form.cleaned_data['first_name']
544             last_name = form.cleaned_data['last_name']
545             affiliation = form.cleaned_data['affiliation']
546             subject = form.cleaned_data['subject']
547             message = form.cleaned_data['message']
548             email = form.cleaned_data['email'] # email of the sender
549             cc_myself = form.cleaned_data['cc_myself']
550
551             recipients = ['yasin.upmc@gmail.com']
552             if cc_myself:
553                 recipients.append(email)
554
555             from django.core.mail import send_mail
556             send_mail("Onelab user submitted a query ", [first_name,last_name,affiliation,subject,message], email, recipients)
557             return render(request,'contact_sent.html') # Redirect after POST
558     else:
559         form = ContactForm() # An unbound form
560
561     return render(request, 'contact.html', {
562         'form': form,
563     })
564
565
566 def slice_request(request):
567     if request.method == 'POST': # If the form has been submitted...
568         form = SliceRequestForm(request.POST) # A form bound to the POST data
569         if form.is_valid(): # All validation rules pass
570             # Process the data in form.cleaned_data
571             slice_name = form.cleaned_data['slice_name']
572             number_of_nodes = form.cleaned_data['number_of_nodes']
573             type_of_nodes = form.cleaned_data['type_of_nodes']
574             purpose = form.cleaned_data['purpose']
575             email = form.cleaned_data['email'] # email of the sender
576             cc_myself = form.cleaned_data['cc_myself']
577
578             recipients = ['yasin.upmc@gmail.com','jordan.auge@lip6.fr']
579             if cc_myself:
580                 recipients.append(email)
581
582             from django.core.mail import send_mail
583             send_mail("Onelab New Slice request form submitted", [slice_name,number_of_nodes,type_of_nodes,purpose], email, recipients)
584             return render(request,'slicereq_recvd.html') # Redirect after POST
585     else:
586         form = SliceRequestForm() # An unbound form
587
588 #    template_env = {}
589 #    template_env['form'] = form
590 #    template_env['topmenu_items'] = topmenu_items('Request a slice', request) 
591 #    template_env['unfold1_main'] = render(request, 'slice_request_.html', {
592 #        'form': form,
593 #    })
594 #    from django.shortcuts                import render_to_response
595 #    from django.template                 import RequestContext
596 #    return render_to_response ('view-unfold1.html',template_env,
597 #                               context_instance=RequestContext(request))
598
599     return render(request, 'slice_request.html', {
600         'form': form,
601         'topmenu_items': topmenu_items('Request a slice', request),
602         'username': the_user (request) 
603     })
604
605
606 class PresViewView(TemplateView):
607     template_name = "view-unfold1.html"
608
609     def get_context_data(self, **kwargs):
610
611         page = Page(self.request)
612
613         pres_view = PresView(page = page)
614
615         context = super(PresViewView, self).get_context_data(**kwargs)
616
617         #context['ALL_STATIC'] = "all_static"
618         context['unfold1_main'] = pres_view.render(self.request)
619
620         # XXX This is repeated in all pages
621         # more general variables expected in the template
622         context['title'] = 'Test view that combines various plugins'
623         # the menu items on the top
624         context['topmenu_items'] = topmenu_items('PresView', self.request)
625         # so we can sho who is logged
626         context['username'] = the_user(self.request)
627
628         prelude_env = page.prelude_env()
629         context.update(prelude_env)
630
631         return context
632
633 def json_me(config_file,type):
634     json_answer = ''
635     for ligne in config_file:
636         if not ligne.startswith('#'):
637             args = ligne.split(';')
638             json_answer += str('{ "name": "' + args[0] + '" ,"id":"' + args[1]  + '" ,"descriptif":"' + args[2]+'"')
639             if type!="dynamic":
640                 json_answer += str(',"contraints":')
641                 if args[3]=="":
642                     json_answer += str('""')
643                 else:
644                     json_answer += str(args[3])
645             json_answer += str('},')
646     return json_answer[:-1]
647
648
649 DIR = '/var/myslice/'
650 STATIC = '%s/config_method_static' % DIR
651 DYNAMIC = '%s/config_method_dynamic' % DIR
652 ANIMATION = '%s/config_method_animation' % DIR
653
654 def pres_view_methods(request, type):
655
656     if type ==None:
657         return 0
658     elif type =="static":
659         config = open(STATIC, "r")
660         json_answer = str('{ "options": [')
661         json_answer += str(json_me(config,"static"))
662         json_answer += str('] }')
663         config.close()
664     elif type =="dynamic":
665         config = open(DYNAMIC, "r")
666         json_answer = str('{ "options": [')
667         json_answer += str(json_me(config,"dynamic"))
668         json_answer += str('] }')
669         config.close()
670     elif type =="animation":
671         config = open(ANIMATION, "r")
672         json_answer = str('{ "options": [')
673         json_answer += str(json_me(config,"animation"))
674         json_answer += str('] }')
675         config.close()
676     elif type =="all":
677         config = open(STATIC, "r")
678         json_answer = str('{ "static": [')
679         json_answer += str(json_me(config,"static"))
680         json_answer += str('],')
681         json_answer += str('"dynamic": [')
682         config.close()
683         config = open(DYNAMIC, "r")
684         json_answer += str(json_me(config,"dynamic"))
685         json_answer += str('],')
686         json_answer += str('"animation": [')
687         config.close()
688         config = open(ANIMATION, "r")
689         json_answer += str(json_me(config,"animation"))
690         json_answer += str('] }')
691         config.close()
692     else:
693         return 0
694     return HttpResponse (json_answer, mimetype="application/json")
695
696 def pres_view_animation(request, constraints, id):
697
698 # sites crees depuis 2008
699 # static.py?contraints=']date_created':1262325600&id='name_id"'
700
701     # method = request.getvalue('method') #ex : GetSites
702     #constraints = "']date_created':1262325600"
703     #id = "2"
704
705     if id == None:
706         return 0
707
708     # method = 'GetSites'#request.getvalue('method') #ex : GetSites
709     # constraints = {}#request.getvalue('constraints') // nul = {}
710     # response_field = "'site_id','name','date_created'"#request.getvalue('response_field')
711
712     config_file = open(ANIMATION, "r")
713     for ligne in config_file:
714         if not ligne.startswith('#'):
715             ligne = ligne.split('\n')
716             first = ligne[0].split(';')
717             if (str(first[1]) == str(id)):
718                 save = first
719     config_file.close()
720
721     #Les print_method, print_option sont definis par le client (js)
722     #Les animations acceptent que les connexions anonymous
723     # args = "postmsg;animation;;;anonymous;https://www.planet-lab.eu/PLCAPI/;"
724     args = ";;"+str(save[8])+";"+str(save[9])+";anonymous;"+str(save[5])+";"+str(save[6])+";{"+str(constraints)+"};"+str(save[7])+";"
725
726
727     #Creation d'un objet event
728     event = Event(args)
729     cmd = [{"params": {
730             "data": {
731                 "print_options": event.print_options,
732                 "print_method": event.print_method,
733                 "message": event.data
734             }
735         }
736     }]
737
738     json_answer = json.dumps(cmd)
739     return HttpResponse (json_answer, mimetype="application/json")
740
741 def pres_view_static(request, constraints, id):
742     #constraints = "']date_created':1262325600"
743     #id = "2"
744
745     # method = 'GetSites'#request.getvalue('method') #ex : GetSites
746     # constraints = {}#request.getvalue('constraints') // nul = {}
747     # response_field = "'site_id','name','date_created'"#request.getvalue('response_field')
748
749     config_file = open(STATIC, "r")
750     for ligne in config_file:
751         if not ligne.startswith('#'):
752             ligne = ligne.split('\n')
753             first = ligne[0].split(';')
754             if (str(first[1]) == str(id)):
755                 save = first
756     config_file.close()
757
758     #Les print_method, print_option sont definis par le client (js)
759     #Les animations acceptent que les connexions anonymous
760     # args = "postmsg;animation;;;anonymous;https://www.planet-lab.eu/PLCAPI/;"
761     args = ";;"+str(save[8])+";"+str(save[9])+";anonymous;"+str(save[5])+";"+str(save[6])+";{"+str(constraints)+"};"+str(save[7])+";"
762
763
764     #Creation d'un objet event
765     event = Event(args)
766     cmd = [{"params": {
767             "data": {
768                 "print_options": event.print_options,
769                 "print_method": event.print_method,
770                 "message": event.data
771             }
772         }
773     }]
774
775     json_answer = json.dumps(cmd)
776     return HttpResponse (json_answer, mimetype="application/json")