From 4be0d0d89bf8ad0f6a012d1578af181fe5f83b0c Mon Sep 17 00:00:00 2001 From: CruiseDevice Date: Fri, 28 Sep 2018 15:27:22 +0530 Subject: Slot booking and password reset functionality added - Password reset - dashboard skeleton for moderator - Slot booking template - Experiment views - update settings.py --- sbhs/templates/account/account_index.html | 2 +- sbhs/templates/account/home.html | 16 +- sbhs/templates/base.html | 1 - sbhs/templates/slot/new.html | 56 ++-- sbhs/urls.py | 40 ++- sbhs/views.py | 435 ++++++++++++++++++------------ sbhs_server/settings.py | 10 +- 7 files changed, 338 insertions(+), 222 deletions(-) diff --git a/sbhs/templates/account/account_index.html b/sbhs/templates/account/account_index.html index 4b95df0..2d5789a 100644 --- a/sbhs/templates/account/account_index.html +++ b/sbhs/templates/account/account_index.html @@ -11,7 +11,7 @@ {{login_form.as_p}} -   Forgot Password? +   Forgot Password?
diff --git a/sbhs/templates/account/home.html b/sbhs/templates/account/home.html index 16d475a..fa95a26 100644 --- a/sbhs/templates/account/home.html +++ b/sbhs/templates/account/home.html @@ -3,26 +3,20 @@ {% block content %}
- {% if user.profile.is_moderator %} - Show all boards - Show all bookings - Show all images - Test boards - Update MID - Fetch Logs - {% endif %}
-

Welcome to Single Board Heater System Lab

diff --git a/sbhs/templates/base.html b/sbhs/templates/base.html index 3a88c8f..c6294a6 100644 --- a/sbhs/templates/base.html +++ b/sbhs/templates/base.html @@ -35,7 +35,6 @@ {% endfor %}
{% endif %} - {% block content %} {% endblock %}


diff --git a/sbhs/templates/slot/new.html b/sbhs/templates/slot/new.html index 27a0400..ec999c9 100644 --- a/sbhs/templates/slot/new.html +++ b/sbhs/templates/slot/new.html @@ -1,5 +1,6 @@ {% extends "account/home.html" %} {% load staticfiles %} +{% load custom_filter %} {% load widget_tweaks %} {% block title %} Book Slot @@ -26,46 +27,22 @@
-

Book Slot

+
+

Book future slots:

+
{% csrf_token %} - {% for field in form %} - {% if field.errors %} -
- -
- {{field}} - - {% for error in field.errors %} - {{error}} - {% endfor %} - -
-
- {% else %} -
-
- -
- {{field}} - {% if field.help_text %} -

- {{field.help_text}} -

- {% endif %} -
-
- -
- {% endif %} - {% endfor %} - + Book for a given date:
+ {{form.as_p}} +
+
OR
+ Book for current date and time
+ +
+
+
@@ -91,9 +68,12 @@ {% endif %} {{h.start_time}} - {{h.duration}} - {%if h.start_time >= now %} + {{h.end_time}} + {% compare_slot_time h.start_time h.end_time now as slot_status %} + {%if slot_status == "pending" %}

Pending

+ {% elif slot_status == "ongoing" %} +

Ongoing

{% else %}

Finished

{% endif %} diff --git a/sbhs/urls.py b/sbhs/urls.py index 5e79b21..81b63c8 100644 --- a/sbhs/urls.py +++ b/sbhs/urls.py @@ -1,9 +1,12 @@ from django.conf.urls import url - +from django.contrib.auth.views import ( + password_reset, password_change, password_change_done, password_reset_done, + password_reset_confirm, password_reset_complete + ) from . import views urlpatterns = [ - ####### Account URLS ######## + ################## Account URLS #################### url(r'^$', views.index, name='pages_index'), url(r'^about/?$', views.about, name='pages_about'), # url(r'^contact/?$', views.contact, name='pages_contact'), @@ -25,5 +28,38 @@ urlpatterns = [ url(r'^account/update_email/$',views.update_email, \ name='update_email'), + # change password urls + url(r'^account/password-change/$', password_change, + {'template_name': 'account/registration/password_change_form.html'}, + name='password_change'), + url(r'^account/password-change/done/$', password_change_done, + {'template_name': 'account/registration/password_change_done.html'}, + name='password_change_done'), + + # restore password urls + url(r'^account/password-reset/$', password_reset, + {'template_name': 'account/registration/password_reset_form.html'}, + name='password_reset'), + url(r'^account/password-reset/done/$', password_reset_done, + {'template_name': 'account/registration/password_reset_done.html'}, + name='password_reset_done'), + url(r'^account/password-reset/confirm/(?P[-\w]+)/(?P[-\w]+)/$', + password_reset_confirm, + {'template_name': 'account/registration/password_reset_confirm.html'}, + name='password_reset_confirm'), + url(r'^account/password-reset/complete/$', password_reset_complete, + {'template_name': 'account/registration/password_reset_complete.html'}, + name='password_reset_complete'), + + ################## Slot Urls ####################### url(r'^slot/new/$',views.slot_new,name='slot_new'), + + ################## Dashboard Urls ###################### + url(r'^dashboard/$',views.dashboard_index, name='dashboard_index'), + + ################## Experiment urls ##################### + url(r'^experiment/check_connection/$',views.check_connection, + name='experiment_check_connection'), + + url(r'^experiment/initiate/$',views.initiation,name='experiment_initiate') ] diff --git a/sbhs/views.py b/sbhs/views.py index 41525a6..803d460 100644 --- a/sbhs/views.py +++ b/sbhs/views.py @@ -13,7 +13,7 @@ import subprocess # import serial from textwrap import dedent from time import gmtime, strftime -from datetime import datetime +from datetime import datetime, timedelta, date from django.urls import reverse from django.conf import settings @@ -29,7 +29,7 @@ from django.contrib.auth import login, logout, authenticate from django.shortcuts import render, redirect, get_object_or_404 from django.core.exceptions import ObjectDoesNotExist, MultipleObjectsReturned from django.http import HttpResponse, HttpResponseRedirect,\ - Http404, HttpResponseServerError + Http404, HttpResponseServerError, JsonResponse from .models import Board, Experiment, Profile, Slot#, Webcam from .forms import UserLoginForm, UserRegistrationForm, SlotCreationForm @@ -42,11 +42,12 @@ from . import switch_off from . import switch_onn +LIMIT = 2 # ser = serial.Serial('/dev/ttyUSB0') # required for experiment views currentdir = os.path.dirname( - os.path.abspath(inspect.getfile(inspect.currentframe()))) + os.path.abspath(inspect.getfile(inspect.currentframe()))) parentdir = os.path.dirname(currentdir) sys.path.insert(0, parentdir) @@ -55,12 +56,12 @@ sys.path.insert(0, parentdir) def index(request, next_url=None): - if request.user.is_authenticated(): - return render(request,'account/home.html') - return render(request,"pages/pages_index.html") + if request.user.is_authenticated(): + return render(request,'account/home.html') + return render(request,"pages/pages_index.html") def about(req): - return render(req, "pages/about.html") + return render(req, "pages/about.html") def info(request): @@ -71,190 +72,290 @@ def downloads(req): def theory(req): - return render(req, "pages/theory.html") + return render(req, "pages/theory.html") def procedure(req): - return render(req, "pages/procedure.html") + return render(req, "pages/procedure.html") def experiments(req): - return render(req, "pages/experiments.html") + return render(req, "pages/experiments.html") def feedback(req): - return render(req, "pages/feedback.html") + return render(req, "pages/feedback.html") #########Account Views ########### @email_verified def account_index(request): - if request.user.is_authenticated(): - return render(request,'account/home.html') + if request.user.is_authenticated(): + return render(request,'account/home.html') - return render(request,'account/account_index.html',{ - 'login_form':UserLoginForm(request.POST or None), - 'registration_form':UserRegistrationForm(request.POST or None) - }) + return render(request,'account/account_index.html',{ + 'login_form':UserLoginForm(request.POST or None), + 'registration_form':UserRegistrationForm(request.POST or None) + }) def user_login(request): - user = request.user - context = {} - if user.is_authenticated(): - return account_index(request) - - if request.method == 'POST': - form = UserLoginForm(request.POST) - if form.is_valid(): - cd = form.cleaned_data - user = authenticate(username=cd['username'], - password=cd['password']) - if user is not None: - if user.is_active: - login(request,user) - return redirect('account_enter') - else: - messages.success(request,"Account Disabled") - return redirect('account_enter') - else: - messages.success(request, "Username and/or Password is \ - invalid") - return redirect('account_enter') - else: - context={ - "login_form": form - } - else: - form = UserLoginForm() - context = { - "login_form":form - } - return redirect('account_enter') + user = request.user + context = {} + if user.is_authenticated(): + return account_index(request) + + if request.method == 'POST': + form = UserLoginForm(request.POST) + if form.is_valid(): + cd = form.cleaned_data + user = authenticate(username=cd['username'], + password=cd['password']) + if user is not None: + if user.is_active: + login(request,user) + return redirect('account_enter') + else: + messages.success(request,"Account Disabled") + return redirect('account_enter') + else: + messages.success(request, "Username and/or Password is \ + invalid") + return redirect('account_enter') + else: + context={ + "login_form": form + } + else: + form = UserLoginForm() + context = { + "login_form":form + } + return redirect('account_enter') def user_logout(request): - logout(request) - return redirect('account_enter') + logout(request) + return redirect('account_enter') def user_register(request): - user = request.user - if user.is_authenticated(): - return render(request,'account/home.html') - context={} - if request.method == 'POST': - form = UserRegistrationForm(request.POST) - if form.is_valid(): - u_name, pwd, user_email, key= form.save() - new_user = authenticate(username=u_name,password=pwd) - login(request, new_user) - if user_email and key: - success, msg = send_user_mail(user_email, key) - context = { - 'activation_msg':msg - } - return render(request,'account/activation_status.html', - context - ) - return redirect('account_enter') - else: - return redirect('account_enter') - else: - return redirect('account_enter') + user = request.user + if user.is_authenticated(): + return render(request,'account/home.html') + context={} + if request.method == 'POST': + form = UserRegistrationForm(request.POST) + if form.is_valid(): + u_name, pwd, user_email, key= form.save() + new_user = authenticate(username=u_name,password=pwd) + login(request, new_user) + if user_email and key: + success, msg = send_user_mail(user_email, key) + context = { + 'activation_msg':msg + } + return render(request,'account/activation_status.html', + context + ) + return redirect('account_enter') + else: + return redirect('account_enter') + else: + return redirect('account_enter') def activate_user(request, key): - profile = get_object_or_404(Profile, activation_key=key) - context = {} - context['success'] = False - if profile.is_email_verified: - context['activation_msg'] = "Your account is already verified" - return render(request,'account/activation_status.html',context) - if timezone.now() > profile.key_expiry_time: - content['msg'] = dedent( - """ - Your activation time expired. Please try again - """ - ) - else: - context['success'] = True - profile.is_email_verified=True - profile.save() - context['msg'] = "Your account is activated" - return render(request,'account/activation_status.html',context) + profile = get_object_or_404(Profile, activation_key=key) + context = {} + context['success'] = False + if profile.is_email_verified: + context['activation_msg'] = "Your account is already verified" + return render(request,'account/activation_status.html',context) + if timezone.now() > profile.key_expiry_time: + content['msg'] = dedent( + """ + Your activation time expired. Please try again + """ + ) + else: + context['success'] = True + profile.is_email_verified=True + profile.save() + context['msg'] = "Your account is activated" + return render(request,'account/activation_status.html',context) def new_activation(request, email=None): - context = {} - if request.method == 'POST': - email = request.POST.get('email') - try: - user = User.objects.get(email=email) - except MultipleObjectsReturned: - context['email_err_msg'] = 'Multiple entries found for this email \ - Please change your email' - return render(request,'account/activation_status.html',context) - except ObjectDoesNotExist: - context['success'] = False - context['msg'] = "Your account is not verified. Please verify your \ - account" - return render(request, 'account/activation_status.html',context) - - if not user.profile.is_email_verified: - user.profile.activation_key = generate_activation_key(user.username) - user.profile.key_expiry_time = timezone.now() \ - + timezone.timedelta(minutes=20) - user.profile.save() - new_user_data = User.objects.get(email=email) - success, msg = send_user_mail(new_user_data.email, \ - new_user_data.profile.activation_key) - - if success: - context['activation_msg'] = msg - else: - context['msg'] = msg - else: - context['activation_msg'] = "Your account is already verified" - return render(request,'account/activation_status.html',{}) + context = {} + if request.method == 'POST': + email = request.POST.get('email') + try: + user = User.objects.get(email=email) + except MultipleObjectsReturned: + context['email_err_msg'] = 'Multiple entries found for this email \ + Please change your email' + return render(request,'account/activation_status.html',context) + except ObjectDoesNotExist: + context['success'] = False + context['msg'] = "Your account is not verified. Please verify your \ + account" + return render(request, 'account/activation_status.html',context) + + if not user.profile.is_email_verified: + user.profile.activation_key = generate_activation_key(user.username) + user.profile.key_expiry_time = timezone.now() \ + + timezone.timedelta(minutes=20) + user.profile.save() + new_user_data = User.objects.get(email=email) + success, msg = send_user_mail(new_user_data.email, \ + new_user_data.profile.activation_key) + + if success: + context['activation_msg'] = msg + else: + context['msg'] = msg + else: + context['activation_msg'] = "Your account is already verified" + return render(request,'account/activation_status.html',{}) def update_email(request): - context = {} - if request.method == 'POST': - email = request.POST.get('email') - username = request.POST.get('username') - user = get_object_or_404(User, username=username) - user.email = email - user.save() - return new_activation(request, email) - else: - context['email_err_msg'] = "Please Update your email" - return render(request,'account/activation_status.html',context) + context = {} + if request.method == 'POST': + email = request.POST.get('email') + username = request.POST.get('username') + user = get_object_or_404(User, username=username) + user.email = email + user.save() + return new_activation(request, email) + else: + context['email_err_msg'] = "Please Update your email" + return render(request,'account/activation_status.html',context) @login_required @email_verified def slot_new(request): - user = request.user - slot_history = Slot.objects.filter(user=user).order_by("start_time") - context = {} - now = datetime.now(pytz.timezone("UTC")) - if not request.user.is_authenticated(): - return redirect('account_enter') - if request.method == 'POST': - if request.POST.get('delete') == "delete": - slots = request.POST.getlist("slots") - Slot.objects.filter(id__in=slots).delete() - return redirect('slot_new') - else: - form = SlotCreationForm(request.POST) - - if form.is_valid(): - new_slot = form.save(commit=False) - if new_slot.start_time >= now: - new_slot.user = user - new_slot.save() - messages.success(request,'Slot created successfully.') - else: - messages.error(request, - 'Start time selected' - + ' is before today.' - + 'Please choose again.' - ) - return redirect('slot_new') - else: - form = SlotCreationForm() - context['history']=slot_history - context['form']=form - context['now'] = now - return render(request,'slot/new.html',context) + user = request.user + slot_history = Slot.objects.filter(user=user).order_by("start_time") + context = {} + now = timezone.now() + if not request.user.is_authenticated(): + return redirect('account_enter') + + if request.method == 'POST': + if request.POST.get('delete') == "delete": + slots = request.POST.getlist("slots") + Slot.objects.filter(id__in=slots).delete() + if request.POST.get("book_date") == "book_date": + form = SlotCreationForm(request.POST) + if form.is_valid(): + new_slot = form.save(commit=False) + if new_slot.start_time >= now: + new_slot.end_time = new_slot.start_time + timedelta( + minutes=settings.SLOT_DURATION + ) + new_slot.user = user + new_slot.save() + messages.success(request,'Slot created successfully.') + else: + messages.error(request, + 'Start time selected' + + ' is before today.' + + 'Please choose again.' + ) + if request.POST.get("book_now") == "book_now": + slot_now = Slot.objects.create(user=user, start_time=now, + end_time=now+timedelta(minutes=55) + ) + messages.success(request,'Slot created successfully.') + return redirect("slot_new") + + else: + form = SlotCreationForm() + context['history']=slot_history + context['form']=form + context['now'] = now + return render(request,'slot/new.html',context) + + +################## Moderator Views ########################## + +@login_required +def dashboard_index(request): + context = {} + return render(request,'dashboard/dashboard_index.html',context) + +###################Experiment Views ###################### + +def check_connection(request): + message = {"message":"TESTOK"} + return JsonResponse(message, safe=True, status=200) + +@login_required +def initial_login(request): + """ Logs in an user for conducting the experiment on the specified + board. + Input: req:request object. + Output: HttpResponse object. + """ + + username = request.POST.get("username") + rpi_ip = '' + try: + assigned_mid = 2 + except Exception as e: + return JsonResponse({ + "STATUS":400, + "MESSAGE":{ + "IS_IP":"1", + "DATA":"Invalid username" + } + }) + rpi_ip = '10.102.54.71' + if rpi_ip is None: + return JsonResponse({ + "STATUS":400, + "MESSAGE":{ + "IS_IP":"1", + "DATA":"Board is currently offline" + } + }) + return JsonResponse({ + "STATUS":200, + "MESSAGE":{ + "IS_IP":"1", + "DATA":rpi_ip + } + }) + + +@csrf_exempt +def initiation(request): + username = request.POST.get("username") + password = request.POST.get("password") + user = authenticate(username=username, password=password) + if user: + if user.is_active: + now = timezone.now() + slots = Slot.objects.filter(user=user, + start_time__gte=now, + end_time__lt = now + ) + + slot = slots.last() + if slot: + filename = '' + message = { + "STATUS":1, + "MESSAGE": filename + } + else: + message = { + "STATUS":0, + "MESSAGE":"Slot has ended. Please book the next slot \ + to continue the experiment" + } + else: + message = { + "STATUS":0, + "MESSAGE":"Your account is not activated. Please check your \ + mail for activation link" + } + else: + message = { + "STATUS":0, + "MESSAGE":"Invalid username and password" + } + + return JsonResponse(message, safe=True, status=200) \ No newline at end of file diff --git a/sbhs_server/settings.py b/sbhs_server/settings.py index 81f8482..3b2a68d 100644 --- a/sbhs_server/settings.py +++ b/sbhs_server/settings.py @@ -11,7 +11,7 @@ https://docs.djangoproject.com/en/1.11/ref/settings/ """ import os -import sbhs_server.credentials as credentials +import sbhs_server.secret as credentials # Build paths inside the project like this: os.path.join(BASE_DIR, ...) BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) @@ -61,7 +61,8 @@ ROOT_URLCONF = 'sbhs_server.urls' TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', - 'DIRS': [os.path.join(BASE_DIR,'templates')], + 'DIRS': [ + os.path.join(BASE_DIR,'templates')], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ @@ -170,3 +171,8 @@ PRODUCTION_URL = '127.0.0.1:8000' IS_DEVELOPMENT=False DEFAULT_FROM_EMAIL = EMAIL_HOST_USER + +RASP_PI_IP = [] +# enter comma separated raspberry pi IPs here + +RASPI_SBHS_CONNECTION = True if RASP_PI_IP else False -- cgit