diff options
author | CruiseDevice | 2018-10-24 16:58:51 +0530 |
---|---|---|
committer | CruiseDevice | 2018-10-24 16:58:51 +0530 |
commit | 8980733d799444665a671c6f8bd66dc16ed755fe (patch) | |
tree | 13e215a5487996f844182038003698319af75fd4 /sbhs/views.py | |
parent | 113918f3a073e94a4f9b6dce25c30a71658e63b9 (diff) | |
download | sbhs_server-8980733d799444665a671c6f8bd66dc16ed755fe.tar.gz sbhs_server-8980733d799444665a671c6f8bd66dc16ed755fe.tar.bz2 sbhs_server-8980733d799444665a671c6f8bd66dc16ed755fe.zip |
Create experiment, moderator urls and update views
- experiment initiation
- create log_data of experiment
- create graph from 1000 instance of log_data of particular mid
- download user log_files
- download zip of complete experiments directory which contains log_files of all the users
- show all bookings in moderator dashboard
- show all connected boards in moderator dashboard
- test connected board if it is vacant.
- fetch_logs from given time of each user.
- seperate raspi_server from main server.
- specify path for experiment logs and global logs
Diffstat (limited to 'sbhs/views.py')
-rw-r--r-- | sbhs/views.py | 510 |
1 files changed, 442 insertions, 68 deletions
diff --git a/sbhs/views.py b/sbhs/views.py index 37d307e..1d8c069 100644 --- a/sbhs/views.py +++ b/sbhs/views.py @@ -6,13 +6,13 @@ import random import zipfile import inspect import pytz -# import MySQLdb import datetime import requests -import subprocess +import subprocess, zipfile # import serial from textwrap import dedent from time import gmtime, strftime +import time from datetime import datetime, timedelta, date from django.urls import reverse @@ -20,6 +20,7 @@ from django.conf import settings from django.db import connection from django.utils import timezone from django.db.models import Count +from django.contrib.auth.models import User # import automatic_slot_booking from django.contrib import messages from django.template.loader import render_to_string @@ -30,21 +31,24 @@ 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, JsonResponse -from urllib.parse import urljoin -from .models import Board, Experiment, Profile, Slot#, Webcam -from .forms import UserLoginForm, UserRegistrationForm, SlotCreationForm +from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger + + +from .models import Board, Experiment, Profile, Slot, UserBoard#, Webcam +from .forms import ( + UserLoginForm, UserRegistrationForm, SlotCreationForm, FilterLogsForm + ) from .send_emails import send_user_mail from sbhs_server import credentials as credentials from sbhs.decorators import email_verified - ################# pages views ####################### - def index(request, next_url=None): 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") @@ -52,6 +56,7 @@ def about(req): def info(request): return render(request,"pages/info.html") + def downloads(req): return redirect("http://sbhs.os-hardware.in/downloads") @@ -59,19 +64,26 @@ def downloads(req): def theory(req): return render(req, "pages/theory.html") + def procedure(req): return render(req, "pages/procedure.html") + def experiments(req): return render(req, "pages/experiments.html") + def feedback(req): return render(req, "pages/feedback.html") #########Account Views ########### @email_verified def account_index(request): - if request.user.is_authenticated(): + user = request.user + if user.is_authenticated(): + if not UserBoard.objects.filter(user=user).exists(): + random_board = Board.objects.order_by('?').last() + UserBoard.objects.create(user=user, board=random_board) return render(request,'account/home.html') return render(request,'account/account_index.html',{ @@ -215,7 +227,7 @@ def update_email(request): @email_verified def slot_new(request): user = request.user - slot_history = Slot.objects.filter(user=user).order_by("start_time") + slot_history = Slot.objects.filter(user=user).order_by("-start_time") context = {} now = timezone.now() if not request.user.is_authenticated(): @@ -261,47 +273,12 @@ def slot_new(request): ###################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 - } - }) + return HttpResponse("TESTOK") +def client_version(request): + return HttpResponse(str(settings.CLIENT_VERSION)) + @csrf_exempt def initiation(request): username = request.POST.get("username") @@ -310,23 +287,45 @@ def initiation(request): if user: if user.is_active: now = timezone.now() - slots = Slot.objects.filter(user=user, - start_time__gte=now, - end_time__lt = now - ) - + slots = Slot.objects.get_current_slots(user).order_by("id") slot = slots.last() - if slot: - filename = '' + board = UserBoard.objects.get(user=user).board + check_status_path = "reset/{0}".format(board.usb_id) + check_status = connect_sbhs(board.raspi_path, check_status_path) + if check_status["status"] and slot: + filename = datetime.strftime(now, "%Y%b%d_%H_%M_%S.txt") + logdir = os.path.join(settings.EXPERIMENT_LOGS_DIR, + user.username + ) + user_file = user.username + "/" + filename + if not os.path.exists(logdir): + os.makedirs(logdir) + + if not Experiment.objects.filter(slot=slot, + log=user_file + ).exists(): + Experiment.objects.create(slot=slot, + log=user_file + ) + message = { "STATUS":1, - "MESSAGE": filename - } + "MESSAGE": filename, + } + elif check_status["status"] and not slot: + message = { + "STATUS":0, + "MESSAGE":"Slot has ended. Please book the next slot." + } + elif not check_status["status"] and slot: + message = { + "STATUS":0, + "MESSAGE":"Slot is booked but Board is currently offline." + } else: message = { "STATUS":0, - "MESSAGE":"Slot has ended. Please book the next slot \ - to continue the experiment" + "MESSAGE":"Board is currently offline. Contact admin." } else: message = { @@ -339,7 +338,6 @@ def initiation(request): "STATUS":0, "MESSAGE":"Invalid username and password" } - return JsonResponse(message, safe=True, status=200) def map_sbhs_to_rpi(client_ip): @@ -351,8 +349,7 @@ def map_sbhs_to_rpi(client_ip): for r_pi in r_pis: rpi_map = {} rpi_map["rpi_ip"] = r_pi - rpi_connect = connect_sbhs(r_pi, "get_machine_ids") - mac_ids = json.loads(rpi_connect) + mac_ids = connect_sbhs(r_pi, "get_machine_ids") board = Board() board.save_board_details(r_pi, mac_ids) rpi_map["mac_ids"] = [i['sbhs_mac_id'] for i in mac_ids] @@ -361,17 +358,179 @@ def map_sbhs_to_rpi(client_ip): rpi_map = {} client_name = client_ip + ":1234" rpi_map["rpi_ip"] = client_name - rpi_connect = connect_sbhs(client_name, "get_machine_ids") - mac_ids = json.loads(rpi_connect) + mac_ids = connect_sbhs(client_name, "get_machine_ids") board = Board() board.save_board_details(client_name, mac_ids) + rpi_map["mac_ids"] = [i['sbhs_mac_id'] for i in mac_ids] + map_machines.append(rpi_map) + return map_machines def connect_sbhs(rpi_ip, experiment_url): connect_rpi = requests.get("http://{0}/experiment/{1}".format( rpi_ip, experiment_url ) ) - return connect_rpi.text + data = json.loads(connect_rpi.text) + return data + +@csrf_exempt +def experiment(request): + try: + username = request.POST.get("username") + server_start_ts = int(time.time() * 1000) + user = User.objects.get(username=username) + slot = Slot.objects.get_current_slots(user)\ + .order_by("start_time").last() + board = UserBoard.objects.get(user=user).board + experiment = Experiment.objects.filter(slot=slot) + if experiment.exists(): + experiment = experiment.first() + now = timezone.now() + endtime = slot.end_time + if endtime > now: + timeleft = int((endtime-now).seconds) + heat = max(min(int(request.POST.get("heat")), 100), 0) + fan = max(min(int(request.POST.get("fan")), 100), 0) + set_heat_url = "set_heat/{0}/{1}".format(board.usb_id, heat) + set_fan_url = "set_fan/{0}/{1}".format(board.usb_id, fan) + get_temp_url = "get_temp/{0}".format(board.usb_id) + set_heat = connect_sbhs(board.raspi_path, set_heat_url) + set_fan = connect_sbhs(board.raspi_path, set_fan_url) + get_temp = connect_sbhs(board.raspi_path,get_temp_url) + temp = get_temp["temp"] + log_data(board.mid, heat, fan, temp) + + server_end_ts = int(time.time() * 1000) + + STATUS = 1 + MESSAGE = "%s %d %d %2.2f" % (request.POST.get("iteration"), + heat, + fan, + temp) + MESSAGE = "%s %s %d %d,%s,%d" % (MESSAGE, + request.POST.get("timestamp"), + server_start_ts, + server_end_ts, + request.POST.get("variables"), + timeleft) + experiment_log_path = os.path.join( + settings.EXPERIMENT_LOGS_DIR, + experiment.log + ) + f = open(experiment_log_path, "a") + f.write(" ".join(MESSAGE.split(",")[:2]) + "\n") + f.close() + # Experiment.objects.create(slot=slot, log=experiment_log_path) + else: + STATUS = 0 + MESSAGE = "Slot has ended. Please book the next slot to \ + continue the experiment." + else: + STATUS = 0 + MESSAGE = "You haven't booked this slot." + + return HttpResponse(json.dumps({"STATUS": STATUS, "MESSAGE": MESSAGE})) + except Exception as e: + raise Exception + return HttpResponse(json.dumps({"STATUS": 0, + "MESSAGE": "Please Contact Admin" + } + ) + ) + +def log_data(mid, heat, fan, temp): + + data = "{0} {1} {2} {3}\n".format(int(time.time()),str(heat), + str(fan), str(temp) + ) + global_logfile = settings.SBHS_GLOBAL_LOG_DIR + "/" + str(mid) + ".log" + try: + with open(global_logfile, "a") as global_loghandler: + global_loghandler.write(data) + return True + except: + return False + +@login_required +def logs(request): + user = request.user + context = {} + all_bookings = Slot.objects.filter(user__username=user) + all_booking_ids = [booking.id for booking in all_bookings] + experiment = Experiment.objects.select_related("slot").filter(slot_id__in=all_booking_ids) + for exp in experiment: + exp.logname = exp.log.split("/")[-1] + context['exp.logname'] = exp.logname + context['experiment'] = experiment + return render(request,'experiment/logs.html',context) + +@login_required +def download_user_log(request, experiment_id): + user = request.user + experiment_data = Experiment.objects.get(slot__id=experiment_id) + f = open(os.path.join(settings.EXPERIMENT_LOGS_DIR, experiment_data.log),"r") + data = f.read() + print(data) + f.close() + return HttpResponse(data, content_type="text/text") + + +# @csrf_exempt +# def reset(req): +# try: +# from pi_server.settings import boards +# user = req.user +# if user.is_authenticated(): +# key = str(user.board.mid) +# experiment = Experiment.objects.select_related().filter(id=boards[key]["experiment_id"]) + +# if len(experiment) == 1 and user == experiment[0].booking.account: +# experiment = experiment[0] +# now = datetime.datetime.now() +# endtime = experiment.booking.end_time() + +# boards[key]["board"].setHeat(0) +# boards[key]["board"].setFan(100) + +# log_data(boards[key]["board"], key, experiment.id, 0, 100) +# if endtime < now: +# boards[key]["experiment_id"] = None +# except: +# pass + +# return HttpResponse("") + +# def log_data(sbhs, mid, experiment_id, heat=None, fan=None, temp=None): +# if heat is None: +# heat = sbhs.getHeat() +# if fan is None: +# fan = sbhs.getFan() +# if temp is None: +# temp = sbhs.getTemp() + +# data = "%d %s %s %s\n" % (int(time.time()), str(heat), str(fan), str(temp)) +# global_logfile = settings.SBHS_GLOBAL_LOG_DIR + "/" + str(mid) + ".log" +# with open(global_logfile, "a") as global_loghandler: +# global_loghandler.write(data) + +# def validate_log_file(req): +# import hashlib +# data = req.POST.get("data") +# data = data.strip().split("\n") +# clean_data = "" +# for line in data: +# columns = line.split(" ") +# if len(columns) >= 6: +# clean_data += (" ".join(columns[0:6]) + "\n") + +# checksum = hashlib.sha1(clean_data).hexdigest() + +# try: +# e = Experiment.objects.get(checksum=checksum) +# return HttpResponse("TRUE") +# except: +# return HttpResponse("FALSE") + ################## Moderator Views ########################## @@ -387,9 +546,224 @@ def moderator_dashboard(request): if not is_moderator(user): raise Http404("You are not allowed to see this page!") else: - all_boards = map_sbhs_to_rpi(request.META["SERVER_NAME"]) - context["all_active_boards"] = all_boards - return render(request, 'dashboard/dashboard_index.html', context) + board_check = map_sbhs_to_rpi(request.META["SERVER_NAME"]) + board = Board() + all_mac_ids = [] + for machines in board_check: + all_mac_ids.extend(machines["mac_ids"]) + board.switch_off_inactive_boards(all_mac_ids) + context["all_boards"] = Board.objects.all() + return render(request, 'dashboard/show_all_boards.html', context) + +@login_required +def profile(request, mid): + user = request.user + context = {} + if not is_moderator(user): + raise Http404("You are not allowed to see this page.") + else: + try: + filename = settings.SBHS_GLOBAL_LOG_DIR + "/" + str(mid) + ".log" + print(filename) + except: + raise Http404("Log does not exist for this profile.") + + delta_T = 1000 + data = subprocess.check_output("tail -n {0} {1}".format( + delta_T, filename + ), + shell=True) + data = data.split("\n".encode()) + + heatcsv = "" + fancsv = "" + tempcsv = "" + + plot = [] + for t in range(len(data)): + line = data[t].decode("utf-8") + entry = line.strip().split(" ") + try: + plot.append([int(float(i)) for i in entry[0:-1] \ + + [float(entry[-1])]]) + heatcsv += "{0},{1}".format(t+1, entry[1]) + fancsv += "{0},{1}".format(t+1,entry[2]) + tempcsv += "{0},{1}".format(t+1, entry[3]) + except: + continue + + plot = zip(*plot) + context["mid"] = mid + context["delta_T"] = delta_T + context["heat"] = heatcsv + context["fan"] = fancsv + context["temp"] = tempcsv + + return render(request,"dashboard/profile.html",context) + +@login_required +def download_log(request, mid): + user = request.user + if not is_moderator(user): + raise Http404("You are not allowed to see this page.") + else: + try: + global_logfile = settings.SBHS_GLOBAL_LOG_DIR + "/" + str(mid) \ + + ".log" + f = open(global_logfile,'r') + data = f.read() + f.close() + return HttpResponse(data, content_type='text/text') + except: + return HttpResponse("Requested log file does not exist") + +def zipdir(path,ziph): + for root, dirs, files in os.walk(path): + for file in files: + ziph.write(os.path.join(root,file)) + +@login_required +def logs_folder_index(request): + user = request.user + if not is_moderator(user): + raise Http404("You are not allowed to see this page.") + else: + if os.path.exists('Experiments.zip'): + os.remove('Experiments.zip') + + with zipfile.ZipFile('Experiments.zip','w',zipfile.ZIP_DEFLATED) as zipf: + path = settings.BASE_DIR + '/experiments/' + zipdir(path,zipf) + + with open('Experiments.zip','rb') as stream: + response = HttpResponse(stream, + content_type='application/force-download') + response['Content-Disposition'] = 'attachment; filename="{0}"'\ + .format('Experiments.zip') + return response + +@login_required +def all_bookings(request): + user = request.user + context = {} + if not is_moderator(user): + raise Http404("You are not allowed to see this page.") + else: + all_bookings = Slot.objects.all().order_by("-start_time") + paginator = Paginator(all_bookings, 20) + page = request.GET.get('page') + try: + slots = paginator.page(page) + except PageNotAnInteger: + slots = paginator.page(1) + except EmptyPage: + slots = paginator.page(paginator.num_pages) + context["slots"] = slots + return render(request,'dashboard/all_bookings.html', context) + + + +@login_required +def all_boards(request): + user = request.user + if not is_moderator(user): + raise Http404("You are not allowed to see this page.") + else: + return render(request,'dashboard/all_boards.html') + + +@login_required +def all_images(request): + user = request.user + if not is_moderator(user): + raise Http404("You are not allowed to see this page.") + else: + return render(request,'dashboard/all_images.html') + +@login_required +def test_boards(request): + user = request.user + now = timezone.now() + context = {} + if not is_moderator(user): + raise Http404("You are not allowed to see this page.") + else: + boards = Board.objects.filter(online=True) + slot_history = Slot.objects.all().order_by("-start_time") + context["boards"] = boards + context["slot_history"] = slot_history[0] + context["now"] = now + return render(request,'dashboard/test_boards.html',context) + +@login_required +def update_mid(request): + user = request.user + if not is_moderator(user): + raise Http404("You are not allowed to see this page.") + else: + return render(request,'dashboard/update_mid.html') + +@login_required +def fetch_logs(request): + user = request.user + context = {} + now = datetime.now() + if not is_moderator(user): + raise Http404("You are not allowed to see this page.") + else: + if request.method == 'POST': + form = FilterLogsForm(request.POST) + if form.is_valid(): + start_date = form.data["start_time"] + end_date = form.data["end_time"] + if start_date and end_date: + ys,ms,ds = [int(x) for x in start_date.split('-')] + ye,me,de =[int(x) for x in end_date.split('-')] + slot = Slot.objects.filter( + start_time__date__gte=date(ys,ms,ds), + end_time__date__lte=date(ye,me,de) + ) + experiment = Experiment.objects.filter(slot__in=slot) + context["experiments"] = experiment + else: + form=FilterLogsForm() + context['form']=form + return render(request,'dashboard/fetch_logs.html',context) + +def download_file(request, experiment_id): + experiment = Experiment.objects.get(id=experiment_id) + response = HttpResponse(content_type='application/text') + response['Content-Disposition'] = 'attachment; filename={0}'.format( + experiment.log + ) + response.write(open("{0}/{1}".format(settings.MEDIA_ROOT, + experiment.log) + ).read()) + return response + +@login_required +def turn_on_all_boards(request): + user = request.user + if not is_moderator(user): + raise Http404("You are not allowed to see this page.") + else: + return HttpResponseRedirect(reverse('moderator_dashboard')) + +@login_required +def turn_off_all_boards(request): + user = request.user + if not is_moderator(user): + raise Http404("You are not allowed to see this page.") + else: + return HttpResponseRedirect(reverse('moderator_dashboard')) + +@login_required +def book_all_suser_slots(request): + user = request.user + if not is_moderator(user): + raise Http404("You are not allowed to see this page.") + else: + return HttpResponseRedirect(reverse('moderator_dashboard')) # @login_required |